The image.draw()
method does not have parameters to rotate images on arbitrary angles. To achieve this effect, we need to work with coordinate system transformations, which are described in detail in the Coordinate system transformations section in Chapter 2, Drawing in 2D.
We need to carry out the following steps for drawing a rotated image:
The following code illustrates these steps. It draws the image rotated at 10 degrees around the current center of coordinates, which is (0, 0).
void testApp::draw(){ ofPushMatrix(); //Store the transformation matrix ofRotate( 10.0 ); //Applying rotation on 10 degrees image.draw( 0, 0 ); //Draw image ofPopMatrix(); //Restore the transformation }
Sometimes, we will want to rotate an image around its center instead of the top-left corner. To achieve this, we need to translate the center of coordinates to the desired center of rotation, rotate the coordinate system, and finally draw an image translated in such a way that the center of the image is located in the coordinate center. The following code demonstrates this by drawing an image that slowly rotates over time:
void testApp::draw(){ ofPushMatrix (); //Shift center of coordinate system ( 0,0 ) to the desired //point, which will be rotation center ofTranslate( 500, 400 ); //Rotate coordinate system, 10 degrees per second ofRotate( 10.0 * ofGetElapsedTimef() ); //Draw image in a way that its center on the screen coincide //with ( 0,0 ) image.draw( -image.width/2, -image.height/2 ); ofPopMatrix(); }
Also, there is a more elegant way to draw an image centered at a particular point. Instead of using image.draw( -image.width/2, -image.height/2 )
, we can change the anchor point
of the image; that is, a point used as the origin while drawing an image. It can be done by calling the following function:
image.setAnchorPercent( 0.5, 0.5 );
The preceding method sets the anchor point to 50 percent; that is, 50 percent of image size, which is the center of the image. Then call the image.draw( 0, 0 )
method, which will draw the image, centered at (0, 0). To reset the anchor to its default state, call image.setAnchorPercent( 0, 0 )
or image.resetAnchor()
.
You can also set an anchor point by specifying it in pixel coordinates (x
, y
) using the image.setAnchorPoint( x, y )
function.
Using ofTranslate()
, ofScale()
, and ofRotate()
is a good way of experimenting with parametric drawing. Here is an example of creating a collage of images:
void testApp::draw(){ //Set up white background ofBackground( 255, 255, 255 ); for (int i=0; i<20; i++) { ofPushMatrix(); //Translate system coordinates to screen center ofTranslate( ofGetWidth() / 2, ofGetHeight() / 2 ); //Rotate coordinate system on i * 15 degrees ofRotate( i * 15 ); //Go right on 50 * i * 10 pixels //in rotated coordinate system ofTranslate( 50 + i * 10, 0 ); //Scale coordinate system for decreasing drawing //image size float scl = 1.0 - i * 0.8 / 20.0; ofScale( scl, scl ); //scl decreases with i, so the images //became gradually smaller //Draw image image.draw( -100, -100, 200, 200 ); ofPopMatrix(); } }
Run the project; you will see a spiral made of images, as shown in the following screenshot: