Matrix Math Jun 08, 2006
Math behind matrices
It's possible to use matrices as a black box. Depending on what you're programming that might be okay, but it couldn't hurt to understand how matrices store transformations. When I started using them in highschool ( wow, that was over a decade ago ) they seemed like magic. In reality though, they aren't that complicated. When I first wrote my own matrix class, I needed to understand how they work, but this knowledge has been helpful in other ways too. Note: I'm using column major matrices here... I think =)
Translation
Translating a point by a vector is easy, just P = P + Translate; The fourth column of the matrix is simply this translation vector. See Tx, Ty, Tz in the matrix in Figure 1. Rotation
Rotation is a bit more tricky. One way to think of rotating a vertex is projecting it onto a new set of axes. For a 3D point, these axes are made up of 3 Orthonormal Basis Vectors. ( This means that each vector is normalized, and independent of the other two.) These are stored in the Matrix in Figure 1 as R1, R2, R3. So for just rotation, a 3x3 matrix will suffice.
Figure 1
Matrix Point Transformed Point | R1x R1y R1z Tx | | X | X = R1 Dot (X,Y,Z) + Tx | R2x R2y R2z Ty | x | Y | Y = R2 Dot (X,Y,Z) + Ty | R3x R3y R3z Tz | | Z | Z = R3 Dot (X,Y,Z) + Tz | 0 0 0 1 | | 1 | W = 1Remember, multiplying matrices is done column times row for each value. If we had put the basis vectors vertically instead of horizontally, it would still be a valid rotation, but in the opposite direction. The transformed point equation in that case would be equivalent to X * vecR1 + Y * vecR2 + Z * vecR3 + vecT Scaling
In rotation, the basis vectors are normalized to be of length 1. If you increase or decrease the magnitude of one of those vectors, it will scale along that axis.
W Coordinate
Why a 4x4 matrix? Do we really need the 4th row of the matrix? For many transformations we don't need it, and it could be left off for a bit of extra speed. What the W coordinate is used for is perspective projection. In homogeneous clip space (0,0) is the center of the screen, the corners are at (-w, -w) and (w, w). We divide each component by w to get the 3d point ( x/w, y/w, z/w ).
You might use this knowledge in a shader. In a vertex shader you transform the vertex into clip space for the renderer. If you send this value through in a tex coordinate, you can use it as an index into a bound screen texture, perhaps used for frame buffer distortion effects. This line converts to range [0,1] texture uv coordinates: Inverting a Matrix
Inverting a 3x3 rotation matrix is done by switching the basis vectors between column vectors and row vectors. To invert the translation vector, we not only take the negative, but also dot it with the inverted basis vectors. The code below is from the Matrix Class.
// Simple but not robust matrix inversion. // (Doesn't work properly if there is a scaling or skewing transformation.) inline CMatrix InvertSimple() const { CMatrix R( 0 ); // Rotation R.mf[0] = mf[0]; R.mf[1] = mf[4]; R.mf[2] = mf[8]; R.mf[3] = 0.0f; R.mf[4] = mf[1]; R.mf[5] = mf[5]; R.mf[6] = mf[9]; R.mf[7] = 0.0f; R.mf[8] = mf[2]; R.mf[9] = mf[6]; R.mf[10] = mf[10]; R.mf[11] = 0.0f; // Translation R.mf[12] = -(mf[12]*mf[0]) - (mf[13]*mf[1]) - (mf[14]*mf[2]); R.mf[13] = -(mf[12]*mf[4]) - (mf[13]*mf[5]) - (mf[14]*mf[6]); R.mf[14] = -(mf[12]*mf[8]) - (mf[13]*mf[9]) - (mf[14]*mf[10]); R.mf[15] = 1.0f; return R; } |