一次搞清旋转方向及三维绕轴旋转矩阵

5,193 阅读5分钟

今天我们一起来讨论下学习图形学过程中经常傻傻分不清楚的旋转方向,三维的逆时针究竟是如何定义的?Games101中闫令琪闫神浅浅提了一下的三维旋转矩阵绕y轴旋转的情况为何与众不同?下面就跟我一起探索吧!如果喜欢我的文章记得点赞关注我哦~ 在文章之前,b站视频:聊聊三维旋转矩阵的前世今生 也对这一内容做了探讨,大家可以结合文章和视频一起理解一下哦~ 文章则对视频中没有深入展开的坐标系加以补充,也提出了另一种思路来加深对三维旋转矩阵的理解。

一、相关概念

1.右手系

规定把右手放在原点的位置,使大拇指,食指和中指互成直角,把大拇指指向x轴的正方向,食指指向y轴的正方向,此时中指所指的方向就是z轴的正方向,由此构成的坐标系就称为右手坐标系

或者使用类似与右手螺旋定则的方式定义右手系,将右手的四指 (除去大拇指的其余手指) 沿着第一个坐标轴 (x轴) 的正向伸展,再将他们向第二个轴(y轴)的正方向环绕(旋转方向如上图右侧子图所示),此时大拇指的方向就是第三个轴(z轴)的正方向,由此构成的坐标系就称为右手坐标系

2.旋转方向

我们经常会困惑三维空间中的逆时针顺时针是如何定义的,网上也很少有清晰的定义,这里我从《3D数学基础:图形与游戏开发》[1]^{[1]}一书中摘录了相关定义供大家参考。

下面是三维空间旋转方向的几种定义方式,以后在没有特殊说明的情况下,旋转方向默认按照逆时针方向(正),此逆时针方向为从旋转轴的正端点向负端点方向看的逆时针。

右手系下
从哪里看 正方向 负方向
从轴的负端点向正端点看 顺时针 逆时针
从轴的正端点向负端点看 逆时针 顺时针

3.向量叉乘方向[2]^{[2]}

  • 叉积 (又名外积)

    • a×b=a bsin(θ) n\vec{\displaystyle\mathbf{a}} \times \vec{\displaystyle\mathbf{b}} = {\displaystyle \|\mathbf {\vec{a}} \|}  {\displaystyle \|\mathbf {\vec{b}} \|} \sin(\theta) {\displaystyle \mathbf {\vec{n}} }
  • 其中 

    • θ{\displaystyle \theta } 表示 a \vec{\displaystyle\mathbf{a}} 和 b\vec{\displaystyle\mathbf{b}}在它们所定义的平面上的夹角(0θ180{\displaystyle 0^{\circ }\leq \theta \leq 180^{\circ }}
    • a{\displaystyle \|\mathbf {\vec{a}} \|} 和 b{\displaystyle \|\mathbf {\vec{b}} \|} 是向量  a \vec{\displaystyle\mathbf{a}} 和 b\vec{\displaystyle\mathbf{b}} 的模长;
    • n{\displaystyle \mathbf {\vec{n}} } 则是一个与 a \vec{\displaystyle\mathbf{a}} 和 b\vec{\displaystyle\mathbf{b}} 所构成的平面垂直的单位向量,方向由右手定则决定
  • 方向

    • 向量 n {\vec{ \displaystyle \mathbf {n} } } 的方向由右手定则决定:将右手食指指向a\vec{\displaystyle\mathbf{a}} 的方向、中指指向 b\vec{\displaystyle\mathbf{b}} 的方向,则此时拇指的方向即为 n{\displaystyle \mathbf {\vec{n}} } 的方向。
    • 使用这一定则意味着外积满足反交换律,a×b=(b×a){\displaystyle \mathbf {\vec{a}} \times \mathbf {\vec{b}} =-(\mathbf {\vec{b}} \times \mathbf {\vec{a}} )} :将右手食指指向 b\vec{\displaystyle\mathbf{b}}、中指指向a\vec{\displaystyle\mathbf{a}},那么拇指就必定指向相反方向,即翻转了外积的符号。

Right_hand_rule_cross_product.svg

  • 坐标表示(图形学里常用,所以提一下)
    • 基向量: i\vec{\displaystyle \mathbf {i}}j\vec{\displaystyle \mathbf {j}}k\vec{\displaystyle \mathbf {k}}

    • 满足以下等式:

      i×j=kj×k=ik×i=j{\displaystyle {\begin{aligned} \mathbf {\vec{i}} \times \mathbf {\vec{j}} &=\mathbf {\vec{k}} \\ \mathbf {\vec{j}} \times \mathbf {\vec{k}} &=\mathbf {\vec{i}} \\ \mathbf {\vec{k}} \times \mathbf {\vec{i}} &=\mathbf {\vec{\vec{j}}} \end{aligned}}}

    • 向量 a\vec{\displaystyle\mathbf{a}}b\vec{\displaystyle\mathbf{b}} 可以定义为平行于基向量的三个正交元素之和:

      a=a1i+a2j+a3kb=b1i+b2j+b3k {\displaystyle {\begin{aligned}\mathbf {\vec{a}} &=a_{1}\mathbf {\vec{i}} +a_{2}\mathbf {\vec{j}} +a_{3}\mathbf {\vec{k}} \\ \mathbf {\vec{b}} &=b_{1}\mathbf {\vec{i}} +b_{2}\mathbf {\vec{j}} +b_{3}\mathbf {\vec{k}} \end{aligned}}}

    • 外积可以表达为这样的行列式:

      a×b=ijka1a2a3b1b2b3{\displaystyle \mathbf {\vec{a}\times \vec{b}} ={\begin{vmatrix}\mathbf {\vec{i}} &\mathbf {\vec{j}} &\mathbf {\vec{k}} \\a_{1}&a_{2}&a_{3}\\b_{1}&b_{2}&b_{3}\\\end{vmatrix}}}

    • 使用拉普拉斯沿第一行展开,得:

      a×b=a2a3b2b3ia1a3b1b3j+a1a2b1b2k=(a2b3a3b2)i(a1b3a3b1)j+(a1b2a2b1)k{\displaystyle {\begin{aligned}\mathbf {\vec{a}\times \vec{b}} &={\begin{vmatrix}a_{2}&a_{3}\\b_{2}&b_{3}\end{vmatrix}}\mathbf {\vec{i}} -{\begin{vmatrix}a_{1}&a_{3}\\b_{1}&b_{3}\end{vmatrix}}\mathbf {\vec{j}} +{\begin{vmatrix}a_{1}&a_{2}\\b_{1}&b_{2}\end{vmatrix}}\mathbf {\vec{k}} \\&=(a_{2}b_{3}-a_{3}b_{2})\mathbf {\vec{i}} -(a_{1}b_{3}-a_{3}b_{1})\mathbf {\vec{j}} +(a_{1}b_{2}-a_{2}b_{1})\mathbf {\vec{k}} \end{aligned}}}

二、旋转矩阵(左乘矩阵)

-1. 旋转方向

再次强调下面提到的三维旋转方向的逆时针均按照下表的定义方式操作。

右手系
从哪里看 正方向
从轴的正端点向负端点看 逆时针

0. 二维旋转矩阵

(x,y)(x, y) 沿着如图 xxyy 方向(逆时针)旋转 θ\theta 角度 对应的旋转矩阵按照如下(左乘)方式作用在点 (x,y)(x, y) 上,推导过程略。

[cosθsinθsinθcosθ][xy]{\displaystyle \left[ {\begin{matrix} \cos\theta & -\sin\theta \\ \sin \theta & \cos\theta \end{matrix}} \right] \left[ \begin{matrix}x\\ y\end{matrix}\right] }

截屏2022-08-03 下午8.53.51.png

1. 绕x轴旋转

  • 旋转矩阵

    [1000cosθsinθ0sinθcosθ]{\displaystyle \left[ {\begin{matrix} 1 & 0 & 0 \\ 0 &\cos\theta & -\sin\theta \\ 0 &\sin \theta & \cos\theta\\ \end{matrix}}\right] }

  • 理解

    • xx 轴旋转,xx 不变

      [10000]{\displaystyle \left[ {\begin{matrix} 1 & 0 & 0 \\ 0 & & \\ 0 & & \\ \end{matrix}}\right] }

    • 逆时针旋转 θ\theta ,在右手系下: y×z=x\mathbf {\vec{y}} \times \mathbf {\vec{z}} =\mathbf {\vec{x}} ,由于xx 不变,不考虑 xx ,原来的变换与二维 yyzz 逆时针旋转θ\theta 角度的变换一致,所以可将二维旋转矩阵 [cosθsinθsinθcosθ]{\displaystyle \left[ {\begin{matrix} \cos\theta & -\sin\theta \\ \sin \theta & \cos\theta \end{matrix}}\right] }直接应用在坐标的 yyzz分量上,即[cosθsinθsinθcosθ][yz]{\displaystyle \left[ {\begin{matrix} \cos\theta & -\sin\theta \\ \sin \theta & \cos\theta \end{matrix}}\right]\left[ {\begin{matrix}y\\z\end{matrix}}\right] }, 所以可以直接将其放入对应的位置

    • 最终得到上面的旋转矩阵

image.png

2. 绕y轴旋转

  • 旋转矩阵

    [cosθ0sinθ010sinθ0cosθ]{\displaystyle \left[ {\begin{matrix} \cos\theta & 0 & \sin\theta \\ 0 &1 &0 \\ -sin\theta &0 & \cos\theta\\ \end{matrix}}\right] }

  • 理解

    • yy 轴旋转,yy 不变

      [00100]{\displaystyle \left[ {\begin{matrix} & 0 & \\ 0 &1 &0 \\ &0 & \\ \end{matrix}}\right] }

    • 逆时针旋转 θ\theta ,在右手系下: z×x=y\mathbf {\vec{z}} \times \mathbf {\vec{x}} =\mathbf {\vec{y}} ,因为 yy 不变,所以不考虑 yy,原来的变换与二维 zzxx 旋转 θ\theta 方向一致,此时二维旋转矩阵
      [cosθsinθsinθcosθ]{\displaystyle \left[ {\begin{matrix} \cos\theta & -\sin\theta \\ \sin \theta & \cos\theta \end{matrix}}\right]}作用在zzxx 分量上,即[cosθsinθsinθcosθ][zx]{\displaystyle \left[ {\begin{matrix} \cos\theta & -\sin\theta \\ \sin \theta & \cos\theta \end{matrix}}\right]}\left[ {\begin{matrix}z\\x\end{matrix}}\right] ,原来的变换还等价于 xxzz 旋转 θ-\theta 角度,所以需要将二维旋转矩阵
      [cosθsinθsinθcosθ]{\displaystyle \left[ {\begin{matrix} \cos\theta & -\sin\theta \\ \sin \theta & \cos\theta \end{matrix}}\right]},稍做处理,即将 θ-\theta 代入其中,得 [cos(θ)sin(θ)sin(θ)cos(θ)]=[cosθsinθsinθcosθ]{\displaystyle \left[ {\begin{matrix} \cos(-\theta) & -\sin(-\theta) \\ \sin(- \theta) & \cos(-\theta ) \end{matrix}}\right] = \left[{\begin{matrix} \cos\theta & \sin\theta \\ -sin\theta & \cos\theta \end{matrix}} \right] },再将其作用在xxzz 分量上,即 [cosθsinθsinθcosθ][xz]{\displaystyle \left[{\begin{matrix} \cos\theta & \sin\theta \\ -sin\theta & \cos\theta \end{matrix}} \right]\left[ {\begin{matrix}x\\z\end{matrix}}\right] },显然这才是我们需要的矩阵,最后将其放入对应的位置

    • 最终得到上面的旋转矩阵

    • 同时也深刻解释了为什么三维绕 yy 轴的旋转矩阵在符号上比其他两种情况特殊。

image.png

3. 绕z轴旋转

  • 旋转矩阵

    [cosθsinθ0sinθcosθ0001]{\displaystyle \left[ {\begin{matrix} \cos\theta & -\sin\theta & 0 \\ sin\theta &\cos\theta &0 \\ 0 &0 &1 \\ \end{matrix}}\right] }

  • 理解

    • zz 轴旋转,zz 不变

      [00001]{\displaystyle \left[ {\begin{matrix} & & 0 \\ & &0 \\ 0&0 &1 \\ \end{matrix}} \right] }

    • 逆时针旋转 θ\theta ,在右手系下: x×y=z\mathbf {\vec{x}} \times \mathbf {\vec{y}} =\mathbf {\vec{z}} ,由于zz 不变,不考虑 zz ,原来的变换与二维 xxyy 旋转 θ\theta 角度等价 ,所以可将二维旋转矩阵 [cosθsinθsinθcosθ]{\displaystyle \left[ {\begin{matrix} \cos\theta & -\sin\theta \\ \sin \theta & \cos\theta \end{matrix}}\right] }直接应用在坐标的 xxyy分量上,即[cosθsinθsinθcosθ][xy]{\displaystyle \left[ {\begin{matrix} \cos\theta & -\sin\theta \\ \sin \theta & \cos\theta \end{matrix}}\right]\left[ {\begin{matrix}x\\y\end{matrix}}\right] }, 所以可以直接将其放入对应的位置

    • 最终得到上面的旋转矩阵

[1]FletcherDunn, IanParberry, 邓恩,等. 3D数学基础:图形与游戏开发[M]. 清华大学出版社, 2005.

[2] zh.wikipedia.org/wiki/%E5%8F…