Skip to content

变换(二维与三维)

线性变换基础 (Linear Transformations)

Section titled “线性变换基础 (Linear Transformations)”

在线性代数中,线性变换 (Linear Transformation) 指一种保持向量加法与标量乘法特性的空间映射。在二维欧几里得空间中,任何线性变换均可用一个 2×22 \times 2 的矩阵来表示:

[xy]=[abcd][xy]=[ax+bycx+dy]\begin{bmatrix} x' \\ y' \end{bmatrix} = \begin{bmatrix} a & b \\ c & d \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix} = \begin{bmatrix} ax + by \\ cx + dy \end{bmatrix}

缩放矩阵通过沿主对角线设置缩放因子 sx,sys_x, s_y 来实现对空间基向量的拉伸或压缩;当缩放因子为负值时,空间将发生对称翻转(Reflection)。

S(sx,sy)=[sx00sy][xy]=[sx00sy][xy]=[sxxsyy]\mathbf{S}(s_x, s_y) = \begin{bmatrix} s_x & 0 \\ 0 & s_y \end{bmatrix} \quad \Rightarrow \quad \begin{bmatrix} x' \\ y' \end{bmatrix} = \begin{bmatrix} s_x & 0 \\ 0 & s_y \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix} = \begin{bmatrix} s_x x \\ s_y y \end{bmatrix}

例如,要实现沿 Y 轴的对称翻转(即 X 坐标取反,Y 坐标不变),只需令 sx=1,sy=1s_x = -1, s_y = 1

[xy]=[1001][xy]=[xy]\begin{bmatrix} x' \\ y' \end{bmatrix} = \begin{bmatrix} -1 & 0 \\ 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix} = \begin{bmatrix} -x \\ y \end{bmatrix}

二维缩放与对称

错切变换使得一个坐标轴的位移量依赖于另一个坐标轴的当前值。这在物理学中常用于描述应变,而在图形学中,它将矩形扭曲为平行四边形。

Shearx(a)=[1a01][xy]=[1a01][xy]=[x+ayy]\mathbf{Shear_x}(a) = \begin{bmatrix} 1 & a \\ 0 & 1 \end{bmatrix} \quad \Rightarrow \quad \begin{bmatrix} x' \\ y' \end{bmatrix} = \begin{bmatrix} 1 & a \\ 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix} = \begin{bmatrix} x + ay \\ y \end{bmatrix}

二维错切

二维旋转矩阵描述了点绕坐标原点逆时针旋转角度 θ\theta 的几何过程。根据三角函数的加法定理推导,旋转矩阵的标准形式为:

R(θ)=[cosθsinθsinθcosθ][xy]=[cosθsinθsinθcosθ][xy]=[xcosθysinθxsinθ+ycosθ]\mathbf{R}(\theta) = \begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{bmatrix} \quad \Rightarrow \quad \begin{bmatrix} x' \\ y' \end{bmatrix} = \begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix} = \begin{bmatrix} x\cos\theta - y\sin\theta \\ x\sin\theta + y\cos\theta \end{bmatrix}

二维旋转

平移是指将几何体沿着给定向量移动一定的距离。从代数上看,它是一个极为简单的坐标加法操作:

[xy]=[xy]+[txty]=[x+txy+ty]\begin{bmatrix} x' \\ y' \end{bmatrix} = \begin{bmatrix} x \\ y \end{bmatrix} + \begin{bmatrix} t_x \\ t_y \end{bmatrix} = \begin{bmatrix} x + t_x \\ y + t_y \end{bmatrix}

二维平移


齐次坐标的引入 (Homogeneous Coordinates)

Section titled “齐次坐标的引入 (Homogeneous Coordinates)”

在上述所有的 2×22 \times 2 线性变换(缩放、对称、错切、旋转)中,无论进行何种矩阵乘法操作,坐标原点 (0,0)(0,0) 永远会被映射回 (0,0)(0,0)

然而,我们刚刚提到的平移变换 (Translation) 破了这一规律,它在底层是一种加法操作。由于包含了平移,这种不再保持原点固定的变换被称为仿射变换 (Affine Transformation)。其代数表达必须在乘法之外,再硬生生地附加一个平移向量:

[xy]=[abcd][xy]+[txty]\begin{bmatrix} x' \\ y' \end{bmatrix} = \begin{bmatrix} a & b \\ c & d \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix} + \begin{bmatrix} t_x \\ t_y \end{bmatrix}

为了将平移操作也统一纳入矩阵乘法的框架中,从而实现变换的级联与硬件级并行加速,图形学引入了齐次坐标 (Homogeneous Coordinates)

通过向二维空间增加第三个维度分量 ww,所有二维仿射变换均可被升维表示为一个 3×33 \times 3 的矩阵乘法:

[xy1]=[abtxcdty001][xy1]=[ax+by+txcx+dy+ty1]\begin{bmatrix} x' \\ y' \\ 1 \end{bmatrix} = \begin{bmatrix} a & b & t_x \\ c & d & t_y \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x \\ y \\ 1 \end{bmatrix} = \begin{bmatrix} ax + by + t_x \\ cx + dy + t_y \\ 1 \end{bmatrix}

点与向量在齐次坐标下具有明确的代数区分:

  • 点 (Point):表示空间中的具体位置,其齐次坐标为 (x,y,1)(x, y, 1)
  • 向量 (Vector):表示方向与大小,具有平移不变性,其齐次坐标为 (x,y,0)(x, y, 0)

从几何拓扑的角度来审视齐次坐标,二维平面可以被视作悬浮在三维空间中 w=1w=1 高度上的一个切片。当我们在三维空间中对这个切片执行一次错切 (Shear) 换时,切片投影在 w=1w=1 平面上的截面,其表现出的相对运动正是一次二维的平移

观察 3D 空间中的错切(Shear)如何对应 2D 空间(w=1 平面)中的平移(Translation)。在画面中按住左键可旋转视角。
  1. 试着在上面的交互模型中拖动滑块 tx
  2. 你会看到三维空间中的半透明长方体发生了明显的错切变形
  3. 但如果你把视线完全聚焦在那个绿色的 w=1w=1 平面上(即真实的 2D 空间),你会发现长方体在这个平面上的横截面,表现为二维平面上的平移
  4. 这种“在更高维度进行线性错切,从而在低维度实现仿射平移”的降维打击,就是齐次坐标最底层的几何美学。

在实际的渲染管线中,一个顶点往往需要经历成百上千次复杂的变换。利用齐次坐标矩阵,我们可以将任意次平移、旋转与缩放乘在一起,预先压缩成一个单一的复合矩阵。

在各大 3D 渲染引擎(如 Unity、Unreal 以及 Three.js)中,物体的本地变换矩阵(Model Matrix)通常是由缩放(Scale)、旋转(Rotation)和平移(Translation)组合而成的,业界俗称 TRS 矩阵

根据矩阵乘法“从右向左”执行的代数特性,为了让物体先基于自身原点进行缩放,然后再进行旋转,最后再将其平移到世界空间的指定位置,变换矩阵的相乘顺序必须严格遵守 TRS\mathbf{T} \cdot \mathbf{R} \cdot \mathbf{S}

Mmodel=TRSvworld=TRSvlocal\mathbf{M}_{model} = \mathbf{T} \cdot \mathbf{R} \cdot \mathbf{S} \quad \Rightarrow \quad \mathbf{v}_{world} = \mathbf{T} \cdot \mathbf{R} \cdot \mathbf{S} \cdot \mathbf{v}_{local}

矩阵乘法不具备交换律(即 ABBAA \cdot B \neq B \cdot A)。在几何意义上,这意味着变换的执行顺序十分关键。先平移后旋转,与先旋转后平移,会得到截然不同的空间位置。

红色路径代表 先平移后旋转 (R · T),物体中心会绕原点画弧线。
蓝色路径代表 先旋转后平移 (T · R),物体仅在自身原点旋转后直线平移。
  1. 观察上方场景中处于原点的两个初始位置完全一致的物体。
  2. 我们为红色路径定义变换逻辑(世界坐标系,从右向左执行):先平移后旋转 (RTR \cdot T)。物体先沿着世界 X 轴平移,然后再绕世界原点旋转。由于旋转中心是绝对原点,平移后的物体会被像甩流星锤一样绕着原点甩出一个圆弧,且自身朝向也随之改变。
  3. 我们为蓝色路径定义变换逻辑(世界坐标系,从右向左执行):先旋转后平移 (TRT \cdot R)。先让物体在原点自转,然后再沿着世界坐标系的 X 轴平移出去。由于平移是基于世界绝对坐标的,所以它无视了自身的朝向,走出了一条笔直的横线(犹如“螃蟹走”)。
  4. 在图中你还可以看到一个重叠:红色的“第一步残影”(仅平移)和蓝色的“最终实体”(原点自转后横移)完全重叠在了一起,形成了一个十字架。这种不同的最终位置证明了矩阵乘法不满足交换律。

三维变换与旋转 (3D Transformations)

Section titled “三维变换与旋转 (3D Transformations)”

在三维空间中,我们将齐次坐标升级为 (x,y,z,1)(x, y, z, 1),所有的变换矩阵也相应地扩充为了 4×44 \times 4 矩阵。

三维的缩放与平移是对二维的自然延伸。

三维平移矩阵 (Translation):将 tx,ty,tzt_x, t_y, t_z 放入第四列,利用 w=1w=1 提取平移量。

T(tx,ty,tz)=[100tx010ty001tz0001]\mathbf{T}(t_x, t_y, t_z) = \begin{bmatrix} 1 & 0 & 0 & t_x \\ 0 & 1 & 0 & t_y \\ 0 & 0 & 1 & t_z \\ 0 & 0 & 0 & 1 \end{bmatrix}

三维缩放矩阵 (Scale):将缩放因子 sx,sy,szs_x, s_y, s_z 放置于主对角线。

S(sx,sy,sz)=[sx0000sy0000sz00001]\mathbf{S}(s_x, s_y, s_z) = \begin{bmatrix} s_x & 0 & 0 & 0 \\ 0 & s_y & 0 & 0 \\ 0 & 0 & s_z & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}

绕主轴旋转 (Principal Axis Rotations)

Section titled “绕主轴旋转 (Principal Axis Rotations)”

与平移和缩放的简单扩充不同,三维旋转的复杂性呈现了指数级的上升。在三维空间中,任何复杂的旋转都可以分解为绕 X,Y,ZX, Y, Z 三个主坐标轴的旋转组合。

以下是绕三大主轴逆时针旋转角度 θ\theta 的标准 4×44 \times 4 矩阵。推导它们的诀窍是:绕哪个轴转,该轴的对应坐标就不变(即所在行和列保持单位阵的结构),而另外两个轴所在平面执行标准的二维旋转

绕 Z 轴旋转(Rz\mathbf{R}_z:Z 坐标不变,X 和 Y 面上进行二维旋转。

Rz(θ)=[cosθsinθ00sinθcosθ0000100001]\mathbf{R}_z(\theta) = \begin{bmatrix} \cos\theta & -\sin\theta & 0 & 0 \\ \sin\theta & \cos\theta & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}

绕 X 轴旋转(Rx\mathbf{R}_x:X 坐标不变,Y 和 Z 面上进行二维旋转。

Rx(θ)=[10000cosθsinθ00sinθcosθ00001]\mathbf{R}_x(\theta) = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & \cos\theta & -\sin\theta & 0 \\ 0 & \sin\theta & \cos\theta & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}

绕 Y 轴旋转(Ry\mathbf{R}_y:Y 坐标不变,Z 和 X 面上进行二维旋转。

Ry(θ)=[cosθ0sinθ00100sinθ0cosθ00001]\mathbf{R}_y(\theta) = \begin{bmatrix} \cos\theta & 0 & \sin\theta & 0 \\ 0 & 1 & 0 & 0 \\ -\sin\theta & 0 & \cos\theta & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}

欧拉角是最直观的三维旋转表示方法,它将复杂的空间旋转分解为绕 X、Y、Z 三个主轴的连续旋转。在航空航天领域,这通常被称为:

  • 俯仰(Pitch):绕 X 轴旋转。
  • 偏航(Yaw):绕 Y 轴旋转。
  • 翻滚(Roll):绕 Z 轴旋转。
观察物体绕三根空间轴的旋转。这被称为“欧拉角(Euler Angles)”。
尝试体会“万向节死锁”:将 Y 轴调至 90°,再尝试调节 X 和 Z 轴,你会发现物体失去了向某个自由度旋转的能力。

罗德里格斯旋转公式 (Rodrigues’ Rotation Formula)

Section titled “罗德里格斯旋转公式 (Rodrigues’ Rotation Formula)”

当我们需要绕任意一根非标准坐标轴 n\mathbf{n} 旋转角度 α\alpha 时,如果强行用欧拉角去拼凑会过程繁琐。罗德里格斯旋转公式给出了直接的解析解。

R(n,α)=cos(α)I+(1cos(α))nnT+sin(α)[0nznynz0nxnynx0]\mathbf{R}(\mathbf{n}, \alpha) = \cos(\alpha)\mathbf{I} + (1 - \cos(\alpha))\mathbf{n}\mathbf{n}^T + \sin(\alpha)\begin{bmatrix} 0 & -n_z & n_y \\ n_z & 0 & -n_x \\ -n_y & n_x & 0 \end{bmatrix}

尽管该公式的代数形式显得较为庞杂,但可以通过几何关系推导。我们可以通过空间向量的正交分解,将其降维成一个简单的二维旋转问题来理解:

  1. 向量分解:首先,将待旋转的空间向量 v\mathbf{v} 沿着旋转轴 n\mathbf{n} 的方向进行投影,拆分为平行分量 v\mathbf{v}_{\parallel} 与垂直分量 v\mathbf{v}_{\perp}
  2. 静止的平行分量:因为 v\mathbf{v}_{\parallel} 与旋转轴 n\mathbf{n} 完全共线,所以在整个旋转过程中,该平行分量将保持静止
  3. 构建旋转面:由于 v\mathbf{v}_{\perp} 垂直于 n\mathbf{n},它在旋转时必定停留在一个完全垂直于 n\mathbf{n} 的空间切面内。
  4. 构造正交基:在这个垂直切面上,我们需要两个互相垂直的基向量来描述二维旋转。第一根基即为 v\mathbf{v}_{\perp} 本身;第二根基,我们可以利用叉乘 (Cross Product) 几何性质,通过 n×v\mathbf{n} \times \mathbf{v}_{\perp} 轻易求得。
  5. 执行二维旋转:此时,在由 v\mathbf{v}_{\perp}n×v\mathbf{n} \times \mathbf{v}_{\perp} 构成的垂直平面上,我们只需直接套用基础的二维旋转公式(分别赋予 cosα\cos\alphasinα\sin\alpha 权重)。最后,将旋转完成的垂直分量,与那个始终静止的平行分量 v\mathbf{v}_{\parallel} 重新相加,便能推导出上述这套完整的空间旋转代数式。

四元数初探 (Introduction to Quaternions)

Section titled “四元数初探 (Introduction to Quaternions)”

尽管罗德里格斯公式给出了绕任意轴旋转的代数解,但在实际的动画系统中,如果我们要让一个物体从朝向 A 平滑插值过渡到朝向 B,直接对两个矩阵进行线性插值会导致形变(因为插值后的矩阵往往不再保持正交),而欧拉角插值又可能触发“万向节死锁”。

为了解决三维旋转的存储效率与平滑插值问题,现代图形学底层引入了四元数 (Quaternion)

四元数由一个实部和三个虚部构成,可以写成 q=a+bi+cj+dk\mathbf{q} = a + bi + cj + dk 的形式。 在几何意义上,用来表示三维空间旋转的“单位四元数”,可以直接与“旋转轴 n\mathbf{n}”和“旋转角 θ\theta”建立直接的三角函数映射:

q=[wxyz]=[cos(θ2)nxsin(θ2)nysin(θ2)nzsin(θ2)]\mathbf{q} = \begin{bmatrix} w \\ x \\ y \\ z \end{bmatrix} = \begin{bmatrix} \cos(\frac{\theta}{2}) \\ \mathbf{n}_x \sin(\frac{\theta}{2}) \\ \mathbf{n}_y \sin(\frac{\theta}{2}) \\ \mathbf{n}_z \sin(\frac{\theta}{2}) \end{bmatrix}
  1. 避免死锁:四元数直接绕空间中的单一任意轴 n\mathbf{n} 旋转,不使用欧拉角的机制,从而避免了万向节死锁。
  2. 极简的存储空间:一个标准的 4×44 \times 4 旋转矩阵需要庞大的 16 个浮点数来存储,而一个单位四元数仅仅只需要 4 个浮点数(w,x,y,zw, x, y, z),这为现代 GPU 密集的骨骼蒙皮动画节省了海量的内存带宽。
  3. 球面插值:四元数原生支持球面线性插值(Slerp)。它可以保证物体在从姿态 A 旋转到姿态 B 时,以恒定的角速度沿大圆弧线进行平滑过渡。