- Mastering openFrameworks:Creative Coding Demystified
- Denis Perevalov
- 808字
- 2021-08-06 16:54:17
Coordinate system transformations
Sometimes we need to translate, rotate, and resize drawings. For example, arcade games are based on the characters moving across the screen.
When we perform drawing using control points, the straightforward solution for translating, rotating, and resizing graphics is in applying desired transformations to control points using corresponding mathematical formulas. Such idea works, but sometimes leads to complicated formulas in the code (especially when we need to rotate graphics). The more elegant solution is in using coordinate system transformations. This is a method of temporarily changing the coordinate system during drawing, which lets you translate, rotate, and resize drawings without changing the drawing algorithm.
Note
The current coordinate system is represented in openFrameworks with a matrix. All coordinate system transformations are made by changing this matrix in some way. When openFrameworks draws something using the changed coordinate system, it performs exactly the same number of computations as with the original matrix. It means that you can apply as many coordinate system transformations as you want without any decrease in the performance of the drawing.
Coordinate system transformations are managed in openFrameworks with the following functions:
ofPushMatrix()
: This function pushes the current coordinate system in a matrix stack. This stack is a special container that holds the coordinate system matrices. It gives you the ability to restore coordinate system transformations when you do not need them.ofPopMatrix()
: This function pops the last added coordinate system from a matrix stack and uses it as the current coordinate system. You should take care to see that the number ofofPopMatrix()
calls don't exceed the number ofofPushMatrix()
calls.Tip
Though the coordinate system is restored before
testApp::draw()
is called, we recommend that the number ofofPushMatrix()
andofPopMatrix()
callings in your project should be exactly the same. It will simplify the project's debugging and further development.ofTranslate( x, y )
orofTranslate( p )
: This function moves the current coordinate system at the vector (x
,y
) or, equivalently, at the vectorp
. Ifx
andy
are equal to zero, the coordinate system remains unchanged.ofScale( scaleX, scaleY )
: This function scales the current coordinate system atscaleX
in the x axis and atscaleY
in the y axis. If both parameters are equal to1.0
, the coordinate system remains unchanged. The value-1.0
means inverting the coordinate axis in the opposite direction.ofRotate( angle )
: This function rotates the current coordinate system around its origin atangle
degrees clockwise. If theangle
value is equal to0
, ork
*360
withk
as an integer, the coordinate system remains unchanged.
All transformations can be applied in any sequence; for example, translating, scaling, rotating, translating again, and so on.
The typical usage of these functions is the following:
- Store the current transformation matrix using
ofPushMatrix()
. - Change the coordinate system by calling any of these functions:
ofTranslate()
,ofScale()
, orofRotate()
. - Draw something.
- Restore the original transformation matrix using
ofPopMatrix()
.
Note
Step 3 can include steps 1 to 4 again.
For example, for moving the origin of the coordinate system to the center of the screen, use the following code in testApp::draw()
:
ofPushMatrix(); ofTranslate( ofGetWidth() / 2, ofGetHeight() / 2 ); //Draw something ofPopMatrix();
If you replace the //Draw something
comment to ofCircle( 0, 0, 100 );
, you will see the circle in the center of the screen.
Tip
This transformation significantly simplifies coding the drawings that should be located at the center of the screen.
Now let's use coordinate system transformation for adding triangular petals to the flower.
Tip
For further exploring coordinate system transformations, see the example in the Rotating images section in Chapter 4, Images and Textures.
Flower with petals example
In this example, we draw petals to the flower from the 02-2D/03-FlowerControlPoints
example, described in the Using control points example section.
Note
This is example 02-2D/04-FlowerWithPetals
.
We want to draw unfilled shapes here, so add the following lines at the beginning of testApp::draw()
:
ofNoFill(); //Draw shapes unfilled
Now add the following code to the end of testApp::draw()
for drawing the petals:
ofPushMatrix(); //Store the coordinate system //Translate the coordinate system center to stem0 ofTranslate( stem0 ); //Rotate the coordinate system depending on the time float angle = ofGetElapsedTimef() * 30; ofRotate( angle ); int petals = 15; //Number of petals for (int i=0; i<petals; i++) { //Rotate the coordinate system ofRotate( 360.0 / petals ); //Draw petal as a triangle ofPoint p1( 0, 20 ); ofPoint p2( 80, 0 ); ofTriangle( p1, -p1, p2 ); } //Restore the coordinate system ofPopMatrix();
This code moves the coordinate system origin to the point stem0
(the blossom's center) and rotates it depending on the current time. Then it rotates the coordinate system on a fixed angle and draws a triangle petals
times. As a result, we obtain a number of triangles that slowly rotate around the point stem0
.

- C語言程序設(shè)計實踐教程(第2版)
- 深入理解Android(卷I)
- Java應(yīng)用與實戰(zhàn)
- Redis Applied Design Patterns
- Cassandra Design Patterns(Second Edition)
- 小程序開發(fā)原理與實戰(zhàn)
- 利用Python進行數(shù)據(jù)分析(原書第3版)
- Android開發(fā):從0到1 (清華開發(fā)者書庫)
- Java程序員面試筆試寶典(第2版)
- LabVIEW虛擬儀器入門與測控應(yīng)用100例
- Django 3.0應(yīng)用開發(fā)詳解
- QPanda量子計算編程
- 跟戴銘學(xué)iOS編程:理順核心知識點
- 分布式數(shù)據(jù)庫HBase案例教程
- Raspberry Pi Blueprints