Intro Graphics Assignment 6
All Curves, All The Time
Due: November 18, 2003
Goals
In this project, you will learn how to draw three kinds of curves. There are many kinds of curves, each with its own unique properties. In addition, you will have to implement some very simple user interaction to let users create and edit curves.
Useful stuff to get you started
Assignment Specifications
Part I --- Bézier curves
In class, we described the De Casteljau algorithm for creating a curve from a set of n control points. The first part of your assignment is to implement that algorithm and actually draw the points.
You should draw a straight line between all your sample points on the curve. So, for instance, if the number of curve subdivisions is 10, you should draw 10 straight line segments on the screen. You may refer to the sample solution to see how this works.
In addition, you must draw the control polygon by connecting the control points with straight lines, and drawing little rectangles at the control points. Again, refer to the sample.
Wait, what control points?
The user of the system will click on the screen to add points.
If the user clicks on a point that already exists, you should let him drag the point around. You can take a look at the sample program to see how this works. If the window is small, it might be really hard to click on a control point. Make your window bigger. In general, Determining if the user has clicked on an existing point will depend on how big you make the points on the screen. This is up to you; just do something reasonable.
You should be able to CLEAR the current set of points with a keystroke. See the sample.
Important note: Things look a little smushed if the window isn't a square, but don't worry about that. If you're in doubt about how your program should behave, you can always refer to the sample solution. If you think you can IMPROVE the sample, feel free, but doing what the sample does is almost never wrong.
Part II --- B-Spline curves
The second part of the assignment is to draw a B-Spline curve based on the points added by the user.
Unlike the Bézier curve, B-Splines are made up of individual connected segments. Each one of these segments should be drawn using the number of divisions set by the user. Therefore, if there are 10 divisions, and you're drawing 5 curve segments, you will actually draw 50 straight lines.
You should also be able to draw rectangles at the knots of the curve. Remember that knots are points where the curve segments join together. This will be very helpful in illustrating the "local control" property of these types of curves. Draw your knots the same size as the control points, preferably in a different color. See the sample implementation for hints on what this should look like. Note that if you just draw a segment and then draw a rectangle at its endpoint, the next segment will appear ``over'' the knot, which looks a little strange. Try to avoid this. See the sample.
Part III --- Koch curves
In class, we learned about the fractal Koch curve. This kind of curve is static (i.e., it's not based on control points), so you can ignore the points for this part of the assignment.
For this curve, the "number of divisions" actually means the number of recursive steps to take in drawing the curve. If this argument is zero, you should just draw a straight, horizontal line. If the number of recursive levels gets too high, this is incredibly slow, so it's a good idea to cap it.
Once again (do we sound like a broken record?), you can see the sample solution to see what this looks like, and about how fast yours might run. Be aware that the sample solution uses a different key to change the division levels for the Koch curve.
Part IV --- Animating curves
Bézier and B-Spline curves do interesting things as their control points move around. Bounce all the user's control points around in the window. Try to match the speed of the sample program.
Using the sample program
When you run the program, a window will appear on your screen. The controls for the program are accessed by either pressing keys or clicking the mouse inside the window.
| Key | Meaning |
| d | Decrease divisions (Bézier and B-spline only) |
| D | Increase divisions (Bézier and B-spline only) |
| w | Decrease divisions (Koch only) |
| W | Increase divisions (Koch only) |
| k | Toggle knot drawing (B-spline only) |
| l | Toggle control polygon drawing |
| a | Toggle animation |
| c | Clear all points |
| r | Insert 50 random points |
| 1 | Bézier drawing |
| 2 | B-Spline drawing |
| 3 | Koch drawing |
| 4 | Circle drawing (extra credit) |
| q | Quit |
Speed
The Bézier algorithm is a lot slower than the B-Spline algorithm as the number of control points gets large (why?). The sample program uses the first B-Spline drawing algorithm I pounded out, while the Bézier drawer went through several revisions to get it faster. Although performance is a huge concern for most graphics applications, concentrate on getting your programs correct before even thinking about ways to make it faster (good advice for almost any software project).
Extra credit
Bézier curves with exactly four control points are cubic curves, just like the pieces of B-Splines. They have nice properties, such as the fact that the tangent to the curve at the endpoints is just the vector connecting the control points on the end (draw a 4-point Bézier curve in your program to see this).
For extra credit, implement a fourth circle-drawing method (you do remember the other three, right?) approximating a circle with n 4-point Bézier curves. You can use your DrawBezier function for this (please please please tell me you have a DrawBezier function), so all you have to do is figure out where the points go. Your function should look something like this:
void DrawCircle( int divisions )
{
for i = 0 to divisions
compute the four points
Click( point1 ); Click( point2 ); Click( point3 ); Click( point4 )
DrawBezier( 20 ) /* or whatever looks reasonable */
ClearPoints()
}
Center your circle at (.5, .5), and give it a radius of .4. The sample solution supports this.
Hint: This part of the assignment may involve some trigonometry and/or calculus to find the control points. Try solving the problem on paper using precisely four curves to figure out the technique. Also, remember that Bézier curves are transformationally invariant, so once you find the points for one of them, you can just pivot the control points around the center of the circle to find the rest (isn't symmetry useful?).