6.837 - Project #3


Ground Rules for all projects:
In this project you will implement a matrix class for transforming three-dimensional points. You will reuse this class in your next project.

Implement the following class:


    public class Matrix3D {
        //
        // Constructors
        //
        public Matrix3D();                  // initialize with identity transform
        public Matrix3D(Matrix3D copy);     // initialize with copy of source
        public Matrix3D(Raster r);          // initialize with a mapping from
                                            // canonical space to screen space

        //
        // General interface methods
        //        
        public void set(int i, int j, float value);          // set element [j][i] to value
        public float get(int i, int j);                      // return element [j][i]

        //
        // Transform points from the in array to the out array
        // using the current matrix. The subset of points transformed
        // begins at the start index and has the specified length
        //
        //    for (i = 0; i < length; i++)
        //        out[start+i] = this * in[start+i]
        //
        public void transform(Point3D in[], Point3D out[], int start, int length);

        public final void compose(Matrix3D src);                        // this = this * src
        public void loadIdentity();                                     // this = identity
        public void translate(float tx, float ty, float tz);            // this = this * t
        public void scale(float sx, float sy, float sz);                // this = this * scale
        public void skew(float kxy, float kxz, float kyz);              // this = this * skew
        public void rotate(float ax, float ay, float ay, float angle);  // this = this * rotate 
        public void lookAt(float eyex, float eyey, float eyez,
                           float atx,  float aty,  float atz,
                           float upx,  float upy,  float upz);          // this = this * lookat

        //
        // Assume the following projection transformations
        // transform points into the canonical viewing space
        //
        public void perspective(float left, float right,                // this = this * persp
                                float bottom, float top,
                                float near, float far);
        public void orthographic(float left, float right,               // this = this * ortho
                                 float bottom, float top,
                                 float near, float far);
    }

You are free to implement the Matrix3D class (define instance variables and private helper methods) as you wish. Note that matrices are composed on the right, and points are column vectors.

While you are primarily responsible for testing your class, I have provided an example test program that you can use as a starting point.

By clicking and dragging within the window you can rotate the displayed object (Please feel free to improve/expand the user interface). I've exaggerated the perspective on the cow object so that it is more obvious.

The object file contains commands to set up the viewing position and field-of-view of the displayed window. These include:

Hopefully the meaning of the first three commands is self evident, and their relation to the lookAt( ) method of the Matrix3D class should be clear. The fov command specifies the horizontal field-of-view of the raster. From this (and some assumptions including square pixels and a symmetric viewing frustum) it is possible to call the perspective method. You might want to glance at the code to figure out how it is used.

The source for this applet and its associated files follow:

Please use your own test applet to display the functionality of your class on your project web page. You may, however, use my test program as a starting point, but please document any modifications that you made as both comments in the code and on the project web page. Your test program should exercise each method in your Matrix3D. I make no guarantee that my test program does.