Матричное представление преобразований
Матрица 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 с фиктивной 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-й строке представляют перевод.
В Windows GDI+ можно хранить аффинное преобразование в объекте Matrix . Так как третий столбец матрицы, представляющий аффинное преобразование, всегда имеет значение (0, 0, 1), при построении объекта Matrix в первых двух столбцах указывается только шесть чисел. Оператор Matrix myMatrix(0.0f, 1.0f, -1.0f, 0.0f, 3.0f, 4.0f);
создает матрицу, показанную на предыдущем рисунке.
Составные преобразования
Составное преобразование — это последовательность преобразований, которые следуют друг за другом. Рассмотрим матрицы и преобразования из следующего списка:
- Матрица 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 предоставляет несколько методов для создания составного преобразования: Matrix::Multiply, Matrix::Rotate, Matrix::RotateAt, Matrix::Scale, Matrix::Shear и Matrix::Translate. В следующем примере создается матрица составного преобразования, которое сначала вращается на 30 градусов, затем масштабируется в 2 раза в направлении y, а затем преобразует 5 единиц в направлении x.
Matrix myMatrix;
myMatrix.Rotate(30.0f);
myMatrix.Scale(1.0f, 2.0f, MatrixOrderAppend);
myMatrix.Translate(5.0f, 0.0f, MatrixOrderAppend);
Матрица показана на рисунке ниже.