Homework 3, due Wednesday, Sept 25.

When you have finished this assignment, post the working applet onto the web. The grader and I will be able to look at it there; there is no need to send any email, unless you think we don't yet have the correct URL of your web folder for this class.

In this assignment, I want you to extend the previous assignment by replacing the Matrix_3x3 class with a Matrix_4x4 class, and allow the user to manipulate (rotate, translate, scale) three dimensional objects via mouse movements.

NOTE: For this assignment, you will not yet need to use ray tracing.

The user should be doing all the manipulations in 3D object space, and the last thing you should do to a vertex before drawing it, is the viewport transform that converts object space x,y,z to pixel values for x,y.

For now, when you do this final step, you can just ignore object space x. Essentially you'll be implementing an orthogonal camera view, without any perspective. We'll cover perspective viewing in a later lecture.

Structurally, your work for this assignment should look remarkably similar to what you did for the previous assignment. Of course you'll need to give the user the option to rotate about any of the three axes, x, y or z.


Helpful notes:

If I find that people are having problems that I should call to the class's attention, I'll keep adding them to these notes. So you might want to keep checking back here periodically to see if I've added anything you can use.

Thursday, Sept 19

Recall that the three rotation matrix primitives are:

RotateX(θ) =
1 0 0 0
0 cos(θ) -sin(θ) 0
0        sin(θ) cos(θ) 0       
0 0 0 1
RotateY(θ) =
cos(θ) 0        sin(θ) 0       
0 1 0 0
-sin(θ) 0 cos(θ) 0
0 0 0 1
RotateZ(θ) =
cos(θ) -sin(θ) 0        0       
sin(θ) cos(θ) 0 0
0 0 1 0
0 0 0 1

*****

You might find it useful within the Matrix_4x4 class to implement set and get methods for individual elements, with the calling signatures:
   void set(int i, int j, double value);   // SET ONE COEFFICIENT IN A MATRIX
   double get(int i, int j);               // GET ONE COEFFICIENT IN A MATRIX

*****

To make it easier to scale about an arbitrary point, you may want to create a method in the Matrix_4x4 class:
   public void scale(double sx, double sy, double sz, double x, double y, double z) {
      translate(-x, -y, -z);
      scale(sx, sy, sz);
      translate(x, y, z);
   }
You can also create similar methods for rotating about an arbitrary point about each of the three axes.

*****

You might want to implement a method internal to Matrix_4x4 that just does a matrix multiply, with the calling signature:
   void multiply(Matrix_4x4 M);
This method would modify the coefficients of the Matrix_4x4 object that called it.

Given such a method, you could implement, say, translate(x,y,z) by something like:

   Matrix_4x4 tmp = new Matrix_4x4();
   ...

   public void translate(double x,double y,double z) {
      tmp.identity();
      tmp.set(3,0, x);
      tmp.set(3,1, y);
      tmp.set(3,2, z);
      multiply(tmp);
   }