Матрицы преобразований

Библиотека 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. Она формируется так:

  1. Поворот по кватерниону.
  2. Добавление смещения позиции.
  3. Применение масштабирования (если необходимо).

Пример генерации матрицы преобразования:

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 имеет:

  1. Позицию (Vec3) — смещение в мировом пространстве.
  2. Ориентацию (Quaternion) — поворот тела.
  3. Локальные точки (Vec3) — координаты в локальной системе тела.
  4. Мировые точки — результат применения кватерниона и смещения.
  5. Неявную матрицу 4x4 — используется для рендеринга и интеграции с другими движками.

Эта структура обеспечивает точное моделирование движения и взаимодействия тел в трёхмерном пространстве. Правильное использование кватернионов и матриц позволяет эффективно управлять физикой без ошибок, связанных с углами Эйлера и преобразованиями координат.