次の方法で共有


変換順序が重要な理由

1 つの Matrix オブジェクトは、1 つの変換または一連の変換を格納できます。 後者は複合変換と呼ばれます。 複合変換の行列は、個々の変換の行列を乗算することによって取得されます。

複合変換の例

複合変換では、個々の変換の順序が重要です。 たとえば、最初に回転し、その後に拡大縮小してから平行移動するのと、最初に平行移動し、その後に回転して拡大縮小するのでは、異なる結果が得られます。 GDI+ では、複合変換は左から右に構築されます。 S、R、および T がそれぞれスケール、回転、および平行移動行列の場合、積 SRT (その順序) は、最初にスケーリングし、次に回転し、次に平行移動する複合変換の行列です。 製品 SRT によって生成されるマトリックスは、製品 TRS によって生成されるマトリックスとは異なります。

順序が重要な理由の 1 つは、座標系の原点に対して回転やスケーリングなどの変換が行われることです。 原点を中心とするオブジェクトをスケーリングすると、原点から離れたオブジェクトのスケーリングとは異なる結果が生成されます。 同様に、原点を中心とするオブジェクトを回転すると、原点から離れたオブジェクトを回転する場合とは異なる結果が得られます。

次の例では、スケーリング、回転、平行移動を (その順序で) 組み合わせて複合変換を形成します。 RotateTransform メソッドに渡 Append 引数は、回転がスケーリングに従うことを示します。 同様に、Append 引数を TranslateTransform メソッドに渡すと、翻訳が回転に従うことを示します。 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)

複合変換の個々の変換の順序を逆にする 1 つの方法は、メソッド呼び出しのシーケンスの順序を逆にすることです。 演算の順序を制御する 2 つ目の方法は、行列の順序引数を変更することです。 次の例は前の例と同じですが、AppendPrependに変更されている点が異なります。 行列乗算は、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)

直前の例の結果は、このトピックの最初の例の結果と同じです。 これは、メソッド呼び出しの順序と行列乗算の順序の両方を逆にしたためです。

関連項目