共用方式為


為何轉換順序很重要

Matrix 一物件可以儲存單一轉換或一連串的轉換。 後者稱為複合轉換。 複合轉換的矩陣是藉由乘以個別轉換的矩陣來取得。

複合轉換範例

在複合轉換中,個別轉換的順序很重要。 例如,如果您第一次旋轉,然後調整,然後轉譯,則得到的結果與第一次轉譯、旋轉、縮放結果不同。 在 GDI+中,複合轉換是從左至右建置。 如果 S、R 和 T 分別是尺規、旋轉和轉譯矩陣,則產品 SRT(依該順序)是第一個縮放的複合轉換矩陣,然後旋轉,然後轉譯。 產品 SRT 所產生的矩陣與產品 TRS 所產生的矩陣不同。

其中一個原因是輪替和縮放等轉換是在座標系統的原點上完成的。 縮放位於原點的物件會產生與調整已移出原點的物件不同的結果。 同樣地,旋轉位於原點的 物件會產生與旋轉已移離原點的物件不同的結果。

下列範例結合縮放、旋轉和轉譯(依該順序)形成複合轉換。 傳遞至 方法的 RotateTransform 引數 Append 表示輪替會遵循縮放比例。 同樣地,傳遞至 方法的 TranslateTransform 引數 Append 表示轉譯會遵循旋轉。 AppendPrepend 是 列舉的成員 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)

下列範例會進行與上述範例相同的方法呼叫,但會反轉呼叫的順序。 產生的作業順序是先轉譯,然後旋轉,然後調整,這會產生與第一個小數位數非常不同的結果,然後旋轉,然後轉譯。

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)

在複合轉換中反轉個別轉換順序的其中一種方式,就是反轉方法呼叫序列的順序。 控制作業順序的第二種方式是變更矩陣順序引數。 下列範例與上述範例相同,但已變更為 PrependAppend 矩陣乘法是以 SRT 的順序完成,其中 S、R 和 T 是縮放、旋轉和轉譯的矩陣。 複合轉換的順序是先調整,然後旋轉,然後轉譯。

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)

上一個範例的結果與本主題中第一個範例的結果相同。 這是因為我們反轉了方法呼叫的順序和矩陣乘法的順序。

另請參閱