GDIplus Graphics Transformation—Significance of Transformation Order


Jump to: navigation, search
CSharp-Online.NET:Articles
.NET Articles

GDI+ Graphics Transformation

© 2004 Pearson Education, Inc.

The Significance of Transformation Order

The Matrix object can store a single transformation or a sequence of transformations. As we learned in Section 10.5, a sequence of transformations is called a composite transformation, which is a result of multiplying the matrices of the individual transformations.

In a composite transformation, the order of the individual transformations is very important. Matrix operations are not cumulative. For example, the result of a GraphicsRotateTranslateScaleGraphics operation will be different from the result of a GraphicsScaleRotateTranslateGraphics operation. The main reason that order is significant is that transformations like rotation and scaling are done with respect to the origin of the coordinate system. The result of scaling an object that is centered at the origin is different from the result of scaling an object that has been moved away from the origin. Similarly, the result of rotating an object that is centered at the origin is different from the result of rotating an object that has been moved away from the origin.

The MatrixOrder enumeration, which is an argument to the transformation methods, represents the transformation order. It has two values: Append and Prepend.

Let’s write an application to see how transformation order works. We create a Windows application and add a MainMenu control and three menu items to the form. The MatrixOrder class is defined in the System.Drawing.Drawing2D namespace, so we also add a reference to this namespace.

Listing 10.22 draws a rectangle before and after applying a ScaleRotateTranslate transformation sequence.

Listing 10.22 Scale → Rotate → Translate transformation order

private void First_Click(object sender,
    System.EventArgs e)
{
    // Create a Graphics object
    Graphics g = this.CreateGraphics();
    g.Clear(this.BackColor);
    // Create a rectangle
    Rectangle rect =
        new Rectangle(20, 20, 100, 100);
    // Create a solid brush
    SolidBrush brush =
        new SolidBrush(Color.Red);
    // Fill rectangle
    g.FillRectangle(brush, rect);
    // Scale
    g.ScaleTransform(1.75f, 0.5f);
    // Rotate
    g.RotateTransform(45.0f, MatrixOrder.Append);
    // Translate
    g.TranslateTransform(150.0f, 50.0f,
        MatrixOrder.Append);
    // Fill rectangle again
    g.FillRectangle(brush, rect);
    // Dispose of objects
    brush.Dispose();
    g.Dispose();
}

Figure 10.33 shows the output from Listing 10.22. The original rectangle is in the upper left; on the lower right is the rectangle after composite transformation.


Image:GraphicsProgGDIp10-33.jpg
Figure 10.33. Scale → Rotate → Translate composite transformation


Now let’s change the order of transformation to TranslateRotateScale with Append, as shown in Listing 10.23.

Listing 10.23 Translate → Rotate → Scale transformation order with Append

private void Second_Click(object sender,
    System.EventArgs e)
{
    // Create a Graphics object
    Graphics g = this.CreateGraphics();
    g.Clear(this.BackColor);
    // Create a rectangle
    Rectangle rect =
        new Rectangle(20, 20, 100, 100);
    // Create a solid brush
    SolidBrush brush =
        new SolidBrush(Color.Red);
    // Fill rectangle
    g.FillRectangle(brush, rect);
    // Translate
    g.TranslateTransform(100.0f, 50.0f,
        MatrixOrder.Append);
    // Scale
    g.ScaleTransform(1.75f, 0.5f);
    // Rotate
    g.RotateTransform(45.0f,
        MatrixOrder.Append);
    // Fill rectangle again
    g.FillRectangle(brush, rect);
    // Dispose of objects
    brush.Dispose();
    g.Dispose();
}

Figure 10.34 shows the output from Listing 10.23. The original rectangle is in the same place, but the transformed rectangle has moved.


Image:GraphicsProgGDIp10-34.jpg
Figure 10.34. Translate → Rotate → Scale composite transformation with Append


Now let’s keep the code from Listing 10.23 and change only the matrix transformation order from Append to Prepend, as shown in Listing 10.24.

Listing 10.24 Translate → Rotate → Scale transformation order with Prepend

private void Third_Click(object sender,
    System.EventArgs e)
{
    // Create a Graphics object
    Graphics g = this.CreateGraphics();
    g.Clear(this.BackColor);
    // Create a rectangle
    Rectangle rect =
        new Rectangle(20, 20, 100, 100);
    // Create a solid brush
    SolidBrush brush =
        new SolidBrush(Color.Red);
    // Fill rectangle
    g.FillRectangle(brush, rect);
    // Translate
    g.TranslateTransform(100.0f, 50.0f,
        MatrixOrder.Prepend);
    // Rotate
    g.RotateTransform(45.0f,
        MatrixOrder.Prepend);
    // Scale
    g.ScaleTransform(1.75f, 0.5f);
    // Fill rectangle again
    g.FillRectangle(brush, rect);
    // Dispose of objects
    brush.Dispose();
    g.Dispose();
}

The new output is shown in Figure 10.35. The matrix order affects the result.


Image:GraphicsProgGDIp10-35.jpg
Figure 10.35. Translate → Rotate → Scale composite transformation with Prepend


Previous_Page_.gif Next_Page_.gif


Personal tools