Класс Quat: кватернионы и операции над ними

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

Основы кватернионов

Кватернион — это расширение комплексных чисел, состоящее из четырёх компонентов: (x, y, z, w). В Oimo.js кватернион хранится в виде объекта класса Quat:

let q = new OIMO.Quat();

По умолчанию создаётся единичный кватернион ( (x=0, y=0, z=0, w=1) ), который соответствует отсутствию вращения.

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

  • x — компонент вдоль оси X
  • y — компонент вдоль оси Y
  • z — компонент вдоль оси Z
  • w — скалярная часть, отвечающая за угол вращения

Основные методы класса Quat

set(x, y, z, w)

Задаёт значения кватерниона вручную:

q.set(0, 0, 0, 1);
copy(q2)

Копирует значения из другого кватерниона q2:

let q1 = new OIMO.Quat();
let q2 = new OIMO.Quat();
q2.set(0.5, 0.5, 0.5, 0.5);
q1.copy(q2);
identity()

Сбрасывает кватернион к единичному состоянию:

q.identity(); // q теперь (0,0,0,1)
invert()

Инвертирует кватернион, что соответствует обратному вращению:

q.invert();
normalize()

Приводит кватернион к единичной длине, что необходимо для корректных вычислений вращений:

q.normalize();

Вращение с помощью кватернионов

Кватернионы позволяют описывать вращения без эффекта гимбал-лок, характерного для Эйлеровых углов. В Oimo.js вращение можно задавать через:

  • setAxisAngle(axis, angle) — создаёт кватернион по оси и углу:
let axis = new OIMO.Vec3(0, 1, 0); // ось Y
q.setAxisAngle(axis, Math.PI / 2); // вращение на 90 градусов
  • mul(q2) — умножение кватернионов, что эквивалентно последовательному применению вращений:
let q3 = new OIMO.Quat();
q3.copy(q).mul(q2); // q3 = q * q2
  • slerp(q2, t) — сферическая линейная интерполяция между двумя кватернионами:
q.slerp(q2, 0.5); // полпути между q и q2

Преобразование кватерниона в матрицу

Для применения вращения к объекту необходимо преобразовать кватернион в матрицу 3x3 или 4x4:

let m = new OIMO.Mat33();
q.toMat33(m); // m теперь содержит матрицу вращения

Также можно использовать toMat44() для 4x4 матриц, пригодных для OpenGL/WebGL.

Применение к телам в Oimo.js

Кватернионы тесно связаны с объектами RigidBody. Их ориентация хранится в body.getOrientation(), возвращающей кватернион. Для вращения тела можно использовать:

let bodyQuat = body.getOrientation();
bodyQuat.mul(q); // добавление вращения к текущей ориентации

Операции с векторами

Кватернионы позволяют поворачивать векторы в пространстве без прямого использования матриц:

let v = new OIMO.Vec3(1, 0, 0);
let rotatedV = q.mulVec3(v); // поворот вектора v с помощью q

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

Рекомендации по использованию

  • Всегда нормализовать кватернионы после вычислений, чтобы избежать накопления ошибок.
  • Для плавных анимаций использовать slerp вместо линейной интерполяции компонентов.
  • При комбинировании вращений учитывать порядок умножения: (q_1 * q_2) означает сначала q2, затем q1.

Класс Quat является ядром вращательных вычислений в Oimo.js и обеспечивает стабильность и точность при работе с динамическими телами, камерой и анимациями. Его методы позволяют компактно и эффективно реализовывать любые 3D-вращения без использования громоздких матриц и без риска гimbal-lock.