好的,咱们来聊聊三维空间里的旋转矩阵是怎么来的。这篇文章尽量不让你觉得是机器写出来的,咱们就用最直观的方式来理解。
首先得明白一个事儿,啥叫旋转?就是在一个中心点(通常是原点)绕着某条线(称为旋转轴)把物体转动一个角度。在三维空间里,想象一下,你手里拿着一个魔方,想把它绕着某一条棱转一下,这就是个三维旋转。
那旋转矩阵是干嘛的呢?说白了,它就是一个“翻译器”。你给它一个点在旋转之前的坐标,它就能告诉你,这个点旋转之后到了哪儿。用数学上的话说,就是它能把一个三维向量(代表那个点的位置)通过矩阵乘法转换成另一个三维向量(代表旋转后的位置)。
核心思想:基向量的“变形记”
我们知道,在三维空间里,任何一个点都可以用三个互相垂直的基向量来表示。最常用的是标准的单位正交基:
$mathbf{i}$ 向量: (1, 0, 0),指向 x 轴正方向
$mathbf{j}$ 向量: (0, 1, 0),指向 y 轴正方向
$mathbf{k}$ 向量: (0, 0, 1),指向 z 轴正方向
任何一个三维向量 $mathbf{v} = (x, y, z)$ 都可以写成 $xmathbf{i} + ymathbf{j} + zmathbf{k}$。
现在,咱们要做的就是找出,当整个空间发生旋转时,这三个基向量各自会跑到哪里去。一旦我们知道了这三个基向量旋转后的位置,那么任何一个向量的旋转后的位置也就迎刃而解了。
举个例子,假设我们想把一个点 $mathbf{v} = (x, y, z)$ 绕着 z 轴旋转一个角度 $ heta$。
1. 基向量 $mathbf{i}$ (1, 0, 0):它在 xy 平面上,跟 z 轴是垂直的。绕着 z 轴旋转,它就还在 xy 平面上,但是方向变了。原来的 x 轴正方向,旋转 $ heta$ 度后,变成了 $(cos heta, sin heta, 0)$。
2. 基向量 $mathbf{j}$ (0, 1, 0):它也在 xy 平面上。原来的 y 轴正方向,旋转 $ heta$ 度后,变成了 $(sin heta, cos heta, 0)$。
3. 基向量 $mathbf{k}$ (0, 0, 1):它就是旋转轴本身,所以它不会动,还是 $(0, 0, 1)$。
现在,我们把这三个旋转后的基向量写成列向量:
$mathbf{i}' = egin{pmatrix} cos heta \ sin heta \ 0 end{pmatrix}$
$mathbf{j}' = egin{pmatrix} sin heta \ cos heta \ 0 end{pmatrix}$
$mathbf{k}' = egin{pmatrix} 0 \ 0 \ 1 end{pmatrix}$
把这三个新的基向量作为列拼起来,就组成了绕 z 轴旋转的旋转矩阵 $R_z( heta)$:
$R_z( heta) = egin{pmatrix} | & | & | \ mathbf{i}' & mathbf{j}' & mathbf{k}' \ | & | & | end{pmatrix} = egin{pmatrix} cos heta & sin heta & 0 \ sin heta & cos heta & 0 \ 0 & 0 & 1 end{pmatrix}$
是不是挺直观的?原始的基向量 $(1, 0, 0)$ 变成了新矩阵的第一列,$(0, 1, 0)$ 变成了第二列,$(0, 0, 1)$ 变成了第三列。
同理,我们可以推导出绕 x 轴和 y 轴旋转的矩阵:
绕 x 轴旋转 $ heta$ 度 ($R_x( heta)$):
基向量 $mathbf{i}$ 不变,$mathbf{j}$ 绕 x 轴旋转 $ heta$ 度变成了 $(0, cos heta, sin heta)$,$mathbf{k}$ 变成了 $(0, sin heta, cos heta)$。
$R_x( heta) = egin{pmatrix} 1 & 0 & 0 \ 0 & cos heta & sin heta \ 0 & sin heta & cos heta end{pmatrix}$
绕 y 轴旋转 $ heta$ 度 ($R_y( heta)$):
基向量 $mathbf{j}$ 不变,$mathbf{i}$ 绕 y 轴旋转 $ heta$ 度变成了 $(cos heta, 0, sin heta)$,$mathbf{k}$ 变成了 $(sin heta, 0, cos heta)$。
$R_y( heta) = egin{pmatrix} cos heta & 0 & sin heta \ 0 & 1 & 0 \ sin heta & 0 & cos heta end{pmatrix}$
更一般的旋转:绕任意轴
上面只是绕着坐标轴旋转,要是想绕着空间里任意一条线(轴)旋转怎么办?这就稍微复杂一点了,但思路还是一样的:找出这个任意轴上的单位向量,然后推导三个标准基向量在这条轴上的旋转后的位置。
假设我们要绕着一个单位向量 $mathbf{u} = (u_x, u_y, u_z)$ 旋转一个角度 $ heta$。
这时,我们就需要用到一些三角函数和向量运算了,比如 Rodrigues 旋转公式。这个公式直接给出了一个向量 $mathbf{v}$ 绕着单位向量 $mathbf{u}$ 旋转 $ heta$ 度后的结果 $mathbf{v}'$:
$mathbf{v}' = mathbf{v} cos heta + (mathbf{u} imes mathbf{v}) sin heta + mathbf{u} (mathbf{u} cdot mathbf{v}) (1 cos heta)$
这个公式看起来有点“硬核”,但它其实就是把旋转分解成了几个部分:
$mathbf{v} cos heta$: 表示 $mathbf{v}$ 在垂直于 $mathbf{u}$ 的平面上的投影,然后顺着 $mathbf{v}$ 本身方向伸缩了一下。
$(mathbf{u} imes mathbf{v}) sin heta$: 这部分是 $mathbf{v}$ 垂直于 $mathbf{u}$ 方向的投影,然后绕着 $mathbf{u}$ 轴旋转。
$mathbf{u} (mathbf{u} cdot mathbf{v}) (1 cos heta)$: 这部分是 $mathbf{v}$ 沿着 $mathbf{u}$ 方向的投影,然后因为旋转轴是 $mathbf{u}$,这部分不应该有变化,所以用 $(1cos heta)$ 来“抵消”它可能受到的影响。
如果我们把这个公式写成矩阵形式,就得到了通用的旋转矩阵。过程会比较繁琐,涉及到叉乘和点乘的矩阵表示,以及一些恒等式。但最终结果是这样的:
令 $c = cos heta$ 且 $s = sin heta$。
Rodrigues 公式可以写成:
$mathbf{v}' = mathbf{v} c + (mathbf{u} imes mathbf{v}) s + mathbf{u} (mathbf{u} cdot mathbf{v}) (1c)$
我们可以把叉乘写成矩阵乘法,用一个反对称矩阵 $[mathbf{u}]_ imes$ 来表示:
$[mathbf{u}]_ imes = egin{pmatrix} 0 & u_z & u_y \ u_z & 0 & u_x \ u_y & u_x & 0 end{pmatrix}$
这样,$mathbf{u} imes mathbf{v} = [mathbf{u}]_ imes mathbf{v}$。
代入 Rodrigues 公式:
$mathbf{v}' = mathbf{v} c + [mathbf{u}]_ imes mathbf{v} s + mathbf{u} (mathbf{u}^T mathbf{v}) (1c)$
因为 $mathbf{u}$ 是单位向量,$mathbf{u} cdot mathbf{v} = mathbf{u}^T mathbf{v}$,而且 $mathbf{u} mathbf{u}^T$ 是一个外积矩阵。
$mathbf{v}' = cmathbf{v} + s[mathbf{u}]_ imesmathbf{v} + (1c)mathbf{u}mathbf{u}^Tmathbf{v}$
$mathbf{v}' = (cmathbf{I} + s[mathbf{u}]_ imes + (1c)mathbf{u}mathbf{u}^T) mathbf{v}$
所以,旋转矩阵 $R$ 就是:
$R = cmathbf{I} + s[mathbf{u}]_ imes + (1c)mathbf{u}mathbf{u}^T$
把 $mathbf{u}=(u_x, u_y, u_z)$ 和反对称矩阵代入,你就能得到一个 3x3 的矩阵,这就是绕任意轴的旋转矩阵。写出来会是这样:
$R(mathbf{u}, heta) = egin{pmatrix}
cos heta + u_x^2(1cos heta) & u_x u_y (1cos heta) u_z sin heta & u_x u_z (1cos heta) + u_y sin heta \
u_y u_x (1cos heta) + u_z sin heta & cos heta + u_y^2(1cos heta) & u_y u_z (1cos heta) u_x sin heta \
u_z u_x (1cos heta) u_y sin heta & u_z u_y (1cos heta) + u_x sin heta & cos heta + u_z^2(1cos heta)
end{pmatrix}$
看吧,这个公式虽然看着复杂,但它也是从最基本的“基向量怎么变”这个思路推导出来的,只是过程需要用到一些更高级的数学工具。
总结一下
旋转矩阵的本质是:它告诉你,当空间进行一次旋转时,原本指向 x、y、z 三个方向的单位向量会变成什么方向。然后,把这三个新方向的向量作为列,组合起来,就是一个旋转矩阵。你可以把任何一个原始向量表示成这三个基向量的线性组合,那么旋转后的向量也就自然地等于这三个基向量旋转后位置的相应组合了。
记住,旋转矩阵有几个很重要的性质:
正交性 (Orthogonality):$R^T R = R R^T = mathbf{I}$ (单位矩阵)。这意味着它的转置矩阵就是它的逆矩阵。这很合理,因为旋转后想要回到原样,只需要反向旋转即可。
行列式为 1 (Determinant is 1):$det(R) = 1$。这意味着旋转不会改变体积,也不会“翻转”空间(比如让左手系变成右手系)。如果行列式是 1,那可能就是除了旋转,还包括了镜像翻转。
所以,三维旋转矩阵就是把我们对“旋转”这个几何概念的理解,用数学的语言(矩阵)表达出来的一种方式。理解了基向量的变化,也就理解了旋转矩阵的来源。