Matrix Operations
Addition, Negation, Subtraction and Scaling
Nothing much needs to be said about these operations. The procedures for adding, negating,
subtracting and scaling matrices are the same as those for simple vectors. Actually, the
need to do any of these operation on matrices is fairly uncommon.
Matrix Multiplication
In general, the result of multiplying one matrix with another is formed from dot products of
the left matrix's rows and the right matrix's columns. For this reason the width of the left
matrix and the height of the right matrix must be equal. The ‘free’ dimensions,
the height of the left matrix and the width of the right matrix define the height and width
of the result.
Matrices are commonly used to transform the positions of vertices in 3D
graphics. Possible transformations include scaling, shearing and rotation in any combination.
The transformation is achieved by multiplying each vertex's position vector (itself a kind of
matrix) with the transformation matrix to form a new set of vertices.
To multiply a matrix and a vector, assemble a new vector from the dot products of successive
rows of the matrix and the original vector. Strictly speaking, you're supposed to transpose
the rows you extract from the matrix so they become column vectors. The dot product function
needs two column vectors to work with. That's just prissy talk, really, when you can run your
left finger across rows of the matrix and your right finger down the column of the vector
as you perform the dot product operation.
| P′ |
= TP |
|
| = |
 | |  |
 |
T₁₁ | | T₁₂ | | T₁₃ |
 |
| T₂₁ | T₂₂ | T₂₃ |
| T₃₁ | T₃₂ | T₃₃ |
 | |  |
|
|
|
|
|
|
| = |
 | |  |
 |
T₁₁Px+T₁₂Py+T₁₃Pz |
 |
| T₂₁Px+T₂₂Py+T₂₃Pz |
| T₃₁Px+T₃₂Py+T₃₃Pz |
 | |  |
|
Matrix multiplication is associative, even when the terms are a mixture
of matrices and vectors. A transformation T₁, followed by another
transformation T₂, then by T₃, all to be performed
on a vector P may be written like this:
P‴ = T₃T₂T₁P
= T₃(T₂(T₁P))
= (T₃T₂T₁)P
The last one is interesting because it shows that successive transformations can be
combined into one matrix. This is handy when you have to perform compound transformations
on thousands of vertices in a 3D program, say. You just have to know how to multiply one
matrix by another.
The product of two matrices is calculated like this: Each entry in the product is positioned
at some row i and some column j. Take row i from the left-hand matrix and transpose it. Now
find the dot product of that and a column j taken from the right-hand matrix. That is the
value of the entry at row i, column j. Repeat for the remaining entries.
 | |  |
 |
A₁₁ | | A₁₂ | | A₁₃ |
 |
| A₂₁ | A₂₂ | A₂₃ |
| A₃₁ | A₃₂ | A₃₃ |
 | |  |
|
 | |  |
 |
B₁₁ | | B₁₂ | | B₁₃ |
 |
| B₂₁ | B₂₂ | B₂₃ |
| B₃₁ | B₃₂ | B₃₃ |
 | |  |
|
= |
 | |  |
 |
Arow1T·Bcol1 | | Arow1T·Bcol2 | | Arow1T·Bcol3 |
 |
| Arow2T·Bcol1 | Arow2T·Bcol2 | Arow2T·Bcol3 |
| Arow3T·Bcol1 | Arow3T·Bcol2 | Arow3T·Bcol3 |
 | |  |
|
OpenGL transformations
The graphics API OpenGL actually performs its transformations in reverse order to the
sequence of tranformation commands in the program. This might seem a horribly backward way
of doing things but actually leads to a simple interpretation of the transformations.
In OpenGL, each successive transformation command moves the coordinate system around relative
to the previous one. The camera transform changes the coordinate system from
the default Right, Up, Back to East, North, Up in metres, say. A translation to an aircraft's
position in the world and a suitable rotation transform changes the current coordinate
system to Starboard, Forward, Up, say. The plane may be drawn using its natural coordindates.
Translate and rotate to the position and orientation of a laptop carried abord the plane and
apply a suitable scale transform to change the cuurent coordinate system to the virtual
laptop's screen, so that (0, 0, 0) is at the top left of the laptop's screen and
(640, 480, 0) is at the bottom right. Assuming your camera is set up to see the
laptop's screen, perhaps though the aircraft's window, further drawing commands will behave
as if it's the virtuallaptop you're drawing to, not your real computer display.
The combined transformation matrix is a product of the camera matrix, some translations,
rotations and a scale for the laptop's screen's resolution:
Mcombined = CTaircraftRaircraftTlaptopRlaptopSlaptop
That looks great and even reads left-to-right in the same order as the transformation
cammands given in OpenGL code. Hang on! looking at the expression
"T₃(T₂(T₁P))" as described
in the previous section, aren't the OpenGL vertices first transformed by Slaptop
and last transformed by C, the camera's tranformation matrix?
Yes, they are. When you look at the transformation matrices in right-to-left order,
each transformation is applied to the vertices about a fixed coordinate system aligned
to the (real) computer display. When you look the same matrices in left-to-right order,
each transformation shifts the coordinate system around relative in position, orientation
and scale to the previous one.
When a transformation command given to OpenGL, the transform's matrix is cunningly
postmultiplied to the current ‘modelview’ matrix. The combined
transformation then used to transform the OpenGL vertices by the usual way, by
matrix premultiplication of the vertices. This is how OpenGL handles the moving
reference frame method of specifying transformations.
Hopefully, you now understand the order of transformations in a product of
transformation matrices, whether you regard transformations as something that happens
to vertices about a fixed, global reference frame, or as a way of specifying
successively local coordinate systems on which new vertices can be specified.
Transposing a Matrix
Tranposing a matrix is almost as trivial as tranposing a vector, Take the first
row of the original matrix, transpose it and use it for the first column of the the
tranposed matrix. Repeat for the other rows. ATcol(n) =
Arow(n)T.
 | |  |
T |
 |
spam | | eggs | | biscuits |
 |
| sausage | beans | brain |
 | |  |
|
= |
 | |  |
 |
spam | | sausage |
 |
| eggs | beans |
| biscuits | brain |
 | |  |
|
It happens that AB = (BA)T. Matrix multiplication is not
commutative.
The inverse of a rotation matrix can be found simply by transposing the matrix. This is
handy to know, since finding the inverse of any old matrix is often laborious.
2D Matrix Transformations
The 2D identity matrix and the general form of the three basic transformation matrices are listed below.
The blue grids and axes indicate the transformed positions of the vertices taken from the
green grids. A point (2,1), say, on the green xy grid, represented as a vector
[2 1]T is transformed to the point (2, 1) om the blue
x′y′ grid.
In OpenGL, the blue grids and axes show the new coordinate system relative to the
previous one, after the transformation command is issued.
The inverse of each matrix is also given. An inverse transformation matrix can be used to
undo the original transformation, though in OpenGL it's usually faster and easier to simply
use the matrix push and pop commands.
| Transformation |
Description |
Matrix |
Inverse |
 |
|
Identity (Nothing happens) |
|
|
|
Scaling (scale = 0.5) |
|
|
|
Shearing along x (x-shear = 0.6) |
|
|
|
Rotation (θ = 30°) |
|
|
Finding the inverse of an arbitrary matrix can be a bit of a hassle, and if you can understand statements
like the inverse of a matrix A is the matrix formed from A's cofactors,
transposed and scaled by the inverse of the determinant of A and the
determinant of the matrix A can be found by cofactor expansion along any row or column
of A, you probably know more about linear algebra than what these web pages have
to offer. At least the inverse of any rotation matrix is trivial to find. The inverse of a rotation matrix
is its transpose.
What about Translation?
It would seem that displacing all the vertices equally or moving the origin to a new location would be
easy. Translation via matrix multiplication is actually impossible. Never mind that OpenGL can perform
translation with a matix. It's still impossible. Notice how the origin in each of the diagrams above
are unaffected by the transformations. That's because it's full of zeros and can't be multiplied by
anything to form a product that isn't also full of zeros. Translation can only be performed
by adding a displacement vector to the position vector of each vertex you come across.
The impossibility of a translation matrix would seem to limit the usefulness of matrix multiplication since
commonly required transformations involve translations upon rotations upon more translations and
yet more rotations with a bit of scaling thrown in somewhere. A single matrix that combines these
transformations cannot exist, and performing multiple matrix operations and vector additions is
computationally exorbitant.
The page on Homogeneous Matrices
describes how translation with a matrix can be done. Prepare to breakfast at Milliways
or at least lose a few sanity points.
3D Matrix Transformations
The 3D matrices for scaling and shearing, apart from being 3×3 in size, are trivially different from
the ones used for 2D transformations. The 3D identity matrix is just a fatter version of the 2D one:
The only 3D transformation matrices that require a bit of thought are the ones used for rotation.
Rotation about a principal axis
Rotation about a principal axis in 3D is really a rotation in a plane formed by two other axes. It's not hard
to see that the matrices below are copies of the 2D rotation matrix padded out with extra ones and zeros.
| Matrix |
|
Description |
 |
 | |  |
 |
1 | | 0 | | 0 |
 |
| 0 | cosθ | ⁻sinθ |
| 0 | sinθ | cosθ |
 | |  |
|
Rotation by θ about x |
 | |  |
 |
cosθ | | 0 | | ⁻sinθ |
 |
| 0 | 1 | 0 |
| sinθ | 0 | cosθ |
 | |  |
|
Rotation by θ about y |
 | |  |
 |
cosθ | | ⁻sinθ | | 0 |
 |
| sinθ | cosθ | 0 |
| 0 | 0 | 1 |
 | |  |
|
Rotation by θ about z |
By multiplying all three of these matrices, with appropriate values of θ for
each, it's possible to come up with a matrix that can be used to transform a set of vertices to any new
orientation, given those three euler angles.
Describing orientation with euler angles is useful for jointed objects such
as gun turrets, cameras on dollies and other gimbled bits of machinery. Most
such machinery have pitch upon yaw or roll upon pitch upon yaw.
Rotation about an arbitrary axis through the origin
This is best done with quaternion rotation, whatever
quaternions are, exactly. Although the maths looks daunting, it's
not really all that computationally expensive.
Let A be a unit vector that lies in the axis of rotation.
Let θ be the rotation angle.
This rotation can be described as a quaternion, Q where
| Qx = Axsin( |
| θ |
 |
| 2 |
|
), |
|
| Qy = Aysin( |
| θ |
 |
| 2 |
|
), |
|
| Qz = Azsin( |
| θ |
 |
| 2 |
|
), |
|
| Qw = cos( |
| θ |
 |
| 2 |
|
) |
|
This rotation quaternion can be converted into an equivalent matrix, T.
sx = 2Qx,
sy = 2Qy,
sz = 2Qz
wx = sxQw,
wy = syQw,
wz = szQw
xx = sxQx,
yy = syQy,
zz = szQz
xy = syQx,
yz = szQy,
zx = sxQz
| T = |
 | |  |
 |
1 − (yy + zz) | | xy + wz | | zx − wy |
 |
| xy − wz | 1 − (xx + zz) | yz + wx |
| zx + wy | yz − wx | 1 − (xx + yy) |
 | |  |
|
Rotation about an arbitrary axis anywhere
Consider a point P that lies on the axis of rotation. For each vector to be
transformed, subtract P so that P becomes the new origin, rorate
about the origin as usual, then add P to the rotated vector to restore the
original origin.
In OpenGL, simply translate by P, do the rotation, then translate by ⁻P.
Homogeneous Matrices
Read all about them on the next page.