Matrices are useful in 3d graphics. Not only are they fast, but once you get used to them, it makes things a lot simpler. Matrices are better than standard equations for these reasons:
For this article, I'm going to discuss matrices and their applications. I'm gonna start with the use of matrices in solving systems of linear equations, the basic operations on matrices and their applications in 3d graphics. I might be able to put in some code and algos in between. Don't worry, matrices are not as hard as you thought they are. :*). I'm gonna be discussing those things you'd need in making a 3d game engine using matrices. Which means that most matrix stuff I'm going to include in here are the easy ones. So without further ado....
Remember the linear equation...
No? How about this?
These two equations are just two of the many forms of linear equations. The first one (ax+by=c) is the "standard" form and y=mx+b is the "slope-intercept" form. We'll be discussing the standard form when dealing with matrices.
Given 2 equations:
and
How do you get the solution to both equations? The solution is actually the "intersection" of both lines defined by the above equations. For those who have done some algebra, we know that there are a number of ways to find the solution.
They are:
Solving via elimination:
Make the coeficients of x the same by multiplying equ 1 by 3 and equ 2 by 2 then subtract.
Using back substitution (equ 1):
The solution is (2,1)
However when made into code, this is very cumbersome and not flexible. What we need is an algorithmic way to solve the system. And the answer is the matrix. How do we go about solving this system using a matrix? First let me discus the ECHELON method of solving this system, as it's almost parallel to the matrix method except for the last part.
Solving via the Echelon method:
Multiply both sides of equ 1 by 1/2 so that x will have a coefficient of 1.
Eliminate x from equ 2 by adding (-3) times equ 3 to equ 2.
Using back substitution in equ 1, x = 2. Look at the coefficients of x and y. They both have coefficients of 1 arranged diagonally. ie..
This is called the TRIANGULAR or LOW ECHELON form of the system. Be sure to remember this as we well be encountering this a lot of times. And now, what you've been waiting for!!!!
Solving the system the Matrix way!!!
Rules:
We first write the system in rows and columns. This is called the AUGMENTED matrix. Be sure that each equation is in standard form (ax + by = c).
* This is parallel to the Echelon method above so be sure to check from time to time.
2 | -3 | 1 |
3 | 2 | 8 |
*Note we only used the numeric coefficients.
*2, -3, 1 , 3, 2 and 8 are called the ELEMENTS of the matrix and 2 is located at row1,col1; 8 at row2, col3; and so on...
To get 1 in row1, col1 we multiply the first row by 1/2.
1 | -3/2 | 1/2 |
3 | 2 | 8 |
Add (-3) times the elements of row1 to row2.
1 | -3/2 | 1/2 |
0 | 13/2 | 13/2 |
To get 1 in row 2, col 2; multiply row 2 by the reciprocal of 13/2 which is 2/13.
1 | -3/2 | 1/2 |
0 | 1 | 1 |
So...
See, triangular form!!! Use back substitution to get x.
I'll test your skills with a 3-equation system:
We don't need to change the element i r1,c1 since it's already 1. BTW, you can interchange any rows as you like if it makes the solution easier (Rule A).
Augmented matrix:
1 | 1 | -1 | 6 |
2 | -1 | 1 | -9 |
1 | -2 | 3 | 1 |
Eliminate the first element in row 2 by adding (-2) x row 1 to row 2.
1 | 1 | -1 | 6 |
0 | -3 | 3 | -21 |
1 | -2 | 3 | 1 |
Eliminate the first element in row 3 by adding (-1) x row 1 to row 3.
1 | 1 | -1 | 6 |
0 | -3 | 3 | -21 |
0 | -3 | 4 | -5 |
To get 1 in row2,col2; Multiply row 2 by -1/3.
1 | 1 | -1 | 6 |
0 | 1 | -1 | 7 |
0 | -3 | 4 | 7 |
Eliminate the second element in row 3 by adding (3) x row 2 to row 3.
1 | 1 | -1 | 6 |
0 | 1 | -1 | 7 |
0 | 0 | 1 | 16 |
Translating this matrix to equation form:
(This is the triangular form of the equations)
*The method I discussed above is called the "GAUSSIAN REDUCTION". If you don't know who Karl F. Gauss is then this article is not for you. :*) j/k
It is customary to name Matrices with capital letters. The following is Matrix A.
A = |
|
With this notation, the first row and first column is a11 (read: "a sub one-one").
Matrices are classified according to size(by the number of rows and columns they contain). For example matrix A is a 4 x 4 Matrix. On the other hand our matrix solution above is a 2 x 3 matrix:
1 | -3/2 | 1/2 |
0 | 1 | 1 |
Certain matrices have special names like a SQUARE matrix as in 3 x 3, 2 x 2, Basically the same number of row and columns. A ROW matrix on the other hand is just a matrix of one row. Guess what a COLUMN matrix is? :*)
To add two matrices together, add their corresponding elements. ONLY MATRICES OF THE SAME SIZE CAN BE ADDED. Same goes for subtraction.
5 | -6 |
8 | 9 |
+
-4 | 6 |
8 | -3 |
=
5+(-4) | -6+6 |
8+8 | 9+(-3) |
=
1 | 0 |
16 | -6 |
To multiply a scalar value by a matrix, you just multiply all elements of the matrix by the scalar value.
5 * |
| = |
|
RULE: You can only multiply matrices if A has the same number of columns as B. ROW by COLUMN. Ohh this is gonna be *messy*. :*)
Given:
A = |
|
B = |
|
Locate row1 of A and col1 of B, then multiply corresponding elements and add the products.
Row 1 of A
-3 | 4 | 2 |
*
Column 1 of B
6 | 2 | 3 |
=
|
+ |
|
+ |
|
= |
|
Next Row1 of A by Col2 of B
|
+ |
|
+ |
|
= |
|
Row 2 of A and Col 1 of B
|
+ |
|
+ |
|
= |
|
Lastly, Row 2 of a and col 2 of B
|
+ |
|
+ |
|
= |
|
The product matrix:
32 | -4 |
-18 | 12 |
In general...
Cij = Ai1 * B1j + Ai2 * B2j ...For Square matrices, there are two ways to multiply as they have the same number of rows and columns. Warning: Multiplication of matrices is not commutative.
So in two 4*4 matrices, the resulting matrix is calculated as...
Now that we know how to do stuff with matrices, we will now learn its applications is 3d graphics!!!! Woot!!!
In 3d graphics its often easier to make the origin(0,0,0) as your viewpoint. ie. Where the lens of your camera is (The LEFT-HANDED system lends itself well with this if you want to make a doom-like engine). Instead of making the camera move around your world, you can make your world move around the camera. Relativity at its best!!!
Unless you want to do shearing and some other special effects, it's convenient to represent your 3d point/vector as [x y z]. I like to make this vector as a column matrix (see column matrix above). Modifying the points position is space requires another matrix. For simplicity, I'll make the the transfomation matrix a ROW matrix, [A B C]. To transform a point, you just multiply the our [x,y,z] vector with the with our ROW matrix. Remember our matrix multiplication property? COLUMN x ROW.
|
* |
|
Now if a = 1, b=0, c=0
If a = 0, b=1, c=0
If a = 0, b=0, c=1
In matrix form:
|
|
*Notice how it looks like the "Triangular" form of the matrix. :*)
So to transform and entire 3d point by the vector matrix using the matrix notation above, you just multiply the point vector by the matrix.
*x',y',z' are the new points.
|
* |
|
= |
|
=
Now as we will be using a 4x4 matrix, let me introduce you to the matrices we'll be using.
Our initial "do-nothing" matrix. This means that it will produce exactly the same values as was before the transform. We always begin with this matrix.
|
|
Unless you'd want to do some nasty FX like shearing, etc., the last row is always 0 0 0 1.
Scales the matrix by sx, sy and sz.
|
|
Translation means just to "move" the point by Tx, Ty, Tz.
|
|
Rotates the points in the x-axis by angle.
ca = COS(angle)
sa = SIN(angle)
|
|
|
|
|
|
Note that the axis of rotation is NOT being transformed in the 3 rotational matrices. Now with all the abstract math out of the way, the fun part....
To make a 3d object rotate around space using matrices, you just combine all the transformation matrices into one final parent matrix and use that matrix to transform your points. Here's the pseudo code:
*Codes 2 to 9 can be interchanged in any way you want. If you have normals you'd like to rotate, you can use the same transformation matrix to rotate them. I urge you to experiment and play with the order of operations so that you may see how it changes the entire transformation.
Here's the working QB code for you to enjoy:
matrix.bas
As an excersise, why don't you make a gouraud filled polygon using matrices to rotate your model and normals? Be sure to rotate with the same matrix.
You might say, "But your rotation tutorial has some very fast ready-made matrix constants. It's also fairly faster as we don't have to multiply matrices." Yes those constants are faster than the matrix method but they are limited. Here are some limitations:
Some of you may have already seen matrices defined like this:
Translation matrix:
1 | 0 | 0 | 0 |
0 | 1 | 0 | 0 |
0 | 0 | 1 | 0 |
Tx | Ty | Tz | 1 |
This is the DirectX and OpenGL system of matrices where rows are swapped with the columns. So be sure to use this system if you're coding via DX or OGL. I'm using the "standard" math notation in this article.
Credits:
Mark Feldman for his matrix doc. (I was having problems with the rotation matrices until I read your doc. Thanks!!!)
Plasma for SetVideoSeg
wildcard for this "series" idea.
Hugo Elias for his WuPixel doc.
Toshi for his kind comments.
3D ica for their excellent doc.
And you the reader of this doc.
Biskbart for the torus.
Happy Coding!!!!
Richard Eric M. Lope (Relsoft)
http://rel.betterwebber.com/
vic_viperph@yahoo.com
*For questions and suggestions, I hang out at the qbasicnews.com forum at http://forum.qbasicnews.com.
Author: | Rel (Richard Eric M. Lope) |
Email: | vic_viperph@yahoo.com |
Website: | http://rel.betterwebber.com/ |
Released: | 2004 |