Библиотека Cannon.js предоставляет инструменты для физического моделирования в браузере с использованием JavaScript. Одним из ключевых аспектов работы с физикой является правильное использование матриц преобразований для описания положения, ориентации и движения объектов в пространстве.
Для описания позиции тела в Cannon.js используется объект
Vec3. Он представляет собой трёхмерный вектор и позволяет
хранить координаты по осям x, y, z. Пример создания
вектора позиции:
const position = new CANNON.Vec3(0, 5, 0);
Для ориентации тел в пространстве применяются
кватернионы, представленные объектом
Quaternion. Кватернионы удобны для поворотов, так как
избегают проблемы “углов Эйлера” (gimbal lock). Создание
кватерниона:
const quaternion = new CANNON.Quaternion();
quaternion.setFromEuler(Math.PI / 2, 0, 0, "XYZ");
Метод setFromEuler принимает углы Эйлера по осям и
последовательность вращений.
Объект Body в Cannon.js представляет физическое тело.
При создании тела указываются масса, форма (Shape), позиция
и ориентация:
const body = new CANNON.Body({
mass: 1,
position: new CANNON.Vec3(0, 10, 0),
shape: new CANNON.Box(new CANNON.Vec3(1, 1, 1))
});
body.quaternion.setFromEuler(0, Math.PI / 4, 0);
Ключевые свойства тела:
position — трёхмерный вектор положения.quaternion — кватернион, определяющий ориентацию.velocity — вектор линейной скорости.angularVelocity — вектор угловой скорости.Хотя Cannon.js не предоставляет явной реализации матриц 4x4, матрицы преобразований вычисляются на основе позиции и кватерниона. Матрица трансформации тела используется для преобразования локальных координат в мировые и обратно.
Пример вычисления мировой позиции точки, заданной в локальных координатах тела:
const localPoint = new CANNON.Vec3(1, 0, 0);
const worldPoint = new CANNON.Vec3();
body.quaternion.vmult(localPoint, worldPoint); // поворот
worldPoint.vadd(body.position, worldPoint); // смещение
Функция vmult умножает вектор на кватернион, выполняя
вращение, а vadd прибавляет смещение тела.
Для визуализации или интеграции с рендерером (Three.js, Babylon.js) часто требуется матрица 4x4. Она формируется так:
Пример генерации матрицы преобразования:
function getTransformMatrix(body) {
const q = body.quaternion;
const p = body.position;
const matrix = [
1 - 2*q.y*q.y - 2*q.z*q.z, 2*q.x*q.y - 2*q.z*q.w, 2*q.x*q.z + 2*q.y*q.w, p.x,
2*q.x*q.y + 2*q.z*q.w, 1 - 2*q.x*q.x - 2*q.z*q.z, 2*q.y*q.z - 2*q.x*q.w, p.y,
2*q.x*q.z - 2*q.y*q.w, 2*q.y*q.z + 2*q.x*q.w, 1 - 2*q.x*q.x - 2*q.y*q.y, p.z,
0, 0, 0, 1
];
return matrix;
}
Эта матрица может быть использована для интеграции с графическим движком или для дальнейших вычислений физики, требующих преобразований.
В Cannon.js часто необходимо преобразовать точку из локальной системы координат тела в мировую и обратно:
Пример обратного преобразования:
const worldPoint = new CANNON.Vec3(5, 10, 0);
const localPoint = new CANNON.Vec3();
worldPoint.vsub(body.position, localPoint); // смещение относительно тела
body.quaternion.conjugate().vmult(localPoint, localPoint); // вращение в обратную сторону
Использование конъюгата кватерниона выполняет обратное вращение.
Cannon.js позволяет обновлять позиции и ориентации тела каждый кадр. После применения сил или импульсов:
body.applyImpulse(new CANNON.Vec3(0, 10, 0), body.position);
world.step(1/60); // шаг симуляции
После world.step свойства position и
quaternion тела обновляются автоматически, что отражает
новые матрицы преобразований для всех точек объекта.
Каждое тело в Cannon.js имеет:
Vec3) — смещение в мировом
пространстве.Quaternion) — поворот
тела.Vec3) — координаты в
локальной системе тела.Эта структура обеспечивает точное моделирование движения и взаимодействия тел в трёхмерном пространстве. Правильное использование кватернионов и матриц позволяет эффективно управлять физикой без ошибок, связанных с углами Эйлера и преобразованиями координат.