轉換順序為何很重要
單一 Matrix 物件可以儲存單一轉換或轉換序列。 後者稱為 複合轉換。 復合轉換的矩陣是藉由乘以個別轉換的矩陣來取得。
在複合轉換中,個別轉換的順序很重要。 例如,如果您第一次旋轉,然後調整,然後轉譯,則得到的結果與第一次轉譯、旋轉、縮放結果不同。 在 Windows GDI+中,複合轉換是從左至右建置。 如果 S、R 和 T 分別是縮放、旋轉和平移矩陣,則依次相乘 SRT(按此順序)代表一個複合轉換矩陣,它首先縮放,然後旋轉,最後平移。 產品 SRT 所產生的矩陣與產品 TRS 所產生的矩陣不同。
其中一個原因是像旋轉和縮放這樣的轉換是相對於座標系統的原點完成的。 當縮放位於原點的物件時,結果會與縮放已從原點移動的物件不同。 同樣地,旋轉位於原點的 物件會產生與旋轉已移離原點的物件不同的結果。
下列範例結合縮放、旋轉和轉譯(依該順序)形成複合轉換。 傳遞至 Graphics::RotateTransform 方法的參數 MatrixOrderAppend 指定旋轉將在縮放之後進行。 同樣地,傳遞至 Graphics::TranslateTransform 方法的自變數 MatrixOrderAppend 會指定翻譯會遵循旋轉。
Rect rect(0, 0, 50, 50);
Pen pen(Color(255, 255, 0, 0), 0);
graphics.ScaleTransform(1.75f, 0.5f);
graphics.RotateTransform(28.0f, MatrixOrderAppend);
graphics.TranslateTransform(150.0f, 150.0f, MatrixOrderAppend);
graphics.DrawRectangle(&pen, rect);
下列範例會進行與上一個範例相同的方法呼叫,但會反轉呼叫的順序。 生成的操作順序是先平移,然後旋轉,然後縮放,這會產生截然不同的結果,比先縮放,然後旋轉,再平移的順序。
Rect rect(0, 0, 50, 50);
Pen pen(Color(255, 255, 0, 0), 0);
graphics.TranslateTransform(150.0f, 150.0f);
graphics.RotateTransform(28.0f, MatrixOrderAppend);
graphics.ScaleTransform(1.75f, 0.5f, MatrixOrderAppend);
graphics.DrawRectangle(&pen, rect);
在複合轉換中反轉個別轉換順序的其中一種方式,就是反轉方法呼叫序列的順序。 控制作業順序的第二種方式是變更矩陣順序自變數。 下列範例與上一個範例相同,不同之處在於 MatrixOrderAppend 已變更為 MatrixOrderPrepend。 矩陣乘法是以 SRT 的順序完成,其中 S、R 和 T 是縮放、旋轉和轉譯的矩陣。 復合轉換的順序是先調整,然後旋轉,然後轉譯。
Rect rect(0, 0, 50, 50);
Pen pen(Color(255, 255, 0, 0), 0);
graphics.TranslateTransform(150.0f, 150.0f,MatrixOrderPrepend);
graphics.RotateTransform(28.0f, MatrixOrderPrepend);
graphics.ScaleTransform(1.75f, 0.5f, MatrixOrderPrepend);
graphics.DrawRectangle(&pen, rect);
上述範例的結果與我們在本節第一個範例中達成的結果相同。 這是因為我們反轉了方法呼叫的順序和矩陣乘法的順序。