Por que a ordem das transformações é importante
Um único objeto Matrix pode armazenar uma única transformação ou uma sequência de transformações. Este último é chamado de transformaçãocomposta. A matriz de uma transformação composta é obtida multiplicando as matrizes das transformações individuais.
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 Windows GDI+, as transformações compostas são criadas 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. O dimensionamento de um objeto 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 MatrixOrderAppend passado para o método Graphics::RotateTransform especifica que a rotação seguirá o dimensionamento. Da mesma forma, o argumento MatrixOrderAppend passado para o método Graphics::TranslateTransform especifica que a tradução seguirá a rotação.
Rect rect(0, 0, 50, 50);
Pen pen(Color(255, 255, 0, 0), 0);
graphics.ScaleTransform(1.75f, 0.5f);
graphics.RotateTransform(28.0f, MatrixOrderAppend);
graphics.TranslateTransform(150.0f, 150.0f, MatrixOrderAppend);
graphics.DrawRectangle(&pen, rect);
O exemplo a seguir faz as mesmas chamadas de método que o exemplo anterior, mas a ordem das chamadas é invertida. A ordem resultante das operações é primeiro traduzida, depois gira, depois dimensiona, o que produz um resultado muito diferente da primeira escala, depois gira e, em seguida, converte:
Rect rect(0, 0, 50, 50);
Pen pen(Color(255, 255, 0, 0), 0);
graphics.TranslateTransform(150.0f, 150.0f);
graphics.RotateTransform(28.0f, MatrixOrderAppend);
graphics.ScaleTransform(1.75f, 0.5f, MatrixOrderAppend);
graphics.DrawRectangle(&pen, rect);
Uma maneira de reverter a ordem das transformações individuais em uma transformação composta é reverter 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 do exemplo anterior, exceto que MatrixOrderAppend foi alterado para MatrixOrderPrepend. 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.
Rect rect(0, 0, 50, 50);
Pen pen(Color(255, 255, 0, 0), 0);
graphics.TranslateTransform(150.0f, 150.0f,MatrixOrderPrepend);
graphics.RotateTransform(28.0f, MatrixOrderPrepend);
graphics.ScaleTransform(1.75f, 0.5f, MatrixOrderPrepend);
graphics.DrawRectangle(&pen, rect);
O resultado do exemplo anterior é o mesmo resultado que obtivemos no primeiro exemplo desta seção. Isso ocorre porque invertemos a ordem das chamadas de método e a ordem de multiplicação da matriz.