# Exercise 3

 Number of Points 100 Due Date Tuesday, October 25, 2005, before class (Problems 1 and 2) Tuesday, October 25, 2005, 11pm
Please note the change of due date/time

Please do the following problems. Problems 1 and 2 should be on paper, and Problem 3 via e-mail. Windows version is expected.

• (25 points)
Consider the following two circular arcs joining at the origin:
f(u) = ( cos(u + PI/2), -(1 + sin(u + PI/2)), 0 )
g(v) = ( -cos(v + PI/2), 0, 1 - sin(v + PI/2) )
where both u and v are in the range of 0 and PI. Note that circular arcs f(u) and g(v) lie on the xy- and xz-coordinate planes, respectively. Analyze the continuity at the origin. More precisely, are f(u) and g(v) C1, C2, G1 or G2 at the origin f(PI) = g(0) = (0,0,0)? Are they curvature continuous?

• (25 points)
Given six control points on the xy-plane (0,-2), (-2,-2), (-2,2), (2,2), (2,-2) and (0,-2), do the following:
• Compute the partition of unity at u = 0.5.
• Use de Casteljau's algorithm to find the point on the curve that corresponds to u = 0.5.
• Subdivide the Bézier curve at u = 0.5 and list the control points of the resulting curve segments.
• Increase the degree of this curve to six and list the new set of control points.
• Since the starting point and the ending point of this curve are the same (0,-2). Discuss the continuity issue at the joining point. More precisely, is it C1, C2, G1, G2 or curvature continuous?
For each problem, you should draw a diagram that contains all computations and show the computations in detail. You will receive no credit if you only show the answer and/or a diagram without calculation.

• (50 points)
Design and implement a program that can show all intermediate polylines of de Casteljau's algorithm as the curve program of DesignMentor does.

You do not have to write all functions. As in the previous exercise, you only need to modify two functions for reading in data and displaying the curve. Click here to download a package for this problem. After unzip and untar (see below), you can make it with one of the four makefiles. The executable will be named as render. Run it and you will see the following on screen:

It displays a Bézier curve of degree 3 defined by four control points shown as blue squares and a yellow disk. This yellow disk does not move. It is used as an example. You can click on Exit to close this window and use the left and right arrow keys to change the value of u shown in the middle of the bottom of this window. The range of u is 0 and 1. Press the left-arrow (resp., right-arrow) key to decrease (resp., increase) the value of u.

### System Notes

To unzip and untar, move Exer-3.tar.gz to your working directory and issue the following commands:
```               gzip -d Exer-3.tar.gz
tar xvf Exer-3.tar
```
You will see four makefiles, each of which is designed to generate an executable under a particular system.

Makefile.SunMesa compiles the system without using OpenGL hardware. Makefile.SunOpenGL compiles the system using Sun's OpenGL library. The generated executable runs much faster. Makefile.SunMesa is for you to compile your program under Linux with Mesa. Finally, Makefile.SGI is for me to grade your program.

To make this system, say using Makefile.SunMesa, issue the following command:

```               make -f Makefile.SunMesa
```

As in the previous exercise, you need to modify cs390_init() to read in a data file whose name is supplied to you with **argv. The file has the following format:

```n <------------ degree.  number of control points = n+1
x0 y0 z0 <----- 0-th control point
x1 y1 z1 <----- 1st control point
x2 y2 z2 <----- 2nd control point
......
xn yn zn <----- n-th control point
```

To draw a Bézier curve, we need to know more about OpenGL. In draw_bezier_curve(), the first for loop puts the control points on screen:

```glColor3f(CS390_POINTS_COLOR);     /* select a color             */
glPointSize(8);                    /* select the size of a point */
glBegin(GL_POINTS);                /* ask OpenGL to show 3d Pts  */
for(i = 0; i < n; i++) {       /* for each point ....        */
glVertex3dv(&points_data[i][0]);   /* display it         */
}
glEnd();                           /* end of point display       */
```
Next, we draw a Bézier curve with the OpenGL function glEvalCoord1d(). This is the so-called one-dimensional evaluator. In the following, glEnable() enables evaluator mapping; glMap1d() creates a one-dimensional evaluator, and glBegin() and glEnd() ask the evaluator to generate a sequence of points on the curve and connect them into a curve, the desired Bézier curve.
```glColor3f(CS390_CURVE_COLOR);      /* select a drawing color     */
glLineWidth(2);                    /* select a line width        */
if(n >= 2) {                       /* draw curve only if n >= 2  */
glEnable(GL_MAP1_VERTEX_3);    /* activate mapping and do it */
glMap1d(GL_MAP1_VERTEX_3, 0.0, 1.0, 3, n, &points_data[0][0]);
glBegin(GL_LINE_STRIP);        /* draw a line strip          */
for(i = 0; i <= 100; i++) {     /* 100 segments          */
glEvalCoord1d((GLdouble) (i * 1.0) / 100);  /* gen pt*/
}
glEnd();                       /* end of line strip          */
}
```
You need to do two things. First, you need to read all control points into the data array data[][]. You can assume there are less than 100 control points. Second, use glMap1d() to take this data array as the sixth parameter and create an evaluator so that when a u is given the evaluator will generate the corresponding point on the curve.

However, OpenGL does not actually draw a curve. Instead, it requires you to subdivide the domain with many points. Then, OpenGL gets the corresponding points on the curve and joins the adjacent ones with line segments (i.e., line strip). Therefore, if the number of subdivision points is low, the generated Bézier curve looks like a polyline; however, too many subdivision points could slow down your program. In the sample program we use 100. Feel free to modify this value.

The for loop above lets variable i run from 0 to 100. For each i, it is converted to the range of 0 and 1 with (i * 1.0) / 100. This value is sent to glEvalCoord1d(), which in turn will generate a corresponding point on the curve for OpenGL to do the connect-the-dot drawing operation.

Basically, you do not need to change this part at all.

If you look at draw.c carefully, you will see a global double variable u. Each time cs390_draw() is called, a value of u is passed to you with this global variable. The value of u comes from pressing the left- and right-arrow keys.

Modify draw.c so that it can display the following:

1. Draw a disk at the point on curve that corresponds to the current value of u. Function draw_disk() takes the coordinates of a point and the size of a disk and puts a disk at the desired place. Please do not modify this function if it is possible.
2. Draw the control polyline of the input control points.
3. Given the value of u, draw all intermediate polylines of applying de Casteljau's algorithm at u. This de Casteljau net should be drawn with a color that is different from that of the curve and that of the control polyline.
To draw a polyline, use the GL_LINE_STRIP feature:
```glBegin(GL_LINE_STRIP);
/* generate a vertex on the polyline */
/* some other activities */
glEnd();
```
For a discussion of glVertex3dv(), please see Exercise 2.

With a correct implementation, you can drag or rotate the generated Bézier curve and use the left- and right- arrow keys to increase and decrease the value of u. Then, the computation of de Casteljau's algorithm will be shown vividly on screen.

### An Important Note

Feel free to modify the colors of the objects. However, keep in mind that the color selections must be able to distinguish different objects. Do not use similar colors for near-by objects. You can also use different colors for different polylines of the computed de Casteljau net.

Here are important notes for this exercise.

• Submit the first two problems on paper. This part is due on October 24 in class. Please keep the following in mind; otherwise, you will risk lower grade.
1. Write clearly and to the point.
2. Present all computation details and intermediate steps. Writing down only the answers is not acceptable.
3. When you are asked to analyze something, you should write down your conclusion first and then use detailed calculations to support your finding. Only a conclusion or vague discussion (i.e., "I believe it is G2 because it looks smooth") is not acceptable.

• Submit the third problem with the following materials:
1. A README file in which your effort and the logic of your program should be presented in detail. Make sure your name and e-mail address appear in the very beginning of this file as shown below:
```NAME:      your name
EXERCISE:  3
```

SSN is not required.

2. File Exer-3.tar.gz. Please do not change the structure of the files. Just modify draw.c would suffice. Do not change the makefiles as I will use my SGI machine for grading. Please cd to your working directory and only tar the files.
3. The following is a sample input file. It will generate a Bézier curve of degree 7. Click here to download a copy of this file input-0.dat.
```7
-40  -40  -40
-40   40  -40
-40   40   40
-40  -40   40
40  -40   40
40   40   40
40   40  -40
40  -40  -40
```
In your version of Exer-3.tar.gz, in addition to the above sample input, add two more test files input-1.dat and input-2.dat for me to test your program. Each of your test files should contain at least five control points. Interesting curve design will receive up to 5 bonus points. I will also use my own files for testing with the following command:
```render  input-file-name
```

If you need a working program and other files for your testing, click here to learn more. Note that these files are for your reference only, you should not submit them as your work. Otherwise, you will receive no credit for this problem. You can also use DesignMentor to verify your work.

• If you have any questions, please stop by or send e-mails to me.