
Для записи трёхмерных поворотов программисты графики используют кватернионы. Однако в кватернионах сложно разобраться, потому что изучают их поверхностно. Мы просто принимаем на веру странные таблицы умножения и другие загадочные определения, и используем их как «чёрные ящики», поворачивающие векторы так, как нам нужно. Почему
Существует способ описания поворотов под названием ротор, который относится к области и комплексных чисел (в 2D), и кватернионов (в 3D), и даже обобщается до любого количества измерений.
Мы можем создавать роторы практически полностью с нуля, вместо того, чтобы определять из ничего кватернионы и пытаться объяснить, как они работают задним числом. Это занимает больше времени, но мне кажется, что это стоит того, потому что их гораздо легче понять!
Кроме того, для визуализации и понимания трёхмерных роторов не нужно использовать четвёртое пространственное измерение.
Было бы здорово, если бы начали вытеснять использование и изучение кватернионов, заменяя их роторами. Заменить их очень просто, а код останется почти таким же. Всё, что можно делать с кватернионами, например, интерполяцию и устранение блокировки осей (Gimbal lock), можно сделать и с роторами. Но понимать мы начинаем гораздо больше.
(В оригинале статьи все графики интерактивны, а за статьёй следует видео. Нажимая на кнопки воспроизведения, можно запустить соответствующий раздел видео. Также можно нажать под видео кнопку перехода, чтобы перейти к соответствующему разделу статьи. Можно развернуть окно, чтобы для видео было больше места, или установить для него постоянный размер.)
1. Плоскости поворотов
1.1. Повороты выполняются на двухмерных плоскостях
В трёхмерном пространстве мы обычно воспринимаем повороты как происходящие вокруг осей, как колесо вращается на оси, но вместо этого корректнее будет представлять плоскость, на которой лежит колесо. Эта плоскость перпендикулярна оси.

Эта старушка крутит колесо в плоскости
Так получается, потому что если мы разделили вектор на две части, одна из которых лежит на плоскости (

Поворот в плоскости
В двухмерном пространстве есть только одна плоскость, в которой возможен поворот (внешней части нет). Поэтому считать, что повороты происходят вокруг третьей оси (перпендикулярной к 2D-плоскости) строго говоря неверно, потому что для выполнения поворотов мы не должны добавлять ещё одно измерение.
Если рассказать двухмерному «плоскоземельщику» (который живёт внутри 2D-плоскости и никогда не выбирался из двухмерного пространства) о перпендикулярной оси поворота, то он бы спросил: «В каком направлении указывает эта ось? Я не могу её представить!»
Примечание
И в более высоких измерениях (4D и выше) невозможно определить один вектор нормали к 2D-плоскости (например, в 4D у 2D-плоскости есть два направления нормалей, в 5D есть три направления нормалей, а вих
)
1.2. Точное направление поворотов
Кроме того, когда мы думаем о повороте вокруг оси, направление поворота не определено, и поэтому его нужно определять по правилу (так называемому «правилу правой руки»).
Однако если считать, что повороты происходят внутри плоскостей, то направление становится понятным: поворот в плоскости
Примечание
Помню, что когда я впервые узнал о трёх матрицах 3D-поворотов вдоль ортогональных плоскостей, то первым делом подумал: какого чёрта матрицаимеет противоположный знак? Так получается из-за правила правой руки, по которому мы должны определять поворот вокруг оси
так, чтобы он выполнялся от
к
, а не от
к
, чтобы сохранять постоянное «праворукое» направление поворота. Когда мы начинаем говорить непосредственно о самой плоскости, это правило становится ненужным.
2. Бивекторы

2.1. Внешнее произведение
Для вычисления оси поворота при повороте одного вектора
Вместо этого мы возьмём то, что называется внешним произведением (также известное как двухмерное векторное произведение), двух векторов, создав новый элемент под названием «бивектор» (или 2-вектор)
Поначалу идея бивектора может казаться странной, но скоро мы увидим, что они почти столь же фундаментальны, как и сами векторы. Если вектор можно сравнить с прямой, то бивектор подобен плоскости… Свойства внешнего произведения ухватывают важные свойства плоскостей.
2.2. Базис для бивекторов

Бивекторы, как и векторы, имеют компоненты. Но они определяются на базисе плоскостей, а не прямых, как векторы.
Три ортогональных базисных плоскости — это
Но сначала давайте рассмотрим более простой двухмерный случай…
2.3. Двухмерные бивекторы
В 2D есть только одна плоскость, а именно
В оригинале статьи с 2D-бивектором можно поэкспериментировать на интерактивном графике, изменяя (единичные) векторы, из которых он составлен:

Можно увидеть, что при изменении угла между векторами площадь параллелограмма меняется (в соответствии с синусом угла).
Если векторы совпадают или параллельны, то они не образуют правильной плоскости и результат будет равен нулю. Это простое свойство определяет то, чем является бивектор:
Взглянув на сумму двух векторов, можно увидеть, что из свойства следует:
Следовательно:
Так же, как направление поворота, важен порядок аргументов во внешнем произведении. Перемена мест аргументов меняет знак результата (это называется «антисимметрией»).
На графике знак обозначается цветом, который сменяется с синего на зелёный. Знак меняется, когда поворот из
Можно увидеть, что свойства внешнего произведения устроены так, что передают свойства плоскостей и поворотов.
2.4. Двухмерные бивекторы из неединичных векторов
Очевидно, что векторы не обязаны быть единичной длины, и на этом графике данное ограничение устранено:

Площадь параллелограмма со знаком пропорциональна длинам обоих векторов:
Мы можем получить истинное значение, подставив векторы в виде компонентов:
2.5. Трёхмерные бивекторы

Так же, как координаты вектора
Проекции вектора являются длинами этого вектора вдоль каждого базисного вектора, а проекции бивектора являются площадями плоскости на каждую базисную плоскость.
Для вектора:
Для бивектора:
Где
Компоненты 3D-бивектора — это просто три 2D-проекции бивектора на базисные 2D-плоскости.
Пользуясь тем же методом, что и раньше, мы находим, что истинные величины компонентов выглядят во многом похоже на компонент XY из двухмерного случая, но применённого ко всем трём плоскостям:
Можно поэкспериментировать с 3D-бивектором на интерактивном графике в оригинале статьи:

Примечание
Норма бивектораопределяется аналогично норме вектора (квадратный корень из суммы квадратов компонентов). Это равно площади параллелограмма, образованного
и
, т.е.
, где
— угол между
и
.
Если мы разделим бивектор на его норму, то сократим две длины векторов и (абсолютное) значение синуса угла, то есть у нас останется бивектор
Напоминает ли вам что-нибудь внешнее произведение? В 3D определение внешнего произведения очень схоже с определением векторного произведения. На самом деле, вектор в 3D, получаемый из векторного произведения (например, вектор нормали) будет иметь три компонента, равные компонентам бивектора (числа будут теми же, но базис отличается).
Определение бивектора имеет геометрический смысл, а не появляется из ниоткуда. Помню, что когда изучал векторные произведения, я думал: «Какого чёрта оно возвращает вектор, длина которого равна площади параллелограмма, образованного этими двумя векторами? Это кажется таким случайным. И почему нам можно превратить площадь параллелограмма в длину вектора?»
2.6. Семантика векторов и бивекторов
В 3D бивектор имеет три координаты, по одной на плоскость: (
(*)
В 2D есть только один базисный бивектор (), а в 3D есть 3 базисных бивектора (
,
,
), в 4D есть 6 базисных бивектора (
,
,
,
,
,
) и так далее...
В программировании они оба имеют одинаковую схему размещения в памяти, но разные операции. Использование 3D-вектора вместо 3D-бивектора похоже на «преобразование типа» бивектора.
Вот пример: вы могли видеть, что векторы нормалей преобразуются иначе, чем обычные векторы, с помощью «обратного переноса» матрицы
Тривекторы
Мы можем продолжать брать внешнее произведение для получения не только ориентированных 2D-площадей, но и ориентированных 3D-объёмов. Тривекторможно получить, дважды выполнив внешнее произведение:
В трёхмерном пространстве всё на этом заканчивается. Как и в 2D, где есть только одна плоскость, заполняющая всё 2D-пространство, в 3D есть только один объём, заполняющий всё 3D-пространство.
[Но в nD мы можем продолжать создавать ещё большие внешние произведения векторов, пока не достигнем n-ного измерения. Например в 4D у нас есть четыре базисных тривектора (3-вектора) (,
,
,
) и один базисный 4-вектор
]
В 3D тривектор имеет только один базисный компонент (), равный объёму параллелепипеда, образованного тремя векторами. Тройное внешнее произведение является улучшенной версией скалярного тройного произведения (
), потому что в нём задействован только один тип операций, оно возвращает корректный тип (объём вместо скаляра) и работает в любом количестве измерений.
3. Геометрическое произведение
3.1. Умножение векторов друг на друга
Геометрическое произведение
Примечание
Наличие обратных величин полезно, потому что каким бы ни был объект, он не повлияет на векторы, то есть будет вести себя так же, как и при умножении числа на 1.
Чтобы определить произведение, сначала заметим, что можно разделить произведение (или любую функцию, получающую два аргумента) на сумму части, которая не изменяется, если мы поменяем аргументы местами, и на ту часть, которая изменится, следующим образом:
Первый член больше не зависит от порядка аргументов
Скалярное произведение двух векторов (также называемое внутренним произведением) симметрично и является мерой расстояния (
Аналогично, внешнее произведение двух векторов антисимметрично, поэтому полезно будет приравнять его к антисимметричной части:
Кроме того, скалярное произведение содержит косинус угла между двумя векторами (
Примечание
Именно полнота описания делает произведение обратимым, потому что мы можем перейти от одного вектора к другому с помощью информации, содержащейся в их произведении. Если я дам вами
, то вы сможете получить
. Это невозможно сделать, зная только косинус или только синус/плоскость.
То есть геометрическое произведение равно:
Это странно, потому что умножение двух векторов даёт сумму двух различных вещей: скаляра и бивектора. Однако это похоже на то, как комплексное число является суммой скаляра и «мнимого» числа, поэтому вы уже могли к этому привыкнуть. Здесь часть с бивектором соответствует «мнимой» части комплексного числа. Только это не «мнимое» значение, это просто бивектор, который мы по-настоящему можем показать графически!
По сути, перемножив два вектора, мы вычисляем их полезные свойства («длину их проекций друг на друга» / «косинус угла» (
Можно выразить геометрическое произведение через синус и косинус:
3.2. Таблица умножения
Таблица умножения позволяет сделать произведение более конкретным: давайте посмотрим, что произойдёт, если мы получим произведения базисных векторов (
Для любого базисного вектора, например оси
Для любой пары базисных векторов, например, осей
(то есть мы можем назвать
Это даёт нам следующую таблицу:
По сути, эта таблица тривиальна, по сравнению, например, с таблицей кватернионов.
Примечание
Например, вот умножение двух векторови
:
3.3. Формула отражения (традиционный вид)

Отражение на вектор [в оригинале статьи каждый вектор можно перемещать]
Если у нас есть единичный вектор
Это делается обычным образом: мы разделяем
Затем, для того, чтобы отразить вектор, перевернём перпендикулярную часть, а параллельную оставим неизменной:
3.4. Формула отражения (вид для геометрического произведения)
На этом этапе мы можем заменить скалярное произведение
(
Это даёт нам абсолютно то же самое, но в другой записи. Использование записи в виде простого произведения вместо формулы для кодирования такой фундаментальной операции, как отражение, будет очень полезным!
Как работает многократное геометрическое произведение
Если вы не понимаете, как работает многократное взятие геометрического произведения, то просто посмотрите на базисные векторы. Есть всего три возможных случая:
Результаты будут следующими: вектор, вектор, вектор + тривектор. Однако последний случай может возникнуть, только когда все три вектора независимы, что никогда не истинно для
Подробности
Любопытствующие могут посмотреть, на то, что происходит на каждом этапес точки зрения геометрического произведения.
- Первый этап:
Если, как и раньше, мы разделимна часть, перпендикулярную к плоскости (
), и часть, параллельную ей (
), то мы получим:
, потому что эти векторы перпендикулярны, а
, потому что эти векторы параллельны.
Первый член — это просто длина проекциина
, т.е. первый член — это просто длина
.
Давайте назовёмнормализованной версией
, то есть
. Тогда второй член — это просто бивектор
, умноженный на длину
.
Этот бивекторсоставлен из двух перпендикулярных единичных векторов, то есть это очень чистое представление плоскости векторов
и
. Он не содержит информацию об их относительном угле или их длинах, только ориентацию плоскости.
То есть оба члена являются просто разложениемна две ортогональные проекции (
и
), а также образуемой ими плоскость (
):
Прежде чем переходить к следующему шагу, мы можем заменить внешнее произведение геометрическим, потому чтои
перпендикулярны, а потому их внешнее и геометрическое произведение будут эквивалентными (так так часть со скалярным произведением из их геометрического произведения равна нулю).
- Второй этап будет следующим:
Первый член — это просто компонентвдоль
, т.е. компонент
, перпендикулярный плоскости. Другими словами, первый член — это просто
.
Так каки
(снова) перпендикулярны, их геометрическое произведение просто является их внешним произведением, то есть можно поменять их местами и изменить знак.
- И наконец, последний этап переворачивает знак:
То есть мы видим, что компонент, перпендикулярный плоскости, перевёрнут, а параллельная часть остаётся такой же!
Примечание
Длинане очень важна, поэтому ниже мы её игнорируем, но если
не является единичным вектором, то мы должны выполнить деление на его длину и формула превращается в
, что больше походит на «послойное произведение», к которому вы уже должны были привыкнуть.
3.5. Два отражения — это поворот: ситуация в 2D
Оказывается, что если мы применим к
Мы можем показать каждый последующий этап отражения на показанном ниже графике:

Также в оригинале статьи можно изменить векторы
3.6. Два отражения — это поворот: ситуация в 3D
В случае 3D вектор

3.7. Роторы
С точки зрения геометрического произведения два отражения просто соответствуют следующему:
Мы называем
Применение ротора
И на этом всё!
Сравнение 3D-роторов и кватернионов
Можно заметить, что 3D-роторы во многом выглядят как кватернионы:
На самом деле, код/математика практически те же самые! Главное различие в том, что

Однако, как мы видели, 3D-роторы — это трёхмерная концепция, не требующая для визуализации использования «четырёхмерных двойных поворотов» или «стереографического проецирования». Попытка визуализировать кватернионы, работающие в 4D, для объяснения 3D-поворотов немного похожа на то, чтобы пытаться понять движение планет с геоцентрической точки зрения. Т.е. такой подход слишком сложен, потому что мы смотрим на него с неверной точки зрения.
Как мы увидели, моделирование поворотов как происходящих внутри плоскостей, а не вокруг векторов, сильно нам помогает. Например, квадраты базисных бивекторов дают
Умножение двух бивекторов друг на друга даёт третий бивектор, но по сути это тривиально, и нам не нужно запоминать, что
(Заметьте, что мы использовали
Эти свойства являются следствием геометрического произведения, а не возникают ниоткуда!
Дополнительное чтение
(Кстати, в геометрической алгебре есть не только роторы, но и другие крутые штуки!)
- Linear and Geometric Algebra by Macdonald [ссылка на Amazon]
Отличный источник, очень чёткий и понятный, потому что подразумевалось, что он заменит учебник линейной алгебры для студентов. - Geometric Algebra For Computer Science by Dorst et al. [ссылка на Amazon]
Отличный источник, потому что программирование иногда позволяет лучше разобраться в предмете.Примечание: в этой книге авторы дают понять, что геометрическая алгебра медленее, чем кватернионы (и тому подобное...). На самом деле она должна иметь примерно такой же код (т.е. не стоит писать код для геометрической алгебры, создавая обобщённую struct, которая может содержать все возможные типы k-векторов, просто пишите при необходимости по одной struct для каждого типа k-векторов. То есть для замены кватернионов можно написать одну структуру Bivector и одну структуру Rotor, которая является Scalar + Bivector).