btQuaternion является фундаментальным типом данных в
физическом движке Bullet, доступном через библиотеку
Ammo.js в JavaScript. Кватернионы позволяют компактно и
эффективно представлять вращения в 3D-пространстве, избегая проблемы
гимбал-локов, присущей углам Эйлера. В Ammo.js кватернионы активно
используются для задания ориентации объектов, расчета поворотов и
интеграции физических симуляций с графическим отображением.
btQuaternionСоздание кватерниона возможно с помощью конструктора:
let q = new Ammo.btQuaternion(x, y, z, w);
Где:
x, y, z — компоненты вектора имагинальной
части;w — скалярная часть кватерниона.По умолчанию кватернион (0, 0, 0, 1) представляет
нулевое вращение.
Углы Эйлера определяют вращение вокруг осей X,
Y, Z. В Ammo.js для преобразования углов
Эйлера в кватернион используется метод setEulerZYX:
let q = new Ammo.btQuaternion();
q.setEulerZYX(yaw, pitch, roll);
Особенности:
yaw, pitch, roll
задаются в радианах.Пример:
let q = new Ammo.btQuaternion();
q.setEulerZYX(Math.PI / 2, 0, Math.PI / 4);
В результате q содержит кватернион, эквивалентный
повороту на 90° вокруг оси Y и 45° вокруг оси Z.
Другой способ задания вращения — через ось вращения
и угол. В Ammo.js используется метод
setRotation с нормализованным вектором оси и углом:
let axis = new Ammo.btVector3(1, 0, 0); // ось X
let angle = Math.PI / 2; // угол 90 градусов
let q = new Ammo.btQuaternion();
q.setRotation(axis, angle);
Важно:
Для последовательного применения вращений к объекту используется
метод op_mul:
let q1 = new Ammo.btQuaternion();
q1.setEulerZYX(0, Math.PI / 2, 0);
let q2 = new Ammo.btQuaternion();
q2.setEulerZYX(0, 0, Math.PI / 4);
let qCombined = new Ammo.btQuaternion();
qCombined.op_mul(q1, q2); // qCombined = q1 * q2
Особенности:
q1 * q2 ≠ q2 * q1).Для передачи ориентации объекта в графический движок часто требуется матрица трансформации:
let transform = new Ammo.btTransform();
transform.setIdentity();
transform.setRotation(q);
setIdentity() сбрасывает трансформацию.setRotation(q) задает вращение объекту через
кватернион.Матрица, сформированная этим способом, может быть использована для OpenGL/WebGL или Three.js.
Чтобы избежать накопления ошибок численного интегрирования, кватернионы необходимо нормализовать после сложных операций:
q.normalize();
Нормализация гарантирует, что длина кватерниона остается равной 1, что критично для корректного физического моделирования.
let q = new Ammo.btQuaternion();
q.setRotation(new Ammo.btVector3(0, 1, 0), Math.PI / 2);
rigidBody.getWorldTransform().setRotation(q);
let q1 = new Ammo.btQuaternion();
q1.setEulerZYX(0, 0, 0);
let q2 = new Ammo.btQuaternion();
q2.setEulerZYX(0, Math.PI / 2, 0);
let qResult = new Ammo.btQuaternion();
Ammo.btQuaternion.slerp(q1, q2, 0.5, qResult); // половинное вращение
let currentRot = rigidBody.getWorldTransform().getRotation();
let deltaRot = new Ammo.btQuaternion();
deltaRot.setEulerZYX(0, Math.PI / 4, 0);
currentRot.op_mul(currentRot, deltaRot);
rigidBody.getWorldTransform().setRotation(currentRot);
btQuaternion в Ammo.js является универсальным
инструментом для работы с 3D-вращениями. Использование методов
setEulerZYX, setRotation, op_mul
и normalize позволяет точно задавать ориентацию,
комбинировать вращения и интегрировать их в физическую симуляцию.
Кватернионы обеспечивают высокую стабильность и компактность вычислений
по сравнению с матрицами и углами Эйлера.