Home Page

Home Page

Comp 236

Programming Assignment 3:  Bicubic Bezier Surfaces

Background

Code Specifics

Top-Level Pseudocode

    setup OpenGL
    init Bezier patch array with teapot.txt
    build mesh of 3D points for each patch      // fancy stuff happens here
    set camera position/rotation

    for each patch
    {
        map 3D mesh vertices to image plane     // Program 1 "one true way"
        draw patch as wire-frame                // uses OpenGL to draw 2D lines
        calculate normals                       // more fancy stuff happens here
        map normals to image plane and draw
    }

Details of Building Mesh

First, calculate delta t based on the desired number of curves. (Note that the code assumes an equal number of steps in s and t, so the t and dt variables are also conceptually s and ds). Next, precalculate values for the Bernstein basis functions (i.e. the blending functions). Lastly, perform iterative evaluation of the bicubic polynomials to get points on the surface.

    // precalculate values for Bernstein basis functions

    double dt = 1.0 / ((double)numCurves-1.0);  // delta t
    double t = 0;                               // initial t value

    for( unsigned i = 0; i < numCurves; i++ )
    {
        b0[i] = (1 - t) * (1 - t) * (1 - t);    // (1-t) cubed
        b1[i] = 3 * (1 - t) * (1 - t) * t;      // 3(1-t)(1-t)t
        b2[i] = 3 * (1 - t) * t * t;            // 3(1-t)(t squared)
        b3[i] = t*t*t;                          // t cubed
        t += dt;
    }
    // perform iterative eval of the bicubic polynomials

    for( i = 0; i < numCurves; i++ )
    {
        // column 0
        x gets blending of column0 x values
        y gets blending of column0 y values
        z gets blending of column0 z values
        p0 = Point3D( x, y, z );

        // column 1
        x gets blending of column1 x values
        y gets blending of column1 y values
        z gets blending of column1 z values
        p1 = Point3D( x, y, z );

        similarly for columns 2 and 3

        //***
        // For current value of s, use new control points to 
        // calculate points on the t curve.
        //***
        for( unsigned j = 0; j < numCurves; j++ )
        {
            x = b0[j]*p0.x + b1[j]*p1.x + b2[j]*p2.x + b3[j]*p3.x;
            y = b0[j]*p0.y + b1[j]*p1.y + b2[j]*p2.y + b3[j]*p3.y;
            z = b0[j]*p0.z + b1[j]*p1.z + b2[j]*p2.z + b3[j]*p3.z;
            mesh(i,j) = Point3D( x, y, z );
        }

    }

The code for calculating the normals is very similar.

Example Images

Source Code and Such

The source code is here. The executable is here. You also need the teapot definition file, which is in the zip file with the executable.

To run the executable, put the hw3.exe file and the teapot.txt file in the same directory, and then launch the executable. The teapot should spin in various ways. When it stops, press any key (except x) to step to the next image in the sequence.

References

http://www.cs.wpi.edu/~matt/courses/cs563/talks/surface/bez_surf.html
Also Foley & vanDam (of course) and Hearn & Baker.

Email Jason Stewart