我的理解能力很差劲。看了多次的图形学基础章节,每次看到最基本的变换矩阵,我都觉得反人类。我得先在脑子里给它乘开,就这一步我的脑子就得先旋转90度去操作(第n行乘上第n列这种)。我觉得是不是我的心智模型搭建错了,既然发明了矩阵这个工具,我何必还要反向拆出来呢。
感觉要建立一种直觉,死记硬背数字排列实在是难为自己。
下面是push 千问爱卿给我的答案。谢谢千问。
如何辨识是AI写的还是我自己写的非常简单,我说话已经不太遵循标准中文语法了。但有时候看到AI写的博客又觉得差点意思,在知乎上和CSDN上看到明显的AI生成的博客看一眼我就走了。可能是因为我自己也能问出来?我觉得如果要和AI一起写博客,应该补充一些自己的理解模型和学习期间的心路历程,说白了最后是写给自己看的。这些混乱的、自嘲的、带着个人体温的东西,可能才是最想留下的,知识的堆砌AI们已经做得太好了。
下面就是知识堆砌()
核心视角:齐次坐标与矩阵拆解
在图形学(特别是 OpenGL、DirectX 或 UE 引擎)中,我们引入**齐次坐标 (Homogeneous Coordinates)**,将 3D 点 $(x, y, z)$ 扩展为 $(x, y, z, 1)$。这个看似多余的 $1$,正是让 $4 \times 4$ 矩阵能够统一处理平移的关键。
我们可以将一个标准的变换矩阵拆解为四个部分来理解:
$$
\begin{bmatrix}
\text{旋转/缩放} & \text{旋转/缩放} & \text{旋转/缩放} & \mathbf{\text{平移 (Translation)}} \
(X\text{轴新方向}) & (Y\text{轴新方向}) & (Z\text{轴新方向}) & (X,Y,Z \text{位移}) \
\hline
0 & 0 & 0 & 1
\end{bmatrix}
$$
记忆的逻辑非常清晰:前三列决定了物体的朝向和胖瘦(即旋转与缩放),第四列决定了物体的位置(即平移),而最后一行永远是 $0, 0, 0, 1$,这是为了维持齐次坐标的数学性质,通常不需要额外关注。
1. 平移矩阵 (Translation):最简单的位置移动
平移的直觉非常直接:让物体在 $X, Y, Z$ 轴上分别移动 $T_x, T_y, T_z$。因为平移只跟位置有关,跟方向无关,所以它只出现在矩阵的第四列。这是因为点是 $(x,y,z,1)$,只有乘以第四列的数值,那个常数 $1$ 才能把平移量“带进去”加到坐标上。
其矩阵形态是单位矩阵的基础上,仅在最后一列填入移动距离:
$$
T = \begin{bmatrix}
1 & 0 & 0 & \mathbf{T_x} \
0 & 1 & 0 & \mathbf{T_y} \
0 & 0 & 1 & \mathbf{T_z} \
0 & 0 & 0 & 1
\end{bmatrix}
$$
验证一下就会发现,对角线的 $1$ 保持了原坐标不变,而最后一列的数值通过乘以 $w=1$ 直接加到了 $x, y, z$ 上,实现了 $x+T_x$ 的效果。
2. 缩放矩阵 (Scaling):改变坐标轴长度
缩放的直觉是改变坐标轴的“刻度”。如果想让 $X$ 轴拉长 $S_x$ 倍,只需修改对角线上对应的数字即可。因此,缩放矩阵的特征是只有对角线有值,其余全为 $0$(最后一行除外)。
$$
S = \begin{bmatrix}
\mathbf{S_x} & 0 & 0 & 0 \
0 & \mathbf{S_y} & 0 & 0 \
0 & 0 & \mathbf{S_z} & 0 \
0 & 0 & 0 & 1
\end{bmatrix}
$$
这里还有一个有趣的特例:如果某个轴向的缩放值为 $-1$(例如 $S_x = -1$),那就意味着物体沿该轴的垂直平面进行了镜像翻转。
3. 旋转矩阵 (Rotation):最难但有套路
旋转矩阵之所以难记,是因为涉及 $\sin$ 和 $\cos$ 的位置以及正负号的变化。但只要掌握核心心法,就能化繁为简:
- 绕谁转,谁不变:绕 $Z$ 轴旋转,$Z$ 轴所在的行和列就保持 $0,0,1,0$ 的状态(除了对角线是 $1$),这相当于把 3D 问题降维成了 2D 问题。
- 剩下的 $2 \times 2$ 就是标准 2D 旋转:形式通常为 $\begin{bmatrix} \cos\theta & -\sin\theta \ \sin\theta & \cos\theta \end{bmatrix}$。
具体的旋转矩阵如下(以左手坐标系为例,如 UE/DirectX):
- 绕 Z 轴旋转:就像在桌面上转纸片,$X$ 和 $Y$ 变,$Z$ 不变。负号位于右上角(第一行第二列),记忆口诀是“像转盘子,负号在上”。
- 绕 X 轴旋转:$Y$ 和 $Z$ 变,$X$ 不变。右下角的 $2 \times 2$ 结构与绕 $Z$ 轴类似,负号依然在上方(相对于该 $2 \times 2$ 子矩阵),口诀是“像翻书,负号在上”。
- 绕 Y 轴旋转(最容易错):$X$ 和 $Z$ 变,$Y$ 不变。注意 $Y$ 轴在中间,其对应的 2D 平面是 $X-Z$,顺序发生了变化。为了保持手性定则的连续性,$\sin$ 的负号跑到了左下角(第三行第一列)。口诀是“只有 $Y$ 轴反转了,负号在下”。
终极记忆表格与结构总结
为了方便复习,我们可以将上述规律浓缩为一张表(基于左手坐标系):
| 变换类型 | 矩阵形态特征 | 关键数字位置 | 一句话记忆 |
|---|---|---|---|
| 平移 | 单位矩阵 + 最后一列 | $M_{14}, M_{24}, M_{34}$ | 只有最后一列有非 0 非 1 的数 |
| 缩放 | 对角线矩阵 | $M_{11}, M_{22}, M_{33}$ | 只有对角线有数 |
| 绕 Z 转 | Z 轴锁死 | $-\sin$ 在右上 ($M_{12}$) | 像转盘子,负号在上 |
| 绕 X 转 | X 轴锁死 | $-\sin$ 在右上 ($M_{23}$) | 像翻书,负号在上 |
| 绕 Y 转 | Y 轴锁死 | $-\sin$ 在左下 ($M_{31}$) | 中间轴特殊,负号在下 |
总结来说,别再去背那 16 个数字了。只要记住:左上 $3 \times 3$ 管旋转缩放,右侧 $3 \times 1$ 管平移,底部 $1 \times 4$ 固定不变。对于旋转,只需区分 $Y$ 轴的负号位置与其他两轴不同即可。
深度思考:为什么必须是 4x4?
你可能会问,为什么不能用 $3 \times 3$ 矩阵?如果是 $3 \times 3$ 矩阵,它只能做旋转和缩放这类线性变换,做不到平移。因为在数学上,线性变换必须保持原点不动($A \times \vec{0} = \vec{0}$),你无法通过 $3 \times 3$ 矩阵乘法让 $(0,0,0)$ 变成 $(1,1,1)$。
引入第 4 个维度 $w=1$ 后,我们将 3D 空间嵌入到了 4D 空间的一个切片里。此时,平移变成了 4D 空间里的“剪切 (Shear)”变换。这样做的好处是巨大的:我们可以把平移、旋转、缩放全部乘在一起,合并成一个巨大的矩阵 $M = T \times R \times S$。在计算时,顶点 $V$ 只需要算一次 $V’ = M \times V$,这种统一的操作极大地迎合了 GPU 的计算偏好。
实战中的顺序陷阱
最后,在实际编程(如 UE 的 C++ 或 HLSL)中,矩阵乘法的顺序至关重要,因为矩阵乘法不满足交换律($A \times B \neq B \times A$)。
在列向量习惯(OpenGL, GLSL, UE5 默认数学库)中,运算顺序是从右往左读的。如果我们构造矩阵 $M = T \times R \times S$,那么对顶点 $v$ 的变换过程实际上是 $v’ = T \times (R \times (S \times v))$。这意味着执行顺序是:**先缩放 (Scale),再旋转 (Rotate),最后平移 (Translate)**。
这个顺序符合我们的直觉:想象你是一个角色,你应该先原地蹲下或长高(缩放),然后原地转身(旋转),最后沿着现在的朝向走出去(平移)。如果你颠倒了顺序,比如先平移再旋转,你就会绕着世界原点转圈,而不是原地转身了。而在行向量习惯中,顺序则是从左往右,先写的先执行。理解这一点,能避免很多调试时的诡异 Bug。
通过以上梳理,希望你对 $4 \times 4$ 矩阵不再感到恐惧。只要理解了其背后的几何意义和结构逻辑,这些矩阵就不再是冷冰冰的数字堆砌,而是操控虚拟世界的强大指令。