# 第六章 变换矩阵

类似于“旋转”、“平移”、“缩放”和“投影”等几何变换,都可以使用矩阵乘法实现。本章的主题就是使用变换矩阵来完成几何变换。

# 2D 线性变换

使用一个 2x2 的矩阵去改变或变换一个 2D 向量:

[a11a12a21a22][xy]=[a11x+a12ya21x+a22y]\begin{bmatrix} a_{11} & a_{12} \\ a_{21} & a_{22}\end{bmatrix} \begin{bmatrix} x \\ y\end{bmatrix} = \begin{bmatrix} a_{11}x + a_{12}y \\ a_{21}x + a_{22}y \end{bmatrix}

像这种使用一个简单的矩阵乘法将一个向量变为另外一个向量的操作,被称为线性变换。我们可以通过改变左侧的矩阵来实现各种各样的变换,下面开始讨论。

# 缩放

最简单的变换是沿着坐标轴进行缩放变换。缩放变换能改变向量的大小和方向

scale(sx,sy)=[sx00sy]scale(s_x, s_y) = \begin{bmatrix} s_x & 0 \\ 0 & s_y \end{bmatrix}

将它应用到向量上:

[sx00sy][xy]=[sxxsyy]\begin{bmatrix} s_x & 0 \\ 0 & s_y \end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix} = \begin{bmatrix} s_xx \\ s_yy \end{bmatrix}

从缩放矩阵的对角线可以直接获得两个坐标轴的缩放因子。

# 切变

切变的效果就是将物体沿着侧面推出去,就像桌上有一叠扑克牌,然后我们沿着一个方法推牌,那么位于底部的扑克牌不会移动,而越是靠上的扑克牌移动越远。

水平方向上的切变

shearx(s)=[1s01]shear_x(s) = \begin{bmatrix} 1 & s \\ 0 & 1 \end{bmatrix}

垂直方向上的切变

sheary(s)=[10s1]shear_y(s) = \begin{bmatrix} 1 & 0 \\ s & 1 \end{bmatrix}

另一个理解的切变的办法是:将切变看作是绕 x 轴或 y 轴的旋转。

a. 绕竖轴顺时针旋转 ϕ\phi

[1tanϕ01]\begin{bmatrix} 1 & \tan\phi \\ 0 & 1 \end{bmatrix}

b. 绕横轴顺时针旋转 ϕ\phi

[10tanϕ1]\begin{bmatrix} 1 & 0 \\ \tan\phi & 1 \end{bmatrix}

# 旋转

假设将向量 a\bold{a} 逆时针旋转角度 ϕ\phi 后得到一个新向量b\bold{b}。若 a\bold{a} 与 x 轴的夹角为 α\alpha ,且它的长度为r=xa2+ya2r = \sqrt{x_a^2 + y_a^2},我们还知道

xa=rcosαya=rsinαx_a = r\cos\alpha\, y_a = r\sin\alpha

因为向量 bb 是由 aa 旋转 ϕ\phi 得到的,所以它的长度也是 r,并且它与 x 轴的夹角为 α+ϕ\alpha + \phi。根据三角函数公式:

xb=rcos(α+ϕ)=rcosαcosϕrsinαsinϕx_b = r\cos(\alpha + \phi) = r\cos\alpha\cos\phi - r\sin\alpha\sin\phi

yb=rsin(α+ϕ)=rsinαcosϕ+rcosαsinϕy_b = r\sin(\alpha + \phi) = r\sin\alpha\cos\phi + r\cos\alpha\sin\phi

代入 xa=rcosαx_a = r\cos\alphaya=rsinαy_a = r\sin\alpha 可得:

xb=xacosϕyasinϕx_b = x_a\cos\phi - y_a\sin\phi

yb=xasinϕ+yacosϕy_b = x_a\sin\phi + y_a\cos\phi

由此可知,旋转矩阵为:

rotate(ϕ)=[cosϕsinϕsinϕcosϕ]rotate(\phi) = \begin{bmatrix} \cos\phi & -\sin\phi \\ \sin\phi & \cos\phi \end{bmatrix}

同时这也是一个正交矩阵

# 反射

我们可以使用一个负数比例使得任何一个向量基于某个坐标轴进行反射:

reflecty=[1001]reflect_y = \begin{bmatrix} -1 & 0 \\ 0 & 1 \end{bmatrix}

reflectx=[1001]reflect_x = \begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix}

虽然人们可能会认为对角线的两个元素都为-1 的矩阵也是一个反射,但实际上它只是一个 π 弧度的旋转而已。

# 组合变换

在图形学程序中经常会对一个物体应用多个变换。例如,对一个物体先进行缩放操作 SS,再进行旋转操作 RR,用向量表示:

首先,v_2 = Sv_1,接着,v_3 = Rv_2

换一个写法:

v3=R(Sv1)v_3 = R(Sv_1)

因为矩阵乘法满足结合律,因此:

v3=(RS)v1v_3 = (RS)v_1

换句话说,我们可以使用两个变换矩阵相乘后得到的同样大小的矩阵来表示分别进行这两个变换后的结果:

M=RSM = RS

请记住:这些变换矩阵是从右往左应用,那么形如 M=RSM=RS 这样,就是先应用SS,后应用 RR

# 分解变换

有些时候,将一个组合变换分解成一些简单的部分也极其重要。例如,将变换分解为几个旋转操作和缩放操作,大多时候是十分有效的。但是,一般变换都在内部使用了旋转和缩放混合后的矩阵表示。如果能通过计算将矩阵拆解成所需的碎片,调整碎片,再将碎片相乘重新组合矩阵,就可以实现这种操作。

事实证明,无论矩阵中的条目是什么,这种分解或因式化都是可能的--而这一事实为我们提供了一种富有成效的思考方式,即如何看待变换以及它们对被变换的几何体的影响。

# 对称特征值分解

我们先从对称矩阵开始,回顾 5.4 章节提到的,一个对称矩阵通过特征值分解后可写成如下乘法形式:

A=RSRTA = RSR^T

此等式中 RR 是一个正交矩阵,SS 是一个对角矩阵,我们将 RR 的列(特征向量)称为 v1v_1v2v_2 ,将 SS 的对角线项(特征值)称为 λ_1 和 λ_2。

用几何学术语来说,我们现在可以把 RR 看作是旋转,把 SS 看作是缩放,所以这只是一个多步骤的几何变换:

  • 绕着 x 轴和 y 轴旋转 v1v_1v2v_2 (RTR^T 变换)
  • 在 x 轴和 y 轴上缩放 (λ_1, λ_2) (SS 变换)
  • 将 x 轴和 y 轴旋转至 v1v_1v2v_2 (RR 变换)

# 奇异值分解

对于非对称的矩阵也可以进行类似的分解操作——奇异值分解(5.4.1 章节提到)。非对称矩阵的不同之处在于矩阵的对角线两侧的元素不再相同:

A=USVTA = USV^T

旋转矩阵R被两个正交矩阵UV代替,