概述
方法来自于《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}
⎣ ⎡ c o s ( − h ) 0 s i n ( − h ) 0 1 0 − s i n ( − h ) 0 c o s ( − 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}
⎣ ⎡ c o s h c o s b + s i n h s i n p s i n b s i n b c o s p − s i n h c o s b + c o s 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 c o s b c o s p s i n b s i n h + c o s h s i n p c o s b s i n h c o s p − s i n p c o s h c o s p ⎦ ⎤ 这个旋转矩阵是从惯性坐标系旋转到物体坐标系的旋转矩阵。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}
⎣ ⎡ 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 − 0 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 − c o s θ ) + n x s i n θ n x 2 ( 1 − c o s θ ) + c o s θ ⎦ ⎤
这个东西就是我们绕任意轴n旋转
θ
\theta
θ 的旋转矩阵,具体的推导我有单独介绍过。 然后我们想一下四元数的概念,其四个分量分别是
w
=
c
o
s
(
θ
/
2
)
w = cos(\theta/2)
w = c o s ( θ / 2 )
x
=
n
x
s
i
n
(
θ
/
2
)
x = n_xsin(\theta/2)
x = n x s i n ( θ / 2 )
y
=
n
y
s
i
n
(
θ
/
2
)
y = n_ysin(\theta/2)
y = n y s i n ( θ / 2 )
z
=
n
z
s
i
n
(
θ
/
2
)
z = n_zsin(\theta/2)
z = n z s i n ( θ / 2 ) 我们所需要做的事情,仅仅是把上面的矩阵用x,y,z,w替换一下就行了,利用倍角公式
c
o
s
2
α
=
1
−
s
i
n
2
α
cos2\alpha = 1-sin^2\alpha
c o s 2 α = 1 − s i n 2 α 可以做到这一点,具体的计算过程我不写了,写起来一大串,知道方法即可。 最后得到的结果如下所示:
[
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}
⎣ ⎡ 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 ⎦ ⎤
4.从旋转矩阵到四元数
同旋转矩阵到欧拉角一样,我们需要从矩阵本身来逆推一下,计算原理本身不难,我们设旋转矩阵为M,则有
M
11
+
M
22
+
M
33
=
4
w
2
−
1
M11+M22+M33=4w^2-1
M 1 1 + M 2 2 + M 3 3 = 4 w 2 − 1
M
11
−
M
22
−
M
33
=
4
x
2
−
1
M11-M22-M33=4x^2-1
M 1 1 − M 2 2 − M 3 3 = 4 x 2 − 1
−
M
11
+
M
22
−
M
33
=
4
y
2
−
1
-M11+M22-M33=4y^2-1
− M 1 1 + M 2 2 − M 3 3 = 4 y 2 − 1
−
M
11
−
M
22
+
M
33
=
4
z
2
−
1
-M11-M22+M33=4z^2-1
− M 1 1 − M 2 2 + M 3 3 = 4 z 2 − 1 这样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 = [ c o s ( θ / 2 ) ( ( s i n ( θ / 2 ) n x ) ( s i n ( θ / 2 ) n y ) ( s i n ( θ / 2 ) n z ) ) 那么我们很容易就能把欧拉角的三个旋转转化为四元数,记住旋转角度要取反,因为欧拉角是坐标轴的旋转,点的旋转和坐标轴的旋转是相反的。 绕y轴
h
=
[
c
o
s
(
−
h
/
2
)
(
0
s
i
n
(
−
h
/
2
)
0
)
]
h = [cos(-h/2) (0 sin(-h/2) 0)]
h = [ c o s ( − h / 2 ) ( 0 s i n ( − 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 = [ c o s ( − p / 2 ) ( s i n ( − p / 2 ) 0 0 ) ] 绕z轴
b
=
[
c
o
s
(
−
b
/
2
)
(
00
s
i
n
(
−
b
/
2
)
)
]
b = [cos(-b/2) (00sin(-b/2))]
b = [ c o s ( − b / 2 ) ( 0 0 s i n ( − 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}
⎣ ⎢ ⎢ ⎡ 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 ⎦ ⎤ ⎦ ⎥ ⎥ ⎤ 依次把三个四元组相乘,就能得到最后的结果了,结果为:
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}
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 ) ⎦ ⎤ ⎦ ⎥ ⎥ ⎤
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-y 2)) cosp!=0 h = arctan(-xz-wy/(1/2-y2-z 2)) cosp=0 b = arctan(xy-wz/(1/2-x2-z 2)) cosp!=0 b=0 cosp = 0