- The Ultimate 3D Coding Tutorial (C) Ica /Hubris 1996,1997,1998
- Over 150k of pure sh...er, 3d coding power!
1 Vector and Matrix Algebra
Vectors are lines which have a constant direction and length (or
magnitude), and can be moved arbitrarily in a given coordinate system.
A vector is drawn as in the following picture (a short perpendicular line
(not necessary) at the starting point, and an arrowhead at the ending point):
Vectors are usually marked the same way as the coordinates of a point:
a=(x1,y1,z1), where x1 is the x-axis vector coefficient, y1 and
z1 respectively. This vector a can be drawn so that we draw a point
into the coordinates (x1,y1,z1), and a line from the origin to that point.
The x-, y-, and z-axis unit vectors (vectors that have a length
of one) have their own special symbols: i, j, and k,
respectively. So the x-axis unit vector is i=(1,0,0), etc.
Vectors are marked as alphabetical symbols with a line over them, or
the symbol being written with a bold font. I'm naturally using here the
1.1.2 Vector equation
Now we'll calculate the equation of a vector AB. If the point A
is (Ax,Ay,Az), and the point B (Bx,By,Bz), where x, y, and z are subscripts,
the equation of AB (the vector which starts in the point A and ends
in the point B that is) is
AB = (Bx-Ax,By-Ay,Bz-Az)= (X,Y,Z).
This means that the direction of a vector is found by taking an arbitrary
point and then going X units from that point to the direction of the x-axis,
then Y units to the direction of the y-axis, and finally Z units to the
direction of the z-axis. When we draw a line between this point and the
first point, we've got the vector whose equation is (X,Y,Z). Note!
The starting point is always substracted from the ending
1.1.3 Vector length
The length of the vector AB is marked as the vector's absolute value
and calculated by adding the squares of its terms together and taking a
square root of the result:
|AB| = sqrt( X^2 + Y^2 + Z^2 ).
This is the same equation as the distance between the point (X,Y,Z) and
An unit vector is a vector whose length is one. We can calculate
an unit vector from a vector by dividing all the terms of the vector by
the length of the vector.
Calculating a vector's length is needed for example with phong shading
and vertex normal calculation.
Problem: Let a = (1,1,1). Derive the unit vector
which is parallel to a.
|a| = sqrt ( 1^2 + 1^2 + 1^2 ) = sqrt(3),
the unit vector which is parallel to a:
1/sqrt(3)*(1,1,1) = ( 1/sqrt(3) , 1/sqrt(3) , 1/sqrt(3) ).
1.1.4 Vector addition
Vector addition is performed by adding the terms together. Substraction
respectively, but a negative vector points to the opposite direction than
a positive vector.
a + b = (Ax+Bx,Ay+By,Az+Bz).
Problem: Let a = (2,-6) and b = (1,3). Calculate
| 2a - b |.
2a = (2*2,2*(-6)) = (4,-12).
2a-b = (4-1,-12-3) = (3,-15).
|2a-b| = sqrt( 3^2 + (-15)^2 ) = sqrt(9+225) = sqrt(234).
1.1.5 Dot product
One vector can be multiplied by another by two ways, and the first one
is called the dot product (or scalar product if you wish). A dot
product is read like "a dot b" and it is calculated by multiplying
the length of a by the length of b and by the cosine of the
angle between the two vectors. Another way to calculate it is to multiply
the terms of the two vectors together and to add the products together.
The geometric meaning of dot product is the length of a projected
to b. Note! The angle between the two vectors means
always the smaller one between them when the two vectors start from the
a dot b = |a||b|cos(a,b)=
Ax*Bx + Ay*By + Az*Bz
Cos(a,b) means the angle alpha.
Note! Vectors are perpendicular when the angle between
them is 90 degrees (cos90 = 0 -> a dot b = 0)!
Dot product is needed for example in phong illuminating and many other
light manipulation operations.
Problem: Calculate the angle between the vectors a+b
and a-b, where a = (3,1) and b = (1,-7).
a+b = (3+1 , 1-7) = (4,-6)
a-b = (3-1 , 1+7) = (2,8)
(a+b) dot (a-b) = |a+b| *
|a-b| * cos(a+b,a-b), on the
(a+b) dot (a-b) = 4*2 + (-6)*8 = 8-48 =
|a+b| = sqrt( 4^2 + (-6)^2 ) = sqrt(16+36) = sqrt(52),
|a-b| = sqrt( 2^2 + 8^2 ) = sqrt(4+64) = sqrt(68). From
sqrt(52) * sqrt(68) * cos(a+b,a-b) = -40
cos(a+b,a-b) = -40 / sqrt(52*68).
The angle is thus 132.3 degrees.
1.1.6 Vector projection
We are trying to calculate the projection of a vector on another vector,
or to calculate vector a's component which is parallel to a vector
b. Note! All vectors should be ensured to be unit
vectors for the calculations to give the correct answer!
To clarify, all the vectors in the picture start from the same point, and
the projection vector of a on b is the short vector which
is parallel to b.
All we need to do is to calculate the dot product of a and b
and to multiply b by it:
a's component parallel to b = (a dot b)*b.
The result of a dot product is a constant, so (a dot b) just
scales b which at least I find rational :)
Vector projection is needed at least when converting a vector to a matrix.
1.1.7 Cross product
In the 3-space, we define the cross product (or vector product) axb
("a cross b") of two vectors a and b as a vector
which is perpendicular to each of the vectors a and b and
whose length |a x b| tells the area of the parallelogram
defined by the two vectors:
|a x b| = |a||b|sin(a,b) (Note:
this is the equation for the area of a parallelogram, and is used also
Note! a and b need not to be perpendicular
to each other even though you might think so by looking at the picture
Some other things to remember about cross product:
- a x a = 0,
- a x b = -(b x a),
- r being a constant, (ra) x b = r(a x b),
- a x (b + c) = a x b + a x c,
- i x j = k (and respectively k x i
= j and j x k = i).
The cross product expression can be written in an easy-to-remember form
by using determinants. A two-row determinant is defined as a table
of four numbers, the value of which is calculated as follows:
To solve a cross product, we use three-row determinants:
= ( Ay*Bz-By*Az , Az*Bx-Bz*Ax , Ax*By-Bx*Ay )
In English, we pick each of the i, j, and k, hide
the column and row going through it, create a two-row determinant from
the remaining part of the table, and solve it normally. Note!
Every second sign is a +, every second a -! REMEMBER this! (the signs go
There's no restrictions in the size of a determinant, and all of them
can be solved respectively. For example, from a four-row determinant we
generate four three-row determinants etc.
Cross product is needed for example when calculating normals and plane
Problem: Find the area of the parallelogram determined by
the vectors (1,-1,2) and (2,3,-1).
Solution: (We use the hard way to demonstrate determinants)
Area = the length of this vector = sqrt( (-5)^2 + 5^2 + 5^2 ) = sqrt(75).
1.1.8 Scalar triple product
A scalar triple product is marked as (axb) dot c,
and its absolute value tells the volume of the parallelogramic object determined
by the three vectors (cf. parallelogram in cross product). Note!
If this volume is zero, the three vectors are of course on the same plane!
Problem: Find a constant a so that the vectors (1,-1,2), (1,3,-1),
and (a,-4,1) are on the same plane.
Solution: On the same plane -> scalar triple product = 0. We
first calculate the cross product of arbitrary two of the vectors and then
the dot product of this vector and the third vector.
This ought to be zero, -5a - 15 = 0 <=> -5a = 15 <=> a = -3.
(Algebra ja Geometria, Simo K. Kivela, Otatieto 1989; translated into English)
A specially ordered table of real or complex numbers is caller a matrix:
So, matrices are marked as a table of numbers in great brackets (or round
brackets). Determinants are different from matrices in that they have only
absolute value symbol -like vertical lines around the table (see 1.1.6).
The numbers a(y,x) are matrix elements. They form p rows
and n columns. The type of the matrix is p x n; if needed,
it can also be written together with the matrix symbol: A(pxn).
The first index j of a matrix element a(j,k) shows
the row on which the element is located; the latter index k shows
respectively the column (the indices go thus like in C's tables: compared
to the representation of a point (x,y), in matrices and C language tables
the indices are (y,x)).
We use capital latin letters as names or symbols for matrices.
Matrices of the type 1 x n are called horizontal- or row vectors.
Exceptionally, they are marked with small latin letters:
a = [ a(1) a(2) .. a(n) ]
The elements can be separated with commas for clarity.
If the amounts of rows and columns in a matrix are equal, we call the
matrix a square matrix (cf. 3x3 or 4x4 matrices in 3D operations).
Matrix elements whose indices are equal form the diagonal of a square
matrix; in other words this is the line from the upper left corner to the
lower right corner of a matrix. If all the other elements than the ones
on the diagonal are equal to zero, we call the matrix a diagonal matrix:
A special case of diagonal matrices is a unit matrix (or the identity
matrix), whose all elements a(x,x) (the elements which are located
on the diagonal that is) are equal to one. The symbol of a unit matrix
A matrix whose all elements are zero, is called a zero matrix.
The type of a zero matrix is not restricted. The symbol is O (or
o if the matrix is a vector).
A matrix is called orthogonal if its row or column vectors (that
is, the vectors formed by the rows or columns of the matrix) are perpendicular
to each other and they are unit vectors.
A matrix B defined like this
A*B = I <=> B = A^(-1),
is called the inverse matrix of A.
1.2.2 Matrix operations
Matrix addition is defined so that every element b(j,k) of the second
matrix is added to every element a(j,k) of the first matrix:
188.8.131.52 Multiplying by a scalar
(A scalar = a constant) This goes like addition, but instead of the +'s
we put *'s, and instead of b(j,k) we put the scalar with which we
want to multiply the matrix. Multiplying by a scalar scales a matrix.
Here's the algorithm:
Matrix multiplication can be clarified by regarding it as the dot products
of the vectors formed by the rows of the first matrix and the columns of
the second matrix: first the uppermost row of the first matrix and the
first column of the second matrix, then the same uppermost row of the first
matrix and the second column of the second matrix, etc. And the results
into the new matrix as in the picture above.
Note! Only certain types of matrices can be multiplied
by each other. That is, if the first matrix is of the size p x q, the second
one should be of the size q x r, where p, q, and r are not restricted.
When we multiply a p x q sized matrix by a q x r sized matrix, we get a
p x r sized matrix as a result, as can easily be seen from the definition
of matrix multiplication.
Matrix multiplication is needed in object transformations.
184.108.40.206.1 Multiplying by a vector
The case is easiest to understand by making the desired vector a horizontal
Xi+Yj+Zk = [ X Y Z ].
Now we multiply this vector (which actually is a matrix) by the desired
Neat, isn't it? :) This formula can also be used for vertex transformations,
when the letters (X,Y,Z) tell the original coordinates of a vertex, and
the result tells the transformated coordinates, respectively.
Vector*matrix can be thought of as projecting the vector as related
to the new coordinate axes (the ones in the matrix).
Definition: The transpose of a matrix A(pxn) is
C(nxp) = AT,
where C(j,k) = A(k,j). In other words, the matrix is 'flipped'
Transponation is needed when rotating round an arbitrary vector. NOTE!
The transpose of an orthogonal matrix is also its inverse! (this piece
of information is used in optimizing 3D routines -- see chapter 2.7.)
Back to the index