В этом примере рассматриваются концепции трехмерных вращений и того, как кватернионы используются для описания ориентации и вращений. Кватернионы являются перекосным полем гиперкомплексных чисел. Они нашли применение в аэрокосмической, компьютерной графике и виртуальной реальности. В 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);
Кватернионы это числа в выражении
где
и и являются реальными числами. В остальном примере четыре числа и называются частями кватерниона.
Ось и угол поворота инкапсулированы в кватернионные части. Для единичной векторной оси вращения [x, y, z] и угла поворота, кватернион, описывающий это вращение,
Обратите внимание, что чтобы описать вращение с помощью кватерниона, кватернион должен быть модулем кватернионом. Кватернион модуля имеет норму 1, где норма определяется как
Существует множество способов создать кватернион в 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
Кватернионы имеют четко определенные арифметические операции. Сложение и вычитание аналогичны комплексным числам: части складываются/вычитаются независимо. Умножение сложнее из-за предыдущего уравнения:
Это означает, что умножение кватернионов не коммутативно. То есть для кватернионов и. Однако каждый кватернион имеет мультипликативную обратную, поэтому кватернионы могут быть разделены. Массивы 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
ans = quaternion 0.6 + 2.2667i + 0.53333j - 0.13333k
Левое деление q
по p
эквивалентно.
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
функция вращает точку с помощью кватерниона q через следующее уравнение:
где
и указывает на кватернионное сопряжение. Обратите внимание, что вышеуказанное умножение кватерниона приводит к кватерниону с вещественной частью, равной 0. Части, и результата образуют повернутую точку (,,).
Рассмотрим пример поворота точки сверху. Точку (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
функция принимает кватернион и точку, чтобы вычислить
Снова вышеописанное кватернионное умножение приводит к кватерниону с 0 вещественной частью. (,,) части результата образуют координату точки в новой повернутой системе координат. Использование 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