Course Links

Resources

External

Introduction

The goal of this homework is to practice working with transformation matrices in a computational setting. This time we'll implement each transformation matrix in JavaScript, then use them to create an animation. The homework builds on both Lab M and Lab 3. In some ways we are implementing Lab 3 from scratch, which should hopefully make the order of transformations clearer. We'll also be working with a global transformation matrix, which is exactly how HTML Canvas and WebGL work.

Identity matrix

First, create a fork of the starter code. There is one function implemented called pushMatrix. This function is going to take in a new transformation matrix, multiply the current matrix by this new transformation, and then replace the current matrix with the result. Finally, it will set the current matrix internally (erasing any previous transformations), using the Canvas setTransform method.

For this part, implement a function to create the identity matrix:

function identityMatrix() {
  ...
}

This should return a 3x3 (2D) array. Then, inside the init method (right before draw), call the identityMatrix method to set the currMatrix to the identity. Our currMatrix variable is global, meaning that we don't have different matrices for each object -- they all share the same drawing environment. Later on, if you want to animate multiple objects doing different things, you will have to keep track of a separate transformation for each of them.

Matrix multiplication

Next implement a matrix multiplication function. (You may already have done so as part of Lab M; if so you can use that solution here.)

function matrixMultiply(M1, M2) {
  ...
}

It should take in two matrices, M1, and M2, and return the result of M1*M2 as a new matrix. Your function should be general, in the sense that it should be able to take in any two matrices with matching inner dimensions.

If you have not finished Lab M, I strongly recommend that you try to write matrixMultiply for yourself before looking at any solution. You may use the solution to check your work and make sure that it is right.

Transformation matrices

Similar to the identity matrix, create functions for each of the following transformation types: scale, rotate, translate, reflection (either across the x or y axis), and shear (choose either x or y direction). Use the arguments below:

function scaleMatrix(sx, sy)     // usually called S
function rotateMatrix(theta)     // usually called R
function translateMatrix(tx, ty) // usually called T
function reflectionMatrix()      // usually called F
function shearMatrix(lambda)     // usually called H

Each of these functions should return a 3x3 matrix using homogeneous coordinates.

Testing

Inside draw, test each of your methods, and their compositions. After creating each transformation matrix, call the pushMatrix function to multiply it by the current matrix. If you want to undo transformations later, you can multiply by the inverse transformations in the reverse order. Alternately, you can set currMatrix back to the identity and start from scratch.

Note 1: in this homework, outside of creating shapes and using graphics.setTransform(...) inside pushMatrix, we will not be using ANY built-in transformations. This part should all be from scratch. The idea is to understand how the built-in transform functions are operating by implementing the same behavior ourselves. (When you want to animate multiple objects, it will also be useful to keep track of multiple matrices because the built-in transform only has a single one.)

Note 2: if you would prefer to put the call to pushMatrix inside each transformation matrix function, you can do that instead. In this case, rename your functions to be translate instead of translateMatrix, etc., since their behavior is to alter future drawings rather than simply return a matrix.

Figure 8

Create a second page in your repl called fig8.html. You can do this using the Add File button in the file pane. Once you have done that copy the contents of index.html into it. We'll make further modifications to this new file, leaving your matrix tests unchanged for me to see in index.html.

To make your added page accessible, you can place a link in the main index.html page. At the bottom of the file, add the line shown below in red:

<body onload="init()">
    <a href="fig8.html">Figure 8</a><br>
    <canvas id="theCanvas" width="450" height="300"></canvas>
</body>
</html>

In the new file, using your transformation matrices and the setInterval method for a timer, create an animation that moves a shape (square, circle, etc) in a smooth figure 8 motion (like an ice-skater or drawing an infinity symbol). Each lobe can be circular, and the motion should transition smoothly from one lobe of the figure eight to the other. In order to do this, you will probably want to use a counter that keeps track of the number of steps to complete one circle before shifting to the other.

Tip: if you would like to clear the canvas before each step of your animation, use this procedure:

  
graphics.save(); // save the current set of transformations
graphics.setTransform(1, 0, 0, 1, 0, 0); // reset matrix to the identity
graphics.clearRect(0, 0, canvas.width, canvas.height); // clear canvas
graphics.restore(); // restore the transformations you had before

This makes sure the canvas is cleared properly without any transformations, but it still saves whatever transformations you were working with. Other than this, you may not use setTransform except in pushMatrix!

Your own animation

Create a third page with a version of your code that performs a custom animation.

Bronze
Implement only the figure eight described above.
Silver
Implement an additional animation of your choice that is different from the figure 8. Your animation should include at least three different transformation matrix types, and should smoothly transition from one motion type to another at least once. For example, it might move in a straight line for a while and then move downwards, then stop and grow larger.
Gold
Create an animation involving at least 3 different shapes moving independently at the same time. Your animation should include at least three different transformation types, and should include at least three transitions from one motion type to another. In order to achieve the independent motions, it will be easiest to give each object its own separate transformation matrix that is installed just before drawing the object.

For silver and gold, your custom animation should appear in a new page called my_anim.html and it should be linked from the main page just like fig8.html. Please indicate in your reflection statement which level you implemented, and how you met the criteria. Besides these constraints, the animation is completely up to you! Extra credit is possible for animations that show exceptional creativity/artistry.

Submit

You'll have three separate files to submit for this homework: your original tests of the transformation matrices in index.html, your version of a figure 8 in fig8.html, and your own animation (if attempted) in my_anim.html. No screenshot necessary this time. If I open the figure 8 file in a web browser, I should immediately see the animation working (same for your own animation). If you wish to submit a zip file of the entire repl, that's fine also.

Collaboration:

For this assignment, you may work with a partner (pair programming) as long as you pick someone with whom you have not worked before.