Compartir a través de


Importancia del orden de transformación

Un único objeto Matrix puede almacenar una sola transformación o una secuencia de transformaciones. Este último se denomina transformación compuesta. La matriz de una transformación compuesta se obtiene multiplicando las matrices de transformaciones individuales.

Ejemplos de transformación compuesta

En una transformación compuesta, el orden de las transformaciones individuales es importante. Por ejemplo, si primero gira, después escala y, a continuación, traslada, obtendrá un resultado diferente que si primero traslada, luego gira y, a continuación, escala. En GDI+, las transformaciones compuestas se crean de izquierda a derecha. Si S, R y T son matrices de escala, rotación y traslación respectivamente, el producto SRT (en ese orden) es la matriz de la transformación compuesta que primero escala, luego gira y luego traslada. La matriz producida por el producto SRT es diferente de la matriz producida por el producto TRS.

Un orden con motivos es significativo, porque las transformaciones como la rotación y el escalado se realizan con respecto al origen del sistema de coordenadas. El escalado de un objeto centrado en el origen genera un resultado diferente al escalado de un objeto que se ha alejado del origen. De forma similar, la rotación de un objeto centrado en el origen genera un resultado diferente a la rotación de un objeto que se ha alejado del origen.

En el ejemplo siguiente se combinan el escalado, la rotación y la traslación (en ese orden) para formar una transformación compuesta. El argumento Append pasado al método RotateTransform indica que la rotación seguirá el escalado. De la misma forma, el argumento Append pasado al método TranslateTransform indica que la traslación seguirá la rotación. Los valores Append y Prepend son miembros de la enumeración MatrixOrder.

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)

En el ejemplo siguiente se realiza la misma llamada de método que en el ejemplo anterior, pero se invierte el orden de las llamadas. El orden resultante de las operaciones es trasladar primero, luego girar y, a continuación, escalar, lo que genera un resultado muy diferente al de escalar primero, luego girar y, a continuación, trasladar.

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)

Una manera de invertir el orden de las transformaciones individuales en una transformación compuesta es invertir el orden de una secuencia de llamadas de métodos. Una segunda manera de controlar el orden de las operaciones es cambiar el argumento de orden de matriz. El ejemplo siguiente es el mismo que el ejemplo anterior, excepto que Append se ha cambiado por Prepend. La multiplicación de matriz se realiza en el orden SRT, donde S, R y T son las matrices de escala, rotación y traslación, respectivamente. El orden de la transformación compuesta es primero escalar, luego girar y, a continuación, trasladar.

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)

El resultado del ejemplo anterior es el mismo que el resultado del primer ejemplo de este tema. Esto se debe a que se invierte el orden de las llamadas de método y el orden de la multiplicación de la matriz.

Consulte también