共用方式為


為何轉換順序很重要

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

複合轉換範例

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

順序很重要的原因之一是旋轉和縮放等變換是相對於座標系統的原點進行的。 縮放位於原點的物件會產生與縮放已移出原點的物件不同的結果。 同樣地,旋轉位於原點的物件會產生與旋轉已移離原點的物件不同的結果。

下列範例結合縮放、旋轉及平移 (依該順序) 形成複合轉換。 傳遞至 RotateTransform 方法的引數 Append 表示旋轉將會遵循縮放比例。 同樣地,傳遞至 TranslateTransform 方法的引數 Append 表示平移會遵循旋轉。 AppendPrependMatrixOrder 列舉的成員。

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)

在複合轉換中反轉個別轉換順序的其中一種方式,就是反轉方法呼叫序列的順序。 控制作業順序的第二種方式是變更矩陣順序引數。 下列範例與上述範例相同,不同之處在於 Append 已變更為 Prepend。 矩陣乘法是以 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)

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

另請參閱