You manipulate the CTM to rotate, scale, or translate the page before drawing an image, thereby transforming the object you are about to draw. Before you transform the CTM, you need to save the graphics state so that you can restore it after drawing. You can also concatenate the CTM with an affine transform (see “Creating Affine Transforms”). Each of these four operations—translation, rotation, scaling, and concatenation—is described in this section along with the CTM functions that perform each operation.
The following line of code draws an image, assuming that you provide a valid graphics context, a pointer to the rectangle to draw the image to, and a valid CGImage object. The code draws an image, such as the sample rooster image shown in Figure 5-2. As you read the rest of this section, you’ll see how the image changes as you apply transformations.
CGContextDrawImage (myContext, rect, myImage); |
Translation moves the origin of the coordinate space by the amount you specify for the x and y axes. You call the function CGContextTranslateCTM to modify the x- and y-coordinates of each point by a specified amount. Figure 5-3 shows an image translated by 100 units in the x axis and 50 units in the y axis, using the following line of code:
CGContextTranslateCTM (myContext, 100, 50); |
Rotation moves the coordinate space by the angle you specify. You call the function CGContextRotateCTM to specify the rotation angle, in radians. Figure 5-4 shows an image rotated by –45 degrees about the origin, which is the lower left of the window, using the following line of code:
CGContextRotateCTM (myContext, radians(–45.)); |
The image is clipped because the rotation moved part of the image to a location outside the context. You need to specify the rotation angle in radians.
It’s useful to write a radians routine if you plan to perform many rotations.
#include <math.h> |
static inline double radians (double degrees) {return degrees * M_PI/180;} |
Scaling changes the scale of the coordinate space by the x and y factors you specify, effectively stretching or shrinking coordinates. The magnitude of the x and y factors governs whether the new coordinates are larger or smaller than the original. In addition, by making the x factor negative, you can flip the coordinates along the x-axis; similarly, you can flip coordinates horizontally, along the y-axis, by making the y factor negative. You call the function CGContextScaleCTM to specify the x and y scaling factors. Figure 5-5 shows an image whose x values are scaled by .5 and whose y values are scaled by .75, using the following line of code:
CGContextScaleCTM (myContext, .5, .75); |
Concatenation combines two matrices by multiplying them together. You can concatenate several matrices together to form a single matrix that contains the cumulative effects of the matrices. You call the function CGContextConcatCTM to combine the CTM with an affine transform. Affine transforms, and the functions that create them, are discussed in “Creating Affine Transforms.”
Another way to achieve a cumulative effect is to perform two or more transformations without restoring the graphics state between transformation calls. Figure 5-6 shows an image that results from translating an image and then rotating it, using the following lines of code:
CGContextTranslateCTM (myContext, w,h); |
CGContextRotateCTM (myContext, radians(-180.)); |
Figure 5-7 shows an image that is translated, scaled, and rotated, using the following lines of code:
CGContextTranslateCTM (myContext, w/4, 0); |
CGContextScaleCTM (myContext, .25, .5); |
CGContextRotateCTM (myContext, radians ( 22.)); |
The order in which you perform multiple transformations matters; you get different results if you reverse the order. Reverse the order of transformations used to create Figure 5-7 and you get the results shown in Figure 5-8, which is produced with this code:
CGContextRotateCTM (myContext, radians ( 22.)); |
CGContextScaleCTM (myContext, .25, .5); |
CGContextTranslateCTM (myContext, w/4, 0); |
Last updated: 2007-12-11