lengthl + ratio * length2 == constant
Например, если коэффициент ratio равен 2, то lenghtl будет меняться пропорционально удвоенной Ienght2. Также сила на отрезке присоединенном к bodyl будет равна
половине сдерживающей силы на отрезке
присоединенном к body2. Когда одна сторона полностью удлинилась, могут возникнуть проблемы. Отрезок на другой стороне получится нулевым. В этом случае уравнение ограничения будет иметь единственное решение (причем плохое). Поэтому талевое соединение ограничивает максимальную длину, которую любой из отрезков может достичь. Хотя, может потребоваться контролировать максимальную длину по геймплейным причинам. Задание максимально-возможной длины для отрезков повышает стабильность и дает больше контроля над ситуацией.
Вот пример определения талевого соединения:
b2Vec2 anchorl = myBodyl->GetWorldCenter(); b2Vec2 anchor2 = myBody2->GetWorldCenter(); b2Vec2 groundAnchorl(pl.x, pi.у + 10. Of); b2Vec2 groundAnchor2(p2.x, p2.у + 12.Of); float32 ratio = l.Of; b2PulleyJointDef jointDef;
jointDef.Initialize(myBodyl, myBody2, groundAnchorl, groundAnchor2, anchorl, anchor2, ratio); jointDef.maxLengthl = 18.Of; jointDef.maxLength2 = 20.Of;
7.2.5. Передаточноесоединение
При создании сложных, хитроумных механизмов не обойтись без использования зубчатых соединений. В принципе, можно создать шестерни, объединяя несколько фигур для моделирования зубьев, но это очень не эффективно и довольно утомительно. Также придется настроить шестерни, чтобы зубья находились в зацеплении. Поэтому Box2D имеет более простой способ: передаточное соединение .
joint!
badyl
Для передаточного соединения необходимо чтобы два тела имели болтовое или призматическое соединение с статичным телом (или с землёй).
Подобно коэффициенту ratio в талевом соединении, передаточное соединение имеет коэффициент передачи. Однако в данном случае коэффициент передачи может быть отрицательным. Также следует помнить, что, если одно соединение болтовое (вращение), а другое призматическое (перемещение), то коэффициент передачи будет иметь размерность длины или единицы делённой на размерность длины.
coordinatel + ratio * coordinate2 == constant
Пример использования передаточного соединения:
b2GearJointDef jointDef; jointDef.bodyl = myBodyl; jointDef.body2 = myBody2; jointDef.jointl = myRevoluteJoint; jointDef.joint2 = myPrismaticJoint; jointDef.ratio = 2.Of * b2_pi / myLength;
Важно помнить, что передаточное соединение зависит от двух других соединений. Что может привести к опасной ситуации. Что произойдет, если эти соединения будут удалены?
Внимание
Необходимо сначала удалять передаточное соединение перед удалением болтовых/призматических. Иначе возникнет исключительная ситуация из-за неправильных указателей в передаточном соединении. Также необходимо удалять передаточное соединение перед удалением соединенных тел.
7.2.6. Соединениескурсороммыши
Соединение с курсором мыши используется в тестовом стенде для перетаскивания объектов при помощи мыши. Исходный код находится в b2MouseJoint.h.
7.3. Фабрика соединений
Соединения создаются и уничтожаются при помощи методов-фабрик мира. Поэтому следует вспомнить старое замечание:
Внимание
Не пытайтесь создавать тела или соединения на стеке или на хипе, используя new или maiioc. Необходимо создавать и удалять тела и соединения только с помощью методов создания и уничтожения тел и соединений класса b2Worid.
Вот пример работы с болтовым (revolute) соединением, от его создания и до уничтожения:
b2RevoluteJointDef jointDef; jointDef.bodyl = myBodyl; jointDef.body2 = myBody2;
jointDef.anchorPoint = myBodyl->GetCenterPosition(); b2RevoluteJoint* joint = myWorld->CreateJoint(&jointDef) ; ... сделать что-нибудь ... myWorld->DestroyJoint(joint); joint = NULL;
Считается хорошим тоном обнулять указатели после их уничтожения. Это станет
причиной гарантированного падения программы в случае использования указателя после
его уничтожения.
Время жизни соединения не всегда определяется просто. Запомните это
предупреждение:
Внимание
После уничтожения тела, сразу уничтожаются соединения прикрепленные к нему.
Такая предосторожность не является строгим правилом. Можно так организовать
свой игровой движок, что соединения всегда будут уничтожаться до уничтожения присоединенных к ним тел. В этом случае вам не нужно будет реализовывать класс "обработчик" (listener class). Более точную информацию смотрите в Разделе 9.2, "Неявное уничтожение".
7.4. Использованиесоединений
Часто, соединения создаются и не трогаются до их уничтожения. Однако в соединениях хранится много полезной информации, которую можно использовать для создания более разнообразного моделирования.
Во-первых, можно получить тела, которые соединены, якорную точку и пользовательские данные.
b2Body* GetBodyl(); b2Body* GetBody2(); b2Vec2 GetAnchorl(); b2Vec2 GetAnchor2(); void* GetUserData();
Все соединения имеют силу и вращающий момент реакции. Это те силы, которые применяются ко второму телу в якорной точке. Эти силы можно использовать для разрыва соединения или для переключения другого игрового события. Эти функции могут выполнять различные вычисления, поэтому их не стоит вызывать слишком часто.