От переводчика: ровно 175 лет и 3 дня назад были изобретены кватернионы. В честь этой круглой даты я решил подобрать материал, объясняющий эту концепцию понятным языком.

Концепция кватернионов была придумана ирландским математиком сэром Уильямом Роуэном Гамильтоном в понедельник 16 октября 1843 года в Дублине, Ирландия. Гамильтон со своей женой шёл в Ирландскую королевскую академию, и переходя через Королевский канал по мосту Брум Бридж, он сделал потрясающее открытие, которое сразу же нацарапал на камне моста.

$i^2=j^2=k^2=ijk=-1$




Памятная табличка на мосту Брум Бридж через Королевский канал в честь открытия фундаментальной формулы умножения кватернионов.

В этой статье я постараюсь объяснить концепцию кватернионов простым для понимания образом. Я объясню, как можно визуализировать кватернион, а также расскажу о разных операциях, которые можно выполнять с кватернионами. Кроме того, я сравню использование матриц, углов Эйлера и кватернионов, а затем попытаюсь объяснить, когда стоит использовать кватернионы вместо углов Эйлера или матриц, а когда этого делать не нужно.

Содержание


  • 1. Введение
  • 2. Комплексные числа
    • 2.1. Сложение и вычитание комплексных чисел
    • 2.2. Умножение комплексного числа на скалярное значение
    • 2.3. Произведение комплексных чисел
    • 2.4. Квадрат комплексных чисел
    • 2.5. Сопряжённые комплексные числа
    • 2.6. Абсолютное значение комплексного числа
    • 2.7. Частное двух комплексных чисел
  • 3. Степени $i$
  • 4. Комплексная плоскость
    • 4.1. Роторы
  • 5. Кватернионы
    • 5.1. Кватернионы как упорядоченная пара
    • 5.2. Сложение и вычитание кватернионов
    • 5.3. Произведение кватернионов
    • 5.4. Вещественный кватернион
    • 5.5. Умножение кватерниона на скалярную величину
    • 5.6. Чистые кватернионы
    • 5.7. Аддитивная форма кватерниона
    • 5.8. Единичный кватернион
    • 5.9. Бинарная форма кватерниона
    • 5.10. Сопряжённые кватернионы
    • 5.11. Норма кватерниона
    • 5.12. Нормализация кватерниона
    • 5.13. Обратный кватернион
    • 5.14. Скалярное произведение кватернионов
  • 6. Повороты
  • 7. Интерполяция кватернионов
    • 7.1. SLERP
      • 7.1.1. Разность кватернионов
      • 7.1.2. Возведение кватерниона в степень
      • 7.1.3. Дробная разность кватернионов
      • 7.1.4. Факторы, которые нужно учитывать
    • 7.2. SQUAD
  • 8. Заключение
  • 9. Загрузка демо
  • 10. Справочные материалы

Невозможно полностью понять кватернионы за 45 минут.

В этой статье чрезвычайно много математики, так что она не для слабаков.

Введение


В компьютерной графике для описания позиции в пространстве (перемещения), а также ориентации в пространстве (поворота) используются матрицы. Также можно также использовать одну матрицу преобразований для описания масштаба объекта. Эту матрицу можно считать «пространством базиса». Если умножить вектор или точку (или даже другую матрицу) на матрицу преобразований, то мы «преобразуем» этот вектор, точку или матрицу в пространство, представленное этой матрицей.

В этой статье я не буду в подробностях рассказывать о матрицах преобразований. Подробно о матрицах преобразований можно прочитать в моей статье Matrices.

В данной статье я хочу рассказать об альтернативном способе описания ориентации объекта (поворота) в пространстве при помощи кватернионов.

Комплексные числа


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

Наряду с хорошо известными множествами чисел (натуральным, целым, вещественным и рациональным), система комплексных чисел добавляет новое множество чисел, называемых мнимыми числами. Мнимые числа были придуманы для решения определённых уравнений, не имевших решений, например:

$x^2+1=0$


Чтобы решить это выражение, нам нужно заявить, что $x^2=-1$, а это, как известно, невозможно, потому что квадрат любого числа (положительного или отрицательного) всегда положителен.

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

Мнимое число имеет следующий вид:

$i^2=-1$


Не пытайтесь понять это допущение, потому что логичных причин его существования нет. Нам просто нужно принять, что $i$ — это просто некая величина, квадрат которой равен $-1$.

Множество мнимых чисел можно обозначить как $\mathbb{I}$.

Множество комплексных чисел (обозначаемое символом $\mathbb{C}$ — это сумма вещественного и мнимого числа в следующей форме:

$z=a+bi~~a,b\in\mathbb{R},~~i^2=-1$


Можно также заявить, что все вещественные числа являются комплексными с $b=0$, а все мнимые числа являются комплексными с $a=0$.

Сложение и вычитание комплексных чисел


Комплексные числа можно складывать и вычитать сложением и вычитанием вещественной и мнимой частей.

Сложение:

$(a_1+b_1i)+(a_2+b_2i)=(a_1+a_2)+(b_1+b_2)i$


Вычитание:

$(a_1+b_1i)-(a_2+b_2i)=(a_1-a_2)+(b_1-b_2)i$


Умножение комплексного числа на скалярное значение


Комплексное число умножается на скаляр умножением каждого члена комплексного числа на скаляр:

$\lambda(a+bi)=\lambda{a}+\lambda{b}i$


Произведение комплексных чисел


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

$\begin{array}{rcl}z_1 & = & (a_1+b_1i) \\ z_2 & = & (a_2+b_2i) \\ z_1z_2 & = & (a_1+b_1i)(a_2+b_2i) \\ & = & a_1a_2+a_1b_2i+b_1a_2i+b_1b_2i^2 \\ & = & (a_1a_2-b_1b_2)+(a_1b_2+b_1a_2)i\end{array}$


Квадрат комплексных чисел


Также комплексное число можно возвести в квадрат, умножив на само себя:

$\begin{array}{rcl}z & = & (a+bi) \\ z^2 & = & (a+bi)(a+bi) \\ & = & (a^2-b^2)+2abi\end{array}$


Сопряжённые комплексные числа


Сопряжённой величиной комплексного числа является комплексное число с изменённым знаком мнимой части, обозначаемой как $\bar{z}$ или как $z^*$.

$\begin{array}{rcl}z & = & (a+bi) \\ z^* & = & (a-bi)\end{array}$


Перемножение комплексного числа с его сопряжённой величиной даёт интересный результат.

$\begin{array}{rcl}z & = & (a+bi) \\ z^* & = & (a-bi) \\ zz^* & = & (a+bi)(a-bi) \\ & = & a^2-abi+abi+b^2 \\ & = & a^2+b^2\end{array}$


Абсолютное значение комплексного числа


Мы можем использовать сопряжённое число комплексного числа, чтобы вычислить абсолютное значение (или норму, или величину) комплексного числа. Абсолютное значение комплексного числа — это квадратный корень из комплексного числа, умноженного на его сопряжённое число. Оно обозначается как $|z|$:

$\begin{array}{rcl}z & = & (a+bi) \\ |z| & = & \sqrt{zz^*} \\ & = & \sqrt{(a+bi)(a-bi)} \\ & = & \sqrt{a^2+b^2}\end{array}$


Частное двух комплексных чисел


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

$\begin{array}{rcl}z_1 & = & (a_1+b_1i) \\ z_2 & = & (a_2+b_2i) \\ \cfrac{z_1}{z_2} & = & \cfrac{a_1+b_1i}{a_2+b_2i} \\ & = & \cfrac{(a_1+b_1i)(a_2-b_2i)}{(a_2+b_2i)(a_2-b_2i)} \\ & = & \cfrac{a_1a_2-a_1b_2i+b_1a_2i-b_1b_2i^2}{a_2^2+b_2^2} \\ & = & \cfrac{a_1a_2+b_1b_2}{a_2^2+b_2^2}+\cfrac{b_1a_2-a_1b_2}{a_2^2+b_2^2}i \end{array}$


Степени $i$


Если мы утверждаем, что $i^2=-1$, то должна существовать возможность возводить $i$ и в другие степени.

$\begin{array}{rrrrrrr}i^0 & = & & & & & 1 \\ i^1 & = & & & & & i \\ i^2 & = & & & & & -1 \\ i^3 & = & ii^2 & = & & & -i \\ i^4 & = & i^{2}i^{2} & = & & & 1 \\ i^5 & = & ii^4 & = & & & i \\ i^6 & = & ii^5 & = & i^2 & = & -1\end{array}$


Если мы продолжим записывать этот ряд, то заметим закономерность $(1,i,-1,-i,1,\dots)$.

Похожая закономерность возникает при увеличении отрицательных степеней.

$\begin{array}{rcr}i^0 & = & 1 \\ i^{-1} & = & -i \\ i^{-2} & = & -1 \\ i^{-3} & = & i \\ i^{-4} & = & 1 \\ i^{-5} & = & -i \\ i^{-6} & = & -1\end{array}$


Возможно, вы уже видели такую закономерность в математике, но в виде $(x,y,-x,-y,x,\dots)$, который получается поворотом точки на 90° против часовой стрелки на двухмерной декартовой плоскости; ряд $(x,-y,-x,y,x,\dots)$ создаётся поворотом точки на 90° градусов на двухмерной декартовой плоскости.


Декартова плоскость

Комплексная плоскость


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


Комплексная плоскость

Как видно из предыдущего ряда, мы можем сказать, что если умножим комплексное число на $i$, то сможем поворачивать комплексное число на комплексной плоскости с шагом в 90°.

Давайте проверим, верно ли это. Мы возьмём на комплексной плоскости произвольную точку $p$:

$p=2+i$


и умножим её на $i$, получив $q$:

$\begin{array}{rcl}p & = & 2+i \\ q & = & pi \\ & = & (2+i)i \\ & = & 2i+i^2 \\ & = & -1+2i\end{array}$


Умножив $q$ на $i$, получим $r$:

$\begin{array}{rcl}q & = & -1+2i \\ r & = & qi \\ & = & (-1+2i)i \\ & = & -i+2i^2 \\ & = & -2-i\end{array}$


А умножив $r$ на $i$, получим $s$:

$\begin{array}{rcl}r & = & -2-i \\ s & = & ri \\ & = & (-2-i)i \\ & = & -2i-i^2 \\ & = & 1-2i\end{array}$


А умножив $s$ на $i$, получим $t$:

$\begin{array}{rcl}s & = & 1-2i \\ t & = & si \\ & = & (1-2i)i \\ & = & i-2i^2 \\ & = & 2+i\end{array}$


И мы получили ровно то, с чего начинали ($p$). Если нанести эти комплексные числа на комплексную плоскость, то получим следующий результат.


Комплексные числа на комплексной плоскости

Теперь мы можем выполнять поворот на комплексной плоскости и по часовой стрелке, умножая комплексное число на $-i$.

Роторы


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

$q=\cos\theta+i\sin\theta$


При умножении любого комплексного числа на ротор $q$ получаем общую формулу:

$\begin{array}{rcl} p & = & a + bi \\ q & = & \cos\theta+i\sin\theta \\ pq & = & (a+bi)(\cos\theta+i\sin\theta) \\ a^{\prime}+b^{\prime}i & = & a\cos\theta-b\sin\theta+(a\sin\theta+b\cos\theta)i \end{array}$


Что также можно записать в матричном виде:

$\begin{bmatrix} a^{\prime} & -b^{\prime} \\ b^{\prime} & a^{\prime} \end{bmatrix}=\begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{bmatrix}\begin{bmatrix}a & -b \\b & a \end{bmatrix}$


Что является способом поворота против часовой стрелки произвольной точки на комплексной плоскости относительно точки начала координат.

Кватернионы


Узнав о системе комплексных чисел и комплексной плоскости, мы можем вывести их в трёхмерное пространство, добавив к системе чисел наряду с $i$ ещё два мнимых числа.

Кватернионы имеют следующий обобщённый вид

$q=s+xi+yj+zk~~s,x,y,z\in\mathbb{R}$


Где в соответствии со знаменитым выражением Гамильтона:

$i^2=j^2=k^2=ijk=-1$



$\begin{array}{ccc}ij=k & jk=i & ki=j \\ ji=-k & kj=-i & ik=-j\end{array}$


Можно заметить, что отношения между $i$, $j$ и $k$ очень похожи на правила векторного умножения единичных декартовых векторов:

$\begin{array}{ccc}\mathbf{x}\times \mathbf{y}=\mathbf{z} & \mathbf{y}\times \mathbf{z}=\mathbf{x} & \mathbf{z}\times \mathbf{x}=\mathbf{y} \\ \mathbf{y}\times \mathbf{x}=-\mathbf{z} & \mathbf{z}\times \mathbf{y}=-\mathbf{x} & \mathbf{x}\times \mathbf{z}=-\mathbf{y}\end{array}$


Гамильтон также заметил, что мнимые числа $i$, $j$ и $k$ можно использовать для представления трёх декартовых единичных векторов $\mathbf{i}$, $\mathbf{j}$ и $\mathbf{k}$ с теми же свойствами мнимых чисел, так что $\mathbf{i}^2=\mathbf{j}^2=\mathbf{k}^2=-1$.


Графическое представление свойств $\mathbf{ij}$, $\mathbf{jk}$, $\mathbf{ki}$

На представленном выше изображении графически представлены взаимосвязи между декартовыми единичными векторами в виде $\mathbf{i}$, $\mathbf{j}$ и $\mathbf{k}$.

Кватернионы как упорядоченная пара


Также мы можем представить кватернионы в виде упорядоченной пары:

$q=[s,\mathbf{v}]~~s\in\mathbb{R}, \mathbf{v}\in\mathbb{R}^3$


Где $\mathbf{v}$ можно также представить как его отдельные компоненты:

$q=[s,x\mathbf{i}+y\mathbf{j}+z\mathbf{k}]~~s,x,y,z\in\mathbb{R}$


С помощью этой записи мы можем проще представить общие черты кватернионов и комплексных чисел.

Сложение и вычитание кватернионов


Кватернионы можно складывать и вычитать аналогично комплексным числам:

$\begin{array}{rcl}q_a & = & [s_a,\mathbf{a}] \\ q_b & = & [s_b,\mathbf{b}] \\ q_a+q_b & = & [s_a+s_b,\mathbf{a}+\mathbf{b}] \\ q_a-q_b & = & [s_a-s_b,\mathbf{a}-\mathbf{b}]\end{array}$


Произведения кватернионов


Также мы можем выразить произведение двух кватернионов:

$\begin{array}{rcl}q_a & = & [s_a,\mathbf{a}] \\ q_b & = & [s_b,\mathbf{b}] \\ q_{a}q_{b} & = & [s_{a},\mathbf{a}][s_{b},\mathbf{b}] \\ & = & (s_{a}+x_{a}i+y_{a}j+z_{a}k)(s_{b}+x_{b}i+y_{b}j+z_{b}k) \\ & = & (s_{a}s_{b}-x_{a}x_{b}-y_{a}y_{b}-z_{a}z_{b}) \\ & & +(s_{a}x_{b}+s_{b}x{a}+y_{a}z_{b}-y_{b}z_{a})i \\ & & +(s_{a}y_{b}+s_{b}y_{a}+z_{a}x_{b}-z_{b}x_{a})j \\ & & +(s_{a}z_{b}+s_{b}z_{a}+x_{a}y_{b}-x_{b}y_{a})k\end{array}$


Что даёт нам ещё один кватернион. Если мы заменим в предыдущем выражении мнимые числа $i$, $j$ и $k$ упорядоченными парами (также известными как кватернионные единицы), то получим

$i=[0,\mathbf{i}]~j=[0,\mathbf{j}]~k=[0,\mathbf{k}]$


А подставив обратно в исходное выражение с $[1,\mathbf{0}]=1$, получим:

$\begin{array}{rcl}[s_{a},\mathbf{a}][s_{b},\mathbf{b}] & = & (s_{a}s_{b}-x_{a}x_{b}-y_{a}y_{b}-z_{a}z_{b})[1,\mathbf{0}] \\ & & +(s_{a}x_{b}+s_{b}x{a}+y_{a}z_{b}-y_{b}z_{a})[0,\mathbf{i}] \\ & & +(s_{a}y_{b}+s_{b}y_{a}+z_{a}x_{b}-z_{b}x_{a})[0,\mathbf{j}] \\ & & +(s_{a}z_{b}+s_{b}z_{a}+x_{a}y_{b}-x_{b}y_{a})[0,\mathbf{k}]\end{array}$


Развернув это выражение в сумму упорядоченных пар, получим:

$\begin{array}{rcl}[s_{a},\mathbf{a}][s_{b},\mathbf{b}] & = & [s_{a}s_{b}-x_{a}x_{b}-y_{a}y_{b}-z_{a}z_{b},\mathbf{0}] \\ & & +[0,(s_{a}x_{b}+s_{b}x{a}+y_{a}z_{b}-y_{b}z_{a})\mathbf{i}] \\ & & +[0,(s_{a}y_{b}+s_{b}y_{a}+z_{a}x_{b}-z_{b}x_{a})\mathbf{j}] \\ & & +[0,(s_{a}z_{b}+s_{b}z_{a}+x_{a}y_{b}-x_{b}y_{a})\mathbf{k}]\end{array}$


Если умножить на кватернионную единицу и извлечь общие векторые компоненты, то можно переписать это уравнение следующим образом:

$\begin{array}{rcl}[s_{a},\mathbf{a}][s_{b},\mathbf{b}] & = & [s_{a}s_{b}-x_{a}x_{b}-y_{a}y_{b}-z_{a}z_{b},\mathbf{0}] \\ & & +[0,s_{a}(x_{b}\mathbf{i}+y_{b}\mathbf{j}+z_{b}\mathbf{k})+s_{b}(x_{a}\mathbf{i}+y_{a}\mathbf{j}+z_{a}\mathbf{k}) \\ & & +(y_{a}z_{b}-y_{b}z_{a})\mathbf{i}+(z_{a}x_{b}-z_{b}x_{a})\mathbf{j}+(x_{a}y_{b}-x_{b}y_{a})\mathbf{k}]\end{array}$


Это уравнение даёт нам сумму двух упорядоченных пар. Первая упорядоченная пара — это вещественный кватернион, а вторая — чистый кватернион. Две этих упорядоченных пары можно соединить в одну упорядоченную пару:

$\begin{array}{rcl}[s_{a},\mathbf{a}][s_{b},\mathbf{b}] & = & [s_{a}s_{b}-x_{a}x_{b}-y_{a}y_{b}-z_{a}z_{b}, \\ & & s_{a}(x_{b}\mathbf{i}+y_{b}\mathbf{j}+z_{b}\mathbf{k})+s_{b}(x_{a}\mathbf{i}+y_{a}\mathbf{j}+z_{a}\mathbf{k}) \\ & & +(y_{a}z_{b}-y_{b}z_{a})\mathbf{i}+(z_{a}x_{b}-z_{b}x_{a})\mathbf{j}+(x_{a}y_{b}-x_{b}y_{a})\mathbf{k}]\end{array}$


Если подставить, то мы получим

$\begin{array}{rcl}\mathbf{a} & = & x_{a}\mathbf{i}+y_{a}\mathbf{j}+z_{a}\mathbf{k} \\ \mathbf{b} & = & x_{b}\mathbf{i}+y_{b}\mathbf{j}+z_{b}\mathbf{k} \\ \mathbf{a}\cdot\mathbf{b} & = & x_{a}x_{b}+y_{a}y_{b}+z_{a}z_{b} \\ \mathbf{a}\times\mathbf{b} & = & (y_{a}z_{b}-y_{b}z_{a})\mathbf{i}+(z_{a}x_{b}-z_{b}x_{a})\mathbf{j}+(x_{a}y_{b}-x_{b}y_{a})\mathbf{k}\end{array}$


Получаем:

$[s_{a},\mathbf{a}][s_{b},\mathbf{b}]=[s_{a}s_{b}-\mathbf{a}\cdot\mathbf{b},s_{a}\mathbf{b}+s_{b}\mathbf{a}+\mathbf{a}\times\mathbf{b}]$


Это и есть общее уравнение произведения кватернионов.

Вещественный кватернион


Вещественный кватернион — это кватернион, в который входит вектор $\mathbf{0}$:

$q=[s,\mathbf{0}]$


А произведением двух вещественных кватернионов является ещё один вещественный кватернион:

$\begin{array}{rcl}q_a & = & [s_a,\mathbf{0}] \\ q_b & = & [s_b,\mathbf{0}] \\ q_{a}q_{b} & = & [s_a,\mathbf{0}][s_b,\mathbf{0}] \\ & = & [s_{a}s_{b},\mathbf{0}]\end{array}$


Что аналогично произведению двух комплексных чисел, содержащих нулевой мнимый член.

$\begin{array}{rcl}z_1 & = & a_1+0i \\ z_2 & = & a_2+0i \\ z_{1}z_{2} & = & (a_1+0i)(a_2+0i) \\ & = & a_{1}a_{2}\end{array}$


Умножение кватерниона на скалярную величину


Также мы можем умножать кватернион на скаляр, при этом придерживаясь следующего правила:

$\begin{array}{rcl}q & = & [s,\mathbf{v}] \\ \lambda{q} & = & \lambda[s,\mathbf{v}] \\ & = & [\lambda{s},\lambda\mathbf{v}]\end{array}$


Мы можем убедиться в этом с помощью показанного выше произведения вещественных кватернионов, умножив кватернион на скаляр как вещественный кватернион:

$\begin{array}{rcl}q & = & [s,\mathbf{v}] \\ \lambda & = & [\lambda,\mathbf{0}] \\ \lambda{q} & = & [\lambda,\mathbf{0}][s,\mathbf{v}] \\ & = & [\lambda{s},\lambda\mathbf{v}]\end{array}$


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


Кроме вещественных кватернионов, Гамильтон также определил чистый кватернион как кватернион с нулевым скалярным членом:

$q=[0,\mathbf{v}]$


Или если записать по компонентам:

$q=xi+yj+zk$


И мы снова можем взять произведение двух чистых кватернионов:

$\begin{array}{rcl}q_a & = & [0,\mathbf{a}] \\ q_b & = & [0,\mathbf{b}] \\ q_{a}q_{b} & = & [0,\mathbf{a}][0,\mathbf{b}] \\ & = & [-\mathbf{a}\cdot\mathbf{b},\mathbf{a}\times\mathbf{b}]\end{array}$


в соответствии с представленным выше правилом произведения кватернионов.

Аддитивная форма кватерниона


Кроме того, мы можем выразить кватернионы как сумму вещественной и чистой частей кватерниона:

$\begin{array}{rcl}q & = & [s,\mathbf{v}] \\ & = & [s,\mathbf{0}]+[0,\mathbf{v}]\end{array}$


Единичный кватернион


Взяв произвольный вектор $\mathbf{v}$, можно выразить этот вектор и через его скалярную величину, и через его направление следующим образом:

$\mathbf{v}=v\mathbf{\hat{v}}~\text{где}~v=|\mathbf{v}|~\text{и}~|\mathbf{\hat{v}}|=1$


Объединив это определение с определением чистого кватерниона, получим:

$\begin{array}{rcl}q & = & [0,\mathbf{v}] \\ & = & [0,v\mathbf{\hat{v}}] \\ & = & v[0,\mathbf{\hat{v}}]\end{array}$


Также мы можем описать единичный кватернион, имеющий нулевой скаляр и единичный вектор:

$\hat{q}=[0,\mathbf{\hat{v}}]$


Бинарная форма кватерниона


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

$\begin{array}{rcl}q & = & [s,\mathbf{v}] \\ & = & [s,\mathbf{0}]+[0,\mathbf{v}] \\ & = & [s,\mathbf{0}]+v[0,\mathbf{\hat{v}}] \\ & = & s+v\hat{q}\end{array}$


Что даёт нам способ представить кватернион в форме, очень похожей на комплексные числа:

$\begin{array}{rcl}z & = & a+bi \\ q & = & s + v\hat{q}\end{array}$


Сопряжённое число кватерниона


Сопряжённое число кватерниона можно вычислить, взяв противоположную по знаку векторную часть кватерниона:

$\begin{array}{rcl}q & = & [s,\mathbf{v}] \\ q^* & = & [s,-\mathbf{v}]\end{array}$


Произведение кватерниона и его сопряжённого числа даёт нам следующее:

$\begin{array}{rcl}qq^* & = & [s,\mathbf{v}][s,-\mathbf{v}] \\ & = & [s^2-\mathbf{v}\cdot-\mathbf{v},-s\mathbf{v}+s\mathbf{v}+\mathbf{v}\times-\mathbf{v}] \\ & = & [s^2+\mathbf{v}\cdot\mathbf{v},\mathbf{0}] \\ & = & [s^2+v^2,\mathbf{0}]\end{array}$


Норма кватерниона


Вспомним определение нормы комплексного числа:

$\begin{array}{rcl}|z| & = & \sqrt{a^2+b^2} \\ zz^* & = & |z|^2\end{array}$


Аналогично, норма (или величина) кватерниона определяется как:

$\begin{array}{rcl}q & = & [s,\mathbf{v}] \\ |q| & = & \sqrt{s^2+v^2}\end{array}$


Что позволяет нам выразить норму кватерниона следующим образом:

$qq^*=|q|^2$


Нормализация кватерниона


Имея определение нормы кватерниона, мы можем использовать её для нормализации кватерниона. Кватернион нормализуется делением на $|q|$:

$q^{\prime}=\frac{q}{\sqrt{s^2+v^2}}$


Например, давайте нормализуем кватернион:

$q=[1,4\mathbf{i}+4\mathbf{j}-4\mathbf{k}]$


Сначала нам нужно вычислить норму кватерниона:

$\begin{array}{rcl}|q| & = & \sqrt{1^2+4^2+4^2+(-4)^2} \\ & = & \sqrt{49} \\ & = & 7\end{array}$


Затем мы должны разделить кватернион на норму кватерниона, чтобы вычислить нормализованный кватернион:

$\begin{array}{rcl}q^{\prime} & = & \cfrac{q}{|q|} \\[1.0em] & = & \cfrac{(1+4\mathbf{i}+4\mathbf{j}-4\mathbf{k})}{7} \\[1.0em] & = & \cfrac{1}{7}+\cfrac{4}{7}\mathbf{i}+\cfrac{4}{7}\mathbf{j}-\cfrac{4}{7}\mathbf{k}\end{array}$


Обратный кватернион


Обратный кватернион обозначается как $q^{-1}$. Для вычисления обратного кватерниона мы берём сопряжённое число кватерниона и делим его на квадрат нормы:

$q^{-1}=\frac{q^*}{|q|^2}$


Чтобы показать это, мы можем воспользоваться определением обратной величины:

$qq^{-1}=[1,\mathbf{0}]=1$


И умножить обе стороны на сопряжённое число кватерниона, что даст нам:

$q^{*}qq^{-1}=q^{*}$


Подстановкой мы получаем:

$\begin{array}{rcl}|q|^{2}q^{-1} & = & q^{*} \\ q^{-1} & = & \cfrac{q^{*}}{|q|^{2}}\end{array}$


Для единичных кватернионов-норм, норма которых равна 1, мы можем записать:

$q^{-1}=q^{*}$


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


Аналогично скалярному произведению векторов мы можем вычислить скалярное произведение двух кватернионов, перемножив соответствующие скалярные части и просуммировав результаты:

$\begin{array}{rcl}q_1 & = & [s_1,x_1\mathbf{i}+y_1\mathbf{j}+z_1\mathbf{k}] \\ q_2 & = & [s_2,x_2\mathbf{i}+y_2\mathbf{j}+z_2\mathbf{k}] \\ q_1{\cdot}q_2 & = & s_{1}s_{2}+x_{1}x_{2}+y_{1}y_{2}+z_{1}z_{2}\end{array}$


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

$\cos\theta=\frac{s_{1}s_{2}+x_{1}x_{2}+y_{1}y_{2}+z_{1}z_{2}}{|q_{1}||q_{2}|}$


Для единичных кватернионов-норм мы можем упростить уравнение:

$\cos\theta=s_{1}s_{2}+x_{1}x_{2}+y_{1}y_{2}+z_{1}z_{2}$


Повороты


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

$q=\cos\theta+i\sin\theta$


Благодаря схожести комплексных чисел с кватернионами должна существовать возможность выразить кватернион, который можно использовать для поворота точки в трёхмерном пространстве:

$q=[\cos\theta,\sin\theta\mathbf{v}]$


Давайте проверим, верна ли эта теория, вычислив произведение кватерниона $q$ и вектора $\mathbf{p}$. Во-первых, мы можем выразить $\mathbf{p}$ как чистый кватернион в следующем виде:

$p=[0,\mathbf{p}]$


А $q$ — это единичный кватернион-норма в виде:

$q=[s,\lambda\mathbf{\hat{v}}]$


Тогда

$\begin{array}{rcl}p^{\prime} & = & qp \\ & = & [s,\lambda\mathbf{\hat{v}}][0,\mathbf{p}] \\ & = & [-\lambda\mathbf{\hat{v}}\cdot\mathbf{p},s\mathbf{p}+\lambda\mathbf{\hat{v}}\times\mathbf{p}]\end{array}$


Мы видим, что результатом является общий кватернион со скалярной и векторной частями.

Давайте сначала рассмотрим «особый» случай, при котором $\mathbf{p}$ перпендикулярен $\mathbf{\hat{v}}$. В таком случае член скалярного произведения $-\lambda\mathbf{\hat{v}}\cdot\mathbf{p}=0$ и результат становится чистым кватернионом:

$p^{\prime}=[0,s\mathbf{p}+\lambda\mathbf{\hat{v}}\times\mathbf{p}]$


В таком случае для поворота $\mathbf{p}$ относительно $\mathbf{\hat{v}}$ мы просто подставляем $s=\cos\theta$ и $\lambda=\sin\theta$.

$p^{\prime}=[0,\cos\theta\mathbf{p}+\sin\theta\mathbf{\hat{v}}\times\mathbf{p}]$


Например, давайте повернём вектор $\mathbf{p}$ на 45° относительно оси Z; тогда наш кватернион $q$ будет равен:

$\begin{array}{rcl}q & = & [\cos\theta,\sin\theta\mathbf{k}] \\ & = & \left[\frac{\sqrt{2}}{2},\frac{\sqrt{2}}{2}\mathbf{k}\right]\end{array}$


И давайте возьмём вектор $\mathbf{p}$, который относится к особому случаю, где $\mathbf{p}$ перпендикулярен $\mathbf{k}$:

$p=[0,2\mathbf{i}]$


Теперь давайте найдём произведение

$qp$

:

$\begin{array}{rcl}p^{\prime} & = & qp \\ & = & \left[\frac{\sqrt{2}}{2},\frac{\sqrt{2}}{2}\mathbf{k}\right][0,2\mathbf{i}] \\ & = & \left[0,2\frac{\sqrt{2}}{2}\mathbf{i}+2\frac{\sqrt{2}}{2}\mathbf{k}\times\mathbf{i}\right] \\ & = & [0, \sqrt{2}\mathbf{i}+\sqrt{2}\mathbf{j}]\end{array}$


Что даёт нам чистый кватернион, повёрнутый на 45° относительно оси $\mathbf{k}$. Мы можем также убедиться, что величина конечного вектора сохранилась:

$\begin{array}{rcl}|\mathbf{p}^{\prime}| & = & \sqrt{\sqrt{2}^{2}+\sqrt{2}^{2}} \\ & = & 2\end{array}$


В точности то, чего мы и ожидали!

Мы можем показать это графически следующим изображением:


Поворот кватерниона (1)

Теперь давайте рассмотрим кватернион, не ортогональный к $\mathbf{p}$. Если мы примем для векторной части кватерниона смещение в 45° от $\mathbf{p}$, то получим:

$\begin{array}{rcl}\mathbf{\hat{v}} & = & \frac{\sqrt{2}}{2}\mathbf{i}+\frac{\sqrt{2}}{2}\mathbf{k} \\ \mathbf{p} & = & 2\mathbf{i} \\ q & = & [\cos\theta,\sin\theta\mathbf{\hat{v}}] \\ p & = & [0,\mathbf{p}]\end{array}$


А умножив наш вектор $\mathbf{p}$ на $q$, получим:

$\begin{array}{rcl}p^{\prime} & = & qp \\ & = & [\cos\theta,sin\theta\mathbf{\hat{v}}][0,\mathbf{p}] \\ & = & [-\sin\theta\mathbf{\hat{v}}\cdot\mathbf{p},\cos\theta\mathbf{p}+\sin\theta\mathbf{\hat{v}}\times\mathbf{p}]\end{array}$


После подстановки $\mathbf{\hat{v}}$, $\mathbf{p}$ и $\theta=45^{\circ}$ получаем:

$\begin{array}{rcl}p^{\prime} & = & \left[-\frac{\sqrt{2}}{2}\left(\frac{\sqrt{2}}{2}\mathbf{i}+\frac{\sqrt{2}}{2}\mathbf{k}\right)\cdot(2\mathbf{i}),\frac{\sqrt{2}}{2}2\mathbf{i}+\frac{\sqrt{2}}{2}\left(\frac{\sqrt{2}}{2}\mathbf{i}+\frac{\sqrt{2}}{2}\mathbf{k}\right)\times2\mathbf{i}\right] \\ & = & [-1,\sqrt{2}\mathbf{i}+\mathbf{j}]\end{array}$


То есть это больше не чистый кватернион, он не повёрнут на 45° а норма вектора больше не равна 2 (она уменьшилась до $\sqrt{3}$).

Этот результат можно показать графически.


Поворот кватерниона (2)

Строго говоря, некорректно представлять кватернион $p^{\prime}$ в трёхмерном пространстве, потому что на самом деле это четырёхмерный вектор! Ради упрощения я покажу только векторный компонент кватернионов.

Однако не всё потеряно. Гамильтон выяснил (но не опубликовал этого), что если мы затем умножим результат $qp$ на значение, обратное $q$, то результатом будет чистый кватернион, а норма векторного компонента сохранится. Давайте посмотрим, можно ли применить это в нашем примере.

Для начала давайте вычислим $q^{-1}$:

$\begin{array}{rcl}q & = & \left[\cos\theta,\sin\theta\left(\frac{\sqrt{2}}{2}\mathbf{i}+\frac{\sqrt{2}}{2}\mathbf{k}\right)\right] \\ q^{-1} & = & \left[\cos\theta,-\sin\theta\left(\frac{\sqrt{2}}{2}\mathbf{i}+\frac{\sqrt{2}}{2}\mathbf{k}\right)\right]\end{array}$


При $\theta=45^{\circ}$ получаем:

$\begin{array}{rcl}q^{-1} & = & \left[\frac{\sqrt{2}}{2},-\frac{\sqrt{2}}{2}\left(\frac{\sqrt{2}}{2}\mathbf{i}+\frac{\sqrt{2}}{2}\mathbf{k}\right)\right] \\ & = & \frac{1}{2}\left[\sqrt{2},-\mathbf{i}-\mathbf{k}\right]\end{array}$


Объединив предыдущее значение $qp$ и $q^{-1}$, получим:

$\begin{array}{rcl}qp & = & \left[-1,\sqrt{2}\mathbf{i}+\mathbf{j}\right] \\ qpq^{-1} & = & \left[-1,\sqrt{2}\mathbf{i}+\mathbf{j}\right]\frac{1}{2}\left[\sqrt{2},-\mathbf{i}-\mathbf{k}\right] \\ & = & \frac{1}{2}\left[-\sqrt{2}-\left(\sqrt{2}\mathbf{i}+\mathbf{j}\right)\cdot(-\mathbf{i}-\mathbf{k}),\mathbf{i}+\mathbf{k}+\sqrt{2}\left(\sqrt{2}\mathbf{i}+\mathbf{j}\right)-\mathbf{i}+\sqrt{2}\mathbf{j}+\mathbf{k}\right] \\ & = & \frac{1}{2}\left[-\sqrt{2}+\sqrt{2},\mathbf{i}+\mathbf{k}+2\mathbf{i}+\sqrt{2}\mathbf{j}-\mathbf{i}+\sqrt{2}\mathbf{j}+\mathbf{k}\right] \\ & = & \left[0,\mathbf{i}+\sqrt{2}\mathbf{j}+\mathbf{k}\right]\end{array}$


Что является чистым кватернионом, а норма результата равна:

$\begin{array}{rcl}|p^{\prime}| & = & \sqrt{1^2+\sqrt{2}^2+1^2} \\ & = & \sqrt{4} \\ & = & 2\end{array}$


что равно $\mathbf{p}$, то есть норма вектора сохранилась.

На изображении ниже показан результат поворота.


Поворот кватерниона (3)

Мы видим, что результат является чистым кватернионом, а норма исходного вектора сохранилась, но вектор повернулся на 90°, а не на 45°, что вдвое больше необходимого! Поэтому для корректного поворота вектора $\mathbf{p}$ на угол $\theta$ относительно произвольной оси $\mathbf{\hat{v}}$ нам нужно взять половинный угол и создать следующий кватернион:

$q=\left[\cos\frac{1}{2}\theta,\sin\frac{1}{2}\theta\mathbf{\hat{v}}\right]$


Что является общим видом кватерниона поворота!

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


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

С помощью кватернионов мы можем определить несколько методов, представляющих интерполяцию поворота в 3D-пространстве. Первый рассматриваемый мной метод называется SLERP. Он используется для плавной интерполяции точки между двумя ориентациями. Второй метод является развитием SLERP и называется SQUAD. Он используется для интерполяции по ряду ориентаций, задающих путь.

SLERP


SLERP расшифровывается как Spherical Linear Interpolation (сферическая линейная интерполяция). SLERP предоставляет возможность плавной интерполяции точки между двумя ориентациями.

Я обозначу первую ориентацию как $q_1$, а вторую как $q_2$. Интерполируемую точку обозначим как $\mathbf{p}$, интерполированную точку обозначим как $\mathbf{p}^{\prime}$. Параметр интерполяции $t$ будет интерполировать $\mathbf{p}$ от $q_1$ при $t=0$ до $q_2$ при $t=1$.

Стандартная формула линейной интерполяции имеет вид:

$\mathbf{p}^{\prime}=\mathbf{p_1}+t(\mathbf{p_2}-\mathbf{p_1})$


Вот основные шаги для применения этого уравнения:

  • Вычисляем разность между $\mathbf{p_1}$ и $\mathbf{p_2}$.
  • Берём дробную часть этой разности.
  • Корректируем исходное значение на дробную разность между двумя точками.

Мы можем использовать тот же основной принцип, чтобы выполнить интерполяцию между двумя ориентациями кватернионов.

Разность кватернионов


Первый шаг означает, что нам нужно вычислить разность между $q_1$ и $q_2$. В контексте кватернионов это аналогично вычислению угловой разности между двумя кватернионами.

$\Delta{q}=q_1^{-1}q_2$


Возведение кватерниона в степень


На следующем шаге нужно взять дробную часть этой разности. Мы можем вычислить дробную часть кватерниона, возведя его в степень, значение которой находится в интервале $[0…1]$.

Общая формула возведения кватерниона в степень имеет следующий вид:

$q^t=\exp(t\log{q})$


Где экпоненциальная функция для кватернионов выглядит так:

$\begin{array}{rcl}\exp(q) & = & \exp\left([0,\theta\mathbf{\hat{v}}]\right) \\ & = & [\cos\theta,\sin\theta\mathbf{\hat{v}}] \end{array}$


А логарифм кватерниона имеет вид:

$\begin{array}{rcl}\log{q} & = & \log(\cos\theta{+}\sin\theta\mathbf{\hat{v}}) \\ & = & \log\left(\exp(\theta\mathbf{\hat{v}})\right) \\ & = & \theta\mathbf{\hat{v}} \\ & = & [0,\theta\mathbf{\hat{v}}] \end{array}$


При $t=0$ мы имеем следующее:

$\begin{array}{rcl}q^0 & = & \exp(0\log{q}) \\ & = & \exp([\cos(0),\sin(0)\mathbf{\hat{v}}]) \\ & = & \exp([1,\mathbf{0}]) \\ & = & [1,\mathbf{0}]\end{array}$


А при $t=1$ мы имеем

$\begin{array}{rcl}q^1 & = & \exp(\log{q}) \\ & = & q\end{array}$


Дробная разность кватернионов


Чтобы вычислить интерполированный угловой поворот, мы изменяем исходную ориентацию $q_1$ на дробную часть разности между $q_1$ и $q_2$.

$q^{\prime}=q_1\left(q_1^{-1}q_2\right)^t$


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

Мы можем применить похожую формулу для выполнения сферической интерполяции векторов в кватернионы. Общий вид сферической интерполяции для векторов задаётся так:

$\mathbf{v}_t=\frac{\sin(1-t)\theta}{\sin\theta}\mathbf{v}_1+\frac{\sin{t\theta}}{\sin\theta}\mathbf{v}_2$


Графически это можно показать следующим изображением.


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

Эту формулу можно без изменений применить к кватернионам:

$q_t=\frac{\sin(1-t)\theta}{\sin\theta}q_1+\frac{\sin{t\theta}}{\sin\theta}q_2$


И мы можем получить угол $\theta$, вычислив скалярное произведение $q_1$ и $q_2$.

$\begin{array}{rcl}\cos\theta & = & \cfrac{q_1{\cdot} q_2}{|q_1||q_2|} \\ & = & \cfrac{s_{1}s_{2}+x_{1}x_{2}+y_{1}y_{2}+z_{1}z_{2}}{|q_1||q_2|} \\ \theta & = & \cos^{-1}\left(\cfrac{s_{1}s_{2}+x_{1}x_{2}+y_{1}y_{2}+z_{1}z_{2}}{|q_1||q_2|}\right)\end{array}$


Факторы, которые нужно учитывать


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

Во-первых, если скалярное произведение кватернионов оказывается отрицательным значением, то интерполяция пойдёт по «долгому пути» на четырёхмерной сфере, а это не всегда желательно. Чтобы решить эту проблему, мы можем проверить результат скалярного произведения и если он отрицательный, то можно взять значение, противоположное одной из ориентаций. Инвертирование скалярной и векторной части кватерниона не меняет представляемую им ориентацию, но сделав это, мы гарантируем, что поворот будет происходить по «кратчайшему» пути.

Ещё одна проблема возникает, если угловая разность между $q_1$ и $q_2$ очень мала, при этом $\sin\theta$ становится 0. Если это происходит, то при делении на $\sin\theta$ мы можем получить неопределённый результат. В таком случае можно вернуться к использованию линейной интерполяции между $q_1$ и $q_2$.

SQUAD


Так же, как SLERP можно использовать для интерполяции между двумя кватернионами, SQUAD (Spherical and Quadrangle — сферическая и четырёхугольная) можно использовать для плавной интерполяции по пути поворотов.

Если у нас есть ряд кватернионов:

$q_1,q_2,q_3,\cdots,q_{n-2},q_{n-1},q_{n}$


И мы определили «вспомогательный» кватернион ($s_i$), который мы можем считать промежуточной контрольной точкой:

$s_i=\exp\left(-\frac{\log\left(q_{i+1}q_i^{-1}\right)+\log\left(q_{i-1}q_i^{-1}\right)}{4}\right)q_i$


Ориентация вдоль части кривой определяется как:

$q_{i-1},q_i,q_{i+1},q_{i+2}$


при времени t это даёт нам:

$\mathrm{squad}(q_i,q_{i+1},s_i,s_{i+1},t)=\mathrm{slerp}(\mathrm{slerp}(q_i,q_{i+1},t),\mathrm{slerp}(s_i,s_{i+1},t),2t(1-t))$


Заключение


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

  • Интерполяция кватернионов с помощью SLERP и SQUAD предоставляет способ плавной интерполяции между ориентациями в пространстве.
  • Конкатенация поворотов с помощью кватернионов выполняется быстрее, чем объединение поворотов, выраженных в матричном виде.
  • Для единичных кватернионов-норм обратная величина поворота берётся вычитанием векторной части кватерниона. Вычисление обратной величины матрицы поворота значительно медленнее, если матрица не ортонормирована (если она ортонормирована, то это всего лишь транспонирование матрицы).
  • Преобразование кватернионов в матрицы немного быстрее, чем для углов Эйлера.
  • Для описания поворота кватернионам требуется всего 4 числа (3, если они нормализованы. Вещественную часть можно вычислять во время выполнения программы), в то время как матрицам необходимо не менее 9 значений.

Однако наряду со всеми преимуществами использования кватернионов существует также несколько недостатков.

  • Кватернионы могут становиться недействительными из-за ошибки округления чисел с плавающей запятой; однако эту «вкравшуюся ошибку» можно устранить ренормализацией кватерниона.
  • Вероятно, самое значительное препятствие для применения кватернионов — высокая сложность их понимания. Надеюсь, эту проблему вы решите, прочитав мою статью.

Есть множество математических библиотек, реализующих кватернионы, и только некоторые из них реализуют кватернионы правильно. По моему собственному опыту хорошей математической библиотекой с качественной реализацией кватернионов является GLM (OpenGL Math Library). Если вы хотите использовать кватернионы в собственных приложениях, то рекомендую эту библиотеку.

Загрузка демо


Я создал небольшое демо, демонстрирующее использование кватерниона для поворота объекта в пространстве. Демо было создано в Unity 3.5.2, можете скачать бесплатно скачать этот движок и просмотреть исходный код демо. В файле zip также содержится двоичный исполняемый файл Windows, но в Unity вы можете собрать приложение и для Mac.

Understanding Quaternions.zip

Справочные материалы


Quaternions for Computer Graphics

Vince, J (2011). Quaternions for Computer Graphics. 1st. ed. London: Springer.



Dunn, F. and Parberry, I. (2002). 3D Math Primer for Graphics and Game Development. 1st. ed. Plano, Texas: Wordware Publishing, Inc.

Комментарии (48)


  1. Scratch
    19.10.2018 09:01

    И вот это всё мистеру Гамильтону пришло в голову когда он проходил под мостом???


    1. Refridgerator
      19.10.2018 09:57

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


    1. Dvlbug
      19.10.2018 23:01

      Менделеев к этой увлекательной истории во сне периодической таблице химических элементов относился с плохо скрываемой иронией. О своей таблице он говорил: «Я над ней, может быть, двадцать лет думал, а вы думаете: сидел и вдруг… готово».


  1. Pentoxide
    19.10.2018 10:08

    Ещё интересное видео про кватернионы и зачем они вообще понадобились, также упомнинание про октонианы:

    Заголовок спойлера


  1. Scogun
    19.10.2018 10:25

    Как-то для студенческих нужд написал библиотеку. Недавно переписал её на Kotlin. Может кому пригодится?


    1. Refridgerator
      19.10.2018 11:33

      Для C# реализация кватернионов есть в XNA, я её оттуда когда-то давно выковыривал. Она более полная.


      1. Scogun
        19.10.2018 12:59

        Я больше писал её для матриц и было это в 2006 вроде. Потом вспомнил, сдул пыль и выложил на Github. Ни на какие лавры не претендую.


    1. lgorSL
      19.10.2018 23:15

      Кстати, в книге "3D Math Primer for Graphics and Game Development" (она приведена в конце статьи) очень хорошо объяснены кватернионы и приведена их реализация на C++. Имхо, намного подробнее и понятнее, чем в статье выше. Я когда читал книгу, потихоньку написал свою велосипедную реализацию на java.


    1. MechanicZelenyy
      20.10.2018 09:13
      +1

      Если вас заинтересует можете поучаствовать в этом проекте: github.com/altavir/kmath


      1. Scogun
        20.10.2018 10:16

        Мне сначала свой Android проект до beta довести, а там — вполне может быть. Спасибо за предложение!


  1. FGV
    19.10.2018 10:39

    >3, если они нормализованы. Вещественную часть можно вычислять во время выполнения программы

    Это корректно только если повороты на угол менее 180 градусов.

    p.s. В свое время разбирался шо такое кватернионы по «Кинематика и динамика твердого тела (кватернионное изложение), pdf легко гуглится.


  1. GeMir
    19.10.2018 12:50

    Статья настолько же интересная, насколько ужасны иллюстрации к ней.

    Жаль, визуализаций кватернионов в GeoGebra не так много.


    1. homocomputeris
      19.10.2018 20:10

      И не менее ужасны пробелы между строками.


    1. slovak
      19.10.2018 21:47

      Вот хорошее введение (скоро обещают продолжение)


    1. agarus
      20.10.2018 14:25

      Как-то неадекватно выглядит эта анимация даже в дефолтном состоянии настроек. Это особенно заметно, когда ставишь галочку «трассировки».


  1. Ndochp
    19.10.2018 15:57
    +1

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

    Курсеровский курс по комплексным с вами не согласен. Там прямо отдельно было сказано, что квадратные уравнения — фигня. И так понятно, что корней нету. А вот когда при решении кубического (у которого корень есть всегда) на промежуточной стадии получаешь корень из отрицательного — вот тогда грустно. Корень то нужен. Поэтому, пришлось изобретать теорию.


  1. 0serg
    19.10.2018 18:02
    +2

    Вычисление обратной величины матрицы поворота значительно медленнее, если матрица не ортонормирована (если она ортонормирована, то это всего лишь транспонирование матрицы).

    Матрица поворота всегда ортонормирована. Если она не ортонормирована то это плохая матрица поворота которую долго-долго умножали и округляли пока она не перестала быть чистым поворотом :).


  1. 0serg
    19.10.2018 18:11
    +2

    Я бы упомянул в статье связь кватернионов с более простой и понятной конструкцией — вектором вращения. Любое вращение в 3D есть вращение на какой-то угол (a) вокруг оси заданное единичным вектором (v). Так вот соответствующий этому вращению кватернион есть
    $$ cos(a/2) + sin(a/2) * (i*v.x +j*v.y + k*v.z)$$
    То бишь мнимая часть кватерниона — это вектор оси вращения, домноженный на sin(a/2) а угол поворота определяется действительной частью кватерниона.


    1. GeMir
      19.10.2018 23:39
      +1

      $$ cos(a/2) + sin(a/2) * (i*v.x +j*v.y + k*v.z)$$
      Вы же правда не используете * как знак умножения в TeX? :)
      image


      1. 0serg
        20.10.2018 11:32

        Поскольку в комментариях TeX не поддерживается то \cdot был бы менее читабелен :)


    1. michael_vostrikov
      20.10.2018 08:16

      i — это не вектор направления, это вектор поворота на 90?. Корень из i — это i ^ 1/2, половина угла, поворот на 45?. Потому и есть связь между тригонометрическими функциями и экспонентой в комплексной степени.


      1. 0serg
        20.10.2018 12:09

        Аналогия с комплексными числами здесь только сбивает с толку на самом деле. К примеру в комплексных числах (i) и (-i) — это два разных поворота сохраняющих условную «ось z» а в кватернионах это один и тот же поворот сохраняющий ось x. Потому как кватернионы к векторам не умножением применяются (в отличие от 2D случая с комплексными числами)


      1. michael_vostrikov
        20.10.2018 12:42

        Не пытайтесь понять это допущение, потому что логичных причин его существования нет. Нам просто нужно принять, что i — это просто некая величина, квадрат которой равен -1

        Вот кстати логичная причина существования: поворачиваем положительный единичный вектор 2 раза на 90 градусов.


    1. dmagin
      21.10.2018 19:57

      Вектор вращения — это описание оператора вращения? Если да, то к чему и как применяется?

      И еще. Я правильно понимаю, что начало определенного таким образом вектора всегда совпадает с началом координат? То есть если надо описать вращение относительно параллельного вектора, то надо еще указать дополнительно координаты точки начала вектора? Или как?


      1. 0serg
        21.10.2018 21:40

        Вектор вращения — это единичный вектор сонаправленный оси вращения умноженный на угол вращения (скаляр). Т.е. направление вектора задает ось вращения а длина вектора — поворот. Но не суть важно, там их несколько родственных вариантов, объединенных идеей задания вращения чере «ось и угол» (axis and angle). Он интуитивен и подобно кватернионам удобен для интерполяции вращений, только там формулы чуть сложнее и медленнее и потому применяются реже. Можете почитать про «формулу вращения Родригеса» для примера. В основном это очень классная вещь для параметризации возможных матриц вращений если требуется решать какую-нибудь задачку на поиск оптимального поворота.

        В обсуждаемой статье идет речь о задании «чистых» вращений (линейных операторов), которые по определению вращают исключительно относительно начала координат. Для задания евклидовых движений в 3D (повороты относительно произвольной оси как частный случай и винты как общий) одних кватернионов недостаточно, у них 6 степеней свободы (у вращений вокруг произвольной оси — пять). Там есть схожий формализм с векторами вращения, только надо 2 трехмерных вектора задавать а не один.


        1. dmagin
          22.10.2018 15:31

          спасибо


  1. shuhray
    19.10.2018 21:14
    -1

    Сейчас пишу программу для интерактивных геометрических построений, причём геометрия не евклидова, а эллиптическая (она проще, а картинки красивее)
    mega.nz/#!WhgSXIIA!-QohSfyl0MQS9P_0fBj0InFcadFfvj4IOShLy4SeI5g
    (примеры, открывать Мозиллой)
    И вот с кватернионами вожусь.


    1. TheShock
      20.10.2018 01:25
      +1

      Неужели сложно залить на какой-нибудь хостинг? Тот же github.io?


      1. shuhray
        20.10.2018 05:06

        Для гитхуба ещё не готово, но когда сделаю, здесь на хабре тоже напишу.


  1. Daddy_Cool
    19.10.2018 23:56

    Школьником (в классе 6м кажется) прочитал про кватернионы в «Кванте». Подумал, что четыре числа определяющих кватернион замечательно совпадают с количеством измерений мира. А значит, можно описывать мир кватернионами в которых одно к-число содержит время+три координаты. И эта идея а) моя, б) безусловна гениальна. ))))


    1. SilverHorse
      20.10.2018 16:05
      +1

      Вынужден разочаровать, но эта идея: а) приходила в голову практически любому человеку, который впервые в жизни знакомился с кватернионами как существующим где-то там математическим объектом (я, прочитавший в школе том Аванты+ вслед за старым справочником Выгодского, в их числе); б) нисколько не гениальна, здесь работает принцип, согласно которому мозг ищет закономерности там, где их может не быть, основываясь только на внешнем подобии объектов (кватернионы действительно похожи на алгебраические объекты вида «3+1», фигурирующие в уравнениях СТО и преобразованиях Лоренца, но математически фундаментально от них отличаются); в) предыдущие два пункта становятся очевидны любому, кто начинает копать матчасть и курить матаппарат, задействованный в различных прикладных областях физики.

      Я тоже, будучи школьником, любил находить «очевидные» закономерности и гордиться этим, внутренне считая себя великим гением. Только меня потом быстро опускали с небес на землю, когда я начинал в присутствии кого-то сведущего об этом рассуждать) Отдельное спасибо моему преподу по физике, который любил задавать каверзные вопросы, дающие человеку самому понять, что он заблуждается. Это нормально, все через это проходят, не вы первый, не вы последний.


      1. Daddy_Cool
        21.10.2018 03:31

        Видимо в моем посте было недостаточно смайликов. Через три года я дошел до преобразований Лоренца и моя наивность, в плане того, что я до этого додумался первым (ха-ха) стала очевидна.
        Кстати есть любопытная историческая тема с поиском триплетов (увы, невозможных).


    1. shuhray
      20.10.2018 20:39

      Не огорчайтесь, идея правильная. Есть способ задавать преобразования Лоренца парами кватернионов.


  1. denisart
    20.10.2018 11:53

    Не пытайтесь понять это допущение, потому что логичных причин его существования нет.

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


    1. 1vanK
      20.10.2018 12:50

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


      1. denisart
        20.10.2018 12:59

        Так, о чем именно вы говорите?
        Я говорю о фразе, что i^2 = -1 получается естественно, понять это можно. Нет никакого следствия, а есть много эквивалентных способов построить комплексные числа: удвоение алгебр по Кэли, фактор по неприводимому многочлену, алгебраическое описание группы изометрий R^2,…


  1. Salat13
    20.10.2018 11:53
    +1

    Вот на самом деле видео про Гамильтона и его замечательную жизнь, которое каждый должен посмотреть :)

    No one uses my quaternions, but just you wait


  1. 1vanK
    20.10.2018 11:59

    В свое время тупил и никак не мог понять, почему i^2 = -1, j^2 = -1, но i != j. Потом понял, что есть другая аналогия, (-1)^2 = 1, 1^2 = 1, но 1 != -1 и обрел душевный покой :) Может кому то еще поможет ) А еще понял, что некорректно заявлять, что i = sqrt(-1), как нас учили в школе. Мы можем только i^2 заменить на -1 и обратно.


    1. litwr2
      20.10.2018 12:13

      Почему некорректно?


      1. 1vanK
        20.10.2018 12:19
        +1

        ну потому что тогда получится, что i = sqrt(-1), j = sqrt(-1), а значит i == j, что неправильно


        1. KvanTTT
          21.10.2018 01:20

          Ну и еще как минимум теряется значение -sqrt(-1), которое тоже подходит.


        1. michael_vostrikov
          21.10.2018 10:10

          Можно как-то так писать: i = sqrtx(-1), j = sqrty(-1). В двумерном варианте только одно мнимое направление, там будет просто sqrt(). Просто тут много решений, как у sin(x) = -1, подходит i в любой нечетной степени.


          1. mayorovp
            22.10.2018 09:48

            Нельзя так писать даже для комплексных чисел. Потому что в комплексных числах sqrt — многозначная функция, которая всегда возвращает два значения с противоположными знаками.


            1. michael_vostrikov
              22.10.2018 10:49

              Ну да, я скорее про то, что геометрически это разные sqrt, у одной значения лежат в одной плоскости, у другой в другой.


        1. 0serg
          21.10.2018 14:47

          Не, это Вы просто с комплексным анализом и его «многозначными функциями» толком не знакомы :). С точки зрения комплексного анализа sqrt(1) = ±1 — и +1 и -1 являются значениями sqrt(1) и из этого не следует что -1 == +1. Впрочем из-за этой неоднозначности разумнее конечно все же писать i^2=-1 поскольку sqrt(-1)=±i.


    1. Refridgerator
      21.10.2018 20:19

      Мнимые единицы есть не только в комплексных числах. В дуальных числах i?=0, а в двойных i?=1, при этом i?1. Соответственно и определить в них мнимую единицу как корень из нуля или единицы никак не получится.


  1. 1vanK
    20.10.2018 12:18

    del


    1. 1vanK
      20.10.2018 12:19

      del