BezierPath

Now, we are ready for a little bit more of a complicated example that will allow you to draw a continuous Bézier curve. Bézier curves are called so because of a french engineer Pierre Bézier who actually patented and made them popular by applying them in designs. Bézier curves are widely used in computer graphics, animations, and other fields. The concept of Bézier curves allows us to create parametric curved lines by using the Cartesian coordinate system and numbers.

Go to your Cinder samples folder (/Users/You/cinder/samples/ on Mac OS X and C:cindersamples if you use Windows).

Go to the folder named bezierPath. Open xcode/bezierPath.xcodeproj, if you are a Mac OS X user (vc10ezierPath.sln, if you are using Windows). Compile and run the project.

BezierPath

Click-and-drag to place points on the surface of the window. You will start to see the line after the second click. By moving the mouse while you hold it down, you can control the curvature of the line segment that is being drawn. Play around a bit to get a better understanding about how Bézier curves work.

To add some extra geek-fun to the process, let's change something as we did in the previous example. Close the application window and open the file bezierPathApp.cpp in the editor. Let's assume that we don't like the circles that are drawn on the screen to indicate the points that form the path—we want to draw rectangles instead. Navigate to a block of code that looks like the following code snippet:

// draw the control points
gl::color( Color( 1.0f, 1.0f, 0.0f ) );
for( size_t p = 0; p < mPath.getNumPoints(); ++p )
gl::drawSolidCircle( mPath.getPoint( p ), 2.5f );

As you can see in the comment in the preceding block, this block is responsible for drawing the control points. It sets the color of the next thing to be drawn (or circle in this case) with the help of the following line:

gl::color( Color( 1.0f, 1.0f, 0.0f ) );

This uses a for loop to iterate through all the data in the mPath object. Circles are drawn with the help of the following line:

gl::drawSolidCircle( mPath.getPoint( p ), 2.5f );

Just by looking at the function name we can tell that it draws circles. gl:: tells us that this function resides in the Cinder OpenGL namespace (Cinder uses namespaces a lot, and that makes its code more readable indeed), draw tells us that it draws something, solid means that this function draws something solid, and circle concludes this by making it clear that with the help of OpenGL a solid circle will be drawn.

Two parameters are passed to the function. The first one is a point object that holds x and y coordinate values and the other one defines the radius of the circle being drawn in pixels.

Let's start by changing the radius of the circle. Change 2.5f to 10.0f so that it looks like the following:

gl::drawSolidCircle( mPath.getPoint( p ), 10.0f );

Build and run the project to see the change! Hmm, interesting! It is indeed! But let's not celebrate yet, remember, we wanted to change the circle into a rectangle. We will use a function defined as follows:

gl::drawSolidRect( const Rectf &rect, bool textureRectangle=false );

As the name of the function tells us, this function draws a solid rectangle. We have to provide a parameter to the function though. Just one parameter is required (the other one is optional and set to false by default) and that has to be of the type Rectf. A Rectf consisting of four values. The first two values define the upper-right corner of the rectangle and the other two define the location of the bottom-right corner. It is a bit different in most drawing APIs, as usually this kind of object is defined by passing in the x and y coordinates of the top-left corner and the width and height of the rectangle. Not this time. So we have to pass something like the following:

Rectf( float x1, float y1, float x2, float y2 )

Where x1 is the x coordinate of the top-left corner, y1 is the y coordinate of the top-left corner, and x2 and y2 define where the bottom-right corner should be on the screen.

Note

This is just one of the five Rectf (or RectT) constructors in Cinder. If you want to see other ones, take a look in the Cinder online reference at http://libcinder.org/docs/v0.8.4/classcinder_1_1_rect_t.html.

By analyzing the point drawing function (gl::drawSolidCircle( mPath.getPoint( p ), 10.0f );), we get a piece of code that represents an object that holds the x and y coordinates of the current control point:

mPath.getPoint(p)

We can access the x and y coordinates by writing:

mPath.getPoint(p).x

And

mPath.getPoint(p).y

Let's construct our rectangle:

Rectf( mPath.getPoint(p).x, mPath.getPoint(p).y,
  mPath.getPoint(p).x+10.0f, mPath.getPoint(p).y+10.0f )
BezierPath

The number constant 10.0f in the preceding piece of code represents the width and height of the rectangle. As we want the width and height to be equal, we use equal values here. The following is the final code:

// draw the control points
gl::color( Color( 1.0f, 1.0f, 0.0f ) );
for( size_t p = 0; p < mPath.getNumPoints(); ++p ) {
  gl::drawSolidRect( Rectf( mPath.getPoint(p).x,
  mPath.getPoint(p).y, mPath.getPoint(p).x+10.0f,
  mPath.getPoint(p).y+10.0f ) );
}

Build and run the project. What you will see is that rectangles are drawn next to the actual control points, not on them as it should be. Let's fix that:

for( size_t p = 0; p < mPath.getNumPoints(); ++p ) {
  gl::drawSolidRect( Rectf( mPath.getPoint(p).x-5.0f,
  mPath.getPoint(p).y-5.0f, mPath.getPoint(p).x+5.0f,
  mPath.getPoint(p).y+5.0f ) );
}

As you can see, we changed all the 10.0f' values to 5.0f and subtracted 5.0f from the first two parameters of the rectangle constructor. By doing that we moved the top-left corner of the rectangle to left by the half of its width and up by the half of its height (5 pixels), while keeping the same width and height (10 pixels).

Build and run the project, and as you can see, now the rectangle is in its right place.

Maybe this is a bit too complicated in the beginning, but the more you do these kind of adjustments the more you learn. We won't be making any more changes during the rest of this chapter.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.253.55