index.html
page
which links to all
the assignments for this class, not just
for individual assignments.
I will link to your main folder from the class page.
This assignment is going to focus on two things:
double matrix[][] = new double[3][3];
For this assignment, I'd like you to
make a cool and interesting
and creative picture or animation using instances
of shapes
(ie: show the same shapes translated, rotated,
and scaled in different ways).
I also want you to use
the
mouseMove
,
mouseDown
,
mouseDrag
,
mouseUp
or
keyUp
methods
(but please don't feel you need to use all of them),
to allow the user to interact with
your objects in some interesting way,
as per our
"things" example from class.
If you feel more comfortable using
the newer Observer
based model
of input handling instead, please feel free to do so.
You'll find it particularly useful
to use the java.awt
drawLine
, drawPolygon
and
fillPolygon
methods.
As we said in class,
java.awt
methods to draw rectangles and
ovals won't really work very well
once you start rotating and scaling things.
As we discussed in class, you'll need to implement the following primitive operations:
If it were me, I'd probably implement them all as static methods in a class called Matrix2D, but please feel free to do it another way if you feel confident. The reason I like using static methods for this is that it makes it clear that you don't need to keep any data around by creating object instances.
Identity:
1 0 0 0 1 0 0 0 1 translationMatrix(a,b):
1 0 a 0 1 b 0 0 1 rotationMatrix(θ):
cos(theta) -sin(theta) 0 sin(theta) cos(theta) 0 0 0 1 scaleMatrix(a,b):
a 0 0 0 b 0 0 0 1
For example, your method to build a translation matrix might look like this:
public class Matrix2D { ... public static void translationMatrix(double matrix[][], double a, double b) { identity(matrix); matrix[0][2] = a; matrix[1][2] = b; } }You'll also want to implement a method to do matrix multiplication. Remember that you do this by doing nine dot (inner) products. To do this, it's convenient to implement a method that copies the contents of one matrix into another. Then to multiply two matrices A and B:
copy(A,temp); // FIRST COPY TO A TEMPORARY 3×3 MATRIX for (int i = 0 ; i < 3 ; i++) for (int j = 0 ; j < 3 ; j++) A[i][j] = temp[i][0]*B[0][j] + temp[i][1]*B[1][j] + temp[i][2]*B[2][j];For convenience, you'll probably want to make methods
translate(matrix, a, b); rotate(matrix, theta); scale(matrix, a, b);which first create the translation, rotation or scale matrix, respectively, and then do a matrix multiply. For example:
static double tempMatrix[][] = new double[3][3]; ... public static void translate(double matrix[][], double a, double b) { translationMatrix(tempMatrix,a,b); // CREATES A TRANSLATION MATRIX multiply(matrix, tempMatrix); // MODIFIES THE FIRST ARGUMENT IN PLACE }Finally, you'll want to implement a method that applies a matrix transformation to a point. Here's how I might implement that:
public static void transform(double src[], double dst[], double matrix[][]) { dst[0] = matrix[0][0] * src[0] + matrix[0][1] * src[1] + matrix[0][2]; dst[1] = matrix[1][0] * src[0] + matrix[1][1] * src[1] + matrix[1][2]; }Now that you have all the tools, you can make pictures that have instances. For example, let's say you define a square shape as:
double square[][] = {{-1,-1},{1,-1},{1,1},{-1,1}};Notice that I've used small floating point values for the square vertices. In general you might find it easier to model things in floating point coordinates, with (0,0) at the center of the screen. Then after you do your matrix transformations, you can to a ViewPort transformation to get everything into the proper integer pixel coordinates of your applet window.
You can make all kinds of instances of the square by making transformation matrices and then using them to transform the square. You might find it convenient to keep around a temporary array for the transformed points:
double xy[][] = new double[100][2]; ... // TRANSFORM ALL THE POINTS int len = square.length; for (int i = 0 ; i < len ; i++) transform(square[i], xy[i], matrix);as well as temporary arrays for the X and Y pixel coordinates of polygons you want to draw:
int X[] = new int[100]; int Y[] = new int[100];Here's how you might do that ViewPort transformation:
// DO THE VIEWPORT TRANSFORM AND DRAW A POLYGON for (int i = 0 ; i < len ; i++) { X[i] = (int)( width/2 * xy[0]) + width/2; Y[i] = (int)(-width/2 * xy[1]) + height/2; } g.drawPolygon(X[i],Y[i],len);Notice that I've defined the ViewPort transformation so that the origin (0,0) will display at the middle of the screen [width/2,height/2].