На главную Назад Вперёд

Кватернионы

Кватернионы – очень удобное представление поворотных гомотетий трёхмерного пространства. По оси вращения, углу поворота и коэффициенту гомотетии можно построить некий числоподобный объект, называемый кватернионом, который будет задавать соответствующую поворотную гомотетию.

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

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

Кватернион с компонентами \((a_0,a_1,a_2,a_3)\) традиционно записывают так:

\[a_0+a_1 I+a_2 J+a_3 K\]

Над кватернионами определено две операции: сумма и произведение. Сумма производится покомпонентно. Произведение – в соответствии с распределительным законом и равенствами

\[II = -1;\quad JJ = -1;\quad KK = -1\]

\[IJ=K;\quad JK=I;\quad KI=J\]

\[JI=-K;\quad KJ=-I;\quad IK=-J\]

В целях упрощения записи введём ещё одно полезное определение. Пусть \(e_1,e_2,e_3\) – ортонормированный базис в трёхмерном пространстве. Тогда кватернионизацией вектора

\[v=\alpha_1 e_1 + \alpha_2 e_2 + \alpha_3 e_3\]

будем называть кватернион

\[[v] = \alpha_1 I + \alpha_2 J + \alpha_3 K\]

Это определение позволяет любой кватернион \(q\) записывать в виде

\[ q = \alpha + [a] \]

При этом произведение двух кватернионизаций \([a]\) и \([b]\) можно вычислить так:

\[[a][b] = -a\cdot b + [a\times b]\]

Также для кватернионов вводится операция комплексного сопряжения:

\[(\alpha + [a])^* = \alpha - [a]\]

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

\[(\alpha + [a])(\alpha - [a]) = \alpha^2 + a\cdot a\]

Корень из \(qq^*\) (то есть из суммы квадратов компонент) обозначается \(|q|\) и называется длиной кватерниона \(q\).

Геометрический смысл кватернионов

Пусть \(v\) – произвольный вектор в трёхмерном пространстве, а \(q=\alpha + [a]\). Рассмотрим следующее выражение:

\[q[v]q^*\]

Преобразуем его:

\[(\alpha + [a])[v](\alpha - [a]) = (\alpha [v] - a\dot v + [a\times v])(\alpha - [a]) = \]

\[ = \alpha^2 [v] + (a\dot v) [a] + 2\alpha [a\times v] - [(a\times v)\times a]\]

\[ = [\alpha^2 v + (a\dot v) a + 2\alpha (a\times v) - (a\times v)\times a] \]

То есть мы получили следующий факт: \(qvq^*\) является результатом кватернионизации некоторого вектора, который мы сейчас вычислим в удобном нам базисе.

Пусть \(f_1, f_2, f_3\)ортонормированный базис, в котором \(a = \beta f_1\) и \(v = \delta f_1 + \epsilon f_2\) (этот базис никак не коррелирует с базисом \(e_1, e_2, e_3\), относительно которого производится кватернионизация). В этом базисе интересующий нас вектор равен:

\[ \alpha^2 (\delta f_1 + \epsilon f_2) + \beta^2\delta f_1 + 2\alpha\beta\epsilon f_3 - \beta^2\epsilon f_2 = \]

\[ = (\alpha^2 + \beta^2)\delta f_1 + \epsilon ( (\alpha^2 - \beta^2) f_2 + 2\alpha\beta f_3 ) \]

Заметим, что если \(\alpha = k\cos\varphi\) и \(\beta = k\sin\varphi\), то наш вектор равен

\[ k^2 ( \delta f_1 + \epsilon (f_2 \cos(2\varphi) + f_3 \sin(2\varphi) ) ) \]

Как можно заметить, это – в точности результат поворотной гомотетии относительно оси \(f_1\) на угол \(2\varphi\) в положительном направлении с коэффициентом растяжения \(k^2\).

В частности, отображение

\[\lambda_v\, q[v]q^*\]

для \(q=\cos(\psi/2) + [n]\sin(\psi/2)\), где \(|n|=1\), задаёт поворот на угол \(\psi\) относительно оси \(n\) (строго говоря, к правой части этой формулы нужно ещё применить операцию «взять векторную часть»).

Кватернионы и композиция поворотных гомотетий

Путём нехитрых вычислений (всего-то нужно пару раз сложить 64 слагаемых) легко понять, что произведение кватернионов ассоциативно (обладает сочетательным законом), то есть \(a(bc) = (ab)c\). Ассоциативность выгодно отличает произведение кватернионов от векторного произведения, которое таковой не обладает (у векторного произведения вместо ассоциативности т.н. тождество Якоби).

Также нетрудно проверить, что \((ab)^* = b^*a^*\). Поэтому, если мы обозначим

\[ F(q) = \lambda_x\, qxq^* \]

то будет выполнено замечательное равенство:

\[ F(a)\circ F(b) = \lambda_x\, a(bxb^*)a^* = \lambda_x\, (ab)x(ab)^* = F(ab) \]

Смысл этого равенства прост: произведение кватернионов задаёт композицию соответствующих поворотных гомотетий.

Моделирование кватернионов в GLSL

В качестве примера приведём несколько полезных операций для работы с кватернионами, реализованных на GLSL. Кватернионы моделируются четырёхмерными векторами. Скалярная часть кватерниона предполагается находящейся в четвёртой компоненте таких векторов.

// кватернионизация
vec4 qlift(vec3 v) {
    return vec4(v.x, v.y, v.z, 0);
}

// произведение
vec4 qmul(vec4 a, vec4 b) {
    float sa = a.w;
    float sb = b.w;
    vec3  va = a.xyz;
    vec3  vb = b.xyz;

    vec3  v = cross(va, vb) + sa*vb + sb*va;
    float s = - dot(va, vb) + sa*sb;

    return vec4(v.x, v.y, v.z, s);
}

// сопряжённый кватернион
vec4 qconj(vec4 q) {
    return vec4(-q.x,-q.y,-q.z,q.w);
}

// кватернион поворота
vec4 qrot(vec3 axle, float angle) {
    vec3 n = axle / length(axle);

    vec3 v  = sin(angle/2) * n;
    float s = cos(angle/2);

    return vec4(v.x, v.y, v.z, s);
}

// "применение" кватерниона
vec3 apply(vec4 q, vec3 v) {
    return qmul(qmul(q, qlift(v)), qconj(q)).xyz;
}

@ 2016 arbrk1, all rights reversed