1. 简单的想法
一般来说我们可以很容易写出绕坐标轴$x,y,z$旋转任意角度$\theta$的旋转矩阵,这里分别用$\textbf{R}_x(\theta), \textbf{R}_y(\theta), \textbf{R}_z(\theta)$来表示。但更多时候,我们希望给出任意轴$\textbf{r}$和任意角度$\alpha$的旋转矩阵$\textbf{X}$。一个简单的想法即将$\textbf{s}$构成的局部坐标系$Orst$变换到$Oxyz$上,然后应用相应的旋转,最后反变换回去,如下图所示:
首先我们计算$\textbf{M}$,按照Real-Time Rendering (4th Edition)中,一个比较稳定的方法即将绝对值最小值置零,然后交换剩下的值并将前一个值取负,可以验证该方法生成的向量与$\textbf{r}$垂直,只是需要进一步归一化,于是可以有:
2. glm::rotate()
然而很容易发现该方案效率较低,需要多个计算,在glm::rotate()中,使用了Graphics Gems (1st Edition)中提到的另一种方法。该方法更直观地在旋转轴上进行操作,如下图所示。
首先我们有归一化的旋转轴$\textbf{r}$和任意需要旋转的点,这里用向量$\textbf{p}$表示,以及旋转角度$\phi$后的位置$\textbf{p’}$。如上图所示,我们将$\textbf{p}$投影到$\textbf{r}$上得到相应的投影向量:
参考文献
Real-Time Rendering (4th Edition)
Graphics Gems (1st Edition)