Global and Local Transformations
A global transformation is a transformation that applies to every item drawn by a given Graphics object. In contrast, a local transformation is a transformation that applies to a specific item to be drawn.
To create a global transformation, construct a Graphics object, and then manipulate its Transform property. The Transform property is a Matrix object, so it can hold any sequence of affine transformations. The transformation stored in the Transform property is called the world transformation. The Graphics class provides several methods for building up a composite world transformation: MultiplyTransform, RotateTransform, ScaleTransform, and TranslateTransform. The following example draws an ellipse twice: once before creating a world transformation and once after. The transformation first scales by a factor of 0.5 in the y direction, then translates 50 units in the x direction, and then rotates 30 degrees.
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);
The following illustration shows the matrices involved in the transformation.
In the preceding example, the ellipse is rotated about the origin of the coordinate system, which is at the upper-left corner of the client area. This produces a different result than rotating the ellipse about its own center.
A local transformation applies to a specific item to be drawn. For example, a GraphicsPath object has a Transform method that allows you to transform the data points of that path. The following example draws a rectangle with no transformation and a path with a rotation transformation. (Assume that there is no world transformation.)
Matrix myMatrix = new Matrix(); myMatrix.Rotate(45); myGraphicsPath.Transform(myMatrix); myGraphics.DrawRectangle(myPen, 10, 10, 100, 50); myGraphics.DrawPath(myPen, myGraphicsPath);
You can combine the world transformation with local transformations to achieve a variety of results. For example, you can use the world transformation to revise the coordinate system and use local transformations to rotate and scale objects drawn on the new coordinate system.
Suppose you want a coordinate system that has its origin 200 pixels from the left edge of the client area and 150 pixels from the top of the client area. Furthermore, assume that you want the unit of measure to be the pixel, with the x-axis pointing to the right and the y-axis pointing up. The default coordinate system has the y-axis pointing down, so you need to perform a reflection across the horizontal axis. The following illustration shows the matrix of such a reflection.
Next, assume you need to perform a translation 200 units to the right and 150 units down.
The following example establishes the coordinate system just described by setting the world transformation of a Graphics object.
Matrix myMatrix = new Matrix(1, 0, 0, -1, 0, 0); myGraphics.Transform = myMatrix; myGraphics.TranslateTransform(200, 150, MatrixOrder.Append);
The following code (placed at the end of the preceding example) creates a path that consists of a single rectangle with its lower-left corner at the origin of the new coordinate system. The rectangle is filled once with no local transformation and once with a local transformation. The local transformation consists of a horizontal scaling by a factor of 2 followed by a 30-degree rotation.
// 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);
The following illustration shows the new coordinate system and the two rectangles.