Hey there! This tutorial is for those who are new to 3D programming, and need to brush up on that math. I will teach you two primary things here, Vectors and Matrices (with determinants). I'm not going to go into everything, so this isn't designed as a standalone reference. A lot of mathematics books can probably discuss this much better, but anyway, without further ado, lets get on with it shall we?
Vector basics – What is a vector?
Vectors are the backbone of games. They are the foundation of graphics, physics modelling, and a number of other things. Vectors can be of any dimension, but are most commonly seen in 2 or 3 dimensions. I will focus on 2D and 3D vectors in this text. Vectors are derived from hyper-numbers, a sub-set of hyper-complex numbers. But enough of that, you just want to know how to use them right? Good.
The notation for a vector is that of a bold lower-case letter, like i, or an italic letter with an underscore, like i. I'll use the former in this text. You can write vectors in a number of ways, and I will teach you 2 of them: vector equations and column vectors. Vectors can also be written using the two end points with an arrow above them. So, if you have a vector between the two points A and B, you can write that as .
A vector equation takes the form a= xi + yj + zk
i, j and k are unit vectors in the 3 standard Cartesian directions. i is a unit vector aligned with the x axis, j is a unit vector aligned with the y axis, and k is a unit vector aligned with the z axis. Unit vectors are discussed later.
The coefficients of the i, j and k parts of the equation are the vector's components. These are how long each vector is in each of the 3 axes. This may be easier to understand with the aid of a diagram.
This diagram shows a vector from the origin to the point ( 3, 2, 5 ) in 3D space. The components of this vector are the i, j and k coefficients ( 2, 3 and 5 ). So, in the above example, the vector equation would be:
a = 2i + 3j + 5k
This can also be related to the deltas of a line going through 2 points.
The second way of writing vectors is as column vectors. These are written in the following form
where x, y and z are the components of that vector in the respective directions. These are exactly the same as the components of the vector equation. So in column vector form, the above example could be written as:
There are various advantages to both of the above forms, but I will continue to use the column vector form, as it is easier when it comes to matrices. Position vectors are those that originate from the origin. These can define points in space, relative to the origin.
You can manipulate vectors in various ways, including scalar multiplication, addition, scalar product and vector product. The latter two are extremely useful in 3D applications.
There are a few things you should know before moving to the methods above. The first is finding the modulus (also called the magnitude) of a vector. This is basically its length. This can be easily found using Pythagorean theorem, using the vector components. The modulus of a is written |a|.
in 3D and in 2D, where x, y and z are the components of the vector in the 3 axes of movement. Unit vectors are vectors with a magnitude of 1, so |a| = 1.
Vector addition is pretty easy. All you do is add the respective components together. So for instance, take the vectors:
The addition of these vectors would be:
Get it? This can also be represented very easily in a diagram, but I will only consider this in 2D, because it's easier to draw.
This works in the same way as moving the second vector so that its beginning is at the first vector's end, and taking the vector from the beginning of the first vector to the end of the second one. So, in a diagram, using the above example, this would be:
This means that you can add multiple vectors together to get the resultant vector. This is used extensively in mechanics for finding resultant forces.
Subtracting is very similar to adding, and is also quite helpful. All you do is subtract the components in one vector from the components in the other. The geometric representation however is very different.
The visual representation of this is:
Here, a and b are set to be from the same origin. The vector c is the vector from the end of the second vector to the end of the first, which in this case is from the end of b to the end of a. It may be easier to think of this as a vector addition.
Where instead of having:
c = a – b
c = -b + a
which, according to what was said about the addition of vectors would produce:
You can see that putting a on the end of –b has the same result.
Scalar multiplication is easy to come to grips with. All you do is multiply each component by that scalar.
So, say you had the vector a and a scalar k, you would multiply each component by the scalar, getting this result:
This has the effect of lengthening or shortening the vector by the amount k. For instance, take k = 2; this would make the vector a twice as long. Multiplying by a negative scalar reverses the direction of the vector. You can use scalar multiplication to find the unit vector of another vector. So, take the following example:
To find the unit vector of this, we would divide a by |a|. Calling the unit vector "b":
That is the unit vector b in the direction of a. This just scales each of the components, so that the magnitude is equal to 1.
Scalar multiplication is also used in the vector equation discussed earlier. The constants x, y and z are the scalars that scale the i, j and k vectors, before adding them to find the resultant vector.
The Scalar Product (Dot Product)
The scalar product, also known as the dot product, is very useful in 3D graphics applications. The scalar product is written and is read "a dot b".
The definition the scalar product is the following:
Where q is the angle between the 2 vectors a and b. This produces a scalar result, hence the name scalar product. From this you can see that the scalar product of 2 parallel unit vectors is 1, as |a||b| = 1, and cos(0) also is 1. You should also have seen that the scalar product of two perpendicular vectors is 0, as cos(90) = 0, which makes the rest of the expression 0. The geometric interpretation is:
The scalar product can also be written in terms of Cartesian components., I will not go into how this is derived, but the final, simplified formula of a.b is:
We can now put these two equations equal to each other, yielding the equation:
With this, we can find angles between vectors. This is used extensively in the lighting part of the graphics pipeline, as it can see whether a polygon is facing towards or away from the light source. This is also used in deciding what side of planes points are on, which is also used extensively for culling.
The Vector Product (Cross Product)
The vector product, which is also commonly known as the cross product is also useful. The vector product basically finds a vector perpendicular to two other vectors. Great for finding normal vectors to surfaces.
For those that are already familiar with determinants, the vector product is basically the expansion of the following determinant:
For those that aren't, the vector product in expanded form is:
Read "a cross b".
Since the cross product finds the perpendicular vector, we can say that:
i x j = k
j x k = i
k x i = j
Using scalar multiplication along with the vector product we can find the "normal" vector to a plane. A plane can be defined by two vectors, a and b. The normal vector is a vector that is perpendicular to a plane and is also a unit vector. Using the formulas discussed earlier, we have:
This first finds the vector perpendicular to the plane made by a and b then scales that vector so it has a magnitude of 1. Note however, that there are 2 possible normals to the plane defined by a and b. You will get different results by swapping a and b in the vector product. That is:
This is a very important point. If you put the inputs the wrong way round, the graphics API will not produce the desired lighting, as the normal will be facing in the opposite direction.
The Vector Equation of a Straight Line
The vector equation of a straight line is very useful, and is given by a point on the line and a vector parallel to it:
Where p0 is a point on the line and v is the vector. t is called the parameter, and scales v. From this it is easy to see that as t varies, a line is formed in the direction of v. If t only takes positive values, then p0 is the starting point of the line. Diagrammatically, this is:
In expanded form, the equation becomes:
This is called the parametric form of a straight line.
Using this to find the vector equation of a line through two points is easy:
If t is confined to values between 0 and 1, then what you have is a line segment between the points p0 and p1.
Using the vector equation we can define planes, and test for intersections. I won't go into planes much here, as there are many tutorials on them elsewhere, I'll just skim over it.
A plane can be defined as a point on the plane, and two vectors that are parallel to the plane, or:
where s and t the parameters and u and v are the vectors that are parallel to the plane. Using this, it becomes easy to find the intersection of a line and a plane, because the point of intersection must lie on both the line and the plane, so we simply make the two equations equal to each other.
Take the line:
and the plane:
To find the intersection point we simply equate, so that:
Ed. note: The v on the left in the above equation is not the same vector as the v on the right.
We then solve for w, s and t, and then plug into either the line or plane equation to find the point. When testing for a line segment intersection, w must be between 0 and 1.
There are many benefits for using the normal-distance form of a plane too. It's especially useful for testing what sides of a plane points or other shaped objects are. To do this, you dot the normal vector and the position vector of the point being tested, and add the distance of the plane from the origin.
So, if you have the plane
and the point ( x, y, z ), the point is in front of the plane if
and behind if it is < 0. If the result equals zero, the point is on the plane. This is used heavily in culling and BSP trees.