Поделиться через


Матричное представление преобразований

Матрица 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-й строке представляют перевод.

Иллюстрация, показывающая, что первые два столбца наиболее важны для матрицы аффинного преобразования 3x3

В 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);

Матрица показана на рисунке ниже.

Иллюстрация, показывающая матрицу со значениями, выраженными в виде тригонометрических функций, и матрицу с приблизительными значениями этих функций