В Cannon.js локальные координаты играют ключевую роль при работе с телами и соединениями, особенно когда речь идёт о Constraint (связях) и точках крепления. Локальные координаты позволяют задавать положение точки относительно центра масс тела, а не в глобальной системе сцены, что делает управление сложными конструкциями более предсказуемым и стабильным.
Якорная точка — это точка на теле, к которой
прикрепляется соединение, такое как PointToPointConstraint
или HingeConstraint. Она задаётся в локальных координатах
тела:
const localAnchor = new CANNON.Vec3(1, 0, 0);
Здесь (1, 0, 0) обозначает, что точка находится на 1
единицу вдоль оси X относительно центра масс тела. Использование
локальных координат обеспечивает независимость соединения от позиции и
ориентации тела в мире.
Преимущество локальных координат заключается в том, что при вращении или перемещении тела точка соединения остаётся фиксированной относительно тела, что важно для динамических симуляций.
PointToPointConstraintPointToPointConstraint соединяет две точки на разных
телах. Локальные якорные точки задаются через pivotA и
pivotB. Пример:
const bodyA = new CANNON.Body({ mass: 5 });
const bodyB = new CANNON.Body({ mass: 5 });
const pivotA = new CANNON.Vec3(1, 0, 0); // локальная точка на bodyA
const pivotB = new CANNON.Vec3(0, 1, 0); // локальная точка на bodyB
const constraint = new CANNON.PointToPointConstraint(bodyA, pivotA, bodyB, pivotB, 1e6);
world.addConstraint(constraint);
pivotA и pivotB определяют позиции
соединения относительно центров масс.1e6 задаёт силу ограничения,
определяющую жёсткость соединения.Чтобы вычислить глобальные координаты точки на теле, используется матрица трансформации:
const worldPoint = body.pointToWorldFrame(localAnchor);
Этот метод учитывает положение тела (body.position) и
ориентацию (body.quaternion), что позволяет корректно
интегрировать локальные точки в физический мир.
Обратное преобразование — из мировых координат в локальные:
const localPoint = body.pointToLocalFrame(worldPoint);
Оно необходимо, когда требуется определить положение внешней точки относительно текущего тела.
HingeConstraintДля шарнирного соединения HingeConstraint локальные
точки определяют место установки оси вращения на каждом теле:
const pivotA = new CANNON.Vec3(0, 1, 0);
const pivotB = new CANNON.Vec3(0, -1, 0);
const axis = new CANNON.Vec3(0, 0, 1); // ось вращения
const hinge = new CANNON.HingeConstraint(bodyA, bodyB, {
pivotA: pivotA,
pivotB: pivotB,
axisA: axis,
axisB: axis,
});
world.addConstraint(hinge);
pivotA и pivotB задают точки крепления на
телах.axisA и axisB определяют локальную ось
вращения для каждого тела.Использование локальных координат позволяет сохранить правильное вращение, даже если тела перемещаются или вращаются в пространстве.
При изменении body.quaternion локальная точка остаётся
зафиксированной относительно тела, а её глобальная позиция изменяется
автоматически. Для динамических систем это критично, так как соединения
должны корректно следовать за движением и поворотом тела.
pointToWorldFrame и
pointToLocalFrame для отладки и визуализации
соединений.Для отладки удобно визуализировать локальные якоря:
const sphereGeom = new THREE.SphereGeometry(0.05, 8, 8);
const sphereMat = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const localAnchorVisual = new THREE.Mesh(sphereGeom, sphereMat);
scene.add(localAnchorVisual);
function updateAnchorVisual() {
const worldPos = bodyA.pointToWorldFrame(pivotA);
localAnchorVisual.position.set(worldPos.x, worldPos.y, worldPos.z);
}
Так можно наблюдать, как локальная точка перемещается вместе с телом в мире, сохраняя точку крепления визуально корректной.
Этот подход к работе с якорными точками в локальных координатах обеспечивает стабильные физические соединения и упрощает управление сложными объектами в Cannon.js.