Вращение, ориентация и кватернионы

В этом примере рассматриваются концепции трехмерных вращений и того, как кватернионы используются для описания ориентации и вращений. Кватернионы являются перекосным полем гиперкомплексных чисел. Они нашли применение в аэрокосмической, компьютерной графике и виртуальной реальности. В MATLAB ® кватернионная математика может быть представлена путем манипулирования quaternion класс.

The HelperDrawRotation класс используется для иллюстрации нескольких фрагментов этого примера.

dr = HelperDrawRotation;

Повороты в трёх размерностях

Все повороты в 3-D могут быть заданы осью вращения и углом поворота вокруг этой оси. Рассмотрим 3-D изображение чайника на крайнем левом графике. Чайник повернут на 45 степени вокруг оси Z на втором графике. Более комплексное вращение на 15 степени вокруг оси [1 0 1] показано на третьем графике. Кватернионы инкапсулируют ось и угол поворота и имеют алгебру для манипулирования этими вращениями. The quaternion класс, и этот пример, используют соглашение «right-hand rule» для определения вращений. То есть положительное вращение происходит по часовой стрелке вокруг оси вращения, если смотреть с источника.

dr.drawTeapotRotations;

Вращение Точки

Вершины чайника поворачивали вокруг оси вращения в систему координат. Рассмотрим точку (0,7, 0,5), повернутую на 30 степени вокруг оси Z.

figure;
dr.draw2DPointRotation(gca);

Вращение системы координат

Вращение системы координат в некотором смысле противоположно повороту точки. При повороте системы координат точки объекта остаются неподвижными, но система координат ссылки поворачивается. Снова рассмотрим точку (0,7, 0,5). Теперь система координат повернута на 30 степени вокруг оси Z. Обратите внимание, что хотя точка (0,7, 0,5) остается фиксированной, она имеет другие координаты в новой повернутой системе координат ссылки.

figure;
dr.draw2DFrameRotation(gca);

Ориентация

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

Рассмотрим пример, где дочерняя опорная система координат повернута на 30 степени вокруг вектора [1/3 2/3 2/3].

figure;
dr.draw3DOrientation(gca, [1/3 2/3 2/3], 30);

Кватернионы

Кватернионы это числа в выражении

$$a + b\textbf{i} + c\textbf{j} + d\textbf{k}$$

где

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

и$a, b, c,$ и$d$ являются реальными числами. В остальном примере четыре числа$a, b, c,$ и $d$называются частями кватерниона.

Кватернионы для вращений и ориентации

Ось и угол поворота инкапсулированы в кватернионные части. Для единичной векторной оси вращения [x, y, z] и угла поворота, $\alpha$кватернион, описывающий это вращение,

$$\cos\left(\frac{\alpha}{2}\right) +
\sin\left(\frac{\alpha}{2}\right)\left(x\textbf{i} + y\textbf{j}
+ z\textbf{k}\right)$$

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

$$norm(q) = \sqrt{a^2 + b^2 + c^2 + d^2}$$

Существует множество способов создать кватернион в MATLAB, например:

q1 = quaternion(1,2,3,4)
q1 = 

  quaternion


     1 + 2i + 3j + 4k

Массивы кватернионов могут быть сделаны таким же образом:

quaternion([1 10; -1 1], [2 20; -2 2], [3 30; -3 3], [4 40; -4 4])
ans = 

  2x2 quaternion array


      1 +  2i +  3j +  4k     10 + 20i + 30j + 40k
     -1 -  2i -  3j -  4k      1 +  2i +  3j +  4k

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

qmgk = quaternion(magic(4))
qmgk = 

  4x1 quaternion array


     16 +  2i +  3j + 13k
      5 + 11i + 10j +  8k
      9 +  7i +  6j + 12k
      4 + 14i + 15j +  1k

Кватернионы можно индексировать и манипулировать так же, как и любой другой массив:

qmgk(3)
ans = 

  quaternion


      9 +  7i +  6j + 12k

reshape(qmgk,2,2)
ans = 

  2x2 quaternion array


     16 +  2i +  3j + 13k      9 +  7i +  6j + 12k
      5 + 11i + 10j +  8k      4 + 14i + 15j +  1k

[q1; q1]
ans = 

  2x1 quaternion array


     1 + 2i + 3j + 4k
     1 + 2i + 3j + 4k

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

Кватернионы имеют четко определенные арифметические операции. Сложение и вычитание аналогичны комплексным числам: части складываются/вычитаются независимо. Умножение сложнее из-за предыдущего уравнения:

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

Это означает, что умножение кватернионов не коммутативно. То есть$pq \neq qp$ для кватернионов$p$ и. $q$Однако каждый кватернион имеет мультипликативную обратную, поэтому кватернионы могут быть разделены. Массивы quaternion класс можно добавить, вычесть, умножить и разделить в MATLAB.

q = quaternion(1,2,3,4);
p = quaternion(-5,6,-7,8);

Сложение

p + q
ans = 

  quaternion


     -4 +  8i -  4j + 12k

Вычитание

p - q
ans = 

  quaternion


     -6 +  4i - 10j +  4k

Умножение

p*q
ans = 

  quaternion


    -28 - 56i - 30j + 20k

Умножение в обратном порядке (обратите внимание на другой результат)

q*p
ans = 

  quaternion


    -28 + 48i - 14j - 44k

Правое деление p по q эквивалентно.$p(q^{-1})$

p./q
ans = 

  quaternion


         0.6 +  2.2667i + 0.53333j - 0.13333k

Левое деление q по p эквивалентно.$p^{-1}q$

p.\q
ans = 

  quaternion


     0.10345 +  0.2069i +       0j - 0.34483k

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

conj(p)
ans = 

  quaternion


    -5 - 6i + 7j - 8k

Кватернионы могут быть нормированы в MATLAB:

pnormed = normalize(p)
pnormed = 

  quaternion


    -0.37905 + 0.45486i - 0.53067j + 0.60648k

norm(pnormed)
ans =

     1

Повороты точек и систем координат с кватернионами

Кватернионы могут использоваться для поворота точек в статической системе координат ссылки или для поворота самой системы координат ссылки. The rotatepoint функция вращает точку$v = (v_x, v_y, v_z)$ с помощью кватерниона q через следующее уравнение:

$$p v_{quat} p^*$$

где$v_{quat}$

$$v_{quat} = 0 + v_x\textbf{i} + v_y\textbf{j} + v_z\textbf{k}$$

и$p^*$ указывает на кватернионное сопряжение. Обратите внимание, что вышеуказанное умножение кватерниона приводит к кватерниону с вещественной частью, равной $a$0. $b$$c$$d$Части, и результата образуют повернутую точку (,,).$b$$c$$d$

Рассмотрим пример поворота точки сверху. Точку (0,7, 0,5) поворачивали на 30 степени вокруг оси Z. В трёх размерностях эта точка имеет координату 0 Z. Используя формулировку угол-ось, кватернион может быть построен, используя [0 0 1] в качестве оси вращения.

ang = deg2rad(30);
q = quaternion(cos(ang/2), 0, 0, sin(ang/2));
pt = [0.7, 0.5, 0];  % Z-coordinate is 0 in the X-Y plane
ptrot = rotatepoint(q, pt)
ptrot =

    0.3562    0.7830         0

Точно так же rotateframe функция принимает кватернион$q$ и точку$v$, чтобы вычислить

$$p^* v_{quat} p$$

Снова вышеописанное кватернионное умножение приводит к кватерниону с 0 вещественной частью. $b$(,,) $c$$d$части результата образуют координату точки в$v$ новой повернутой системе координат. Использование quaternion класс:

ptframerot = rotateframe(q, pt)
ptframerot =

    0.8562    0.0830         0

Кватернион и его сопряженный имеют противоположные эффекты из-за симметрии в уравнениях поворота точки и системы координат. Вращение сопряженным «отменяет» вращение.

rotateframe(conj(q), ptframerot)
ans =

    0.7000    0.5000         0

Из-за симметрии уравнений этот код выполняет то же вращение.

rotatepoint(q, ptframerot)
ans =

    0.7000    0.5000         0

Другие представления вращения

Часто повороты и ориентации описываются с помощью альтернативных средств: углов Эйлера, матриц поворота и/или векторов поворота. Все они взаимодействуют с кватернионами в MATLAB.

Углы Эйлера часто используются, потому что их легко интерпретировать. Рассмотрим систему координат ссылок, повернутых на 30 степени вокруг оси Z, затем на 20 степени вокруг оси Y, а затем на -50 степени вокруг оси X. При этом повороты вокруг каждой оси являются собственными, каждое последующее вращение - вокруг вновь созданного набора осей. Другими словами, второе вращение вокруг «новой» оси Y, созданной первым вращением, а не вокруг исходной оси Y.

figure;
euld = [30 20 -50];
dr.drawEulerRotation(gca, euld);

Чтобы создать кватернион из этих углов Эйлера с целью поворота системы координат, используйте quaternion конструктор. Поскольку порядок вращений сначала вокруг оси Z, затем вокруг новой оси Y и, наконец, вокруг новой оси X, используйте 'ZYX' флаг.

qeul = quaternion(deg2rad(euld), 'euler', 'ZYX', 'frame')
qeul = 

  quaternion


      0.84313 -  0.44275i + 0.044296j +  0.30189k

The 'euler' флаг указывает, что первый аргумент находится в радианах. Если аргумент находится в степенях, используйте 'eulerd' флаг.

qeuld = quaternion(euld, 'eulerd', 'ZYX', 'frame')
qeuld = 

  quaternion


      0.84313 -  0.44275i + 0.044296j +  0.30189k

Чтобы преобразовать назад в углы Эйлера:

rad2deg(euler(qeul, 'ZYX', 'frame'))
ans =

   30.0000   20.0000  -50.0000

Эквивалентно, eulerd может быть использован метод.

eulerd(qeul, 'ZYX', 'frame')
ans =

   30.0000   20.0000  -50.0000

В качестве альтернативы это же вращение может быть представлено как матрица вращения:

rmat = rotmat(qeul, 'frame')
rmat =

    0.8138    0.4698   -0.3420
   -0.5483    0.4257   -0.7198
   -0.1926    0.7733    0.6040

Преобразование обратно в кватернионы аналогично:

quaternion(rmat, 'rotmat', 'frame')
ans = 

  quaternion


      0.84313 -  0.44275i + 0.044296j +  0.30189k

Так же, как кватернион может использоваться для поворота точки или системы координат, он может быть преобразован в матрицу поворота (или набор углов Эйлера) специально для поворота точки или системы координат. Матрица поворота для поворота точки является транспонированием матрицы для поворота системы координат. Чтобы преобразовать между представлениями поворота, необходимо задать 'point' или 'frame'.

Матрица поворота для участка поворота точки в этом примере:

rotmatPoint = rotmat(q, 'point')
rotmatPoint =

    0.8660   -0.5000         0
    0.5000    0.8660         0
         0         0    1.0000

Чтобы найти местоположение повернутой точки, умножьте правой кнопкой rotmatPoint транспонированным массивом pt.

rotmatPoint * (pt')
ans =

    0.3562
    0.7830
         0

Матрица поворота для секции поворота системы координат этого примера:

rotmatFrame = rotmat(q, 'frame')
rotmatFrame =

    0.8660    0.5000         0
   -0.5000    0.8660         0
         0         0    1.0000

Чтобы найти положение точки во повернутой опорной системе координат, умножьте правой кнопкой rotmatFrame транспонированным массивом pt.

rotmatFrame * (pt')
ans =

    0.8562
    0.0830
         0

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

rv = rotvec(qeul)
rv =

   -0.9349    0.0935    0.6375

Для преобразования в кватернион:

quaternion(rv, 'rotvec')
ans = 

  quaternion


      0.84313 -  0.44275i + 0.044296j +  0.30189k

Расстояние

Одним из преимуществ кватернионов перед углами Эйлера является отсутствие разрывов. Углы Эйлера имеют разрывы, которые варьируются в зависимости от используемой конвенции. The dist функция сравнивает эффект вращения двумя различными кватернионами. Результатом является число в области значений от 0 до pi. Рассмотрим два кватерниона, построенных из углов Эйлера:

eul1 = [0, 10, 0];
eul2 = [0, 15, 0];
qdist1 = quaternion(deg2rad(eul1), 'euler', 'ZYX', 'frame');
qdist2 = quaternion(deg2rad(eul2), 'euler', 'ZYX', 'frame');

Вычитая углы Эйлера, можно увидеть, что вращения вокруг оси Z или оси X нет.

eul2 - eul1
ans =

     0     5     0

Различие между этими двумя вращениями составляет пять степеней вокруг оси Y. The dist показывает также разницу.

rad2deg(dist(qdist1, qdist2))
ans =

    5.0000

Для углов Эйлера, таких как eul1 и eul2Вычисление углового расстояния тривиально. Более сложным примером, который охватывает разрыв угла Эйлера, является:

eul3 = [0, 89, 0];
eul4 = [180, 89, 180];
qdist3 = quaternion(deg2rad(eul3), 'euler', 'ZYX', 'frame');
qdist4 = quaternion(deg2rad(eul4), 'euler', 'ZYX', 'frame');

Хотя eul3 и eul4 представление почти той же ориентации, простое вычитание угла Эйлера создает впечатление, что эти две ориентации очень далеко друг от друга.

euldiff = eul4 - eul3
euldiff =

   180     0   180

Использование dist функция на кватернионах показывает, что существует только двухградусное различие в этих вращениях:

euldist = rad2deg(dist(qdist3, qdist4))
euldist =

    2.0000

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

qpos = quaternion(-cos(pi/4), 0 ,0, sin(pi/4))
qpos = 

  quaternion


    -0.70711 +       0i +       0j + 0.70711k

qneg = -qpos
qneg = 

  quaternion


     0.70711 +       0i +       0j - 0.70711k

qdiff = qpos - qneg
qdiff = 

  quaternion


    -1.4142 +      0i +      0j + 1.4142k

dist(qpos, qneg)
ans =

     0

Поддерживаемые функции

The quaternion Класс позволяет эффективно описать повороты и ориентации в MATLAB. Полный список функций, поддерживаемых кватернионом, можно найти со methods функция:

methods('quaternion')
Methods for class quaternion:

angvel              ismatrix            prod                
cat                 isnan               quaternion          
classUnderlying     isrow               rdivide             
compact             isscalar            reshape             
conj                isvector            rotateframe         
ctranspose          ldivide             rotatepoint         
disp                length              rotmat              
dist                log                 rotvec              
double              meanrot             rotvecd             
eq                  minus               single              
euler               mtimes              size                
eulerd              ndims               slerp               
exp                 ne                  times               
horzcat             norm                transpose           
iscolumn            normalize           uminus              
isempty             numel               validateattributes  
isequal             parts               vertcat             
isequaln            permute             
isfinite            plus                
isinf               power               

Static methods:

ones                zeros