1、简介
旋转变换是计算机图像学中应用非常广泛的一种变换,为了后面解释的需要,我们也添加了平移变换、缩放变化等内容。文章重点介绍关于旋转的变换,包括二维旋转变换、三维旋转变换以及它的一些表达方式(旋转矩阵、四元数、欧拉角等)。
2、平移变换
将三维空间中的一个点 [ x , y , z , 1 ] [x, y, z, 1] [ x , y , z , 1 ] 移动到另外一个点 [ x ′ , y ′ , z ′ , 1 ] [x', y', z', 1] [ x ′ , y ′ , z ′ , 1 ] ,三个坐标轴的移动分量分别为d x = T x , d y = T y , d z = T z , dx=Tx, dy=Ty, dz=Tz, d x = T x , d y = T y , d z = T z , 即
{ x ′ = x + T x y ′ = y + T y z ′ = z + T z \begin{cases} x' = x + Tx \\ y' = y + Ty \\ z' = z + Tz \end{cases} ⎩ ⎪ ⎨ ⎪ ⎧ x ′ = x + T x y ′ = y + T y z ′ = z + T z
平移变换的矩阵如下。
[ x ′ y ′ z ′ 1 ] = [ 1 0 0 T x 0 1 0 T y 0 0 1 T z 0 0 0 1 ] ⋅ [ x y z 1 ] \begin{bmatrix} x'\\ y' \\ z' \\1 \end {bmatrix} = \begin {bmatrix} 1 & 0 & 0 & Tx \\ 0 & 1 &0 & Ty \\ 0 & 0 & 1 & Tz \\ 0 & 0 & 0 & 1 \end {bmatrix} \cdot \begin{bmatrix} x \\ y \\ z \\ 1 \end {bmatrix} ⎣ ⎢ ⎢ ⎡ x ′ y ′ z ′ 1 ⎦ ⎥ ⎥ ⎤ = ⎣ ⎢ ⎢ ⎡ 1 0 0 0 0 1 0 0 0 0 1 0 T x T y T z 1 ⎦ ⎥ ⎥ ⎤ ⋅ ⎣ ⎢ ⎢ ⎡ x y z 1 ⎦ ⎥ ⎥ ⎤
3、缩放变换
将模型放大或者缩小,本质也是对模型上每个顶点进行放大和缩小(顶点坐标值变大或变小),假设变换前的点是 [ x , y , z , 1 ] [x, y, z, 1] [ x , y , z , 1 ] ,变换后的点是 [ x ′ , y ′ , z ′ , 1 ] [x', y', z', 1] [ x ′ , y ′ , z ′ , 1 ] ,那么
{ x ′ = x ∗ S x y ′ = y ∗ S y z ′ = z ∗ S z \begin{cases} x' = x * S_x \\ y' = y * S_y \\ z' = z * S_z \end{cases} ⎩ ⎪ ⎨ ⎪ ⎧ x ′ = x ∗ S x y ′ = y ∗ S y z ′ = z ∗ S z
缩放变换的矩阵如下。
[ x ′ y ′ z ′ 1 ] = [ S x 0 0 0 0 S y 0 0 0 0 S z 0 0 0 0 1 ] ⋅ [ x y z 1 ] \begin{bmatrix} x'\\ y' \\ z' \\1 \end {bmatrix} = \begin {bmatrix} S_x & 0 & 0 & 0 \\ 0 & S_y &0 & 0 \\ 0 & 0 & S_z & 0 \\ 0 & 0 & 0 & 1 \end {bmatrix} \cdot \begin{bmatrix} x \\ y \\ z \\ 1 \end {bmatrix} ⎣ ⎢ ⎢ ⎡ x ′ y ′ z ′ 1 ⎦ ⎥ ⎥ ⎤ = ⎣ ⎢ ⎢ ⎡ S x 0 0 0 0 S y 0 0 0 0 S z 0 0 0 0 1 ⎦ ⎥ ⎥ ⎤ ⋅ ⎣ ⎢ ⎢ ⎡ x y z 1 ⎦ ⎥ ⎥ ⎤
3、逆矩阵
平移变换矩阵的逆矩阵与原来的平移量相同,但是方向相反。
T − 1 ⋅ T = [ 1 0 0 − T x 0 1 0 − T y 0 0 1 − T z 0 0 0 1 ] ⋅ [ 1 0 0 T x 0 1 0 T y 0 0 1 T z 0 0 0 1 ] = I T^{-1} \cdot T = \begin {bmatrix} 1 & 0 & 0 & -T_x \\ 0 & 1 & 0 & -T_y \\ 0 & 0& 1 & -T_z \\ 0 & 0 & 0 & 1 \end {bmatrix} \cdot \begin{bmatrix} 1 & 0 & 0 & T_x \\ 0 & 1 & 0 & T_y \\ 0 & 0& 1 & T_z \\ 0 & 0 & 0 & 1 \end {bmatrix} = I \quad T − 1 ⋅ T = ⎣ ⎢ ⎢ ⎡ 1 0 0 0 0 1 0 0 0 0 1 0 − T x − T y − T z 1 ⎦ ⎥ ⎥ ⎤ ⋅ ⎣ ⎢ ⎢ ⎡ 1 0 0 0 0 1 0 0 0 0 1 0 T x T y T z 1 ⎦ ⎥ ⎥ ⎤ = I
旋转变换矩阵的逆矩阵与原来的旋转轴相同但是角度相反。
R − 1 ⋅ R = [ 1 0 0 0 0 c o s θ s i n θ 0 0 − s i n θ c o s θ 0 0 0 0 1 ] ⋅ [ 1 0 0 0 0 c o s θ − s i n θ 0 0 s i n θ c o s θ 0 0 0 0 1 ] = I R^{-1} \cdot R = \begin {bmatrix} 1 & 0 & 0 & 0 \\ 0 & cos\theta & sin\theta & 0 \\ 0 & -sin\theta & cos\theta & 0 \\ 0 & 0 & 0 & 1 \end {bmatrix} \cdot \begin {bmatrix} 1 & 0 & 0 & 0 \\ 0 & cos\theta & -sin\theta & 0 \\ 0 & sin\theta & cos\theta & 0 \\ 0 & 0 & 0 & 1 \end {bmatrix}= I R − 1 ⋅ R = ⎣ ⎢ ⎢ ⎡ 1 0 0 0 0 c o s θ − s i n θ 0 0 s i n θ c o s θ 0 0 0 0 1 ⎦ ⎥ ⎥ ⎤ ⋅ ⎣ ⎢ ⎢ ⎡ 1 0 0 0 0 c o s θ s i n θ 0 0 − s i n θ c o s θ 0 0 0 0 1 ⎦ ⎥ ⎥ ⎤ = I
R − 1 ⋅ R = [ c o s θ 0 − s i n θ 0 0 1 0 0 s i n θ 0 c o s θ 0 0 0 0 1 ] ⋅ [ c o s θ 0 s i n θ 0 0 1 0 0 − s i n θ 0 c o s θ 0 0 0 0 1 ] = I R^{-1} \cdot R = \begin {bmatrix} cos\theta & 0 & -sin\theta & 0 \\ 0 & 1 & 0 & 0 \\ sin\theta & 0 & cos\theta & 0 \\ 0 & 0 & 0 & 1 \end {bmatrix} \cdot \begin {bmatrix} cos\theta & 0 & sin\theta & 0 \\ 0 & 1 & 0 & 0 \\ -sin\theta & 0 & cos\theta & 0 \\ 0 & 0 & 0 & 1 \end {bmatrix} = I R − 1 ⋅ R = ⎣ ⎢ ⎢ ⎡ c o s θ 0 s i n θ 0 0 1 0 0 − s i n θ 0 c o s θ 0 0 0 0 1 ⎦ ⎥ ⎥ ⎤ ⋅ ⎣ ⎢ ⎢ ⎡ c o s θ 0 − s i n θ 0 0 1 0 0 s i n θ 0 c o s θ 0 0 0 0 1 ⎦ ⎥ ⎥ ⎤ = I
R − 1 ⋅ R = [ c o s θ s i n θ 0 0 − s i n θ c o s θ 0 0 0 0 1 0 0 0 0 1 ] ⋅ [ c o s θ − s i n θ 0 0 s i n θ c o s θ 0 0 0 0 1 0 0 0 0 1 ] = I R^{-1} \cdot R = \begin {bmatrix} cos\theta & sin\theta & 0 & 0 \\ -sin\theta & cos\theta & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end {bmatrix} \cdot \begin {bmatrix} cos\theta & -sin\theta & 0 & 0 \\ sin\theta & cos\theta & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end {bmatrix} = I R − 1 ⋅ R = ⎣ ⎢ ⎢ ⎡ c o s θ − s i n θ 0 0 s i n θ c o s θ 0 0 0 0 1 0 0 0 0 1 ⎦ ⎥ ⎥ ⎤ ⋅ ⎣ ⎢ ⎢ ⎡ c o s θ s i n θ 0 0 − s i n θ c o s θ 0 0 0 0 1 0 0 0 0 1 ⎦ ⎥ ⎥ ⎤ = I
4、旋转变换
4.1 绕原点二维旋转
首先要明确旋转在二维中是绕着某一个点进行旋转,三维中是绕着某一个轴进行旋转。二维旋转中最简单的场景是绕着坐标原点进行的旋转,如下图所示:
如图所示点 ( x , y ) (x, y) ( x , y ) 绕原点 逆时针旋转 θ \theta θ 角 ,得到点 ( x ′ , y ′ ) (x', y') ( x ′ , y ′ )
注:此处的 θ \theta θ 为负值,因此旋转过后的 ( x ′ , y ′ ) (x',y') ( x ′ , y ′ ) 坐标采用 ( α + θ ) (\alpha + \theta) ( α + θ ) 而不是 ( α − θ ) (\alpha - \theta) ( α − θ )
矩阵解释:
[ x ′ y ′ ] = [ c o s θ − s i n θ c o s θ s i n θ ] ⋅ [ x y ] \begin{bmatrix} x'\\ y' \end {bmatrix} = \begin {bmatrix} cos\theta & -sin\theta \\ cos\theta & sin\theta \end {bmatrix} \cdot \begin{bmatrix} x\\ y \end {bmatrix} [ x ′ y ′ ] = [ c o s θ c o s θ − s i n θ s i n θ ] ⋅ [ x y ]
利用矩阵乘法展开为
{ x ′ = x ⋅ c o s θ − y ⋅ s i n θ y ′ = x ⋅ c o s θ + y ⋅ s i n θ \begin{cases}x' = x\cdot cos\theta - y\cdot sin\theta \\ y' =x\cdot cos\theta+y\cdot sin\theta\end{cases} { x ′ = x ⋅ c o s θ − y ⋅ s i n θ y ′ = x ⋅ c o s θ + y ⋅ s i n θ
极坐标解释:
此处不用直角坐标系解释,极坐标解释更便于理解( x , y ) (x,y) ( x , y ) 坐标:{ x = r ⋅ c o s α y = r ⋅ s i n α \begin{cases}x = r\cdot cos\alpha \\ y =r \cdot sin\alpha \end{cases} { x = r ⋅ c o s α y = r ⋅ s i n α
( x ′ , y ′ ) (x',y') ( x ′ , y ′ ) 坐标:{ x ′ = r ⋅ c o s ( α + θ ) = r ⋅ c o s α ⋅ c o s θ − r ⋅ s i n α ⋅ s i n θ = x ⋅ c o s θ − y ⋅ s i n θ y ′ = r ⋅ s i n ( α + θ ) = r ⋅ s i n α ⋅ c o s θ + r ⋅ c o s α ⋅ s i n θ = x ⋅ c o s θ + y ⋅ s i n θ \begin{cases}x' = r\cdot cos(\alpha + \theta) \\ \space\space\space\space\space = r\cdot cos\alpha\cdot cos \theta - r \cdot sin \alpha\cdot sin \theta \\ \space\space\space\space\space = x\cdot cos \theta -y\cdot sin \theta \\ \\ y' =r \cdot sin(\alpha + \theta) \\ \space\space\space\space\space = r\cdot sin\alpha\cdot cos \theta + r \cdot cos \alpha\cdot sin \theta \\ \space\space\space\space\space = x\cdot cos \theta +y\cdot sin \theta \end{cases} ⎩ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎨ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎪ ⎧ x ′ = r ⋅ c o s ( α + θ ) = r ⋅ c o s α ⋅ c o s θ − r ⋅ s i n α ⋅ s i n θ = x ⋅ c o s θ − y ⋅ s i n θ y ′ = r ⋅ s i n ( α + θ ) = r ⋅ s i n α ⋅ c o s θ + r ⋅ c o s α ⋅ s i n θ = x ⋅ c o s θ + y ⋅ s i n θ
4.2 绕任意点的二维旋转
绕原点的旋转是二维旋转最基本的情况,当我们需要进行绕任意点旋转时,我们可以把这种情况转换到绕原点的旋转,思路如下:
首先将旋转点移动到原点处
执行如2所描述的绕原点的旋转
再将旋转点移回到原来的位置
也就是说在处理绕任意点旋转的情况下需要执行两次平移的操作。假设平移的矩阵是 T ( x , y ) T(x,y) T ( x , y ) ,也就是说我们需要得到的坐标 v ′ = T ( x , y ) ∗ R ∗ T ( − x , − y ) v'=T(x,y)*R*T(-x,-y) v ′ = T ( x , y ) ∗ R ∗ T ( − x , − y ) (我们使用的是列坐标描述点的坐标,因此是左乘,首先执行 T ( − x , − y ) T(-x,-y) T ( − x , − y )
在计算机图形学中,为了统一将平移、旋转、缩放等用矩阵表示,需要引入齐次坐标。(假设使用2x2的矩阵,是没有办法描述平移操作的,只有引入3x3矩阵形式,才能统一描述二维中的平移、旋转、缩放操作。同理必须使用4x4的矩阵才能统一描述三维的变换)。
对于二维平移,如下图所示,P P P 点经过x和y方向的平移到 P ′ P' P ′ 点,可以得到:
{ x ′ = x + t x y ′ = y + t y \begin{cases} x′=x+t_x \\ y′=y+t_y \end{cases} { x ′ = x + t x y ′ = y + t y
由于引入了齐次坐标,在描述二维坐标的时候,使用 ( x , y , w ) (x,y,w) ( x , y , w ) 的方式(一般 w = 1 w=1 w = 1 ),于是可以写成下面矩阵的形式
[ x ′ y ′ 1 ] = [ 1 0 t x 0 1 t y 0 0 1 ] ⋅ [ x y 1 ] \begin{bmatrix} x'\\ y' \\1 \end {bmatrix} = \begin {bmatrix} 1 & 0 &tx \\ 0 & 1 & ty \\ 0 & 0 & 1 \end {bmatrix} \cdot \begin{bmatrix} x \\ y \\ 1 \end {bmatrix} ⎣ ⎡ x ′ y ′ 1 ⎦ ⎤ = ⎣ ⎡ 1 0 0 0 1 0 t x t y 1 ⎦ ⎤ ⋅ ⎣ ⎡ x y 1 ⎦ ⎤
按矩阵乘法展开,正好得到上面的表达式。其中平移矩阵是
[ 1 0 t x 0 1 t y 0 0 1 ] \quad \begin {bmatrix} 1 & 0 &tx \\ 0 & 1 & ty \\ 0 & 0 & 1 \end {bmatrix} ⎣ ⎡ 1 0 0 0 1 0 t x t y 1 ⎦ ⎤
此时将绕原点二维旋转 中描述的旋转矩阵也扩展到 3x3 的方式,变为:
[ x ′ y ′ 1 ] = [ c o s θ − s i n θ 0 s i n θ c o s θ 0 0 0 1 ] ⋅ [ x y 1 ] \begin{bmatrix} x'\\ y' \\1 \end {bmatrix} = \begin {bmatrix} cos\theta & -sin\theta & 0 \\ sin\theta & cos\theta & 0 \\ 0 & 0 & 1 \end {bmatrix} \cdot \begin{bmatrix} x \\ y \\ 1 \end {bmatrix} ⎣ ⎡ x ′ y ′ 1 ⎦ ⎤ = ⎣ ⎡ c o s θ s i n θ 0 − s i n θ c o s θ 0 0 0 1 ⎦ ⎤ ⋅ ⎣ ⎡ x y 1 ⎦ ⎤
从平移和旋转的矩阵可以看出,3x3 矩阵的前 2x2 部分是和旋转相关的,第三列与平移相关。有了上面的基础之后,我们很容易得出二维中绕任意点旋转的旋转矩阵了,只需要把三个矩阵乘起来即可:
M = [ 1 − 0 t x 0 1 t y 0 0 1 ] ⋅ [ c o s θ − s i n θ 0 s i n θ c o s θ 0 0 0 1 ] ⋅ [ 1 0 − t x 0 1 − t y 0 0 1 ] M = \begin {bmatrix} 1 & -0 & tx \\ 0 & 1 & ty \\ 0 & 0 & 1 \end {bmatrix} \cdot \begin {bmatrix} cos\theta & -sin\theta & 0 \\ sin\theta & cos\theta & 0 \\ 0 & 0 & 1 \end {bmatrix} \cdot \begin {bmatrix} 1 & 0 & -tx \\ 0 & 1 & -ty \\ 0 & 0 & 1 \end {bmatrix} M = ⎣ ⎡ 1 0 0 − 0 1 0 t x t y 1 ⎦ ⎤ ⋅ ⎣ ⎡ c o s θ s i n θ 0 − s i n θ c o s θ 0 0 0 1 ⎦ ⎤ ⋅ ⎣ ⎡ 1 0 0 0 1 0 − t x − t y 1 ⎦ ⎤
4.3 三维基本旋转
我们可以把一个旋转转换为绕基本坐标轴的旋转,因此有必要讨论一下绕三个坐标值 x , y , z x,y,z x , y , z 的旋转。
本文在讨论过程中使用的是类似于OpenGL中定义的右手坐标系,同时旋转角度的正负也遵循右手坐标系的约定。如下图所示
4.3.1 绕X轴的旋转
在三维场景中,当一个点 P ( x , y , z ) P(x,y,z) P ( x , y , z ) 绕 X X X 轴旋转 θ \theta θ 角得到点 P ′ ( x ′ , y ′ , z ′ ) P'(x',y',z') P ′ ( x ′ , y ′ , z ′ ) 。由于是绕 X X X 轴进行的旋转,因此 X X X 坐标保持不变,Y Y Y 和 Z Z Z 组成的 Y O Z YOZ Y O Z ( O O O 是坐标原点)平面上进行的是一个二维的旋转,可以参考上图(Y Y Y 轴类似于二维旋转中的 X X X 轴,Z Z Z 轴类似于二维旋转中的 Y Y Y 轴),于是有:
{ x ′ = x y ′ = y c o s θ − z s i n θ z ′ = y s i n θ + z c o s θ \begin{cases} x′=x \\ y′=ycos\theta−zsin\theta \\ z′=ysin\theta+zcos\theta \end{cases} ⎩ ⎪ ⎨ ⎪ ⎧ x ′ = x y ′ = y c o s θ − z s i n θ z ′ = y s i n θ + z c o s θ
写成(4x4)矩阵的形式
[ x ′ y ′ z ′ 1 ] = [ 1 0 0 0 0 c o s θ − s i n θ 0 0 s i n θ c o s θ 0 0 0 0 1 ] ⋅ [ x y z 1 ] \begin{bmatrix} x'\\ y' \\ z' \\1 \end {bmatrix} = \begin {bmatrix} 1 & 0 & 0 & 0 \\ 0 & cos\theta & -sin\theta & 0 \\ 0 & sin\theta & cos\theta & 0 \\ 0 & 0 & 0 & 1 \end {bmatrix} \cdot \begin{bmatrix} x \\ y \\ z \\ 1 \end {bmatrix} ⎣ ⎢ ⎢ ⎡ x ′ y ′ z ′ 1 ⎦ ⎥ ⎥ ⎤ = ⎣ ⎢ ⎢ ⎡ 1 0 0 0 0 c o s θ s i n θ 0 0 − s i n θ c o s θ 0 0 0 0 1 ⎦ ⎥ ⎥ ⎤ ⋅ ⎣ ⎢ ⎢ ⎡ x y z 1 ⎦ ⎥ ⎥ ⎤
4.3.2 绕Y轴旋转
绕 Y Y Y 轴的旋转和绕 X X X 轴的旋转类似,Y Y Y 坐标保持不变,除Y轴之外,Z O X ZOX Z O X 组成的平面进行一次二维的旋转(Z Z Z 轴类似于二维旋转的X X X 轴,X X X 轴类似于二维旋转中的 Y Y Y 轴,注意这里是 Z O X ZOX Z O X ,而不是 X O Z XOZ X O Z ,观察上图中右手系的图片可以很容易了解到这一点),同样有:
{ x ′ = z s i n θ + x c o s θ y ′ = y z ′ = z c o s θ − x s i n θ \begin{cases} x′=zsin\theta+xcos\theta \\ y′=y \\ z′=zcos\theta-xsin\theta \end{cases} ⎩ ⎪ ⎨ ⎪ ⎧ x ′ = z s i n θ + x c o s θ y ′ = y z ′ = z c o s θ − x s i n θ
写成(4x4)矩阵的形式
[ x ′ y ′ z ′ 1 ] = [ c o s θ 0 s i n θ 0 0 1 0 0 − s i n θ 0 c o s θ 0 0 0 0 1 ] ⋅ [ x y z 1 ] \begin{bmatrix} x'\\ y' \\ z' \\1 \end {bmatrix} = \begin {bmatrix} cos\theta & 0 & sin\theta & 0 \\ 0 & 1 & 0 & 0 \\ -sin\theta & 0 & cos\theta & 0 \\ 0 & 0 & 0 & 1 \end {bmatrix} \cdot \begin{bmatrix} x \\ y \\ z \\ 1 \end {bmatrix} ⎣ ⎢ ⎢ ⎡ x ′ y ′ z ′ 1 ⎦ ⎥ ⎥ ⎤ = ⎣ ⎢ ⎢ ⎡ c o s θ 0 − s i n θ 0 0 1 0 0 s i n θ 0 c o s θ 0 0 0 0 1 ⎦ ⎥ ⎥ ⎤ ⋅ ⎣ ⎢ ⎢ ⎡ x y z 1 ⎦ ⎥ ⎥ ⎤
4.3.3 绕Z轴旋转
与上面类似,绕 Z Z Z 轴旋转,Z Z Z 坐标保持不变,X O Y XOY X O Y 组成的平面内正好进行一次二维旋转(和上面讨论二维旋转的情况完全一样)
[ x ′ y ′ z ′ 1 ] = [ c o s θ − s i n θ 0 0 s i n θ c o s θ 0 0 0 0 1 0 0 0 0 1 ] ⋅ [ x y z 1 ] \begin{bmatrix} x'\\ y' \\ z' \\1 \end {bmatrix} = \begin {bmatrix} cos\theta & -sin\theta & 0 & 0 \\ sin\theta & cos\theta & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end {bmatrix} \cdot \begin{bmatrix} x \\ y \\ z \\ 1 \end {bmatrix} ⎣ ⎢ ⎢ ⎡ x ′ y ′ z ′ 1 ⎦ ⎥ ⎥ ⎤ = ⎣ ⎢ ⎢ ⎡ c o s θ s i n θ 0 0 − s i n θ c o s θ 0 0 0 0 1 0 0 0 0 1 ⎦ ⎥ ⎥ ⎤ ⋅ ⎣ ⎢ ⎢ ⎡ x y z 1 ⎦ ⎥ ⎥ ⎤
4.4 小结
上面描述了三维变换中绕单一轴旋转的矩阵表达形式,绕三个轴旋转的矩阵很类似,其中绕y轴旋转的矩阵与绕 X X X 和 Z Z Z 轴旋转的矩阵略有点不同(主要是三个轴向顺序和书写矩阵的方式不一致导致的,绕三个不同坐标旋转轴以及其他二个坐标轴组成平面的顺序是: X Y Z XYZ X Y Z (绕 X X X 轴) Y Z X YZX Y Z X (绕Y Y Y 轴) Z X Y ZXY Z X Y (绕 Z Z Z 轴),其中绕 Y Y Y 轴旋转,其他两个轴是 Z X ZX Z X ,这和我们书写矩阵按
[ x y z 1 ] \begin{bmatrix} x\\ y\\z\\1 \end {bmatrix} ⎣ ⎢ ⎢ ⎡ x y z 1 ⎦ ⎥ ⎥ ⎤
的方式不一致,而导致看起来绕 Y Y Y 轴旋转的矩阵似乎是和其他两个矩阵不一致。如果我们颠倒写法,将公式写成
[ z ′ y ′ x ′ 1 ] = [ c o s θ 0 − s i n θ 0 0 1 0 0 s i n θ 0 c o s θ 0 0 0 0 1 ] ⋅ [ z y x 1 ] \begin{bmatrix} z' \\ y' \\ x' \\1 \end {bmatrix} = \begin {bmatrix} cos\theta & 0 & -sin\theta & 0 \\ 0 & 1 & 0 & 0 \\ sin\theta & 0& cos\theta & 0 \\ 0 & 0 & 0 & 1 \end {bmatrix} \cdot \begin{bmatrix} z \\ y \\ x \\ 1 \end {bmatrix} ⎣ ⎢ ⎢ ⎡ z ′ y ′ x ′ 1 ⎦ ⎥ ⎥ ⎤ = ⎣ ⎢ ⎢ ⎡ c o s θ 0 s i n θ 0 0 1 0 0 − s i n θ 0 c o s θ 0 0 0 0 1 ⎦ ⎥ ⎥ ⎤ ⋅ ⎣ ⎢ ⎢ ⎡ z y x 1 ⎦ ⎥ ⎥ ⎤
的方式,那么这三个旋转矩阵看起来在形式上就统一了,都是
[ c o s θ − s i n θ c o s θ s i n θ ] \quad \begin {bmatrix} cos\theta & -sin\theta \\ cos\theta & sin\theta \end {bmatrix} [ c o s θ c o s θ − s i n θ s i n θ ]
这种表现形式了(右上角都是 − s i n θ −sin\theta − s i n θ )
5、绕任意轴的三维旋转
绕任意轴旋转的情况比较复杂,主要分为两种情况,一种是平行于坐标轴的,一种是不平行于坐标轴的。
5.1 平行坐标轴
对于平行于坐标轴的,我们首先将旋转轴平移至与坐标轴重合,然后进行旋转,最后再平移回去。
将旋转轴平移至与坐标轴重合,对应平移操作 T T T
旋转,对应操作 R R R
步骤1的逆过程,对应操作 T − 1 T^{-1} T − 1
整个过程就是P ′ = T − 1 ⋅ R ⋅ T ⋅ P P' = T^{-1} \cdot R \cdot T \cdot P P ′ = T − 1 ⋅ R ⋅ T ⋅ P
5.2 不平行坐标轴
对于不平行于坐标轴的,可按如下方法处理。(该方法实际上涵盖了上面的情况)
绕任意轴的三维旋转可以使用类似于绕任意点的二维旋转一样,将旋转分解为一些列基本的旋转。绕任意轴旋转如下图所示:
将旋转轴平移至原点
将旋转轴旋转至 Y O Z YOZ Y O Z 平面
将旋转轴旋转至于 Z Z Z 轴重合
绕 Z Z Z 轴旋转 θ \theta θ 度
执行步骤3的逆过程
执行步骤2的逆过程
执行步骤1的逆过程
图形详解过程:
步骤1:
将原旋转轴 u u u 平移 v v v 至过原点 O O O ,对应矩阵操作
P 1 = [ 1 0 0 T x 0 1 0 T y 0 0 1 T z 0 0 0 1 ] ⋅ [ x y z 1 ] = T 1 ⋅ P P_1 = \begin {bmatrix} 1 & 0 & 0 & Tx \\ 0 & 1 &0 & Ty \\ 0 & 0 & 1 & Tz \\ 0 & 0 & 0 & 1 \end {bmatrix} \cdot \begin{bmatrix} x \\ y \\ z \\ 1 \end {bmatrix} =T_1 \cdot P P 1 = ⎣ ⎢ ⎢ ⎡ 1 0 0 0 0 1 0 0 0 0 1 0 T x T y T z 1 ⎦ ⎥ ⎥ ⎤ ⋅ ⎣ ⎢ ⎢ ⎡ x y z 1 ⎦ ⎥ ⎥ ⎤ = T 1 ⋅ P
步骤2:
旋转操作,将 u u u 绕 z z z 轴旋转 α \alpha α 角 至 X O Z XOZ X O Z 平面,对应的图如下
P 2 = [ c o s α − s i n α 0 0 s i n α c o s α 0 0 0 0 1 0 0 0 0 1 ] ⋅ [ x 1 y 1 z 1 1 ] = R z ⋅ P 1 P_2 = \begin {bmatrix} cos\alpha & -sin\alpha & 0 & 0 \\ sin\alpha & cos\alpha & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end {bmatrix} \cdot \begin{bmatrix} x_1 \\ y_1 \\ z_1 \\ 1 \end {bmatrix} =R_z \cdot P_1 P 2 = ⎣ ⎢ ⎢ ⎡ c o s α s i n α 0 0 − s i n α c o s α 0 0 0 0 1 0 0 0 0 1 ⎦ ⎥ ⎥ ⎤ ⋅ ⎣ ⎢ ⎢ ⎡ x 1 y 1 z 1 1 ⎦ ⎥ ⎥ ⎤ = R z ⋅ P 1
步骤3:
步骤3也是一个旋转操作,将 u u u 绕 y y y 旋转 β \beta β 至与 x x x 轴重合,对应的图如下
P 3 = [ c o s β 0 s i n β 0 0 1 0 0 − s i n β 0 c o s β 0 0 0 0 1 ] ⋅ [ x 2 y 2 z 2 1 ] = R y ⋅ P 2 P_3 = \begin {bmatrix} cos\beta & 0 & sin\beta & 0 \\ 0 & 1 & 0 & 0 \\ -sin\beta & 0 & cos\beta & 0 \\ 0 & 0 & 0 & 1 \end {bmatrix} \cdot \begin{bmatrix} x_2 \\ y_2 \\ z_2 \\ 1 \end {bmatrix} =R_y \cdot P_2 P 3 = ⎣ ⎢ ⎢ ⎡ c o s β 0 − s i n β 0 0 1 0 0 s i n β 0 c o s β 0 0 0 0 1 ⎦ ⎥ ⎥ ⎤ ⋅ ⎣ ⎢ ⎢ ⎡ x 2 y 2 z 2 1 ⎦ ⎥ ⎥ ⎤ = R y ⋅ P 2
步骤4:
此时原旋转轴经过一系列的操作,已经与 x x x 轴重合了 ,即 u ′ ′ u'' u ′ ′ ,此时原来的 P , Q P , Q P , Q 点已经映射到 P ′ , Q ′ P' ,Q' P ′ , Q ′ ,只需将 P ′ P' P ′ 绕 x x x 轴旋转 θ \theta θ 角便可得到 Q ′ Q' Q ′ 点,此时的操作为:
P 4 = [ 1 0 0 0 0 c o s θ − s i n θ 0 0 s i n θ c o s θ 0 0 0 0 1 ] ⋅ [ x 3 y 3 z 3 1 ] = R x ⋅ P 3 P_4 = \begin {bmatrix} 1 & 0 & 0 & 0 \\ 0 & cos\theta & -sin\theta & 0 \\ 0 & sin\theta & cos\theta & 0 \\ 0 & 0 & 0 & 1 \end {bmatrix} \cdot \begin{bmatrix} x_3 \\ y_3 \\ z_3 \\ 1 \end {bmatrix} =R_x \cdot P_3 P 4 = ⎣ ⎢ ⎢ ⎡ 1 0 0 0 0 c o s θ s i n θ 0 0 − s i n θ c o s θ 0 0 0 0 1 ⎦ ⎥ ⎥ ⎤ ⋅ ⎣ ⎢ ⎢ ⎡ x 3 y 3 z 3 1 ⎦ ⎥ ⎥ ⎤ = R x ⋅ P 3
步骤5:
此时再将 步骤3,2,1逆操作即可得到原始点 P P P 点绕旋转轴 u u u 旋转 θ \theta θ 角后的点 Q Q Q ;
对应的操作即为 Q = T − 1 ⋅ R z − 1 ⋅ R y − 1 ⋅ P 4 Q = T^{-1} \cdot R_z^{-1} \cdot R_y^{-1} \cdot P_4 Q = T − 1 ⋅ R z − 1 ⋅ R y − 1 ⋅ P 4
综述:
对于不平行于坐标轴的旋转其实已经包含了平行于坐标轴的旋转,因此对于绕任意轴的三维旋转可以总结为:
Q = M ⋅ P Q = M \cdot P Q = M ⋅ P
其中 M = T − 1 ⋅ R z − 1 ⋅ R y − 1 ⋅ R x ⋅ R y ⋅ R x ⋅ T M = T^{-1} \cdot R_z^{-1} \cdot R_y^{-1} \cdot R_x \cdot R_y \cdot R_x \cdot T M = T − 1 ⋅ R z − 1 ⋅ R y − 1 ⋅ R x ⋅ R y ⋅ R x ⋅ T
5.3 α,β,θ 角度补充
为了全文的排版,以及读者体验,上述解释全部采用的 α , β , θ \alpha ,\beta ,\theta α , β , θ ,具体从何得来并没有做解释说明,在此将对 α , β , θ \alpha ,\beta ,\theta α , β , θ 的缘由做个详细解释。
在此,假设旋转轴 u u u 由 [ ( a 1 , b 1 , c 1 ) , ( a 2 , b 2 , c 2 ) ] [(a_1,b_1,c_1),(a_2,b_2,c_2)] [ ( a 1 , b 1 , c 1 ) , ( a 2 , b 2 , c 2 ) ] 表示
旋转轴 u u u 经过平移 T 1 T_1 T 1 变换后过原点的旋转轴 u ′ u' u ′ ,u ′ u' u ′ 的坐标为 ( a , b , c ) (a,b,c) ( a , b , c )
旋转轴 u ′ u' u ′ 上的点 ( a , b , c ) (a,b,c) ( a , b , c )
在 X O Y XOY X O Y 平面上的投影为 O A ( a , b , 0 ) OA(a,b,0) O A ( a , b , 0 )
在 X O Z XOZ X O Z 平面上的投影为 O B ( a , 0 , c ) OB(a,0,c) O B ( a , 0 , c )
那么s i n α = b a 2 + b 2 , c o s α = a a 2 + b 2 sin\alpha = { b \over \sqrt{a^2 + b^2}} \space\space , \space\space cos\alpha = {a \over \sqrt{a^2 + b^2}} s i n α = a 2 + b 2 b , c o s α = a 2 + b 2 a s i n β = c a 2 + c 2 , c o s β = a a 2 + c 2 sin\beta = { c \over \sqrt{a^2 + c^2}}\space\space , \space\space cos\beta = {a \over \sqrt{a^2 + c^2}} s i n β = a 2 + c 2 c , c o s β = a 2 + c 2 a
参考链接:
https://www.cnblogs.com/zhoug2020/p/7842808.html
https://www.cnblogs.com/graphics/archive/2012/08/10/2627458.html