Матричное представление преобразований
Матрица размером 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) — элемент матрицы A в строке i и столбце j. Например, A(3, 2) — элемент матрицы A в 3-й строке и 2-м столбце. Предположим, A, B и C являются матрицами и AB = C. Элементы матрицы C вычисляются следующим образом:
C(i, j) = (строка i матрицы A) • (столбец j матрицы B)
На рисунке ниже показано несколько примеров умножения матриц.
Если представить точку на плоскости как матрицу размера 1×2, эту точку можно преобразовать, умножив ее на матрицу размера 2×2. На рисунке ниже показано несколько преобразований, применяемых к точке (2, 1).
Все преобразования, показанные на предыдущем рисунке, являются линейными. Некоторые другие преобразования, такие как сдвиг, не являются линейными и не могут быть выражены в виде умножения на матрицу размера 2×2. Предположим, нужно начать с точки (2, 1), повернуть ее на 90 градусов, сдвинуть на 3 единицы по оси x, а затем сдвинуть на 4 единицы по оси y. Это можно сделать, сначала умножив матрицы, а затем сложив.
Линейное преобразование (умножение на матрицу размера 2×2), за которым следует сдвиг (сложение с матрицей размера 1×2), называется аффинным преобразованием. Вместо хранения аффинного преобразования в паре матриц (одной для линейной составляющей и еще одной для сдвига) можно хранить все преобразование в матрице размера 3×3. Для этого точка на плоскости должна храниться в матрице размера 1×3 с фиктивной третьей координатой. Как правило, третьи координаты делаются равными 1. Например, точка (2, 1) представляется матрицей [2 1 1]. На рисунке ниже показано аффинное преобразование (поворот на 90 градусов, сдвиг на 3 единиц по оси x и на 4 единицы по оси y), выраженное в виде умножения на одну матрицу размера 3×3.
В предыдущем примере точка (2, 1) сопоставляется с точкой (2, 6). Обратите внимание, что третий столбец матрицы размера 3×3 содержит числа 0, 0, 1. Это всегда будет верно для матрицы аффинного преобразования размера 3×3. Важными числами являются шесть чисел в столбцах 1 и 2. Левая верхняя часть 2×2 матрицы представляет линейную составляющую преобразования, а первые два элемента в 3-й строке представляют сдвиг.
В GDI+ аффинное преобразование можно хранить в объектеMatrix. Так как третий столбец матрицы, представляющей аффинное преобразование, всегда содержит значения (0, 0, 1), при создании объекта Matrix указываются только шесть чисел в первых двух столбцах. Оператор Matrix myMatrix = new Matrix(0, 1, -1, 0, 3, 4)
создает матрицу, показанную на предыдущем рисунке.
Составные преобразования
Составное преобразование — это последовательность преобразований, которые следуют друг за другом. Рассмотрим матрицы и преобразования из следующего списка:
Матрица | Преобразование |
---|---|
Матрица A | Повернуть на 90 градусов |
Матрица B | Масштабирование с коэффициентом 2 по оси x |
Матрица C | Сдвиг на 3 единицы по оси y |
Если начать с точки (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 предоставляет несколько методов для создания составных преобразований: Multiply, Rotate, RotateAt, Scale, Shear и Translate. В следующем примере создается матрица составного преобразования, которое сначала выполняет поворот на 30 градусов, затем масштабирование с коэффициентом 2 по оси y, а затем сдвиг на 5 единиц по оси x:
Matrix myMatrix = new Matrix();
myMatrix.Rotate(30);
myMatrix.Scale(1, 2, MatrixOrder.Append);
myMatrix.Translate(5, 0, MatrixOrder.Append);
Dim myMatrix As New Matrix()
myMatrix.Rotate(30)
myMatrix.Scale(1, 2, MatrixOrder.Append)
myMatrix.Translate(5, 0, MatrixOrder.Append)
Матрица показана на рисунке ниже.
См. также
.NET Desktop feedback