Maybe you noted a problem when considering the preceding flower example: drawing primitives by specifying the coordinates of all the vertices is a little cumbersome. There are too many numbers in the code, so it is hard to understand the relation between primitives. To solve this problem, we will learn about using the ofPoint
class and then apply it for drawing primitives using control points.
ofPoint
is a class that represents the coordinates of a 2D point. It has two main fields: x
and y
, which are float
type.
Actually, ofPoint
has the third field z
, so ofPoint
can be used for representing 3D points too (we use this capability in Chapter 7, Drawing in 3D). If you do not specify z
, it sets to zero by default, so in this case you can think of ofPoint
as a 2D point indeed.
To represent some point, just declare an object of the ofPoint
class.
ofPoint p;
To initialize the point, set its coordinates.
p.x = 100.0; p.y = 200.0;
Or, alternatively, use the constructor.
p = ofPoint( 100.0, 200.0 );
You can operate with points just as you do with numbers. If you have a point q
, the following operations are valid:
p + q
or p - q
provides points with coordinates (p.x + q.x
, p.y + q.y
) or (p.x - q.x
, p.y - q.y
)p * k
or p / k
, where k
is the float
value, provides the points (p.x * k
, p.y * k
) or (p.x / k, p.y / k
)p += q
or p -= q
adds or subtracts q
from p
There are a number of useful functions for simplifying 2D vector mathematics, as follows:
All functions' drawing primitives have overloaded versions working with ofPoint
:
We are ready to solve the problem stated in the beginning of the Using ofPoint section. To avoid using many numbers in drawing code, we can declare a number of points and use them as vertices for primitive drawing. In computer graphics, such points are called control points.
Let's specify the following control points for the flower in our simplest flower example:
Now we implement this in the code.
Add the following declaration of control points in the testApp
class declaration in the testApp.h
file:
ofPoint stem0, stem1, stem2, stem3, leftLeaf, rightLeaf;
Then set values for points in the testApp::update()
function as follows:
stem0 = ofPoint( 300, 100 ); stem1 = ofPoint( 300, 270 ); stem2 = ofPoint( 300, 300 ); stem3 = ofPoint( 300, 400 ); leftLeaf = ofPoint( 200, 220 ); rightLeaf = ofPoint( 400, 220 );
Finally, use these control points for drawing the flower in the testApp::draw()
function:
ofBackground( 255, 255, 255 ); //Set white background ofSetColor( 0, 0, 0 ); //Set black color ofCircle( stem0, 40 ); //Blossom ofLine( stem0, stem3 ); //Stem ofTriangle( stem1, stem2, leftLeaf ); //Left leaf ofTriangle( stem1, stem2, rightLeaf ); //Right leaf
You will observe that when drawing with control points the code is much easier to understand.
Furthermore, there is one more advantage of using control points: we can easily change control points' positions and hence obtain animated drawings. See the full example code in 02-2D/03-FlowerControlPoints
. In addition to the already explained code, it contains a code for shifting the leftLeaf
and rightLeaf
points depending on time. So, when you run the code, you will see the flower with moving leaves.