平移矩阵 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] \]
资料
写作不易,您的支持是我写作的动力!