转换的矩阵表示形式
m×n 矩阵是一组以 m 行和 n 列排列的数字。 下图显示了多个矩阵。
可以通过添加单个元素来添加两个相同大小的矩阵。 下图显示了两个矩阵加法示例。
m×n 矩阵可以乘以 n×p 矩阵,结果为 m×p 矩阵。 第一个矩阵的列数必须与第二个矩阵的行数相同。 例如,4 ×2 矩阵可以乘以 2 ×3 矩阵来生成 4 ×3 矩阵。
可以将平面中的点以及矩阵的行和列视为向量。 例如,(2, 5) 是具有两个分量的向量,(3, 7, 1) 是具有三个分量的向量。 两个向量的点积定义如下:
(a, b) • (c, d) = ac + bd
(a, b, c) • (d, e, f) = ad + be + cf
例如,(2, 3) 和 (5, 4) 的点积是 (2)(5) + (3)(4) = 22。 (2, 5, 1) 和 (4, 3, 1) 的点积是 (2)(4) + (5)(3) + (1)(1) = 24。 请注意,两个向量的点积是一个数字,而不是另一个向量。 另请注意,只有当两个向量具有相同数量的分量时,才能计算点积。
让 A (i、 j) 第 i 行 和第 j列 的矩阵 A 中的条目。 例如,A (3、2) 是矩阵 A 中第 3行和第 2 列的条目。 假设 A、B 和 C 是矩阵,且 AB = C。C 的条目的计算如下:
C(i, j) = (A 的 i 行) • (B 的 j 列)
下图显示了矩阵乘法的几个示例。
如果将平面中的某个点视为 1 × 2 矩阵,可以通过将其乘以 2 × 2 矩阵来转换该点。 下图显示了应用于点 (2, 1) 的几个变换。
上图中显示的所有转换都是线性转换。 某些其他转换(如平移)不是线性的,不能用 2 × 2 矩阵表示为乘法。 假设要从点 (2, 1) 开始,将其旋转 90 度,沿 x 方向平移 3 个单位,并沿 y 方向平移 4 个单位。 可以通过执行矩阵乘法和矩阵加法来实现此目的。
线性转换 (乘以 2 × 2 矩阵) 后接 1 × 2 矩阵的平移 (相加) 称为仿射变换。 在一对矩阵中存储仿射转换的替代方法 (一个用于线性部件,另一个用于转换) ,方法是将整个转换存储在 3 × 3 矩阵中。 若要执行此操作,平面中的点必须存储在具有虚拟第 3 个坐标的 1 × 3 矩阵中。 通常的方法是使所有第 3 个坐标等于 1。 例如,点 (2, 1) 由矩阵 [2 1 1] 表示。 下图显示了旋转 90 度 (仿射转换:在 x 方向平移 3 个单位,y 方向的 4 个单位) 用单个 3 × 3 矩阵表示为乘法。
在上一个示例中,点 (2, 1) 映射到点 (2, 6) 。 请注意,3 × 3 矩阵的第三列包含数字 0、0、1。 对于仿射转换的 3 × 3 矩阵,将始终如此。 重要的数字是 1 列和 2 列中的六个数字。 矩阵的左上角 2 × 2 部分表示转换的线性部分,第 3 行的前两个条目表示转换。
在 Windows GDI+ 中,可以将仿射转换存储在 Matrix 对象中。 由于表示仿射转换的矩阵的第三列始终 (0、0、1) ,因此在构造 Matrix 对象时,仅指定前两列中的六个数字。 语句 Matrix myMatrix(0.0f, 1.0f, -1.0f, 0.0f, 3.0f, 4.0f);
构造上图所示的矩阵。
复合变换
复合变换是一个接一个的一系列变换。 考虑以下列表中的矩阵和变换:
- 矩阵 A 旋转 90 度
- 矩阵 B 在 x 方向上按 2 因子缩放
- 矩阵 C 在 y 方向转换 3 个单位
如果从点 (2、1) 开始(由矩阵 [2 1 1] 表示),再乘以 A、B、C,则点 (2,1) 将按列出的顺序进行三次转换。
[2 1 1]ABC = [ –2 5 1]
可以将 A、B 和 C 相乘,而不是将复合转换的三个部分存储在三个单独的矩阵中,以获取存储整个复合转换的单个 3 × 3 矩阵。 假设 ABC = D。那么一个点乘以 D 得到的结果与一个点依次乘以 A、B、C 的结果相同。
[2 1 1]D = [ –2 5 1]
下图显示了矩阵 A、B、C 和 D。
复合转换的矩阵可以通过乘以单个转换矩阵来形成这一事实意味着任何仿射转换序列都可以存储在单个 Matrix 对象中。
注意
复合变换的顺序很重要。 一般来说,旋转、缩放、平移与缩放、旋转、平移是不同的。 同样,矩阵乘法的顺序也很重要。 一般来说,ABC 与 BAC 不同。
Matrix 类提供了几种用于生成复合转换的方法:Matrix::Multiply、Matrix::Rotate、Matrix::RotateAt、Matrix::Scale、Matrix::Shear 和 Matrix::Translate。 以下示例创建复合转换的矩阵,该矩阵首先旋转 30 度,然后在 y 方向按 2 因子缩放,然后在 x 方向平移 5 个单位。
Matrix myMatrix;
myMatrix.Rotate(30.0f);
myMatrix.Scale(1.0f, 2.0f, MatrixOrderAppend);
myMatrix.Translate(5.0f, 0.0f, MatrixOrderAppend);
下图显示了该矩阵。