Freigeben über


Warum die Transformationsreihenfolge signifikant ist

Ein einzelnes Objekt kann eine einzelne Matrix Transformation oder eine Sequenz von Transformationen speichern. Letzteres wird als zusammengesetzte Transformation bezeichnet. Die Matrix einer zusammengesetzten Transformation wird durch Multiplizieren der Matrizen einzelner Transformationen abgerufen.

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. Übersetzungsmatrizen sind, dann ist das Produkt SRT (in dieser Reihenfolge) die Matrix der zusammengesetzten Transformation, die zuerst skaliert, dann rotiert und anschließend ü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 an die Append Methode übergebene Argument RotateTransform gibt an, dass die Drehung der Skalierung folgt. Ebenso gibt das an die Append Methode übergebene Argument TranslateTransform an, dass die Übersetzung der Drehung folgt. Append und Prepend sind Member der MatrixOrder Enumeration.

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 Operationen ist: zuerst translatiert, dann rotiert, dann skaliert, was ein ganz anderes Ergebnis hervorbringt als zuerst skaliert, dann rotiert und schließlich translatiert.

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 ist identisch mit dem vorherigen Beispiel, außer dass Append in Prepend geändert worden ist. Die Matrixmultiplizierung erfolgt in der Reihenfolge SRT, wobei S, R und T die Matrizen für Skalierung, Drehung und Übersetzung sind. Die Reihenfolge der zusammengesetzten Transformation ist 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.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