在线性代数中,线性变换 (Linear Transformation) 指一种保持向量加法与标量乘法特性的空间映射。在二维欧几里得空间中,任何线性变换均可用一个 2×2 的矩阵来表示:
[x′y′]=[acbd][xy]=[ax+bycx+dy]
缩放矩阵通过沿主对角线设置缩放因子 sx,sy 来实现对空间基向量的拉伸或压缩;当缩放因子为负值时,空间将发生对称翻转(Reflection)。
S(sx,sy)=[sx00sy]⇒[x′y′]=[sx00sy][xy]=[sxxsyy]
例如,要实现沿 Y 轴的对称翻转(即 X 坐标取反,Y 坐标不变),只需令 sx=−1,sy=1:
[x′y′]=[−1001][xy]=[−xy]
错切变换使得一个坐标轴的位移量依赖于另一个坐标轴的当前值。这在物理学中常用于描述应变,而在图形学中,它将矩形扭曲为平行四边形。
Shearx(a)=[10a1]⇒[x′y′]=[10a1][xy]=[x+ayy]
二维旋转矩阵描述了点绕坐标原点逆时针旋转角度 θ 的几何过程。根据三角函数的加法定理推导,旋转矩阵的标准形式为:
R(θ)=[cosθsinθ−sinθcosθ]⇒[x′y′]=[cosθsinθ−sinθcosθ][xy]=[xcosθ−ysinθxsinθ+ycosθ]
平移是指将几何体沿着给定向量移动一定的距离。从代数上看,它是一个极为简单的坐标加法操作:
[x′y′]=[xy]+[txty]=[x+txy+ty]
在上述所有的 2×2 线性变换(缩放、对称、错切、旋转)中,无论进行何种矩阵乘法操作,坐标原点 (0,0) 永远会被映射回 (0,0)。
然而,我们刚刚提到的平移变换 (Translation) 破了这一规律,它在底层是一种加法操作。由于包含了平移,这种不再保持原点固定的变换被称为仿射变换 (Affine Transformation)。其代数表达必须在乘法之外,再硬生生地附加一个平移向量:
[x′y′]=[acbd][xy]+[txty]
为了将平移操作也统一纳入矩阵乘法的框架中,从而实现变换的级联与硬件级并行加速,图形学引入了齐次坐标 (Homogeneous Coordinates)。
通过向二维空间增加第三个维度分量 w,所有二维仿射变换均可被升维表示为一个 3×3 的矩阵乘法:
x′y′1=ac0bd0txty1xy1=ax+by+txcx+dy+ty1
点与向量在齐次坐标下具有明确的代数区分:
- 点 (Point):表示空间中的具体位置,其齐次坐标为 (x,y,1)。
- 向量 (Vector):表示方向与大小,具有平移不变性,其齐次坐标为 (x,y,0)。
从几何拓扑的角度来审视齐次坐标,二维平面可以被视作悬浮在三维空间中 w=1 高度上的一个切片。当我们在三维空间中对这个切片执行一次错切 (Shear) 换时,切片投影在 w=1 平面上的截面,其表现出的相对运动正是一次二维的平移。
- 试着在上面的交互模型中拖动滑块
tx。
- 你会看到三维空间中的半透明长方体发生了明显的错切变形。
- 但如果你把视线完全聚焦在那个绿色的 w=1 平面上(即真实的 2D 空间),你会发现长方体在这个平面上的横截面,表现为二维平面上的平移。
- 这种“在更高维度进行线性错切,从而在低维度实现仿射平移”的降维打击,就是齐次坐标最底层的几何美学。
在实际的渲染管线中,一个顶点往往需要经历成百上千次复杂的变换。利用齐次坐标矩阵,我们可以将任意次平移、旋转与缩放乘在一起,预先压缩成一个单一的复合矩阵。
在各大 3D 渲染引擎(如 Unity、Unreal 以及 Three.js)中,物体的本地变换矩阵(Model Matrix)通常是由缩放(Scale)、旋转(Rotation)和平移(Translation)组合而成的,业界俗称 TRS 矩阵。
根据矩阵乘法“从右向左”执行的代数特性,为了让物体先基于自身原点进行缩放,然后再进行旋转,最后再将其平移到世界空间的指定位置,变换矩阵的相乘顺序必须严格遵守 T⋅R⋅S:
Mmodel=T⋅R⋅S⇒vworld=T⋅R⋅S⋅vlocal
矩阵乘法不具备交换律(即 A⋅B=B⋅A)。在几何意义上,这意味着变换的执行顺序十分关键。先平移后旋转,与先旋转后平移,会得到截然不同的空间位置。
- 观察上方场景中处于原点的两个初始位置完全一致的物体。
- 我们为红色路径定义变换逻辑(世界坐标系,从右向左执行):先平移后旋转 (R⋅T)。物体先沿着世界 X 轴平移,然后再绕世界原点旋转。由于旋转中心是绝对原点,平移后的物体会被像甩流星锤一样绕着原点甩出一个圆弧,且自身朝向也随之改变。
- 我们为蓝色路径定义变换逻辑(世界坐标系,从右向左执行):先旋转后平移 (T⋅R)。先让物体在原点自转,然后再沿着世界坐标系的 X 轴平移出去。由于平移是基于世界绝对坐标的,所以它无视了自身的朝向,走出了一条笔直的横线(犹如“螃蟹走”)。
- 在图中你还可以看到一个重叠:红色的“第一步残影”(仅平移)和蓝色的“最终实体”(原点自转后横移)完全重叠在了一起,形成了一个十字架。这种不同的最终位置证明了矩阵乘法不满足交换律。
在三维空间中,我们将齐次坐标升级为 (x,y,z,1),所有的变换矩阵也相应地扩充为了 4×4 矩阵。
三维的缩放与平移是对二维的自然延伸。
三维平移矩阵 (Translation):将 tx,ty,tz 放入第四列,利用 w=1 提取平移量。
T(tx,ty,tz)=100001000010txtytz1
三维缩放矩阵 (Scale):将缩放因子 sx,sy,sz 放置于主对角线。
S(sx,sy,sz)=sx0000sy0000sz00001
与平移和缩放的简单扩充不同,三维旋转的复杂性呈现了指数级的上升。在三维空间中,任何复杂的旋转都可以分解为绕 X,Y,Z 三个主坐标轴的旋转组合。
以下是绕三大主轴逆时针旋转角度 θ 的标准 4×4 矩阵。推导它们的诀窍是:绕哪个轴转,该轴的对应坐标就不变(即所在行和列保持单位阵的结构),而另外两个轴所在平面执行标准的二维旋转。
绕 Z 轴旋转(Rz):Z 坐标不变,X 和 Y 面上进行二维旋转。
Rz(θ)=cosθsinθ00−sinθcosθ0000100001
绕 X 轴旋转(Rx):X 坐标不变,Y 和 Z 面上进行二维旋转。
Rx(θ)=10000cosθsinθ00−sinθcosθ00001
绕 Y 轴旋转(Ry):Y 坐标不变,Z 和 X 面上进行二维旋转。
Ry(θ)=cosθ0−sinθ00100sinθ0cosθ00001
欧拉角是最直观的三维旋转表示方法,它将复杂的空间旋转分解为绕 X、Y、Z 三个主轴的连续旋转。在航空航天领域,这通常被称为:
- 俯仰(Pitch):绕 X 轴旋转。
- 偏航(Yaw):绕 Y 轴旋转。
- 翻滚(Roll):绕 Z 轴旋转。
当我们需要绕任意一根非标准坐标轴 n 旋转角度 α 时,如果强行用欧拉角去拼凑会过程繁琐。罗德里格斯旋转公式给出了直接的解析解。
R(n,α)=cos(α)I+(1−cos(α))nnT+sin(α)0nz−ny−nz0nxny−nx0
尽管该公式的代数形式显得较为庞杂,但可以通过几何关系推导。我们可以通过空间向量的正交分解,将其降维成一个简单的二维旋转问题来理解:
- 向量分解:首先,将待旋转的空间向量 v 沿着旋转轴 n 的方向进行投影,拆分为平行分量 v∥ 与垂直分量 v⊥。
- 静止的平行分量:因为 v∥ 与旋转轴 n 完全共线,所以在整个旋转过程中,该平行分量将保持静止。
- 构建旋转面:由于 v⊥ 垂直于 n,它在旋转时必定停留在一个完全垂直于 n 的空间切面内。
- 构造正交基:在这个垂直切面上,我们需要两个互相垂直的基向量来描述二维旋转。第一根基即为 v⊥ 本身;第二根基,我们可以利用叉乘 (Cross Product) 几何性质,通过 n×v⊥ 轻易求得。
- 执行二维旋转:此时,在由 v⊥ 和 n×v⊥ 构成的垂直平面上,我们只需直接套用基础的二维旋转公式(分别赋予 cosα 与 sinα 权重)。最后,将旋转完成的垂直分量,与那个始终静止的平行分量 v∥ 重新相加,便能推导出上述这套完整的空间旋转代数式。
尽管罗德里格斯公式给出了绕任意轴旋转的代数解,但在实际的动画系统中,如果我们要让一个物体从朝向 A 平滑插值过渡到朝向 B,直接对两个矩阵进行线性插值会导致形变(因为插值后的矩阵往往不再保持正交),而欧拉角插值又可能触发“万向节死锁”。
为了解决三维旋转的存储效率与平滑插值问题,现代图形学底层引入了四元数 (Quaternion)。
四元数由一个实部和三个虚部构成,可以写成 q=a+bi+cj+dk 的形式。
在几何意义上,用来表示三维空间旋转的“单位四元数”,可以直接与“旋转轴 n”和“旋转角 θ”建立直接的三角函数映射:
q=wxyz=cos(2θ)nxsin(2θ)nysin(2θ)nzsin(2θ)
- 避免死锁:四元数直接绕空间中的单一任意轴 n 旋转,不使用欧拉角的机制,从而避免了万向节死锁。
- 极简的存储空间:一个标准的 4×4 旋转矩阵需要庞大的 16 个浮点数来存储,而一个单位四元数仅仅只需要 4 个浮点数(w,x,y,z),这为现代 GPU 密集的骨骼蒙皮动画节省了海量的内存带宽。
- 球面插值:四元数原生支持球面线性插值(Slerp)。它可以保证物体在从姿态 A 旋转到姿态 B 时,以恒定的角速度沿大圆弧线进行平滑过渡。