Homework 9, due Tuesday, Nov 30.

Bicubic spline surface patches:

In class I talked about parametric cubic splines, and then went over parametric bicubic surface patches more carefully. For this assignmnent I would like you to either:

You can use Bezier, BSpline, Catmull-Rom or Hermite patches, or provide the option for more than one of these. At the very least, create a single bicubic patch.

Then when you get that working, try the creation of multiple bicubic patches that fit smoothly together. When you are done, you should use the geometry info for each patch (which will be a 4 × 4 array of values for each of the x,y and z coordinates) to render your patch or patches as polygonal meshes in your z-buffer system, much as you did with sphere-shaped meshes. Feel free to use the Cubic.java class that provides cubic spline support for the interactive cubic curve applet that I showed in class.

Helpful notes:

As you know, for every type of spline there is a unique matrix that transforms the four geometry values in each dimension to the cubic polynomial at3+bt2+ct+d. These matrices are incorporated into class Cubic. For example, you can construct Bezier splines by:

   Cubic xSpline = new Cubic Spline(Cubic.BEZIER, GX);
   Cubic ySpline = new Cubic Spline(Cubic.BEZIER, GY);

where double GX[], GY[] are each arrays containing the four geometry values for their respective coordinate, and Cubic.BEZIER is the Bezier matrix.

Last week you used something like this to transform the four geometry values into (a,b,c,d), in order to evaluate cubic polynomials:

X(t) = axt3 + bxt2 + cxt + dx
Y(t) = ayt3 + byt2 + cyt + dy

In the class Cubic, this evaluation is implemented by method double eval(double t), which could allow you to draw the cubic spline as a curve by looping through values of t, stepping from 0.0 to 1.0, and drawing short lines between successive values:

   for (double t = 0 ; t <= 1 ; t += ε)
      g.drawLine((int)xSpline.eval(t  ), (int)ySpline.eval(t  ),
                 (int)xSpline.eval(t+ε), (int)ySpline.eval(t+ε));

Similarly, you can define the coordinates at (u,v) on a bicubic patch by X(u,v),Y(u,v),Z(u,v) by using the bicubic constructors in the Cubic class. For example, you can construct Bezier surface patches by:

   Cubic xSpline = new Cubic Spline(Cubic.BEZIER, GX);
   Cubic ySpline = new Cubic Spline(Cubic.BEZIER, GY);
   Cubic zSpline = new Cubic Spline(Cubic.BEZIER, GZ);

where the two dimensional arrays double GX[][],GY[][],GZ[][] (note the double indices!) each contain the sixteen geometry values for their respective coordinate.

You can then fill up a geometric mesh (sort of like you did when you made sphere meshes) by:

   for (int j = 0 ; j < nRows ; j++)
   for (int i = 0 ; i < nCols ; i++) {
      double u = (double)i / nCols;
      double v = (double)j / nRows;

      double x = xSpline.eval(u,v);
      double y = ySpline.eval(u,v);
      double z = zSpline.eval(u,v);

      defineVertex(i,j,  x,y,z);

where X(u,v), Y(u,v) and Z(u,v) are implemented by xSpline.eval(u,v), ySpline.eval(u,v) and zSpline.eval(u,v), respectively.