线性变换
二维 线性变换 Linear Transformation 把输入坐标映射为
(x′y′)=(acbd)(xy).
它必须保持原点,并满足可加性与齐次性,因此平移不属于线性变换。缩放、旋转、镜像和错切都可以直接写成 2×2 矩阵。
二维变换
沿两条坐标轴分别缩放 sx,sy:
S(sx,sy)=(sx00sy).
绕原点逆时针旋转 θ:
R(θ)=(cosθsinθ−sinθcosθ).
这个矩阵可以从基向量的变化推出。旋转后的 x 轴单位向量为
Rex=(cosθsinθ),
旋转后的 y 轴单位向量与它垂直,并同样逆时针旋转:
Rey=(−sinθcosθ).
线性映射的矩阵以各基向量的像为列,把两列并在一起就得到 R(θ)。这比单独记四个三角函数符号更容易检查。
关于 y 轴镜像可写成 diag(−1,1)。水平错切的形式为
H(k)=(10k1),x′=x+ky.
旋转矩阵的逆等于转置,并且 R(−θ)=R(θ)−1。二维缩放中,负系数的个数为奇数时会翻转坐标系朝向;两个系数都为负则相当于正缩放后再旋转 180∘,整体朝向不变。任一系数为零都会压扁一个维度,使矩阵不可逆。
齐次坐标
平移 x′=x+tx,y′=y+ty 含有常数项,无法由 2×2 矩阵表示。齐次坐标 Homogeneous Coordinates 为二维坐标增加第三个分量:
点 (x,y)⟶(x,y,1)T,向量 (x,y)⟶(x,y,0)T.
于是平移可以统一写成
T(tx,ty)=100010txty1.
点的末分量为 1,所以会受到平移;向量表示两个点的差,末分量为 0,不应因坐标原点移动而改变。齐次坐标还解释了常见运算:点减点得到向量,点加向量得到点,而两个点相加没有直接的仿射几何意义。
当 w=0 时,(wx,wy,w) 的任意非零整体倍数都表示同一个二维点 (x,y)。这个比例等价性在透视投影中尤为重要。
更一般地,w=0 的齐次坐标 (X,Y,w) 对应仿射点 (X/w,Y/w);w=0 时无法做这种除法,它表示无穷远方向。仿射变换的最后一行固定为 (0,0,1),因此点仍是点、方向仍是方向;透视变换允许改变 w,再通过齐次除法产生随深度变化的缩放。
仿射变换
线性变换与平移组合成 仿射变换 Affine Transformation:
x′y′1=ac0bd0txty1xy1.
仿射变换保持直线、平行关系和同一直线上的长度比,但不一定保持角度与绝对长度。使用齐次矩阵后,缩放、旋转、错切和平移都能参与同一种矩阵乘法,整条变换链可以预先合并。
变换次序
对列向量约定,若希望先应用 A1,再应用 A2,最终结果是
p′=A2A1p.
矩阵从右向左作用。先平移再旋转,与先旋转再平移得到的结果通常不同。例如让物体绕自身中心 c 旋转,应先把中心移到原点,再旋转,最后移回:
M=T(c)R(θ)T(−c).
对列向量,代码中“先做”的变换写在矩阵乘积右侧;改变乘法顺序通常会改变旋转中心和最终位置。

把一串变换预乘为单个矩阵,可以显著减少大量顶点重复执行时的计算开销。
逆变换
逆变换 Inverse Transformation 用于从目标坐标系返回原坐标系。平移的逆是反向平移,缩放的逆是缩放倒数,旋转的逆是反向旋转。复合变换必须按相反次序逐个撤销:
(TRS)−1=S−1R−1T−1.
若某个缩放轴的系数为零,空间信息已经丢失,变换不可逆。工程中应避免在需要法线变换或坐标反查的路径里引入奇异矩阵。
三维变换
三维仿射变换使用 4×4 齐次矩阵。点写成 (x,y,z,1)T,向量写成 (x,y,z,0)T。缩放和平移为
S=sx0000sy0000sz00001,T=100001000010txtytz1.
绕 x,y,z 轴的旋转分别只改变另外两个坐标。任意三维旋转可以由三个轴旋转组合,但 欧拉角 Euler Angles 的次序会影响结果,并可能出现 万向节锁 Gimbal Lock。四元数能更稳定地插值旋转,不过不属于本课程的展开重点。

比较不同教材或 API 的矩阵前,应先统一列向量或行向量约定、左右手系和相机方向;否则即使矩阵形式相似,符号和乘法次序也可能不同。
按右手系和列向量约定,三个轴旋转矩阵为
Rx(θ)=10000cosθsinθ00−sinθcosθ00001,
Ry(θ)=cosθ0−sinθ00100sinθ0cosθ00001,
Rz(θ)=cosθsinθ00−sinθcosθ0000100001.
例如绕 x 轴旋转时,x 分量不变,yz 平面执行一次二维旋转。改变坐标系手性、向量位于矩阵哪一侧或把主动旋转改为坐标系旋转,都会改变符号与乘法次序。
法线变换
表面切向量会随物体的线性部分 M 变换:
t′=Mt.
法线的定义是与所有切向量垂直。若直接令 n′=Mn,非均匀缩放后一般有
(Mn)T(Mt)=nTMTMt=0,
法线会失去垂直性。
设正确的法线变换为 n′=Gn。要求任意原切向量满足
(n′)Tt′=(Gn)TMt=nTGTMt=0.
原来已有 nTt=0,因此只要选择
GTM=I,
就能保持这条关系。解得
G=M−T.
所以 法线矩阵 Normal Matrix 是模型或 Model–View 线性部分的逆转置:
n′=normalize(M−Tn).
平移不影响方向,只取齐次矩阵左上角的 3×3 线性部分。纯旋转时 M−T=M,直接乘旋转矩阵没有问题;非均匀缩放和错切时必须使用逆转置。
归一化只能修正长度,不能修正非均匀缩放造成的方向错误。
任意轴旋转
令旋转轴 n 为单位向量。先把待旋转向量 p 分成平行和垂直两部分:
p∥=(n⋅p)n=nnTp,
p⊥=p−p∥.
平行分量在旋转中保持不变。垂直平面内,p⊥ 与 n×p⊥ 互相垂直、长度相同,构成二维旋转所需的两条基。因此
p′=p∥+cosαp⊥+sinα(n×p⊥).
又因为 n×p∥=0,代入分解并整理:
p′=cosαp+(1−cosα)nnTp+sinα(n×p).
把叉积写成反对称矩阵 [n]×p=n×p,便得到 Rodrigues 旋转公式 Rodrigues’ Rotation Formula:
R(n,α)=cosαI+(1−cosα)nnT+sinα0nz−ny−nz0nxny−nx0.
前两项共同保留轴向分量并缩放垂直分量,第三项补上垂直平面内旋转 90∘ 的方向。代入 p=n 可得 Rn=n;代入 α=0 可得 R=I,都是直接的正确性检查。
若旋转轴经过点 c 而不经过原点,应先平移 −c,完成旋转后再移回:
M=T(c)R(n,α)T(−c).