Поворот (вращение) — это одно из фундаментальных линейных преобразований в компьютерной графике‚ робототехнике‚ физическом моделировании и разработке игр. В отличие от перемещения (трансляции) или масштабирования‚ поворот сохраняет расстояния между точками и углы между векторами‚ что делает его ортогональным преобразованием. В этой статье мы подробно разберем основные способы представления поворотов‚ их математическую природу‚ преимущества и недостатки‚ а также нюансы интерполяции и композиции вращений.
Матрица поворота: классический подход
Матрица поворота (Rotation Matrix) — это квадратная ортогональная матрица (обычно 3×3 для 3D или 4×4 в однородных координатах)‚ детерминант которой равен +1. Она используется для линейного преобразования векторов в пространстве с сохранением длины и углов.
Структура матрицы
В трехмерном пространстве матрица поворота состоит из трех ортонормированных векторов-столбцов (или строк‚ в зависимости от соглашения — column-major vs row-major)‚ которые задают новые оси координат после поворота:
- Forward (Dir), вектор направления «вперед» (обычно ось Z).
- Up, вектор направления «вверх» (обычно ось Y).
- Right (Side) — вектор направления «вправо» (обычно ось X)‚ который можно получить как векторное произведение
Right = Dir × Up.
В примере с ориентацией головы персонажа: вектор side будет смотреть в направлении одного из ушей. Матрица поворота, это и есть координаты этих трех векторов после преобразования.
Свойства и операции
- Ортогональность:
RT = R-1. Обратная матрица равна транспонированной‚ что упрощает вычисления «обратного» поворота. - Композиция: Последовательное применение поворотов соответствует умножению матриц:
Rtotal = R2 * R1(порядок важен!). - Преобразование векторов:
v' = R * v.
Недостатки матриц
- Избыточность: 9 (или 16) чисел для хранения 3 степеней свободы.
- Накопление ошибок: При множественных умножениях матрица теряет ортогональность (требуется реортонормирование / Gram-Schmidt).
- Сложность интерполяции: Линейная интерполяция компонентов матрицы (LERP) не дает корректного вращения — объект будет сжиматься и искажаться.
Углы Эйлера: интуитивный‚ но опасный способ
Углы Эйлера представляют поворот как последовательность трех вращений вокруг осей координат (например‚ порядок ZYX или XYZ: Yaw — курс‚ Pitch — тангаж‚ Roll — крен).
Проблема «Gimbal Lock» (Потеря степени свободы)
Это главная проблема углов Эйлера. Когда вторая ось поворота (обычно Pitch) выравнивается с первой или третьей (например‚ смотрим строго вверх/вниз)‚ две оси вращения совпадают. Система теряет одну степень свободы: невозможно отличить вращение вокруг одной оси от вращения вокруг другой.
Порядок умножения
Результат критически зависит от порядка применения вращений (интринсик vs экстринсик). В Unity‚ например‚ метод Quaternion.Euler принимает Vector3 (x‚ y‚ z) и внутренне преобразует его в кватернион‚ используя определенный порядок (обычно Z‚ X‚ Y для локальных осей).
Кватернионы: золотой стандарт 3D-вращений
Кватернион (Quaternion) — это гиперкомплексное число вида q = w + xi + yj + zk‚ где w — скалярная часть‚ а (x‚ y‚ z) — векторная часть. Для представления поворотов используются единичные кватернионы (|q| = 1).
Геометрическая интерпретация
Кватернион кодирует поворот вокруг единичного вектора-оси u на угол θ:
w = cos(θ/2)(x‚ y‚ z) = u * sin(θ/2)
Важно: Величина угла поворота не зависит от системы координат (скалярная инвариантность)‚ а ось поворота преобразуется как обычный вектор (контравариантно).
Преимущества кватернионов
- Компактность: 4 числа вместо 9/16.
- Отсутствие Gimbal Lock: Представление непрерывно на всей сфере вращений.
- Эффективная композиция: Умножение кватернионов (
qtotal = q2 * q1) быстрее умножения матриц и соответствует последовательному применению вращений (сначалаq1‚ потомq2в глобальных координатах). - Простая нормализация: Легко поддерживать единичную длину.
Вращение вектора кватернионом
Чтобы повернуть вектор v с помощью кватерниона q‚ используется формула «сэндвича» (сопряжение):
v' = q * v * q-1 = q * v * q
где v рассматривается как кватернион с нулевой скалярной частью (0‚ v)‚ а q — сопряженный кватернион. В библиотеках вроде GLM это выглядит как: vec3 rotated = orientation * unrotated; (перегруженный оператор).
Контравариантные кватернионы
Иногда используют соглашение‚ при котором поворот объекта в одну сторону соответствует повороту кватерниона в другую (аналогично тому‚ как базис координат преобразуется противоположно векторам). Это важно учитывать при интеграции разных библиотек или физических движков.
Интерполяция вращений: SLERP и SQUAD
Главная причина доминирования кватернионов в анимации — возможность плавной интерполяции.
SLERP (Spherical Linear Interpolation)
Интерполирует по кратчайшей дуге на гиперсфере единичных кватернионов.
Slerp(q0‚ q1‚ t) = (sin((1-t)Ω) / sin(Ω)) q0 + (sin(tΩ) / sin(Ω)) q1
- Обеспечивает постоянную угловую скорость.
- Путь минимального вращения (Shortest Path). Критически важно: перед интерполяцией нужно проверить
dot(q0‚ q1) > 0. Если скалярное произведение отрицательно‚ один кватернион нужно инвертировать (q = -q)‚ иначе объект пойдет «длинным путем» (перевернется на 360° вместо 0°).
SQUAD (Spherical Quadrangle / Spline)
Для плавной интерполяции по последовательности ключевых кадров (keyframes) используется SQUAD — сферический аналог кубического сплайна. Он строит промежуточные контрольные кватернионы для обеспечения непрерывности второй производной (углового ускорения).
Как отмечено в источниках (GameDev.ru)‚ при интерполяции по нескольким ключевым кадрам пути поворота могут оказаться «закрученными» — это нормально‚ алгоритм ищет путь минимального вращения между соседними ориентациями в 4D-пространстве.
Преобразование между представлениями
В реальных движках (Unity‚ Unreal‚ кастомные) постоянно приходится конвертировать форматы.
| Из / В | Матрица 3×3 | Кватернион | Углы Эйлера |
|---|---|---|---|
| Матрица 3×3 | — | Извлечение через след матрицы и недиагональные элементы (устойчивый алгоритм). | Сложно‚ неоднозначно (Gimbal Lock)‚ зависит от порядка осей. |
| Кватернион | Формула: R = [ 1-2(y²+z²) -(xy-wz) -(xz+wy) ... ]. Быстро. | — | Через atan2/asin компонентов матрицы‚ полученной из кватерниона. |
| Углы Эйлера | Произведение 3 матриц поворота по осям. | Произведение 3 кватернионов по осям. | — |
Практическая шпаргалка (Best Practices)
- Хранение: Храните ориентацию в кватернионах.
- Рендеринг/Физика: Конвертируйте в матрицы 4×4 (Model Matrix) непосредственно перед отправкой в шейдер или физический движок.
- UI/Редактор: Показывайте пользователю Углы Эйлера (в градусах)‚ так как они интуитивны.
- Ввод (Input): Накопите углы Эйлера от мыши/джойстика → сконвертируйте в кватернион дельты → умножьте на текущую ориентацию.
- Look At: Строится матрица из векторов
Dir‚ Up‚ Right→ конвертируется в кватернион. - Интерполяция: Всегда используйте Slerp (или Nlerp для малых углов/оптимизации) для кватернионов. Никогда не интерполируйте матрицы или углы Эйлера линейно.
Трансформации при повороте — это баланс между математической строгостью и вычислительной эффективностью. Матрицы идеальны для финального преобразования вершин на GPU. Углы Эйлера удобны для человеческого интерфейса и простых случаев (турели‚ FPS-камеры с ограничением по Pitch). Кватернионы являются незаменимым стандартом для внутреннего представления состояния‚ физики‚ скелетной анимации и плавной интерполяции (SLERP/SQUAD). Понимание того‚ как переходить от одного представления к другому и почему q и -q описывают один и тот же поворот‚ — ключевой навык любого графического программиста или инженера по робототехнике.