Кватернионы: применение для трехмерного вращения
Что такое кватернионы и зачем они нужны?
Представь, что тебе нужно плавно повернуть камеру в игре вокруг персонажа или реализовать вращение космического корабля во всех направлениях. С помощью обычных углов Эйлера (yaw, pitch, roll) это делать неудобно — возникает проблема "шарнирного замка" (gimbal lock), когда ты теряешь одну степень свободы.
Кватернионы — это математические объекты, которые отлично подходят для описания вращений в 3D-пространстве. Они помогают избежать проблем углов Эйлера и позволяют делать плавные интерполяции между вращениями.
🎮 Практический совет: В игровых движках Unity и Unreal Engine кватернионы используются повсеместно для представления вращений объектов.
Строение кватерниона
Кватернион состоит из четырех компонентов: одной действительной части и трех мнимых. Мы будем записывать его так:
q = [w, (x, y, z)]
где:
w— скалярная часть (действительная)(x, y, z)— векторная часть (мнимая)
Для вращений мы используем единичные кватернионы — те, у которых длина равна 1:
w² + x² + y² + z² = 1
Как кватернионы представляют вращение
Кватернион вращения задается через ось и угол поворота вокруг этой оси:
q = [cos(θ/2), sin(θ/2) * (x, y, z)]
где:
θ— угол поворота(x, y, z)— единичный вектор оси вращения
💡 Запомни: Угол делится пополам — это ключевой момент для понимания работы кватернионов!
Базовые операции с кватернионами
Умножение кватернионов
Чтобы комбинировать вращения, мы перемножаем кватернионы. Это не коммутативно (порядок имеет значение!):
q1 * q2 ≠ q2 * q1
Формула умножения выглядит так:
q1 * q2 = [ w1*w2 - dot(v1, v2), w1*v2 + w2*v1 + cross(v1, v2) ]
где v1 = (x1, y1, z1) и v2 = (x2, y2, z2)
Вращение вектора с помощью кватерниона
Чтобы повернуть вектор v с помощью кватерниона q, используем формулу:
v' = q * v * q⁻¹
где q⁻¹ — обратный кватернион (для единичного кватерниона это то же самое, что сопряженный: [w, (-x, -y, -z)])
Практическое применение в геймдеве
1. Плавное вращение камеры
Кватернионы позволяют делать сферическую интерполяцию (SLERP) — плавное переход между двумя вращениями:
q(t) = (q1 * sin((1-t)*θ) + q2 * sin(t*θ)) / sin(θ)
где t изменяется от 0 до 1
2. Вращение вокруг произвольной оси
Допустим, мы хотим повернуть объект вокруг оси Y на 45 градусов:
angle = 45° * π/180 = 0.7854 радиан axis = (0, 1, 0) // ось Y q = [cos(0.7854/2), sin(0.7854/2) * (0, 1, 0)] q = [0.9239, (0, 0.3827, 0)]
3. Комбинирование вращений
Если нужно повернуть объект сначала вокруг оси X, потом вокруг оси Y:
q_x = [cos(α/2), sin(α/2) * (1, 0, 0)] q_y = [cos(β/2), sin(β/2) * (0, 1, 0)] q_result = q_y * q_x // важно: сначала применяется последнее вращение!
Сравнение с другими методами
| Метод | Преимущества | Недостатки |
|---|---|---|
| Углы Эйлера | Простота понимания | Проблема шарнирного замка |
| Матрицы вращения | Нет проблемы замка | Избыточность (9 чисел), сложная интерполяция |
| Кватернионы | Компактность (4 числа), плавная интерполяция | Сложнее для понимания |
Практические задачи
Задача 1: Создание кватерниона вращения
Создай кватернион для вращения на 90 градусов вокруг оси Z.
📝 Решение:
1. Переводим угол в радианы:
90° = π/2 ≈ 1.5708 радиан2. Делим угол пополам:
θ/2 = 0.7854 радиан3. Вычисляем компоненты:
w = cos(0.7854) ≈ 0.7071 z = sin(0.7854) * 1 ≈ 0.7071 x = sin(0.7854) * 0 = 0 y = sin(0.7854) * 0 = 04. Получаем кватернион:
q = [0.7071, (0, 0, 0.7071)]
Задача 2: Вращение вектора
Поверни вектор v = (1, 0, 0) с помощью кватерниона из предыдущей задачи.
📝 Решение:
1. Представляем вектор как кватернион:
p = [0, (1, 0, 0)]2. Находим обратный кватернион:
q⁻¹ = [0.7071, (0, 0, -0.7071)]3. Выполняем вращение:
p' = q * p * q⁻¹4. После вычислений получаем:
p' = [0, (0, 1, 0)]5. Вектор повернулся из
(1, 0, 0)в(0, 1, 0)— что и ожидалось при повороте на 90° вокруг Z!