
Notes for February 20 class  Matrices
In class we
gave a visual explanation for how we derived the
solution to a ray intersecting a sphere.
Then we finished going over the basic matrix primitives
(identity, translate, rotate about x,y,z, scale).
Detailed notes about that follow below.
Then we showed how to send matrix values from your
javascript program in the CPU down to
your shader in the GPU.
A version of the program we developed in class
to do this is
here.
At the end of class we saw the video
Carlitopolis.
Homework (due before class next Tuesday):
In Javascript implement the matrix primitives
identity, translation, rotation about x,y, and z, and scale.
Then, starting with a ray traced scene of at least two spheres,
show that you can transform the center location of each sphere in
your scene using the matrix primitives that you have implemented.
Extra credit:
 Implement matrix multiplication, using the math at the bottom of
these notes,
and use it to show that you can transform by more than one matrix
(eg: combining translation with rotation, or rotation about
two different axes).
 Pass into the shader not just one matrix, but an array of matrices.
Transform different sphere centers by
different matrices in your array of matrices.
Transformation matrices
All of the information of a coordinate transformation
can be placed in a 4×4 matrix, as shown in the
figure to the right.
The x, y and z axes form the first three respective
columns of the matrix.
The origin t forms the rightmost column of the matrix.
In this class we will follow the convention of storing
the 16 matrix values in columnmajor order:
[
x_{0},
x_{1},
x_{2},
x_{3},
y_{0},
y_{1},
y_{2},
y_{3},
z_{0},
z_{1},
z_{2},
z_{3},
t_{0},
t_{1},
t_{2},
t_{3}
]



Transforming a point
We can use a 4×4 matrix to transform a vector.
By convention, we represent the input as a column vector, and place it to the right of the matrix.
Also, by convention, if we omit the fourth (homogeneous) coordinate of the input,
as in the example to the right,
we assume a value of 1.0 for its homogeneous coordinate,
unless otherwise specified.
The result of the transformation is another column vector,
which we obtain by taking the inner product
of each successive row of the matrix with the input vector.
In this case, the matrix is rotating the point (1,0,0) about the z axis.



The identity transformation
The identity matrix is the "do nothing" transformation.
It will transform any point or direction to itself.
You generally want to call the identity() method on a matrix
object to initialize that matrix.



The translate transformation
To translate a point, we use only the rightmost column of the matrix.
The rest of the matrix is the same as the identity matrix.
1
 0
 0
 T_{x}


0
 1
 0
 T_{y}


0
 0
 1
 T_{z}


0
 0
 0
 1


Note that translation affects only points, not directions.
Because the homogeneous coordinate of a direction is zero,
its value cannot be affected by the rightmost column of the matrix.



Rotate about the x axis
Rotation about the x axis only affects the y and z axes.
1
 0
 0
 0


0
 cosθ
 sinθ
 0


0
 sinθ
 cosθ
 0


0
 0
 0
 1


"Positive" rotation is counterclockwise
when looking from the positive x direction.



Rotate about the y axis
Rotation about the y axis only affects the z and x axes.
cosθ
 0
 sinθ
 0


0
 1
 0
 0


sinθ
 0
 cosθ
 0


0
 0
 0
 1


"Positive" rotation is counterclockwise
when looking from the positive y direction.



Rotate about the z axis
Rotation about the z axis only affects the x and y axes.
cosθ
 sinθ
 0
 0


sinθ
 cosθ
 0
 0


0
 0
 1
 0


0
 0
 0
 1


"Positive" rotation is counterclockwise
when looking from the positive z direction.



The scale transformation
Like rotation, a scale transformation (which makes shapes bigger or smaller)
uses only the topleft 3×3 portion of the 4#215;4 matrix.
S_{x}
 0
 0
 0


0
 S_{y}
 0
 0


0
 0
 S_{z}
 0


0
 0
 0
 1


In the case illustrated on the right, we are performing a uniform
scale, by using the same values for the three locations
along the diagonal of the matrix.
If we were to use differing values at these three locations,
then we would perform a nonuniform scale,
which would result in the shape becoming squashed or stretched.



Matrix multiply
In order to form composite matrices from these primitives,
we need to be able to multiply matrices.
Matrix multiplication A × B between two matrices A and B proceeds
by multiplying each of the four row vectors that constitute A
by each of the four column vectors that constitute B:
C

=

A_{0,0} 
A_{1,0} 
A_{2,0} 
A_{3,0} 
A_{0,1} 
A_{1,1} 
A_{2,1} 
A_{3,1} 
A_{0,2} 
A_{1,2} 
A_{2,2} 
A_{3,2} 
A_{0,3} 
A_{1,3} 
A_{2,3} 
A_{3,3} 

×

B_{0,0} 
B_{1,0} 
B_{2,0} 
B_{3,0} 
B_{0,1} 
B_{1,1} 
B_{2,1} 
B_{3,1} 
B_{0,2} 
B_{1,2} 
B_{2,2} 
B_{3,2} 
B_{0,3} 
B_{1,3} 
B_{2,3} 
B_{3,3} 

So the value of any entry in the result matrix C_{col,row} is:
C_{col,row} =
A_{(0,row)} B_{(col,0)} +
A_{(1,row)} B_{(col,1)} +
A_{(2,row)} B_{(col,2)} +
A_{(3,row)} B_{(col,3)}

 