Compartilhar via


Por que a ordem das transformações é importante

Um único Matrix objeto pode armazenar uma única transformação ou uma sequência de transformações. Essa última é chamada de transformação composta. A matriz de uma transformação composta é obtida pela multiplicação das matrizes de transformações individuais.

Exemplos de transformação composta

Em uma transformação composta, a ordem das transformações individuais é importante. Por exemplo, girar, ajustar a escala e mover terá um resultado diferente de mover, girar e ajustar a escala. No GDI+, as transformações compostas são construídas da esquerda para a direita. Se S, R e T forem matrizes de escala, rotação e translação, respectivamente, o produto SRT (nesta ordem) será a matriz da transformação composta que primeiro ajusta a escala, em seguida girará e finalmente fará a translação. A matriz produzida pelo produto SRT será diferente da matriz produzida pelo produto TRS.

Um motivo de a ordem ser importante é que transformações, como rotação e colocação em escala, são feitas em relação a origem do sistema de coordenadas. Dimensionar um objeto que está centralizado na origem produz um resultado diferente do dimensionamento de um objeto que foi movido para longe da origem. Da mesma forma, girar um objeto centralizado na origem produz um resultado diferente de girar um objeto movido para fora da origem.

O exemplo a seguir combina colocação em escala, rotação e translação (nessa ordem) para formar uma transformação composta. O argumento Append passado para o método indica que a rotação seguirá o RotateTransform dimensionamento. Da mesma forma, o argumento Append passado para o TranslateTransform método indica que a tradução seguirá a rotação. Append e Prepend são membros da MatrixOrder enumeração.

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.ScaleTransform(1.75F, 0.5F)
e.Graphics.RotateTransform(28, MatrixOrder.Append)
e.Graphics.TranslateTransform(150, 150, MatrixOrder.Append)
e.Graphics.DrawRectangle(pen, rect)

O exemplo a seguir faz com que o mesmo método chame como o exemplo anterior, mas a ordem das chamadas é invertida. A ordem resultante das operações é mover, girar e ajustar a escala, o que produz um resultado muito diferente de ajustar a escala, girar e mover.

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

Uma maneira de inverter a ordem das transformações individuais em uma transformação composta é inverter a ordem de uma sequência de chamadas de método. Outra maneira de controlar a ordem das operações é alterar o argumento de ordem de matriz. O exemplo a seguir é o mesmo que o exemplo anterior, exceto que Append foi alterado para Prepend. A multiplicação de matriz é feita na ordem SRT, em que S, R e T são matrizes para ajustar escala, girar e mover, respectivamente. A ordem da transformação composta é ajustar escala, girar e mover.

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

O resultado do exemplo imediatamente anterior é o mesmo que o resultado do primeiro exemplo neste tópico. Isso ocorre porque invertemos a ordem das chamadas de método e a ordem de multiplicação da matriz.

Confira também