Quaternion для вращений

В трёхмерной графике вращения объектов представляют одну из наиболее сложных задач из-за ограничений эйлеровых углов: возникновения эффекта блокировки кардана (gimbal lock), нестабильности интерполяции и неоднозначности представления ориентации. В CesiumJS для устойчивого описания вращений используется математическая конструкция кватернионов, реализованная в классе Cesium.Quaternion.

Кватернион в контексте CesiumJS представляет четырёхкомпонентный вектор:

  • x
  • y
  • z
  • w

Он описывает вращение в трёхмерном пространстве без потери устойчивости при композиции и интерполяции.


Представление вращения через Quaternion

Любое вращение может быть представлено как поворот вокруг единичной оси на заданный угол. В кватернионной форме это выражается через:

  • вектор оси вращения
  • угол вращения в радианах

CesiumJS использует нормализованную форму кватерниона, где длина равна 1, что обеспечивает корректную композицию вращений.

Базовое создание осуществляется через Cesium.Quaternion.fromAxisAngle:

const axis = Cesium.Cartesian3.normalize(
    new Cesium.Cartesian3(0, 0, 1),
    new Cesium.Cartesian3()
);

const angle = Cesium.Math.toRadians(45);

const q = Cesium.Quaternion.fromAxisAngle(axis, angle, new Cesium.Quaternion());

Внутренне происходит преобразование ось–угол в четырёхмерную форму с использованием тригонометрических функций половинного угла.


Кватернионы и ориентация объектов

В CesiumJS кватернионы часто используются для задания ориентации сущностей (Entity.orientation) или моделей (ModelMatrix).

Типичный сценарий включает установку ориентации объекта в сцене:

const position = Cesium.Cartesian3.fromDegrees(30, 50, 1000);

const heading = Cesium.Math.toRadians(90);
const pitch = Cesium.Math.toRadians(0);
const roll = Cesium.Math.toRadians(0);

const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);

const orientation = Cesium.Transforms.headingPitchRollQuaternion(
    position,
    hpr,
    new Cesium.Quaternion()
);

viewer.entities.add({
    position: position,
    orientation: orientation,
    model: {
        uri: "model.glb"
    }
});

Здесь HeadingPitchRoll преобразуется во внутренний кватернион, учитывающий локальную систему координат ENU (East-North-Up).


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

CesiumJS предоставляет набор операций, обеспечивающих композицию и модификацию вращений.

Умножение кватернионов

Композиция вращений выполняется через умножение:

const result = Cesium.Quaternion.multiply(q1, q2, new Cesium.Quaternion());

Порядок множителей критически важен, так как операция некоммутативна:

  • q1 * q2 ≠ q2 * q1

Результат соответствует последовательному применению вращений.


Нормализация

После операций композиции может возникать численная погрешность. Для восстановления корректной формы используется нормализация:

Cesium.Quaternion.normalize(q, q);

Нормализованный кватернион гарантирует сохранение единичной длины и стабильность дальнейших вычислений.


Обратный кватернион

Обратное вращение определяется через сопряжение (conjugate) для единичных кватернионов:

const inverse = Cesium.Quaternion.conjugate(q, new Cesium.Quaternion());

Это соответствует вращению в противоположную сторону без изменения оси.


Интерполяция вращений (SLERP)

Линейная интерполяция углов приводит к искажениям скорости вращения. В CesiumJS применяется сферическая интерполяция (Slerp — Spherical Linear Interpolation), обеспечивающая равномерное движение по гиперсфере единичных кватернионов.

const result = Cesium.Quaternion.slerp(
    qStart,
    qEnd,
    0.5,
    new Cesium.Quaternion()
);

Параметр интерполяции:

  • 0.0 — начальная ориентация
  • 1.0 — конечная ориентация

Slerp обеспечивает постоянную угловую скорость и отсутствие артефактов вращения.


Связь кватернионов и матриц вращения

Кватернионы тесно связаны с матрицами вращения Cesium.Matrix3 и Cesium.Matrix4.

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

const matrix3 = Cesium.Matrix3.fromQuaternion(q, new Cesium.Matrix3());

И обратное преобразование:

const qFromMatrix = Cesium.Quaternion.fromRotationMatrix(
    matrix3,
    new Cesium.Quaternion()
);

Матрицы удобны для линейных преобразований, но кватернионы обеспечивают более стабильную интерполяцию и композицию вращений.


Локальные системы координат и Quaternion

В CesiumJS вращения часто определяются относительно локальной системы координат:

  • East (восток)
  • North (север)
  • Up (вверх)

Функция Cesium.Transforms.eastNorthUpToFixedFrame строит матрицу преобразования из глобальной системы координат в локальную ENU. Кватернионы могут быть получены из этой матрицы для задания ориентации объектов в локальном пространстве.

const enu = Cesium.Transforms.eastNorthUpToFixedFrame(position);

const orientation = Cesium.Quaternion.fromRotationMatrix(
    Cesium.Matrix3.fromMatrix4(enu, new Cesium.Matrix3()),
    new Cesium.Quaternion()
);

Heading, Pitch, Roll как частный случай Quaternion

Углы Heading-Pitch-Roll представляют последовательные вращения вокруг локальных осей:

  • Heading — вращение вокруг оси Z
  • Pitch — вокруг оси X
  • Roll — вокруг оси Y

CesiumJS преобразует их в кватернион через промежуточные вычисления с учётом порядка вращений, что устраняет неоднозначность, характерную для Эйлеровых углов.


Композиция вращений в сцене

При анимации объектов часто используется последовательное накопление вращений:

const delta = Cesium.Quaternion.fromAxisAngle(axis, angleStep, new Cesium.Quaternion());

Cesium.Quaternion.multiply(current, delta, current);
Cesium.Quaternion.normalize(current, current);

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


Использование в анимациях и таймлайнах

Кватернионы часто применяются в свойствах SampledProperty, где ориентация изменяется во времени:

const property = new Cesium.SampledProperty(Cesium.Quaternion);

property.addSample(time1, q1);
property.addSample(time2, q2);
property.addSample(time3, q3);

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


Численные особенности и стабильность

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

Особое значение имеет сохранение единичной нормы:

  • отклонение нормы приводит к искажению масштаба вращения
  • повторная нормализация восстанавливает корректную геометрию

Применение в моделях и камерных системах

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