Класс pc.Quat: кватернионы, интерполяция, euler-углы

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

Что такое кватернионы?

Кватернионы — это обобщение комплексных чисел в трехмерном пространстве. Они состоят из четырех компонентов: одного действительного и трех мнимых чисел. Они могут быть использованы для представления вращений без ряда проблем, присущих другим методам, таких как гимбал-лок (гибель степени свободы вращения при использовании Эйлеровых углов) или неэффективность матриц преобразования.

Кватернионы имеют следующий вид: [ q = w + xi + yj + zk] где (w) — действительная часть, а (x), (y), (z) — мнимые компоненты.

Для использования кватернионов в PlayCanvas используется класс pc.Quat. Он позволяет выполнять такие операции, как создание кватернионов, их преобразование, интерполяцию и конвертацию в другие представления, такие как Эйлеровы углы.

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

Создание кватерниона

Для создания нового кватерниона в PlayCanvas используется конструктор класса pc.Quat. Он позволяет инициализировать кватернион разными способами:

  1. Единичный кватернион (без вращения):

    var quat = new pc.Quat();
  2. Кватернион, описывающий вращение на заданный угол вокруг оси:

    var axis = new pc.Vec3(1, 0, 0); // Ось вращения
    var angle = Math.PI / 2; // Угол вращения (в радианах)
    var quat = new pc.Quat().setFromAxisAngle(axis, angle);
  3. Кватернион, представляющий собой вращение, заданное Эйлеровыми углами:

    var eulerAngles = new pc.Vec3(Math.PI / 2, 0, 0); // Эйлеровы углы
    var quat = new pc.Quat().setFromEulerAngles(eulerAngles.x, eulerAngles.y, eulerAngles.z);
  4. Кватернион из четырех чисел:

    var quat = new pc.Quat(w, x, y, z); // w, x, y, z — компоненты кватерниона

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

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

  1. Умножение кватернионов: Умножение двух кватернионов выполняет комбинированное вращение. Это важно при создании сложных вращений, состоящих из нескольких этапов.

    var quat1 = new pc.Quat().setFromAxisAngle(axis1, angle1);
    var quat2 = new pc.Quat().setFromAxisAngle(axis2, angle2);
    var result = quat1.mul(quat2);
  2. Инвертирование кватерниона: Инвертированный кватернион представляет собой вращение, которое отменяет действие исходного. Это полезно для отмены вращения или для комбинирования вращений с обратными направлениями.

    var quat = new pc.Quat().setFromAxisAngle(axis, angle);
    var inverted = quat.inverse();
  3. Скалярное произведение: Скалярное произведение двух кватернионов вычисляет степень их схожести.

    var dot = quat1.dot(quat2);
  4. Нормализация кватерниона: Для корректной работы с кватернионами важно поддерживать их нормализацию. Это обеспечивает единичную длину кватерниона, что предотвращает ошибки в вычислениях.

    quat.normalize();

Интерполяция кватернионов

Одной из важнейших задач при работе с кватернионами является интерполяция — вычисление промежуточного кватерниона между двумя существующими кватернионами. В PlayCanvas для этого используется несколько подходов.

Slerp (Spherical Linear Interpolation)

Самым популярным методом интерполяции кватернионов является Slerp (сферическая линейная интерполяция). Этот метод позволяет плавно интерполировать между двумя кватернионами, обеспечивая корректную интерполяцию углов.

var quat1 = new pc.Quat().setFromAxisAngle(axis1, angle1);
var quat2 = new pc.Quat().setFromAxisAngle(axis2, angle2);
var t = 0.5; // Параметр интерполяции (0 - начало, 1 - конец)
var result = pc.Quat.slerp(quat1, quat2, t);

Этот метод возвращает кватернион, который лежит на сфере между quat1 и quat2 в зависимости от значения параметра t. Значение t = 0 соответствует первому кватерниону, а t = 1 — второму.

Lerp (Linear Interpolation)

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

var quat1 = new pc.Quat().setFromAxisAngle(axis1, angle1);
var quat2 = new pc.Quat().setFromAxisAngle(axis2, angle2);
var t = 0.5; // Параметр интерполяции
var result = pc.Quat.lerp(quat1, quat2, t);

Преобразование между кватернионами и Эйлеровыми углами

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

Из кватерниона в Эйлеровы углы

Чтобы получить Эйлеровы углы из кватерниона, используется метод getEulerAngles. Он возвращает вектор с тремя компонентами, которые соответствуют углам поворота вокруг осей X, Y и Z.

var quat = new pc.Quat().setFromAxisAngle(axis, angle);
var euler = quat.getEulerAngles();

Из Эйлеровых углов в кватернион

Для преобразования из Эйлеровых углов в кватернион используется метод setFromEulerAngles:

var eulerAngles = new pc.Vec3(Math.PI / 2, 0, 0);
var quat = new pc.Quat().setFromEulerAngles(eulerAngles.x, eulerAngles.y, eulerAngles.z);

Преимущества кватернионов

  • Отсутствие гимбал-лока. В отличие от Эйлеровых углов, кватернионы не подвержены гимбал-локу, что делает их предпочтительными для работы с 3D-графикой и анимациями.
  • Эффективность. Кватернионы требуют меньшего объема памяти и вычислительных ресурсов по сравнению с матрицами вращения.
  • Интерполяция. Кватернионы обеспечивают более плавную и точную интерполяцию вращений с помощью Slerp.

Заключение

Работа с кватернионами в PlayCanvas предоставляет разработчикам мощные инструменты для манипуляций с вращениями в 3D-пространстве. Используя класс pc.Quat, можно легко создавать, комбинировать и интерполировать вращения, избегая проблем с гимбал-локом и достигая высокой производительности.