欧拉角、四元数、旋转矩阵的互相转换

概述

方法来自于《3D数学基础,图形与游戏开发》这本书。
学习这些转换可以加深自己对这些知识点的理解~两两转换一共有六种情况,下面就依次列举一下这六种情况。

1.从欧拉角转换到矩阵

这种情况的转换不难,还记得我们的旋转矩阵长啥样吗,欧拉角的三个值就是坐标系绕着特定轴旋转的值,注意是坐标系旋转哦,点的旋转值是和坐标系的旋转值相反的,需要把旋转矩阵的角度取反。
比如下面就是绕y轴的旋转矩阵,角度h取反了,
[ c o s ( − h ) 0 − s i n ( − h ) 0 1 0 s i n ( − h ) 0 c o s ( − h ) ] \begin{bmatrix} cos(-h)&0&-sin(-h)\\ 0&1&0\\ sin(-h)&0&cos(-h)\\ \end{bmatrix} cos(h)0sin(h)010sin(h)0cos(h)
我们根据特定的顺序把三个旋转矩阵乘起来就行了,很简单的。
书上是先绕y轴旋转再绕x轴旋转,再绕z轴旋转,得到的结果为:
[ c o s h c o s b + s i n h s i n p s i n b − c o s h s i n b + s i n h s i n p c o s b s i n h c o s p s i n b c o s p c o s b c o s p − s i n p − s i n h c o s b + c o s h s i n p s i n b s i n b s i n h + c o s h s i n p c o s b c o s h c o s p ] \begin{bmatrix} coshcosb+sinhsinpsinb&-coshsinb+sinhsinpcosb&sinhcosp\\ sinbcosp&cosbcosp&-sinp\\ -sinhcosb+coshsinpsinb&sinbsinh+coshsinpcosb&coshcosp\\ \end{bmatrix} coshcosb+sinhsinpsinbsinbcospsinhcosb+coshsinpsinbcoshsinb+sinhsinpcosbcosbcospsinbsinh+coshsinpcosbsinhcospsinpcoshcosp
这个旋转矩阵是从惯性坐标系旋转到物体坐标系的旋转矩阵。h为绕y轴的旋转角度,p为绕x轴的旋转角度,b为绕z轴的旋转角度。

2.从旋转矩阵到欧拉角

当我们知道了从欧拉角到旋转矩阵的矩阵形式,倒推是一件非常简单的事情,假设上面的矩阵为M,则M23 = -sinp,我们能直接得到绕x轴的旋转角度p,然后把M21/M22能直接得到tanb,所以也能得到绕z的旋转角度b,把M13/M33也能直接得到tanh,然后就能得到角度h,于是这一切问题都解决了,是不是很容易。

3.从四元数转换到旋转矩阵

[ n x 2 ( 1 − c o s θ ) + c o s θ n x n y ( 1 − c o s θ ) + n z s i n θ n x n z ( 1 − c o s θ ) − n y s i n θ n x n y ( 1 − c o s θ ) − n z s i n θ n y 2 ( 1 − c o s θ ) + c o s θ n y n z ( 1 − c o s θ ) + n x s i n θ n x n z ( 1 − c o s θ ) + n y s i n θ n y n z ( 1 − 0 c o s θ ) − n x s i n θ n x 2 ( 1 − c o s θ ) + c o s θ ] \begin{bmatrix} n_x^2(1-cos\theta)+cos\theta & n_xn_y(1-cos\theta)+n_zsin\theta&n_xn_z(1-cos\theta)-n_ysin\theta\\ n_xn_y(1-cos\theta)-n_zsin\theta&n_y^2(1-cos\theta)+cos\theta&n_yn_z(1-cos\theta)+n_xsin_\theta\\ n_xn_z(1-cos\theta)+n_ysin\theta&n_yn_z(1-0cos\theta)-n_xsin\theta&n_x^2(1-cos\theta)+cos\theta \end{bmatrix} nx2(1cosθ)+cosθnxny(1cosθ)nzsinθnxnz(1cosθ)+nysinθnxny(1cosθ)+nzsinθny2(1cosθ)+cosθnynz(10cosθ)nxsinθnxnz(1cosθ)nysinθnynz(1cosθ)+nxsinθnx2(1cosθ)+cosθ

这个东西就是我们绕任意轴n旋转 θ \theta θ的旋转矩阵,具体的推导我有单独介绍过。
然后我们想一下四元数的概念,其四个分量分别是
w = c o s ( θ / 2 ) w = cos(\theta/2) w=cos(θ/2)
x = n x s i n ( θ / 2 ) x = n_xsin(\theta/2) x=nxsin(θ/2)
y = n y s i n ( θ / 2 ) y = n_ysin(\theta/2) y=nysin(θ/2)
z = n z s i n ( θ / 2 ) z = n_zsin(\theta/2) z=nzsin(θ/2)
我们所需要做的事情,仅仅是把上面的矩阵用x,y,z,w替换一下就行了,利用倍角公式
c o s 2 α = 1 − s i n 2 α cos2\alpha = 1-sin^2\alpha cos2α=1sin2α
可以做到这一点,具体的计算过程我不写了,写起来一大串,知道方法即可。
最后得到的结果如下所示:
[ 1 − 2 y 2 − 2 z 2 2 x y + 2 w z 2 x z − 2 w y 2 x y − 2 w z 1 − 2 x 2 − 2 z 2 2 y z + 2 w x 2 x z + 2 w y 2 y z − 2 w x 1 − 2 x 2 − 2 y 2 ] \begin{bmatrix} 1-2y^2-2z^2&2xy+2wz&2xz-2wy\\ 2xy-2wz&1-2x^2-2z^2&2yz+2wx\\ 2xz+2wy&2yz-2wx&1-2x^2-2y^2\\ \end{bmatrix} 12y22z22xy2wz2xz+2wy2xy+2wz12x22z22yz2wx2xz2wy2yz+2wx12x22y2

4.从旋转矩阵到四元数

同旋转矩阵到欧拉角一样,我们需要从矩阵本身来逆推一下,计算原理本身不难,我们设旋转矩阵为M,则有
M 11 + M 22 + M 33 = 4 w 2 − 1 M11+M22+M33=4w^2-1 M11+M22+M33=4w21
M 11 − M 22 − M 33 = 4 x 2 − 1 M11-M22-M33=4x^2-1 M11M22M33=4x21
− M 11 + M 22 − M 33 = 4 y 2 − 1 -M11+M22-M33=4y^2-1 M11+M22M33=4y21
− M 11 − M 22 + M 33 = 4 z 2 − 1 -M11-M22+M33=4z^2-1 M11M22+M33=4z21
这样xyzw我们都可以计算出来,但是我们可以同时得到xyzw互为相反的两个跟,而且我们没有判断根是否正确的依据,因对对于四元数来说,所有元素取反得到的结果是一样的,因为相当于 θ \theta θ加上了一个360°,我们对矩阵进行处理,得到另一种方法:
M12+M21 = 4xy
M12-M21 = 4wz
M31+M13 = 4xz
M31- M13 = 4wy
M23 + M32 = 4yz
M23 - M32 = 4wx
这种积的运算可以保留符号信息,所以我们只需要根据上面的式子计算出任意一个变量,然后通过下面的式子就可以得到所有的值,那么选择先计算哪一个变量呢,书中建议是计算出xyzw的平方值,然后选一个最大的来通过下面的式子来计算出其余的量。

5.从欧拉角到四元数

这个得要从四元数的定义下手,绕着n轴旋转 θ \theta θ的四元数如下:
q = [ c o s ( θ / 2 ) ( ( s i n ( θ / 2 ) n x ) ( s i n ( θ / 2 ) n y ) ( s i n ( θ / 2 ) n z ) ) q = [cos(\theta/2) ((sin(\theta/2)n_x) (sin(\theta/2)n_y) (sin(\theta/2)n_z)) q=[cos(θ/2)((sin(θ/2)nx)(sin(θ/2)ny)(sin(θ/2)nz))
那么我们很容易就能把欧拉角的三个旋转转化为四元数,记住旋转角度要取反,因为欧拉角是坐标轴的旋转,点的旋转和坐标轴的旋转是相反的。
绕y轴
h = [ c o s ( − h / 2 ) ( 0 s i n ( − h / 2 ) 0 ) ] h = [cos(-h/2) (0 sin(-h/2) 0)] h=[cos(h/2)(0sin(h/2)0)]
绕x轴
p = [ c o s ( − p / 2 ) ( s i n ( − p / 2 ) 00 ) ] p = [cos(-p/2) (sin(-p/2)0 0)] p=[cos(p/2)(sin(p/2)00)]
绕z轴
b = [ c o s ( − b / 2 ) ( 00 s i n ( − b / 2 ) ) ] b = [cos(-b/2) (00sin(-b/2))] b=[cos(b/2)(00sin(b/2))]

根据四元组的乘法公式
[ w 1 [ x 1 y 1 z 1 ] ] ∗ [ w 2 [ x 2 y 2 z 2 ] ] = [ w 1 w 2 x 1 x 2 − y 1 y 2 − z 1 z 2 [ w 1 x 2 + x 1 w 2 + z 1 y 2 − y 1 z 2 w 1 y 2 + y 1 w 2 + x 1 z 2 − z 1 x 2 w 1 z 2 + z 1 w 2 + y 1 x 2 − x 1 y 2 ] ] \begin{bmatrix}w1\\\begin{bmatrix}x_1\\y_1\\z_1\\\end{bmatrix}\end{bmatrix}* \begin{bmatrix}w2\\\begin{bmatrix}x_2\\y_2\\z_2\\\end{bmatrix}\end{bmatrix}=\begin{bmatrix}w_1w_2x_1x_2-y_1y_2-z_1z_2\\\begin{bmatrix}w_1x_2+x_1w_2+z_1y_2-y_1z_2\\w_1y_2+y_1w_2+x_1z_2-z_1x_2\\w_1z_2+z_1w_2+y_1x_2-x_1y_2\\\end{bmatrix}\end{bmatrix} w1x1y1z1w2x2y2z2=w1w2x1x2y1y2z1z2w1x2+x1w2+z1y2y1z2w1y2+y1w2+x1z2z1x2w1z2+z1w2+y1x2x1y2
依次把三个四元组相乘,就能得到最后的结果了,结果为:
h q b = [ c o s ( h / 2 ) c o s ( p / 2 ) c o s ( b / 2 ) + s i n ( h / 2 ) s i n ( p / 2 ) s i n ( b / 2 ) [ c o s ( h / 2 ) s i n ( p / 2 ) c o s ( b / 2 ) + s i n ( h / 2 ) c o s ( p / 2 ) s i n ( b / 2 ) s i n ( h / 2 ) c o s ( p / 2 ) c o s ( b / 2 ) − c o s ( h / 2 ) s i n ( p / 2 ) s i n ( b / 2 ) c o s ( h / 2 ) c o s ( p / 2 ) s i n ( b / 2 ) − s i n ( h / 2 ) s i n ( p / 2 ) c o s ( b / 2 ) ] ] hqb=\begin{bmatrix}cos(h/2)cos(p/2)cos(b/2)+sin(h/2)sin(p/2)sin(b/2)\\ \begin{bmatrix}cos(h/2)sin(p/2)cos(b/2)+sin(h/2)cos(p/2)sin(b/2)\\sin(h/2)cos(p/2)cos(b/2)-cos(h/2)sin(p/2)sin(b/2)\\cos(h/2)cos(p/2)sin(b/2)-sin(h/2)sin(p/2)cos(b/2)\\\end{bmatrix} \end{bmatrix} hqb=cos(h/2)cos(p/2)cos(b/2)+sin(h/2)sin(p/2)sin(b/2)cos(h/2)sin(p/2)cos(b/2)+sin(h/2)cos(p/2)sin(b/2)sin(h/2)cos(p/2)cos(b/2)cos(h/2)sin(p/2)sin(b/2)cos(h/2)cos(p/2)sin(b/2)sin(h/2)sin(p/2)cos(b/2)

6.从四元数到欧拉角

这个变换我们可以利用旋转矩阵作为中间变量,我们知道旋转矩阵如何表示欧拉角,
p = arcsin(-m23)
h = arctan(m13/m33) cosp!=0
h = arctan(-m31/m11)cosp=0
b = arctan(m13/m33) cosp!=0
b = 0 cosp=0
然而这里涉及到的矩阵的所有的值都可以用四元数表示出来,参考从四元数到旋转矩阵的公式,然后只需要代入到上面的公式就行了,结果如下所示:
p = arcsin(-2(yz+wx))
h = arctan(xz-wy/(1/2-x2-y2)) cosp!=0
h = arctan(-xz-wy/(1/2-y2-z2)) cosp=0
b = arctan(xy-wz/(1/2-x2-z2)) cosp!=0
b=0 cosp = 0

你可能感兴趣的:(图形学基础知识)