## Homework 4, due Monday, Oct 13.

Sorry it took me a little longer to describe this completely. I wanted to make sure that the on-line class notes were all integrated in properly. :-)

When you have finished the assignment below, post the working applet and the source code onto your class web site. You don't need to send email.

This assignment is all about kinematics. That means you're going to make things move! As we described in class on Monday, this is a leap from making individual objects move around, where each object is moved by an independent 4×4 transformation matrix, to making entire coordinated systems of objects move, through a hierarchy (or tree) of transformation matrices.

Your assignment is make an interesting and original animated scene that has such a hierarchy of moving objects in it. Your scene can consist of one or more human figures, or cows or dragons, automobiles, martian creatures, clocks, butterflies, or anything else that strikes your fancy. Make sure to have fun with it.

It is very important that you read the part at the bottom of this assignment about matrix multiplication order. Otherwise you'll have trouble getting things right.

To review: the way you were doing things before, at each animation frame you were able to string together a set of transformations to make a transformation matrix. Using that technique, at each frame you could construct a matrix, and then transform all your points by that matrix. Below is a typical example:

```
double matrix[][] = new double[4][4];                       // TRANSFORMATION MATRIX; CHANGES EACH FRAME
double time = 0;                                            // TIME COUNTER TO ADVANCE THE ANIMATION
double cube[][] = {{-1,-1,-1},{1,-1,-1},{-1,1,-1},{1,1,-1}, // THE VERTICES OF AN *UNTRANSFORMED* CUBE
{-1,-1, 1},{1,-1, 1},{-1,1, 1},{1,1, 1}};
double temp[][] = new double[cube.length][3];               // STORE THE TRANSFORMED VERTICES EACH FRAME
int cubeEdges[][] = {{0,1},{1,3},{3,2},{2,0}, ... };        // EDGES OF THE CUBE (PAIRS OF VERTEX INDICES)

...

public void render(Graphics g) {

...

double x = Math.cos(2 * Math.PI * time);                 // COMPUTE TIME-VARYING PARAMETERS
double y = Math.sin(2 * Math.PI * time);
time += 0.01;

Matrix.identity(matrix);         // CLEAR THE MATRIX
Matrix.translate(matrix, x,y,0); // MOVE IN A CIRCLE
Matrix.scale(matrix, .1,.1,.1);  // SCALE SMALLER

for (int i = 0 ; i < cube.length ; i++)                  // TRANSFORM THE CUBE BY THE MATRIX
Matrix.transform(cube[i], temp[i], matrix);

for (int i = 0 ; i < cubeEdges.length ; i++) {           // DRAW EDGES BETWEEN THE TRANSFORMED POINTS
int i0 = cubeEdges[i][0];
int i1 = cubeEdges[i][0];
g.drawLine(ViewPortX(temp[i0]), ViewPortY(temp[i0],
ViewPortX(temp[i1]), ViewPortY(temp[i1]);
}
}
```

Notice that the above example built a single transformation matrix in each frame, in steps, and then used that single matrix to transform geometry before rendering it.

The key advance we'll be working on is to describe a scene as an entire tree of transformations. At every node of this tree, some part of your scene can be transformed and then rendered. As we discussed, the data structure that lets you traverse a tree is a stack, so you'll need a matrix stack, such as:

```   double mStack[][][] = new double[STACKSIZE][4][4];
```
and a top-of-stack pointer:
```   int mTop = 0;
```
At each frame of your animation the stack needs to start off in its "initial" state:
```   mTop = 0;
Matrix.identity(mStack[mTop]);
```
Then to animate the scene for that frame of animation, you would do a sequence of operations that use this matrix stack. Some of these operations modify the matrix stack itself; others use the matrix at the top of the stack to transform geometry in your scene.

There are several sorts of operations you can perform:

1. You can modify the matrix on top of the stack;
2. You can push or pop the matrix stack;
3. You can use the matrix on top of the stack to transform and render some shape.
Let's take these one at at time:

You already know how to modify a single matrix, by using the methods `identity`, `translate`, `rotateX`, `rotateY`, `rotateZ` and `scale`. For example, you can modify the matrix on top of the stack with such operations as:

```   Matrix.identity(mStack[mTop]);
```
or
```   Matrix.rotateX(mStack[mTop], theta);
```
Also you'll want to be able to push and pop the matrix, to reflect entering and then leaving local branches of the tree that describes the scene (such as the arms and legs of a human figure). A `push` operation can be effected by:
```   Matrix.copy(mStack[mTop], mStack[mTop+1]);
mTop++;
```
and a `pop` operation can be effected by:
```   mTop--;
```
I encourage you to create `push()` and `pop()` methods for this. Make sure that you add error handling to these methods to check for stack overflow or underflow!

Finally, while you're traversing the tree you'll want to render various parts of your scene which are embedded in various "nodes" of the tree. you'll need to transform the actual objects in your scene (arms, legs, trees, automobile parts, etc). You can do this by transforming them by whatever matrix is on top of the stack when that node is reached. For example, if you have a sphere mesh, you might have the following lines of code somewhere:

```   Matrix.copy(mStack[mTop], sphMesh.matrix);
sphMesh.draw(epsilon);
```

Matrix multiplication order:

There is something that might seem counter-intuitive about how you need to multiply the matrices together when traversing the heirarchy tree of your scene. In general, there are two distinct ways you could do matrix multiplication upon a matrix A, by another matrix B:

B × A
or
A × B
Because matrix multiplication is not commutative, these two operations will usually produce different results. Up to now you might have been doing the first method, which is called pre-multiplication of matrix A by matrix B. The second method, in contrast, is called the post-multiplication of matrix A by matrix B.

It turns out that when you want to make hierarchies, you need to post-multiply. This is because as you traverse the tree, going from global parts (eg: pelvis) to local parts (eg: elbow, wrist, finger), you don't want your new transformations to take place in "global coordinates", but rather in the (already transformed) coordinate system of the parent part. For example: a person's right knee should bend about the transformed x access at the end of the person's right thigh, not about the global x axis.

To reiterate:

• Pre-multiplying A by B by doing B × A will cause the change in A to happen in global coordinates;

• Post-multiplying A by B by doing A × B will cause the change in A to happen in the local coordinates of A.

Go back and look at the `Matrix.multiply` method that you have been using within your `translate`, `rotateX`, `rotateY`, `rotateZ` and `scale` methods. You are either doing a pre-multiplication or a post-multiplication. If you want to create a hierarchy of objects, you need to be post-multiplying.

If you're not sure whether you're doing it right, the good news is that there are only two possibilities: if one ordering is wrong, then the other one will work!

Let's take a simple test case, which you can use to test out your matrix multiplication, to see whether you are getting the order right for doing hierarchies. Consider a swinging pendulum with a shaft 10 units long, which swings from a height of 10 units up in y. We can build the pendulum out of two cubes: an elongated one for the pendulum shaft, and a slightly flattened one for the weight at the end.

Let's assume that we have some `cube` object which, when not transformed, extends from -1.0...+1.0 in x, from -1.0...+1.0 in y and from -1.0...+1.0 in z, and that this cube is drawn by `cube.draw()`.

We can model the pendulum by transforming and then drawing the cube twice: once for the shaft, and then differently for the weight.

```   Matrix.identity(m);
Matrix.translate(m, 0,5,0);     // SLIDE THE SHAFT UPWARDS
Matrix.scale(m, .1,5,.1);       // SCALE IT TO ELONGATE IN Y
Matrix.copy(m, cube.matrix); // TRANSFORM THE SHAFT
cube.draw();                 // DRAW THE SHAFT

Matrix.identity(m);
Matrix.scale(m, .5,.5,.1);      // FLATTEN IN Z
Matrix.copy(m, cube.matrix); // TRANSFORM THE WEIGHT
cube.draw();                 // DRAW THE WEIGHT
```
Notice that the code in red only works properly because we have implemented the `scale` method by using post-multiplication on the results of `scaleMatrix`. This ensures that the scaling will take place around the middle of the moved shaft, rather than around the global origin.

But how would we swing this cube? If you have implemented `push()` and `pop()` methods, as well as methods `translate`, `rotateX`, `rotateY`, `rotateZ` and `scale` that always modify `mStack[mTop]`, then this is very straightforward:

```   identity();
translate(0,10,0);    // SLIDE UP TO TOP OF SHAFT
rotateZ(theta);       // ANIMATE SWING OF PENDULUM ABOUT TOP OF SHAFT
push();                  // TRANSFORM AND RENDER THE SHAFT:
translate(0,-5,0);                      // SLIDE DOWN TO MIDDLE OF SHAFT
scale(.1,5,.1);                         // SCALE THE SHAFT
Matrix.copy(mStack[mTop], cube.matrix); // TRANSFORM AND DRAW
cube.draw();
pop();
push();                  // TRANSFORM AND RENDER THE WEIGHT
translate(0,-10,0);                     // SLIDE DOWN TO BOTTOM OF SHAFT
scale(.5,.5,.1);                        // SCALE THE WEIGHT
Matrix.copy(mStack[mTop], cube.matrix); // TRANSFORM AND DRAW
cube.draw();
pop();
```