线性代数之平移、缩放、旋转矩阵

Tags: ,

平移矩阵 Translate Matrix

\[ T = \left[ \begin{matrix} 1&0&0&x\\ 0&1&0&y\\ 0&0&1&z\\ 0&0&0&1\\ \end{matrix} \right] \]

缩放矩阵 Scale Matrix

\[ S = \left[ \begin{matrix} x&0&0&0\\ 0&y&0&0\\ 0&0&z&0\\ 0&0&0&1\\ \end{matrix} \right] \]

旋转矩阵 Rotate Matrix

绕(1,0,0)旋转\(\theta \)角度

\[ R_{(1,0,0)} = \left[ \begin{matrix} 1&0&0&0\\ 0&cos\theta &sin\theta &0\\ 0&-sin\theta &cos\theta &0\\ 0&0&0&1\\ \end{matrix} \right] \]

绕(0,1,0)旋转\(\theta \)角度

\[ R_{(0,1,0)} = \left[ \begin{matrix} cos\theta&0&-sin\theta&0\\ 0&1&0&0\\ sin\theta &0&cos\theta &0\\ 0&0&0&1\\ \end{matrix} \right] \]

绕(0,0,1)旋转\(\theta \)角度

\[ R_{(0,0,1)} = \left[ \begin{matrix} cos\theta&sin\theta&0&0\\ -sin\theta &cos\theta &0&0\\ 0&0&1&0\\ 0&0&0&1\\ \end{matrix} \right] \]

绕任意轴旋转\(\theta \)角度

设旋转轴为\(\vec n\),这是一个单位化的方向向量。设被旋转的向量为\(\vec v\),被旋转后是\(\vec v' \)。

为了求出\(\vec v' \),需要迂回地处理:

  • 将\(\vec v\) 分解为 \(\vec v = \vec v_{\perp }+\vec v_{\parallel } \) ,\( \vec v_{\parallel } \)指的是\(\vec v\)与\(\vec n\)平行的部分,\( \vec v_{\perp } \) 指的是\(\vec v\) 与\(\vec n\)垂直的部分。

  • 分解为两部分后,可以分别对这两个部分做旋转,然后再合并,所以有: \(\vec v' = \vec v'_{\perp }+\vec v'_{\parallel } \)

  • 让 \( \vec v_{\parallel } \) 绕旋转轴\(\vec n\)旋转\(\theta \)角度,它依然保持不变,因为它和\(\vec n\)是同方向的向量,所以有 \( \vec v_{\parallel } = \vec v'_{\parallel } \)

  • 根据上一点,可以得到: \(\vec v' = \vec v'_{\perp }+\vec v_{\parallel } \)。因此,问题简化为求\( \vec v'_{\perp } \)和\( \vec v_{\parallel } \)

  • 分析\( \vec v_{\parallel } \),可以发现它相当于是\(\vec v\)在\(\vec n\)上的投影,根据向量的点积公式:

\[ \vec A\cdot \vec B = |\vec A||\vec B|cos\alpha \]

代入\(\vec v\)、\(\vec n\)后,得到:\( \vec v\cdot \vec n = |\vec v||\vec n|cos\alpha = |\vec v|cos\alpha = |\vec v_{\parallel }| \),即算出了\( \vec v_{\parallel } \)的长度,又因为\( \vec v_{\parallel } \)和\(\vec n\)方向一致、\(\vec n\)长度为1,所以有:

\[ \vec v_{\parallel } = (\vec v\cdot \vec n) \vec n \]

上一步已经解决了\( \vec v_{\parallel } \),剩下的就是求\( \vec v'_{\perp } \)。求\( \vec v'_{\perp } \)之前需要先求出\( \vec v_{\perp } \),而显然\( \vec v_{\perp } = v - \vec v_{\parallel} \)

接着,需要计算一个新的向量\(\vec w \),\( \vec w = \vec n \times \vec v_{\perp } \) (注意叉乘的顺序不能错),所以\(\vec w \)是一个垂直于\( \vec n \)、\( \vec v_{\perp } \)所构成平面的向量。

把\( \vec v_{\perp }\)、\(\vec w \) 分别当做是垂直于\( \vec n \)的2D平面的x、y轴(因为已经有正交关系),那么\( \vec v'_{\perp } \)的含义就是指\( \vec v_{\perp } \)在这个2D坐标系下绕原点旋转\(\theta \)度(Rotation of axes)。从而得到等式:

\[ \vec v'_{\perp } = cos\theta \vec v_{\perp } + sin\theta \vec w \]

可以这么理解:首先因为 \(\vec w = \vec n \times \vec v_{\perp }\),可知 \(\vec w \)和\( \vec v_{\perp } \)等长,假设长度为r,那么可用极坐标表示\(\vec v'_{\perp } = (r, \theta) \),极坐标用笛卡尔坐标表示就是示\(\vec v'_{\perp } = (r cos\theta, r sin\theta) = r cos\theta\vec x + r sin\theta \vec y,\vec x = (1,0),\vec y = (0,1) \),换成自定义的正交坐标系后就是\( cos\theta \vec v_{\perp } + sin\theta \vec w \)。

好了,所有变量都得到了,总结下最终的公式:

\( \vec v_{\parallel } = (\vec v\cdot \vec n) \vec n \)

\( \vec v_{\perp } = \vec v - \vec v_{\parallel} = \vec v - (\vec v\cdot \vec n) \vec n \)

\( \vec w = \vec n \times \vec v_{\perp } \)

\( = \vec n \times (\vec v - \vec v_{\parallel}) \)

\( = \vec n \times \vec v - \vec n \times \vec v_{\parallel} \)

\( = \vec n \times \vec v \)

\( \vec v'_{\perp } = cos\theta \vec v_{\perp } + sin\theta \vec w \)

\( = cos\theta (v - (\vec v\cdot \vec n) \vec n) + sin\theta (\vec n \times \vec v) \)

\( \vec v' = \vec v'_{\perp } + \vec v'_{\parallel } = \vec v'_{\perp } + \vec v_{\parallel } \)

\( = cos\theta (\vec v - (\vec v\cdot \vec n) \vec n) + sin\theta (\vec n \times \vec v) + (\vec v\cdot \vec n) \vec n \)

\( = cos\theta \vec v + (1 - cos\theta)(\vec v\cdot \vec n) \vec n) + sin\theta (\vec n \times \vec v) \)

加粗并居中:

\[ \vec v' = cos\theta \vec v + (1 - cos\theta)(\vec v\cdot \vec n) \vec n) + sin\theta (\vec n \times \vec v) \]

这就是绕任意轴的旋转公式了。 可以在这个wiki看到这条公式,一模一样。

接下来是把这个公式转换成矩阵的形式。方法是,把\(v_{x} = (1,0,0) \)、\(v_{y} = (0,1,0) \)、\(v_{z} = (0,0,1) \),分别代入上面的公式,分别得到:

\[ v_{x}' = \left[ \begin{matrix} n_{x}^{2}(1-cos\theta )+cos\theta \\ n_{x}n_{y}(1-cos\theta )+n_{z}sin\theta \\ n_{x}n_{z}(1-cos\theta )-n_{y}sin\theta \\ \end{matrix} \right] ^{T} \]

\[ v_{y}' = \left[ \begin{matrix} n_{x}n_{y}(1-cos\theta )-n_{z}sin\theta \\ n_{y}^{2}(1-cos\theta )+cos\theta \\ n_{y}n_{z}(1-cos\theta )+n_{x}sin\theta \\ \end{matrix} \right] ^{T} \]

\[ v_{z}' = \left[ \begin{matrix} n_{x}n_{z}(1-cos\theta )+n_{y}sin\theta \\ n_{y}n_{z}(1-cos\theta )-n_{x}sin\theta \\ n_{z}^{2}(1-cos\theta )+cos\theta \\ \end{matrix} \right] ^{T} \]

最终的旋转矩阵为:

\[ R(\vec n, \theta ) = \left[ \begin{matrix} n_{x}^{2}(1-cos\theta )+cos\theta & n_{x}n_{y}(1-cos\theta )+n_{z}sin\theta & n_{x}n_{z}(1-cos\theta )-n_{y}sin\theta &0\\ n_{x}n_{y}(1-cos\theta )-n_{z}sin\theta &n_{y}^{2}(1-cos\theta )+cos\theta &n_{y}n_{z}(1-cos\theta )+n_{x}sin\theta &0\\ n_{x}n_{z}(1-cos\theta )+n_{y}sin\theta &n_{y}n_{z}(1-cos\theta )-n_{x}sin\theta &n_{z}^{2}(1-cos\theta )+cos\theta &0\\ 0&0&0&1\\ \end{matrix} \right] \]

资料

Rodrigues' rotation formula

Rotation of axes

(未经授权禁止转载)
Written on March 20, 2016

写作不易,您的支持是我写作的动力!