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


Значение порядка преобразований

Обновлен: Ноябрь 2007

В одном объекте Matrix может храниться одно преобразование или некоторая последовательность преобразований. Такая последовательность преобразований называется составным преобразованием. Матрица составного преобразования получается с помощью перемножения матриц отдельных преобразований.

Примеры составных преобразований

Порядок следования отдельных преобразований имеет важное значение для составного преобразования. Например, если применяется поворот, затем масштабирование, а затем сдвиг, получается совершенно другой результат, чем если бы сначала был применен сдвиг, затем поворот, а затем масштабирование. В GDI+ построение составных преобразований осуществляется слева направо. Если S, R и T являются матрицами масштабирования, поворота и сдвига, соответственно, тогда произведение SRT (именно в таком порядке) является матрицей составного преобразования, которое сначала масштабирует, затем поворачивает, а затем осуществляет сдвиг. Матрица, равная произведению SRT, отличается от матрицы, являющейся произведением TRS.

Одной из причин важности порядка выполнения преобразований является то, что такие преобразования, как поворот и масштабирование, осуществляются относительно начала координат. Масштабирование объекта, центрированного по началу координат, дает другой результат, чем масштабирование объекта, который куда-либо сдвинут относительно этой точки. Аналогично, поворот объекта, центрированного по началу координат, дает другой результат, чем поворот объекта, который куда-либо сдвинут относительно этой точки.

В следующем примере комбинация масштабирования, поворота и сдвига (именно в таком порядке) используется для конструирования составного преобразования. Аргумент Append, передаваемый методу RotateTransform, указывает на то, что поворот будет выполняться после масштабирования. Аналогично, параметр Append, передаваемый методу TranslateTransform, указывает, что сдвиг должен следовать за поворотом. Значения Append и Prepend являются членами перечисления MatrixOrder.

Dim rect As New Rectangle(0, 0, 50, 50)
Dim pen As New Pen(Color.FromArgb(128, 200, 0, 200), 2)
e.Graphics.ResetTransform()
e.Graphics.ScaleTransform(1.75F, 0.5F)
e.Graphics.RotateTransform(28, MatrixOrder.Append)
e.Graphics.TranslateTransform(150, 150, MatrixOrder.Append)
e.Graphics.DrawRectangle(pen, rect)

Rectangle rect = new Rectangle(0, 0, 50, 50);
Pen pen = new Pen(Color.FromArgb(128, 200, 0, 200), 2);
e.Graphics.ResetTransform();
e.Graphics.ScaleTransform(1.75f, 0.5f);
e.Graphics.RotateTransform(28, MatrixOrder.Append);
e.Graphics.TranslateTransform(150, 150, MatrixOrder.Append);
e.Graphics.DrawRectangle(pen, rect);

В следующем примере осуществляются те же вызовы методов, что и в предыдущем, но порядок вызова методов меняется на обратный. Получающееся при этом составное преобразование (сдвиг, поворот, масштабирование) дает результат, принципиально отличающийся от результата выполнения исходного преобразования (масштабирование, поворот, сдвиг).

Dim rect As New Rectangle(0, 0, 50, 50)
Dim pen As New Pen(Color.FromArgb(128, 200, 0, 200), 2)
e.Graphics.ResetTransform()
e.Graphics.TranslateTransform(150, 150, MatrixOrder.Append)
e.Graphics.RotateTransform(28, MatrixOrder.Append)
e.Graphics.ScaleTransform(1.75F, 0.5F)
e.Graphics.DrawRectangle(pen, rect)

Rectangle rect = new Rectangle(0, 0, 50, 50);
Pen pen = new Pen(Color.FromArgb(128, 200, 0, 200), 2);
e.Graphics.ResetTransform();
e.Graphics.TranslateTransform(150, 150, MatrixOrder.Append);
e.Graphics.RotateTransform(28, MatrixOrder.Append);
e.Graphics.ScaleTransform(1.75f, 0.5f);
e.Graphics.DrawRectangle(pen, rect);

Первым способом изменения порядка выполнения отдельных преобразований, формирующих составное преобразование, на обратный является изменение на обратный порядка вызовов методов. Второй способ управления порядком операций заключается в изменении значения параметра порядка следования матриц. Следующий пример полностью аналогичен предыдущему, но в нем параметр Append заменен на Prepend. Перемножение матриц осуществляется в порядке SRT, где S, R и T являются матрицами масштабирования, поворота и сдвига соответственно. При применении составного преобразования сначала осуществляется масштабирование, затем поворот, а затем сдвиг.

Dim rect As New Rectangle(0, 0, 50, 50)
Dim pen As New Pen(Color.FromArgb(128, 200, 0, 200), 2)
e.Graphics.ResetTransform()
e.Graphics.TranslateTransform(150, 150, MatrixOrder.Prepend)
e.Graphics.RotateTransform(28, MatrixOrder.Prepend)
e.Graphics.ScaleTransform(1.75F, 0.5F)
e.Graphics.DrawRectangle(pen, rect)

Rectangle rect = new Rectangle(0, 0, 50, 50);
Pen pen = new Pen(Color.FromArgb(128, 200, 0, 200), 2);
e.Graphics.ResetTransform();
e.Graphics.TranslateTransform(150, 150, MatrixOrder.Prepend);
e.Graphics.RotateTransform(28, MatrixOrder.Prepend);
e.Graphics.ScaleTransform(1.75f, 0.5f);
e.Graphics.DrawRectangle(pen, rect);

Результаты, полученные в рассмотренном примере и самом первом примере данного раздела, ничем не отличаются друг от друга. Это объясняется тем, что были изменены на обратный как порядок вызовов методов, так и порядок выполнения умножения матриц.

См. также

Ссылки

Matrix

Другие ресурсы

Системы координат и преобразования

Использование преобразований в управляемом GDI+