Computer Graphics

Lab Exercise 3: Matrices, 3D Transformations, and Face Orientation

This week we will construct a class for 4*4 matrices, and use it to transform vectors and points.


Matrix class

We only consider 4*4 matrices. These are used to rotate, scale or translate objects (or any combination of these operations). Matrices are also used later in the implementation of the virtual camera model. If you do not know the difference btween a vector transformation and point transformation, ask your TAs.

The matrix class is supplied to you.

Matrix.java

Matrix.java

3D Transformations

You should make use of the Matrix specification to add the following function to your Point3D, Vector3D and GOjbect classes, to multiply a 3D point by a Matrix.

These methods multiply the Matrix M to the target vector/point and returns the result.

Point3D.java
public Point3D transform(Matrix m);
Vector3D.java
public Vector3D transform(Matrix m);

This one is a mutator.

GObject.java
public void transform(Matrix m);

Face Orientation

For any polyhedral object obviously not all of its faces can be simultaneously visible from any viewpoint.

A technique called back face elimination involves displaying only those polygons that are facing towards the viewpoint. We can use the dot product and the cross product of vector to determine which polygon is facing towards the viewpoint. This involves two steps. First, we find out the surface normal of a polygon. Then we test if the surface normal is pointing towards the viewpoint (front face) or not (back face).

Step 1: Suppose we have 3 vertices of a polygon in counterclockwise order viewing from its front: p1, p2 and p3. Then vectors v1=p2-p1 and v2=p3-p1 are two vectors in the plane of the polygon, and the vector n=v1*v2 (cross product) is the surface normal of the plane and the polygon.

Step 2: Suppose vpn is the vector pointing toward the viewpoint. Then if n.vpn (dot product) is positive, the two vectors form an angle in the range of (-PI/2, PI/2), and thus the polygon is a front face.

You now have to implement the following methods for orientation testing.

Point3D.java
 
public Vector3D vector(Point3D p){/* return the vector that is between this point and p.*/}
public static Vector3D faceNormal(Point3D p1, Point3D p2, Point3D p3){}
public static boolean isFrontFace(Point3D p1, Point3D p2, Point3D p3, Vector3D vpn){}

Notes on 3D Transformation

If column vector is used, for the point (x,y,z) the transform function must compute by using the homogeneous coordinate system:

 
       (xw)       | m00 m01 m02 m03 |   (x)
       (yw)       | m10 m11 m12 m13 |   (y)
       (zw)   =   | m20 m21 m22 m23 | * (z)
       ( w)       | m30 m31 m32 m33 |   (1)
 
= (x*m00+y*m01+z*m02+m03)
  (x*m10+y*m11+z*m12+m13)
  (x*m20+y*m21+z*m22+m23)
  (x*m30+y*m31+z*m32+m33)
 
Then calculate for the new point: 
 
(xw,yw,zw) = (xw/w, yw/w, zw/w)
 
 
For a 3D vector between two 3D points, from p1(x1,y1,z1) to p2(x2,y2,z2), the vector (dx,dy,dz) transformed with 4x4 matrix M can be calculated as: 
 
       (xw1)          (x1)
       (yw1)          (y1)
       (zw1)  =  M  * (z1)
       ( w1)          ( 1)
 
       (xw2)          (x2)
       (yw2)          (y2)
       (zw2)  =  M  * (z2)
       ( w2)          ( 1)
 
(dx,dy,dz) = (xw2/w2-xw1/w1,yw2/w2-yw1/w1,zw2/w2-zw1/w1)
 
For a vector v at a reference point p, you can take the position p1 as the reference point for where the vector is, p1=p, and let p2=p1+v, then use the above method to calculate the transform of a vector. 
Note that transform of a vector is related to the reference point.