Кватернионы: Quaternion

Кватернионы представляют собой расширение комплексных чисел в трёхмерное пространство и используются для описания вращений объектов без проблем с углами Эйлера, таких как gimbal lock. В Cannon.js кватернионы реализованы через класс CANNON.Quaternion и являются ключевым инструментом для работы с ориентацией тел в физическом мире.

Структура кватерниона

Кватернион определяется четырьмя компонентами:

q = new CANNON.Quaternion(x, y, z, w);
  • x, y, z — векторная часть.
  • w — скалярная часть.

Кватернион обычно нормализован, чтобы поддерживать корректное вращение. Ненормализованный кватернион может приводить к искажению ориентации при интеграции.

Основные методы класса CANNON.Quaternion

set(x, y, z, w)

Устанавливает компоненты кватерниона напрямую.

let q = new CANNON.Quaternion();
q.set(0, 0, 0, 1); // идентичное вращение

clone() и copy(quaternion)

Позволяют создавать копии кватернионов или копировать значения из одного к другому.

let q1 = new CANNON.Quaternion(0, 0, 0, 1);
let q2 = q1.clone();
let q3 = new CANNON.Quaternion();
q3.copy(q1);

normalize()

Приведение кватерниона к единичной длине. Обязательный шаг после операций сложения или интеграции.

q.normalize();

mult(quaternion)

Умножение кватернионов используется для последовательного применения вращений. Порядок важен: q1.mult(q2) означает, что вращение q2 применяется после q1.

let q1 = new CANNON.Quaternion(0, 0, 0, 1);
let q2 = new CANNON.Quaternion(0.707, 0, 0, 0.707); // 90° вокруг X
q1.mult(q2, q1); // результат записан в q1

setFromAxisAngle(axis, angle)

Создание кватерниона из оси вращения и угла (в радианах). Ось должна быть нормализована.

let axis = new CANNON.Vec3(0, 1, 0);
let angle = Math.PI / 2;
let q = new CANNON.Quaternion();
q.setFromAxisAngle(axis, angle);

toEuler()

Преобразует кватернион в углы Эйлера (yaw, pitch, roll). Используется для взаимодействия с интерфейсами, которые требуют углы.

let euler = q.toEuler();
console.log(euler); // {x: pitch, y: yaw, z: roll}

Вращение тел через кватернионы

В Cannon.js каждый объект типа Body имеет свойство quaternion, которое определяет ориентацию:

let body = new CANNON.Body({ mass: 1 });
body.quaternion.setFromAxisAngle(new CANNON.Vec3(0, 1, 0), Math.PI / 4);

Для анимации можно применять инкрементальные вращения:

let deltaQ = new CANNON.Quaternion();
deltaQ.setFromAxisAngle(new CANNON.Vec3(0, 0, 1), 0.01);
body.quaternion.mult(deltaQ, body.quaternion);
body.quaternion.normalize();

Нормализация после умножения предотвращает накопление ошибок при численной интеграции.

Интерполяция между кватернионами

Интерполяция используется для плавного перехода между ориентациями. В Cannon.js доступен метод slerp:

let q1 = new CANNON.Quaternion();
let q2 = new CANNON.Quaternion();
q2.setFromAxisAngle(new CANNON.Vec3(0, 1, 0), Math.PI / 2);

let qInterpolated = new CANNON.Quaternion();
q1.slerp(q2, 0.5, qInterpolated); // половина пути между q1 и q2

Параметр t принимает значение от 0 до 1. Результат сохраняется в последний аргумент метода.

Применение к вращательным скоростям

Вращательная скорость (angularVelocity) тела выражается через вектор:

body.angularVelocity.set(1, 0, 0); // вращение вокруг X

Для интеграции вращательной скорости в ориентацию используется формула:

let q = body.quaternion;
let w = body.angularVelocity;

let deltaQ = new CANNON.Quaternion(w.x * dt / 2, w.y * dt / 2, w.z * dt / 2, 0);
deltaQ.mult(q, deltaQ);
q.x += deltaQ.x;
q.y += deltaQ.y;
q.z += deltaQ.z;
q.w += deltaQ.w;
q.normalize();

Это позволяет корректно обновлять ориентацию тела при симуляции физики.

Важные особенности работы с кватернионами

  1. Нормализация обязательна после каждой операции, которая изменяет кватернион, иначе ориентация тела будет искажена.
  2. Порядок умножения имеет значение, так как вращения не коммутативны.
  3. Прямое изменение углов Эйлера рекомендуется только для удобства интерфейсов. Внутренние вычисления физики всегда используют кватернионы.
  4. Интеграция вращательной скорости через кватернионы предотвращает проблемы с угловой скоростью и обеспечивает стабильность симуляции.

Практические сценарии

  • Реализация падений и столкновений: кватернионы позволяют точно отслеживать ориентацию при столкновениях.
  • Плавная анимация поворотов: метод slerp обеспечивает естественные переходы между ориентациями.
  • Реалистичная физика вращения: интеграция угловой скорости через кватернионы поддерживает стабильность при больших угловых ускорениях.

Кватернионы являются фундаментальной частью работы с Cannon.js и обеспечивают мощные возможности для управления ориентацией объектов в трёхмерном пространстве, сочетая точность и устойчивость при численной интеграции.