Матричное представление преобразований
Обновлен: Ноябрь 2007
Матрица 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, задающих аффинные преобразования. Смысловую нагрузку несут только шесть чисел в первом и втором столбцах матрицы преобразования. Верхняя левая часть матрицы размером 2×2 задает линейную часть преобразования, а первые два числа в третьей строке матрицы задают сдвиг.
Интерфейс GDI+ позволяет хранить аффинные преобразования в объекте Matrix. Так как третий столбец матрицы, задающей аффинное преобразование, всегда равен (0, 0, 1), при создании объекта Matrix нужно задавать только шесть чисел в первых двух столбцах. Инструкция Matrix myMatrix = new Matrix(0, 1, -1, 0, 3, 4) создает матрицу, изображенную на приведенном выше рисунке.
Составные преобразования
Составным преобразованием называется серия последовательно применяемых преобразований. Рассмотрим следующие матрицы и преобразования:
Матрица A |
Поворот на 90 градусов. |
Матрица B |
Масштабирование по оси X с коэффициентом 2. |
Матрица C |
Сдвиг на три единицы по оси 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 градусов, затем масштабирование вдоль оси Y с коэффициентом 2 и сдвиг на 5 единиц вдоль оси X.
Dim myMatrix As New Matrix()
myMatrix.Rotate(30)
myMatrix.Scale(1, 2, MatrixOrder.Append)
myMatrix.Translate(5, 0, MatrixOrder.Append)
Matrix myMatrix = new Matrix();
myMatrix.Rotate(30);
myMatrix.Scale(1, 2, MatrixOrder.Append);
myMatrix.Translate(5, 0, MatrixOrder.Append);
На приведенном ниже рисунке изображена полученная матрица.