Week 5 Tutorial Solutions

Question 1: 3D Affine Transformations

What coordinate frames do the following affine matrices represent?

M1 = [[  1,  0,  0,  0],
      [  0,  1, -1,  0], 
      [  0,  1,  1,  0],
      [  0,  0,  0,  1]]

M2 = [[  2,  0,  0,  2],
      [  0, -1,  0,  1],
      [  0,  0,  1,  0],
      [  0,  0,  0,  1]]

M3 = [[  1,  1,  1,  0],
      [  0,  1,  1,  0],
      [  0,  0,  1,  0]
      [  0,  0,  0,  1]]

Hint: rememeber M = [i, j, k, phi].

M1 = [[  1,  0,  0,  0],
      [  0,  1, -1,  0], 
      [  0,  1,  1,  0],
      [  0,  0,  0,  1]]

i = (1,0,0)
j = (0,1,1)
k = (0,-1,1)
phi = (0,0,0)

The j/k axes have been rotated 45 degrees about i, and scales to have length sqrt(2).

M2 = [[  2,  0,  0,  2],
      [  0, -1,  0,  1],
      [  0,  0,  1,  0],
      [  0,  0,  0,  1]]

i = (2,0,0)
j = (0,-1,0)
k = (0,0,1)
phi = (2,1,0)

The origin has been translated to (2,1,0).
The i-axis has been scaled by 2.
The j-axis has been reflected.

M3 = [[  1,  1,  1,  0],
      [  0,  1,  1,  0],
      [  0,  0,  1,  0]
      [  0,  0,  0,  1]]

i = (1,0,0)
j = (1,1,0)
k = (1,1,1)
phi = (0,0,0)

The j-axis is sheared towards the i-axis and scaled by sqrt(2).
The k-axis is sheared towards both the i-axis and the j-axis and scaled by sqrt(3).
The axes are not at right angles to each other. We can check this by using the dot product between the pairs of axes.

Question 2: 3D Rotations

If you rotate a coordinate frame by 90 degrees about x and then rotate the resulting frame by 90 degrees about y, what is the resulting frame? What is the matrix for the combined transformation? What happens if you reverse the order of the rotations?


M = R_x R_y
  =  [1 0  0 0]  [0  0 1 0]
     [0 0 -1 0]  [0  1 0 0]
     [0 1  0 0]  [-1 0 0 0]
     [0 0  0 1]  [0  0 0 1]

  = [0 0 1 0]
    [1 0 0 0]
    [0 1 0 0]
    [0 0 0 1]

i-axis is (0,1,0)
j-axis is (0,0,1)
k-axis is (1,0,0)
i.e. the three axes have been rotated. i->j, j->k, k->i


in the opposite order:

M = R_y R_x
  = [ 0 0 1 0] [1 0  0 0]
    [ 0 1 0 0] [0 0 -1 0]
    [-1 0 0 0] [0 1  0 0]
    [ 0 0 0 1] [0 0  0 1]

  = [ 0 1  0 0]
    [ 0 0 -1 0]
    [-1 0  0 0]
    [ 0 0  0 1]

i-axis is (0,0,-1)
j-axis is (1,0,0)
k-axis is (0,-1,0)



Question 3: 3D Cameras

  1. Consider the following OpenGL code:

    gl.glMatrixMode(GL2.GL_MODELVIEW);
    gl.glLoadIdentity();
    GLU glu = new GLU();
    glu.gluLookAt(0, -3, 3, 0, 1, 0, 0, 0, 1);
    
    gl.glMatrixMode(GL2.GL_PROJECTION);
    gl.glLoadIdentity();
    gl.glOrtho(-4, 4, -3, 3, 1, 4); 
    

    What is the camera's local coordinate frame (in world coordinates) after this call?

    
    The origin is (0, -3, 3).
    
    The k-axis points from the target (0, 1, 0) towards the camera at (0, -3, 3).
    k  = normalise((0, -3, 3) - (0, 1, 0))
       = (0, -4, 3) / sqrt(4*4 + 3*3)
       = (0, -0.8, 0.6)
    
    The i-axis is the cross of the k axis with the up vector (0,1,0)
    i  = normalise(up x k)
       = normalise((0, 0, 1) x (0, -0.8. 0.6))
       = normalise(0.8, 0, 0)
       = (1, 0, 0)
    
    The j-axis is perpendicular to i and k
    j = k x i
      = (0, -0.8, 0.6) x (1, 0, 0)
      = (0, 0.6, 0.8)
    
    

    What is the resulting model-view transform?

    
    The camera-to-world matrix is the combination of the values above
    
    M = [i  j    k   phi]
      = [1  0    0     0]
        [0  0.6 -0.8  -3]
        [0  0.8  0.6   3]
        [0  0    0     1]
    
    The view transform is the inverse of this matrix
    
    V = M-1
      = [1  0   0    0  ]
        [0  0.6 0.8 -0.6]
        [0 -0.8 0.6 -4.2]
        [0  0   0    1  ]
    
    Note: If you do not know how to find the inverse of an arbitrary matrix 
    
    (which you do not need to know how to do for this course) 
    you do in the following way:
    The gluLookAt performs a translation and then a rotation. You can break up the M matrix into 2 parts.
    The matrix M = TR
    where
    T = [1 0 0  0]
        [0 1 0 -3]
        [0 0 1  3]
        [0 0 0  1]
    R = [1    0    0   0]
        [0  0.6 -0.8   0]
        [0  0.8  0.6   0]
        [0  0    0     1]
    
    So to get the inverse matrix we need
    
    V = M-1 = R-1T-1
         
    Inverses of purely rotational matrices can be found by transposing them so
    
    R-1 = [1    0     0   0]
          [0   0.6   0.8  0]
          [0  -0.8   0.6  0]
          [0    0     0   1]
    
    and T-1 = [1 0 0   0]
              [0 1 0   3]
              [0 0 1  -3]
              [0 0 0   1]
    
    Matrix multiplication should give the same answer as above.
    
    
    

    Sketch the view volume in world coordinates.

    The camera is pointing up at angle toward the world Y axis from (0,-3,3) to (0,1,0) (eg like pointing your camera at an angle up towards the ceiling) and the up vector is the z-axis. The view volume is an 8x3x6 rectangular prism centred at (0,-1,1.5) in world co-ordinates (obtained by multiplying matrix for camera to world with the centre in camera coordinates below).

    Sketch the view volume in camera coordinates.

    The orthographic view volume is an 8x6x3 rectangular prism centred at (0,0,-2.5) in camera coordinates, aligned with the camera's coordinate frame.

    What if line 8 were changed to:

    gl.glFrustum(-4, 4, -3, 3, 1, 4); 

    What is the new view volume?

    The perspective view volume is a frustum (truncated pyramid). The near plane a(8x6) rectangle centred at (0,0,-1) in camera coordinates. The far plane is a (32x24) rectangle centred at (0,0,-4) in camera coordinates.

Question 4: Perspective Projections

Consider the following code:

        gl.glMatrixMode(GL2.GL_PROJECTION);
        gl.glLoadIdentity();

        GLU glu = new GLU();
        glu.gluPerspective(60, 1, 1, 10);
        
        gl.glMatrixMode(GL2.GL_MODELVIEW);
        gl.glLoadIdentity();

        gl.glPolygonMode(GL2.GL_FRONT_AND_BACK, GL2.GL_LINE);
        gl.glBegin(GL2.GL_QUADS);
        {
            gl.glVertex3d(1, 1, -2);
            gl.glVertex3d(0, 1, -2);
            gl.glVertex3d(0, 0, -2);
            gl.glVertex3d(1, 0, -2);

            gl.glVertex3d(0, 1, -4);
            gl.glVertex3d(-1, 1, -4);
            gl.glVertex3d(-1, 0, -4);
            gl.glVertex3d(0, 0, -4);
        }
        gl.glEnd();

Question 5: 3D Modeling

Question 6 (advanced - not examinable):

A rotation about any arbitrary axis can be decomposed into a series of rotations about the X, Y or Z axes. How would you compute such a decomposition? (There are many different ways of doing this.)

See http://en.wikipedia.org/wiki/Euler_angles or Euler Angles in the textbook