Найти в Дзене
Степан Гончаров

Углы Эйлера и Кватернионы

Господа, данная публикация будет посвящена вращению объектов и представлению этого вращения в 3D-пространстве. Тема не самая сложная, просто есть нюансы, которые могут многое затруднять. Объяснять я буду на примере GLM C++. Буквально неделю назад эта статья стала бы для меня спасением и мне не пришлось бы разбираться в теме настолько, чтоб самому ее писать, но вот она есть, значит что внятного материала я не обнаружил. Начну я с углов Эйлера, которые чаще всего используются и от них никуда не деться, ведь в кватернионах они тоже есть.
Данных углов всего 3: yaw, pitch и roll. Традиционно все показывают это на примере самолета: Я такие названия не люблю, так что буду называть углы названием оси, вокруг которой происходит вращение XYZ. Отталкиваться будем от того, что каждый из этих углов применяется в матрицах вращения, и их порядок категорически принципиален. Есть ряд традиционных порядков, но я использовал последовательность YXZ, потому что нашел ее раньше остальных. Допустим, что е
Оглавление

Господа, данная публикация будет посвящена вращению объектов и представлению этого вращения в 3D-пространстве. Тема не самая сложная, просто есть нюансы, которые могут многое затруднять. Объяснять я буду на примере GLM C++.

Буквально неделю назад эта статья стала бы для меня спасением и мне не пришлось бы разбираться в теме настолько, чтоб самому ее писать, но вот она есть, значит что внятного материала я не обнаружил.

Углы Эйлера

Начну я с углов Эйлера, которые чаще всего используются и от них никуда не деться, ведь в кватернионах они тоже есть.
Данных углов всего 3: yaw, pitch и roll. Традиционно все показывают это на примере самолета:

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

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

пример поворота на X:-30 Z: -90 но с разными порядками вполнения действий
пример поворота на X:-30 Z: -90 но с разными порядками вполнения действий

Есть ряд традиционных порядков, но я использовал последовательность YXZ, потому что нашел ее раньше остальных.

Пример:

Допустим, что есть некоторый объект, имеющих 2 локальных оси, взаимоперпендикулярных друг к другу:

-3

А теперь повернем их на некоторые углы, в выбранном нами порядке YXZ

-4

И на этом вроде всё, казалось бы, вектора повернуты, но есть ньюанс.
Допустим у нас есть некоторые переменные, которые будут хранить в себе углы объекта, на нашем примере это будет

-5

Допустим что теперь мы хотим довернуть наш объект еще на 30 градусов по X, и всё, что надо, это создать матрицу вращения по X на нужный угол, а в буфере дописать:
angle_x += 30 * radian;
Но это совсем не так просто. Дело в том, что вместе с углом X повернулись и Y, и Z, а углы на деле равны X: 52.1076 Y: 94.4217 Z: 74.8284 градусов, но в буфере по прежнему сохранены старые данные и дальнейшее их использование повлечет за собой кучу ошибок.

Что же делать?

Вот тут я и засел, много информации перебрал и наконец наткнулся на ряд формул:

-6

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

Стоит упомянут про некоторое математическое явление, которое называют Gimbal Lock (шарнирный замок), называется он так потому что для понимания сути явления можно представить 3 кольца, скрепленных шарнирами

С помощью такой установки можно представить примерно любой угол, но есть подвох.

-7

Мы повернули ось X на 90 градусов в глобальной системе, теперь, как видно, вращение по Y(всё также в глобальной системе) невозможно. Шарниры мешают повороту вправо и влево. Также происходит и при перемножении матриц. Это лютая недоработка, которую Эйлер потом пофиксил "Фильтром Эйлера", но в эту тему я лезть не стал.

Кватернионы

Кватернионы придумал Гамельтон почти 200 лет назад, они тесно связаны с комплексными числами, поэтому я не стал насиловать ими свою психику, если интересно почитайте о них подробнее тут:

Кватернионы и вращение пространства — Википедия

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

-8

rotate_quat тут итоговый кватернион поворота, который также перемножается с вектором для вращения. Также стоит отметить, что тут использовался порядок ZYX.

И хотя с виду разница не велика, у них в GLM есть чудесное дополнение в виде
glm::eulerAngles(), которая возвращает вектор углов эйлера)

Казалось бы, бежишь от них, а они повсюду, но как убеждают сторонние источники, кватернионы gimbal lock-ом не болеют.
Всё что надо сделать теперь, чтоб получить наши уголки, это:

-9

На этом всё.