グローバル変換とローカル変換

グローバル変換は、特定の Graphics オブジェクトで描画されるすべての項目に対して適用される変換です。これに対し、ローカル変換は、描画される特定の項目に対して適用される変換です。

グローバル変換

グローバル変換を行うには、Graphics オブジェクトを作成し、そのオブジェクトの Transform プロパティを操作します。Transform プロパティは Matrix オブジェクトであるため、連続するアフィン変換の任意の組み合わせを保持できます。Transform プロパティに格納される変換を、ワールド変換と呼びます。Graphics クラスには、複合ワールド変換を構築するためのメソッドとして、MultiplyTransformRotateTransformScaleTransform、および TranslateTransform が用意されています。ワールド変換の作成前に 1 回、作成後に 1 回楕円を描画する例を次に示します。この変換では、y 方向にファクタ 0.5 のスケーリング、x 方向に 50 単位の平行移動、30°の回転を順に実行します。

myGraphics.DrawEllipse(myPen, 0, 0, 100, 50)
myGraphics.ScaleTransform(1, 0.5F)
myGraphics.TranslateTransform(50, 0, MatrixOrder.Append)
myGraphics.RotateTransform(30, MatrixOrder.Append)
myGraphics.DrawEllipse(myPen, 0, 0, 100, 50)
myGraphics.DrawEllipse(myPen, 0, 0, 100, 50);
myGraphics.ScaleTransform(1, 0.5f);
myGraphics.TranslateTransform(50, 0, MatrixOrder.Append);
myGraphics.RotateTransform(30, MatrixOrder.Append);
myGraphics.DrawEllipse(myPen, 0, 0, 100, 50);

この変換で使用される行列を次の図に示します。

変換

Noteメモ :

上の例の楕円の回転の中心は座標系の原点で、これはクライアント領域の左上隅にあります。この結果は、回転の中心が楕円の中心である場合とは異なります。

ローカル変換

ローカル変換は、描画される特定の項目に対して適用されます。たとえば、GraphicsPath オブジェクトの Transform メソッドを使用すると、そのパスのデータ点を変換できます。次の例は、変換せずに四角形を描画し、回転変換を実行してパスを描画します。ワールド変換は適用されないことを前提とします。

Dim myMatrix As New Matrix()
myMatrix.Rotate(45)
myGraphicsPath.Transform(myMatrix)
myGraphics.DrawRectangle(myPen, 10, 10, 100, 50)
myGraphics.DrawPath(myPen, myGraphicsPath)
Matrix myMatrix = new Matrix();
myMatrix.Rotate(45);
myGraphicsPath.Transform(myMatrix);
myGraphics.DrawRectangle(myPen, 10, 10, 100, 50);
myGraphics.DrawPath(myPen, myGraphicsPath);

さまざまな結果を得るために、ワールド変換とローカル変換を組み合わせて実行できます。たとえば、ワールド変換を使用して座標系を変更し、新しい座標系上に描画されたオブジェクトをローカル変換を使用して回転およびスケーリングできます。

たとえば、クライアント領域の左端から 200 ピクセル、上端から 150 ピクセルの位置にある点を座標系の原点にするとします。また、単位がピクセル、x 軸が右向き、y 軸が上向きであることを前提とします。既定の座標系の y 軸は下向きであるため、水平軸を基準とした反転を実行する必要があります。このような反転の行列を次の図に示します。

変換

次に、右に 200 単位、下に 150 単位の平行移動を実行する必要があるとします。

Graphics オブジェクトのワールド変換を設定することにより、上で説明した座標系を設定する例を次に示します。

Dim myMatrix As New Matrix(1, 0, 0, -1, 0, 0)
myGraphics.Transform = myMatrix
myGraphics.TranslateTransform(200, 150, MatrixOrder.Append)
Matrix myMatrix = new Matrix(1, 0, 0, -1, 0, 0);
myGraphics.Transform = myMatrix;
myGraphics.TranslateTransform(200, 150, MatrixOrder.Append);

左下隅が新しい座標系の原点である四角形 1 つで構成されるパスを作成するコードを次に示します。このコードは、上の例の末尾に記述します。この四角形は、ローカル変換を適用せずに 1 回、ローカル変換を適用して 1 回塗りつぶされます。このローカル変換は、水平方向にファクタ 2 のスケーリングと、それに続く 30°の回転で構成されます。

' Create the path.
Dim myGraphicsPath As New GraphicsPath()
Dim myRectangle As New Rectangle(0, 0, 60, 60)
myGraphicsPath.AddRectangle(myRectangle)

' Fill the path on the new coordinate system.
' No local transformation
myGraphics.FillPath(mySolidBrush1, myGraphicsPath)

' Set the local transformation of the GraphicsPath object.
Dim myPathMatrix As New Matrix()
myPathMatrix.Scale(2, 1)
myPathMatrix.Rotate(30, MatrixOrder.Append)
myGraphicsPath.Transform(myPathMatrix)

' Fill the transformed path on the new coordinate system.
myGraphics.FillPath(mySolidBrush2, myGraphicsPath)
// Create the path.
GraphicsPath myGraphicsPath = new GraphicsPath();
Rectangle myRectangle = new Rectangle(0, 0, 60, 60);
myGraphicsPath.AddRectangle(myRectangle);

// Fill the path on the new coordinate system.
// No local transformation
myGraphics.FillPath(mySolidBrush1, myGraphicsPath);

// Set the local transformation of the GraphicsPath object.
Matrix myPathMatrix = new Matrix();
myPathMatrix.Scale(2, 1);
myPathMatrix.Rotate(30, MatrixOrder.Append);
myGraphicsPath.Transform(myPathMatrix);

// Fill the transformed path on the new coordinate system.
myGraphics.FillPath(mySolidBrush2, myGraphicsPath);

新しい座標系と 2 つの四角形を次の図に示します。

変換

参照

その他の技術情報

座標系と変換
変換