Freigeben über


Warum die Transformationsreihenfolge signifikant ist

Ein einzelnes Matrix-Objekt kann eine einzelne Transformation oder eine Sequenz von Transformationen speichern. Letzteres wird als zusammengesetzte Transformation bezeichnet. Die Matrix einer zusammengesetzten Transformation wird durch die Multiplikation der Matrizen der einzelnen Transformationen erhalten.

Beispiele für zusammengesetzte Transformationen

Bei einer zusammengesetzten Transformation ist die Reihenfolge einzelner Transformationen wichtig. Wenn Sie z. B. zuerst drehen, dann skalieren und dann übersetzen, erhalten Sie ein anderes Ergebnis als wenn Sie zuerst übersetzen, dann drehen und dann skalieren. In GDI+ werden zusammengesetzte Transformationen von links nach rechts erstellt. Wenn S, R und T Skalierungs-, Dreh- bzw. Translationsmatrizen sind, dann ist das Produkt SRT (in dieser Reihenfolge) die Matrix der zusammengesetzten Transformation, die zuerst skaliert, dann gedreht und schließlich übersetzt. Die vom Produkt SRT erzeugte Matrix unterscheidet sich von der Matrix, die vom Produkt TRS erzeugt wird.

Ein Grund, warum die Reihenfolge wichtig ist, besteht darin, dass Transformationen wie Drehung und Skalierung in Bezug auf den Ursprung des Koordinatensystems durchgeführt werden. Die Skalierung eines Objekts, das am Ursprung zentriert ist, erzeugt ein anderes Ergebnis als die Skalierung eines Objekts, das vom Ursprung weg verschoben wurde. Entsprechend erzeugt das Drehen eines Objekts, das am Ursprung zentriert ist, ein anderes Ergebnis als das Drehen eines Objekts, das vom Ursprung entfernt wurde.

Im folgenden Beispiel werden Skalierung, Drehung und Übersetzung (in dieser Reihenfolge) kombiniert, um eine zusammengesetzte Transformation zu bilden. Das Argument Append, das an die RotateTransform-Methode übergeben wird, gibt an, dass die Drehung nach der Skalierung erfolgt. Ebenso weist das an die TranslateTransform-Methode übergebene Argument Append darauf hin, dass die Translation der Rotation folgt. Append und Prepend sind Mitglieder der MatrixOrder Aufzählung.

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)

Im folgenden Beispiel werden dieselben Methodenaufrufe wie im vorherigen Beispiel ausgeführt, die Reihenfolge der Aufrufe wird jedoch umgekehrt. Die resultierende Reihenfolge der Vorgänge ist zuerst verschieben, dann drehen, dann skalieren, was ein sehr anderes Ergebnis erzeugt als zuerst skalieren, dann drehen, dann verschieben.

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)

Eine Möglichkeit zum Umkehren der Reihenfolge einzelner Transformationen in einer zusammengesetzten Transformation besteht darin, die Reihenfolge einer Sequenz von Methodenaufrufen umzukehren. Eine zweite Möglichkeit zum Steuern der Reihenfolge von Vorgängen besteht darin, das Matrixreihenfolgenargument zu ändern. Das folgende Beispiel entspricht dem vorherigen Beispiel, mit der Ausnahme, dass Append in Prependgeändert wurde. Die Matrixmultiplikation erfolgt in der Reihenfolge SRT, wobei S, R und T die Matrizen für Skalierung, Drehung und Translation sind. Die Reihenfolge der zusammengesetzten Transformation ist zuerst skalieren, dann drehen und dann verschieben.

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)

Das Ergebnis des unmittelbar vorangehenden Beispiels entspricht dem Ergebnis des ersten Beispiels in diesem Thema. Dies liegt daran, dass die Reihenfolge der Methodenaufrufe und die Reihenfolge der Matrixmultiplikation umgekehrt wurde.

Siehe auch