Coordinate Systems, Vectors, Planes FAQ
=======================================
Questions

COORDINATE SYSTEMS
==================
Q1. What is a coordinate system?
Q2. What is a point?
Q3. What is a origin?
Q4. What is a vector?
Q5. What is a column vector?
Q6. What is a row vector?
Q7. What is a vertex?
Q8. What are homogeneous coordinates?
Q9. What is the Euclidean coordinate system?
Q10. What is the Polar coordinate system?
Q11. How do I display Polar coordinates?
Q12. What are righthanded and lefthanded coordinate systems?
Q13. Which is the best coordinate system to use?
Q14. How do rotation angles relate to coordinate systems?
Q15. What is a global coordinate system?
Q16. What is a local coordinate system?
Q17. How do I convert Euclidean to Polar coordinates?
Q18. How do I convert Polar to Euclidean coordinates?
Q19. How do I convert between rotation systems?
VECTORS
=======
Q20. How do I represent a vector using the C/C++ programming languages?
Q21. How do I calculate the length of a vector?
Q22. What is the magnitude of a vector?
Q23. What is a normalised vector?
Q24. How do I normalise a vector?
Q25. What is an unit vector?
Q26. What is a direction vector?
Q27. What is an outward normal?
Q28. What is a dot product?
Q29. How do I determine the angle between two vectors?
Q30. What is a cross product?
Q31. How do I add two vectors?
Q32. How do I subtract two vectors?
Q33. How do I scale a vector?
Q34. How do I perform linear interpolation between two vectors?
Q35. How do I perform cubic interpolation between four vectors?
PLANES
======
Q36. What is a plane equation?
Q37. How do I evaluate a point relative to a plane?
Q38. How do I find the point of intersection with a between and a plane?
Q39. How do I calculate the reflection of a vector from a plane equation?
Q40. How is the reflection of a vector equation derived?
Q41. How do I calculate the acceleration of an object on a sloping surface?
DEFORMATION PATCHES
===================
Q42. What are deformation patches?
Q43. What are linear deformation patches?
Q44. How do I perform linear deformation?
Q45. How do I implement a linear deformation system?
Q46. How do I define a cubic deformation patch?
Q47. How do I evaluate a deformation patch?
Q48. How do I implement a deformation patch system?
Q49. How can I use keyframe animation with deformation patches?
Answers

COORDINATE SYSTEMS
==================
Q1. What is a coordinate system?

A coordinate system is a way of defining multidimensional space so that
every individual point in space can be referenced uniquely.
Several types of coordinate systems exist. These include the following:
o Euclidean coordinate system
o Polar coordinate system
A coordinate system may exist in one, two, three or more dimensions.
A one dimensional coordinate system defines a set of coordinates along
a single straight line.
A two dimensional coordinate system defines a flat rectangular space.
This requires a pair of coordinates.
A three dimensional coordinate system defines a solid box. This requires
a triplet of coordinates.
A coordinate system using four or more dimensions requires some
imagination in order to be visualised. Several method exist to handle
this situation.
With four to six dimensions, the first three coordinates can be used to
define standard 3D Euclidean space. The remaining three coordinates
can be converted into a set of RGB color values. This system is used
in CAT or NMR scanners. The first three dimensions are the position of
the patients body. The fourth dimension defines the signal intensity
for an individual voxel or point in the patients body.
Q2. What is a point?

A point is an absolute position in space. It measures the displacement
of the point along each axis or dimension of the coordinate system.
Q3. What is a origin?

The origin is the point within the coordinate system, where the
displacement along each axis or dimension is equal to zero.
For example, with the Euclidean coordinate system, the point (0,0,0)
is the origin.
Q4. What is a vector?

Mathematically speaking, a vector differs from a point in that it
defines the displacement between two points rather than the
physical location of an actual point in space.
A point does not define a direction, while a vector does.
However, a vector between the origin and a point in space, has exactly
the same coordinates.
Q5. What is a column vector?

By convention, two dimensional and three dimensional vectors are
represented as a single vertical column of numeric values ie:
 x   x 
V =   V =  y 
 y   z 
Two dimensions Three dimensions
A list of vectors (eg. the geometry of a 3D model) is represented
simply by adding additional columns ie.
 x1 x2 x3 ... xN 
V =  y1 y2 y4 ... yN 
 z1 z2 z4 ... zN 
Q6. What is row vector?

For problemsolving, a vector may be described as V = (x,y,z) during
the specification of a problem.
This is a row vector. However, rowvectors should not really be used
with any mathematical descriptions.
Q7. What is a vertex?

A vertex is another name for a point. However, it used specifically
when referring to a group of points arranged into a geometric shape.
Q8. What are homogeneous coordinates?

Homogenous coordinates are used in order to implement perspective depth
projection operations using matrices. With ordinary matrix multiplication
it is not possible to divide columns of a matrix by the value of a
particular element ie. Dividing X and Y by Z.
Homogeneous coordinates get around this problem by defining an additional
coordinate W. When vectors are normally defined, this value is always
set to 1.0. Because, of this, it is not usually necessary to store this
value with 3D coordinates and vectors.
The use of this coordinate is the reason why all projection matrices are
4x4 in size.
When a 3D vector is multiplied with a projection matrix, the W
coordinate gets multiplied alongside XYZ. The resulting value is
then used to divide each of X,Y and Z.
A simple perspective matrix will set the value of W to Z.
Q9. What is the Euclidean coordinate system?

Euclidean coordinates can range from 1 to N dimension. Each dimension
is always perpendicular to all the others. Two and three dimensions
are most commonly used by game systems.
In a two dimensional system, each position is defined by two coordinates
X and Y. A twodimensional system is as follows:
++
 
 +Y 
 
 o 
  
  
  
  
 ....oo +X 
 . 
 . 
 . 
 . 
 
++
In a three dimensional system, an additional Z coordinate is added.
++
 
 +Y 
 
 o 
  
  
  
  
 ....oo +X 
 /. 
 / . 
 / . 
 +Z o . 
 
++
For example, a football field can be represented as a coordinate system.
The centre point is the origin. The X axis is the centre line, the Z
axis is the direction from one goal to another and the Y axis is the
height of the football from the ground.
The Euclidean coordinate system can also be extended into four or more
dimensions.
For example, in a flight simulator game, it may be useful to keep track
of the flight path of an aeroplane. In this case, the fourth dimension
actually defines time.
Q10. What is the Polar coordinate system?

The Polar coordinate system differs from the Euclidean coordinate system
in that each point in space is defined in terms of its position and
distance from a sphere with unit radius.
The centre of the sphere is the origin . The first two coordinates
define longitude and latitude on the sphere. In effect they wrap a two
dimensional coordinate system onto the surface of the sphere.
The third coordinate defines the distance of the point from the centre
of the sphere.
Each point defines a triplet of values (latitude, longitude and height).
Latitude ranges from +90 to 90. Longitude ranges from 180 to +180, and
height range from 0 to infinity. Height can be negative.
ie. ( +90, , +r ) defines the North Pole.
( 90, , r ) defines the South Pole.
( 0, 0, r ) is a point on the equator.
Q11. How do I display Polar coordinates?

Longitude and Latitude can be displayed as floating point values or
as degrees, minutes and seconds (and even arcseconds).
These angles are represented in the format
o
dd mm' ss"
where dd ranges from 180 to 180,
mm ranges from 0 to 59,
and ss ranges from 0 to 59.
dd defines the integer number of degrees, while mm and ss take the
fractional part and scale it into two other integers ie:

frac = modf( angle, &dd ) * 3600.0
ss = frac % 60
mm = frac  ss

Q12. What are righthanded and lefthanded coordinate systems?

When working with coordinates in the Euclidean coordinate system
there are two possible ways of arranging the three XYZ coordinate
axii.
One way is to have the positive Zaxis point outwards of the screen.
This is referred to as the "righthanded coordinate system" and is
the system preferred by mathematicians.
The more negative a coordinate is, the further back into the screen it
appears. Coordinates with positive values are behind the observer.
Alternatively, the positive Zaxis can be made to point into the
screen. This is referred to as the "lefthanded coordinate system".
This is opposite to the righthanded coordinate system. The more
positive a coordinate is, the further back into the screen it appears.
Coordinates with positive values are behind the observer.
Lefthanded coordinate system Righthanded coordinate system
++ ++
   
 +Y   +Y 
 ^   ^ 
  +Z    
  o    . 
  /    . 
  /    . 
  /    . 
 /   . 
 .......o> +X   .......o> +X 
 ..   /. 
 . .   / . 
 . .   / . 
 . .   / . 
 . .   o . 
 .   . 
 .   +Z . 
   
++ ++
If the direction of the Yaxis is reversed, then whichever coordinate
system is currently in use becomes the direct opposite.
OpenGl and XGL use the righthanded coordinate system. Direct3D uses
the lefthanded coordinate system.
The terms "lefthanded" and "righthanded" are
derived from the way you can use your thumb, index and middle fingers
to model the
selected coordinate systems.
If you point the index finger of your right hand in the direction of
the Zaxis, then your right thumb points in the direction of the Yaxis
and your right middle finger points in the direction of the Xaxis.
If the direction of the Zaxis is reversed (ie. pointing into the
screen) then this is defined as a "lefthanded" coordinate system.
This is because your left thumb now points in the direction of the
Yaxis and your left middle finger nows points in the direction of
the Xaxis.
Q13. Which is the best coordinate system to use?

In practical use, there is no particular advantage that either the
lefthanded or righthand coordinatee systems has over the other.
The main reason for choosing one system over the other is purely
a matter of convenience.
Such reasons might include maintaining compatability with the
underlying 3D API or geographical coordinate system. For example
OpenGL uses a righthanded coordinate system, while Direct 3D uses
a lefthanded coordinate system.
For an aircraft simulator, it is convenient to "map" the geographical
longitude with the Xaxis, geographical latitude with the Yaxis and
height (or depth) with the Zaxis. When combined together, all three
coordinate axii form the righthanded coordinate system, albeit rotated
90 degrees in the Xaxis.
Righthanded coordinate system
for aircraft simulator
++
 
 +Z 
 ^ +Y 
  o 
  / 
  / 
  / 
  / 
 / 
 .......o +X 
 .. 
 . . 
 . . 
 . . 
 . . 
 . 
 . 
 
++
In the case of a submarine simulator, the Zaxis actually has polarity
reversed, so that positive values of Z represents increasing depth,
while the X and Y still represent longitude and latitude respectively.
Thus, all three coordinate axii form the lefthanded coordinate system,
albeit rotated +90 degrees in the Xaxis.
Lefthanded coordinate system
for submarine simulator
++
 
 . 
 . +Y 
 . o 
 . / 
 . / 
 . / 
 ./ 
 .......o +X 
 . 
 .  
 .  
 .  
 .  
  
 V 
 +Z 
 
++
For the aircraft simulator, converting coordinates to OpenGL is simply
a matter of performing a +90 degree rotation in the Xaxis.
Likewise, for the submatine simulator, the conversion to OpeGL is
simply a matter of performing a 90 degree rotation in the Xaxis.
Q14. How do rotation angles relate to coordinate systems?

By mathematical convention, a positive rotation angle generates a
clockwise rotation when looking from the origin towards the positive
end of the selected rotation axis.
Given this relationship between rotation angles and coordinate
systems, it is possible to derive the rotation matrices for each
rotation axis.
Q15. What is a global coordinate system?

Global coordinate system are used to assign the coordinates of all
points relative to a single common origin.
For example, when tracking the positions of players in a 3D maze, it
is convenient to have all players and obstacles assign coordinates
relative to a single common origin eg. The entrance/exit of the maze.
Q16. What is a local coordinate system?

Local coordinate systems are used to assign the coordinates of all
points relative to one or more origins.
For example, using the Euclidean coordinate system to animate the
movement of a multijointed robot arm, it is convenient to assign
each joint separate local coordinate systems.
The point of rotation of each joint actually becomes the origin of
the related geometry.
This allows for the surface geometry of each joint to be transformed
by the current position of that joint.
The coordinate system need not always Euclidean. In the case of
astronomy and tracking the positions of features on the moon or
other planets, it is necessary to give each planet its own local
polar coordinates system.
However, the position of all planets can be defined using a global
coordinate system, with the Sun being placed at the origin.
Q17. How do I convert Euclidean to Polar coordinates?

With a Euclidean coordinate (x y z), the goal is to convert it into a
Polar coordinate (latitude, longitude, distance).
The conversion is as follows:

distance = sqrt( x*x + y*y + z*z )
x /= distance;
y /= distance;
z /= distance;
xz_dist = sqrt( x*x + z*z )
latitude = atan2( xz_dist, y ) * RADIANS
longitude = atan2( x, z ) * RADIANS

Q18. How do I convert Polar to Euclidean coordinates?

With a Polar coordinate (latitude, longitude, distance), the goal is to
convert it into a Euclidean coordinate (x y z).
The conversion is as follows:

x = cos( latitude ) . sin( longitude )
y = sin( latitude )
z = cos( latitude ) . cos( longitude )

Q19. How do I convert between rotation systems?

Altogether, there are around five different ways in which a rotation
in three dimensions can be represented:
These include:
Euler angles
Matrices
Quaternions
Rotation Axis/Angle
Spherical Rotation Angles
Euler angles define each rotation as a combination of rotations in
each of the three main X, Y and Z axii. Euler angles must be converted
to matrices before any vertex transformations can be performed.
Matrices define each rotation as an 2D array of values which are
multiplied with an array of vertices. They can either be 3x3 or 4x4
in size.
Quaternions define each rotation in 4 dimension instead of three. As a
result they require four floating point values. Quaternions must be
connverted to matrices before any vertex transformation can be
performed.
Rotation Axis/Angles define each rotation as a unit vector along with
a specifiede rotation angle along that axis. Rotation Axis/Angle pairs
must be converted into Quaternions before finally being converted into
a rotation matrix.
Spherical angles define each rotation in terms of latitude/longitude
and a rotation angle. They must be converted into a rotation matrix
through the use of AxisAngle and Quaternion coordinates.
The conversion paths are as follows:
++ ++ ++
 Matrix <===> Quaternion <===> AxisAngle 
++ ++ ++
/\ /\
 
\/ \/
++ ++
 Euler angles   Spherical 
++ ++
A comparision of the various representations is presented below:
++++
 Data type  Size  Usage 
++++
 Euler Angles  FLOAT * 3  Must be converted to a matrix 
   Gimbal lock can occur 
++++
 Matrix  FLOAT * 9  Can be used directly for vertex 
  FLOAT * 16  transformation 
   3x3 matrices can be used for rotation 
   and scaling only. 
   4x4 matrices can be used for both 
   translation and perspective 
++++
 Quaternion  FLOAT * 4  Must be converted to a matrix 
   No danger of Gimbal lock 
++++
 Axis Angle  FLOAT * 4  Must be converted to a matrix through 
   the use of Quaternions. 
   No danger of Gimbal lock 
++++
 Spherical  FLOAT * 3  Must be converted to a matrix through 
   the use of AxisAngle and Quaternion 
   representations. 
   No danger of Gimbal lock 
++++
VECTORS
=======
Q20. How do I represent a vector using the C/C++ programming languages?

The most convenient way of representing a vector using the C/C++
programming languages is through the use of a data structure:
typedef float VFLOAT;
typedef vector3_st
{
VFLOAT vx;
VFLOAT vy;
VFLOAT vz;
} VECTOR3;
or through the use of arrays:
typedef VFLOAT VECTOR3[3];
For convenience and modularity, it is always a good idea to define
labels for commonly used data types that may vary from system to system.
Thus floating point values are given the label "VFLOAT".
Q21. How do I calculate the length of a vector?

The length of a vector is calculated by taking the square root of
the sum of the squares of each coordinate ie.
If the vector is defined as (x,y,z) then the length of the vector is
calculated from:

/ 2 2 2
L = \/ x + y + z
Q22. What is the magnitude of a vector?

This is equivalent to the length of a vector.
Placing a pair of vertical lines around a vector indicates the
magnitude of the vector.
eg. If the variable V is used to represent a vector, then the
expression V indicates the magnitude of a vector.
Q23. What is a normalised vector?

A normalised vector is a vector where the sum of the squares of all
coordinates is equal to one.
For example, the vector ( 2, 2, 0 ) is not normalised, while the
vectors ( 0.707, 0.707, 0.0) and ( 1.0, 0.0, 0.0 ) are normalised.
Q24. How do I normalise a vector?

A vector can be normalised by calculating the magnitude or length of
the vector and dividing each coordinate by this value.
For example, consider the vector
 3.0 
V =  4.0 
 0.0 
The length of this vector is 5.0
V = 5.0
Then the value of the normalised vector is given by:
V  3.0  1  0.6 
 =  4.0  .  =  0.8 
V  0.0  5  0.0 
If the vector is already normalised, then the value of V will be
equal to one, and after division, the vector will remain as before.
Q25. What is an unit vector?

A unit vector is another name for a normalised vector. The sum of the
squares of all coordinates is equal to one.
Q26. What is a direction vector?

A direction vector is another name for a vector, but which is
specifically used for the purpose of determining the direction that
a polygon surface or vertex is facing.
However, direction vectors are not necessarily always normalised.
For example, a direction vector may be used to represent wind direction
of points within a landscape. The magnitude of the vector is used to
represent wind speed combined with the direction of the wind.
Q27. What is an outward normal?

An outward normal is another name for a normalised vector. Similar
in purpose to a direction vector, an outward normal are used
specifically for representing the direction that a polygon surface or
vertex is facing.
Q28. What is a dot product?

The dot product is used to calculate the angle between two vectors.
If v1 and v2 are two normalised vectors, then the dot product is given
by the expression:
v1.v2
For a pair of three dimension vectors this expression is evaluated
using the equation:
d = v1 . v2
 x1   x2 
d =  y1  .  y2 
 z1   z2 
d = x1.x2 + y1.y2 + z1.z2
This can be represented using the C/C++ programming languages as:
d = v1.x * v2.x + v1.y * v2.y + v1.z * v2.z
where * is the standard multiplication operation.
For efficiency, this function can represented as C #define macros or
C++ inline class functions.
Q29. How do I determine the angle between two vectors?

The angle between two normalised vectors can be calculated from the
mathematical expression:
cos A = v1.v2
 x1   x2 
=  y1  .  y2 
 z1   z2 
where cos is the cosine function,
A is the angle between the two vectors,
v1 is the first vector and
v2 is the second vector
The expression v1.v2 is the actual dot product
If the two vectors are not normalised, then the following expression
can be used:
v1.v2
cos A = 
v1 . v2
 
where  is the magnitude or length of the vector.
This takes the dot product of the two vectors, and divides the result
by the product of the lengths of both vectors.
Q30. What is a cross product?

The cross product between two normalised vectors is used to determine
the vector which perpendicular to both the vectors. This is expressed
as the mathematical expression:
v3 = v1 x v2
 x1   x2 
v3 =  y1  x  y2 
 z1   z2 
 y1.z2 + z1.y2 
v3 =  z1.x2 + x1.z2 
 x1.y2 + y1.x2 
This can be represented using the C/C++ programming languages as:
v3.vx = v1.y * v2.z + v1.z * v2.y
v3.vy = v1.z * v2.x + v1.x * v2.z
v3.vz = v1.x * v2.y + v1.y * v2.x
For efficiency, this function can represented as C #define macros or
C++ inline class functions.
Q31. How do I add two vectors?

Adding two vectors together is very simple to perform. This is achieved
by adding together the individual coordinates of each vector. The
operation is defined by the following mathematical expression:
v3 = v1 + v2
 x1   x2 
v3 =  y1  +  y2 
 z1   z2 
 x1 + x2 
v3 =  y1 + y2 
 z1 + z2 
This can be represented using the C/C++ programming languages as:
v3.vx = v1.vx + v2.vx
v3.vy = v1.vy + v2.vy
v3.vz = v1.vz + v2.vz
For efficiency, this function can represented as C #define macros or
C++ inline class functions.
Q32. How do I subtract two vectors?

Subtraction is performed in the same way as addition. This is achieved
by subtracting the individual coordinates of each vector. The
operation is defined by the following mathematical expression:
v3 = v1  v2
 x1   x2 
v3 =  y1    y2 
 z1   z2 
 x1  x2 
v3 =  y1  y2 
 z1  z2 
This can be represented using the C/C++ programming languages as:
v3.vx = v1.vx  v2.vx
v3.vy = v1.vy  v2.vy
v3.vz = v1.vz  v2.vz
For efficiency, this function can represented as C #define macros or
C++ inline class functions.
Q33. How do I scale a vector?

A vector can be scaled (enlarged or reduced) in a way similar to
multiplication. This is achieved by multiplying each coordinate by the
same scaling factor. The mathematical expression for this is as follows:
v2 = v1 . S
 x1 
v3 =  y1  . S
 z1 
 x1.S 
v3 =  y1.S 
 z1.S 
This can be represented using the C/C++ programming languages as:
v3.vx = v1.vx * S
v3.vy = v1.vy * S
v3.vz = v1.vz * S
For efficiency, this function can represented as C #define macros or
C++ inline class functions.
Q34. How do I perform linear interpolation between two vectors?

For many 3D applications, it is sometimes necessary to perform linear
interpolation between two vectors. Such applications can include view
frustum clipping and morphing.
Linear interpolation is implemented by taking the coordinates of two
known points and scaling them in such a way as to generate a series
of points that forms a straight line between them.
This equation is sometimes referred to as a blending function. For
linear interpolation this equations is as follows:
V' = (1t).Va + t.Vb
V' = Va + t.(VbVa)
The second form is more commonly used as it only requires a single
multiplication operation.
This is implemented using the following set of vector operations:
Using the C programming language:
void v3_linear( VECTOR3 *vr, VECTOR3 *va, VECTOR3 *vb, VFLOAT t )
{
v3_sub( &vtemp, vb, va );
v3_scalef( &vtemp, &vtemp, t );
v3_add( &vr, &vtemp, va );
}
Q35. How do I perform cubic interpolation between four vectors?

Given four vectors, the problem is to find a way of determining
intermediate positions specified by a parametric variable t.
This can be achieved by making use of cubic interpolation. The set
of four vectors is combined into a single geometry vector G.
Through the use of spline mathematics, this geometry vector is
converted into an interpolation matrix M.
If the geometry vector is defined as:
 x1 x2 x3 x4 
G =  y1 y2 y3 y4 
 z1 z2 z3 z4 
Then multiplication by the base matrix:
 4.5 9.0 5.5 1.0 
Mb =  13.5 22.5 9.0 0.0 
 13.5 18.0 4.5 0.0 
 4.5 4.5 1.0 0.0 
will generate the 3x4 interpolation matrix Mi:
Mi = G .Mb
This can be implemented through a modified matrixvector multiplication:
m4_multspline( m_cubic, v_geom, v_source );
Interpolation can then be performed by the use of the parametric
variable t:
R = Mi . t
t^3
 xr   A B C D  t^2
 yr  =  E F G H  . t 
 zr   I J K L  1 
This can be implemented through a modified cubic interpolation
algorithm:
v3_cubic( vr, v_geom, t );
The resulting vector can then be used as required.
The function m4_multspline is implemented as follows:

void m4_multspline( MATRIX4 mat, VECTOR3 *vsrc, VECTOR3 *vdst )
{
VFLOAT tx, ty, tz;
int n;
for ( n = 0; n < 4; n++ )
{
vdst[n].vx = vsrc[0].vx * mat[n]
+ vsrc[1].vx * mat[n+4]
+ vsrc[2].vx * mat[n+8]
+ vsrc[3].vx * mat[n+12];
vdst[n].vy = vsrc[0].vy * mat[n]
+ vsrc[1].vy * mat[n+4]
+ vsrc[2].vy * mat[n+8]
+ vsrc[3].vy * mat[n+12];
vdst[n].vz = vsrc[0].vz * mat[n]
+ vsrc[1].vz * mat[n+4]
+ vsrc[2].vz * mat[n+8]
+ vsrc[3].vz * mat[n+12];
}
}

The function v3_cubic is implemented as follows:

void v3_cubic( VECTOR3 *vpos, VECTOR3 *vdst, VFLOAT t )
{
vpos > vx = ((vdst[0].vx*t+vdst[1].vx)*t+vdst[2].vx)*t+vdst[3].vx;
vpos > vy = ((vdst[0].vy*t+vdst[1].vy)*t+vdst[2].vy)*t+vdst[3].vy;
vpos > vz = ((vdst[0].vz*t+vdst[1].vz)*t+vdst[2].vz)*t+vdst[3].vz;
}

In fact, a cubic spline surface can be generated from the combination
of these two algorithms:

void cubic_patch( VECTOR3 *vlist, VECTOR3 *vsurf, int hdiv, int vdiv )
{
MATRIX4 mh_geom[4];
VECTOR3 mv_geom[4], mv_interp[4];
VFLOAT du, dv;
int n, u, v;
if ( hdiv < 1  vdiv < 1 ) /* Not enough subdivisions? */
return; /* No, so return */
for ( n = 0; n < 4; n++ ) /* Horiz. interp */
m4_multspline( m_cubic, vsurf+n*4,mh_geom[n]); /* Make Imatrix */
for ( u = 0; u <= hdiv; u++ ) /* For each column */
{
for ( n = 0; n < 4; n++ )
v3_cubic( mv_geom+n, mh_geom[n], (VFLOAT) u/hdiv );
m4_multspline( m_cubic, mv_geom, mv_interp ); /* Make Imatrix */
for ( v = 0; v <= vdiv; v++, vlist++ ) /* For each row */
v3_cubic( vlist,mv_interp,(VFLOAT) v/vdiv ); /* Save vertex */
}
}

PLANES
======
Q36. What is a plane equation?

Plane equations are widely used in the field of 3D animation to
define and manipulate polygon surfaces. Plane equations are used to
implement back face culling, view frustum culling, clipping and
collision detection.
The plane equation or "equation of the plane" is a mathematical
expression as follows:
Ax + By + Cz + D = 0
where A, B, C and D are known constants and (x,y,z) specifies any
point in threedimensional space.
Q37. How do I evaluate a point relative to a plane?

The position of a point relative to a plane is determined by
evaluating the plane equation ie. Multiplying each coordinate (x,y,z)
with the associated parameters (A,B,C) and adding D.
If the evaluation of a point with the plane equation generates a
positive value then the point is said to be "in front of the plane".
If the evaluation generates a result which is negative, then the point
is said to be "behind the plane".
Otherwise, if the evaluation generates a result which is exactly
zero, then the point is said to be "on the plane".
The values of A,B and C actually define the outward normal of the
surface. As such, the sum of the squares of these values will always
add up to one ie.
2 2 2
A + B + C  1 = 0
In fact, the evaluation of a point relative to the plane is actually
a dot product calculation.
Q38. How do I find the point of intersection with a line and a plane?

For computer animation purpose, it is often convenient to determine
where a straight 3D line intersects a polygon surface. The polygon
surface is represented as a plane equation.
The 3D line may be specified in two possible ways:
o starting and finishing points ( Vs, Vf )
o starting point and direction vector ( Vs, Vd )
If only a starting point and a direction vector are known, then
a dummy end point is calculated by adding the direction vector to
the starting point ie:
Vf = Vs + Vd
This parameter can then be used in the algorithm defined as follows:
In the case that both starting and finishing points are known, it is
possible to determine the point of intersection by evaluating both
points relative to the plane equation and interpolating ie.
Es = P( Vs )
Ef = P( Vf )
Using these two values as weighting factors, it is possible to
interpolate between the two endpoints.
The weighting factor for the two points is evaluated as follows:
Es Ef
Ws =  Wf = 
EfEs EfEs
Then the point of intersection is calculated as follows:
Vp = Ws.Vs + Wf.Vf
Q39. How do I calculate the reflection of a vector from a plane equation?

In order to perform calculations such as a light reflecting off a
reflective surface, it is necessary to be able to calculate the
reflection of a vector off a plane.
The plane is represented as an outward normal.
The mathematical expression for the reflection of a vector is
given by:
V' = 2N.(V.N)  V
where the known (and unknown) parameters are as follows:
N = outward normal for the plane
V = unit vector of light ray
V' = unknown unit vector of reflected light ray
Q40. How is the reflection of a vector equation derived?

The reflection of a vector is visualised by the following drawing:
N
^
V  V'
  
\  /
\  /
\/
o
where:
V is the original direction vector
V' is the reflection direction vector, and
N is the outward normal of the plane
The angle between the vector V and N is given by the dot product ie.
cos(angle) = V.N
So the expression must have a component V.N within it
Then the following angles are known:
At V.N = 0, V' = V
At V.N = 1, V' = N
At V.N = 1, V' = N
Since V.N = 1 gives N and V.N = 1, gives N, this indicates that the
component V.N is multiplied by N, ie.
V' = f( N.(V.N) )
where f() is the evalation function (not completely known).
However, if V.N=0 then a result of V is given.
Therefore, there must also be a V component ie.
V' = f( N.(V.N)  V )
But, since at V=N, V.N=1, this equation would cancel out completely.
Thus, one of the parameters must be scaled by a factor of two.
Then, the final equation is given by:
V' = 2N.(V.N)  V
This can be implemented using the vector library as follows:

void v3_reflect( VECTOR3 *vreflect, VECTOR3 *vdir, VECTOR3 *vnormal )
{
VFLOAT angle;
VECTOR3 vtemp;
angle = v3_dot( vreflect, vnormal ) * 2;
v3_scale( &vreflect, vnormal, angle );
v3_sub( &vreflect, &vreflect, vnormal );
}

Q41. How do I calculate the acceleration of an object on a sloping surface?

In the real world, when an object moves onto a sloping surface, it
experiences acceleration forces due to gravity. However, because of the
existence of the sloping surface, the acceleration will not be directly
in the direction towards the gravitational source. Examples include a
football rolling down a hill and a person sliding down a mudslide.
In a virtual 3D environment, the position of an object is represented
as a vector coordinate, the sloping surface as a plane equation and
gravity is as a direction vector.
The problem can then be defined as combining these parameters together
in order to determine the acceleration force, which is represented as a
direction vector.
The following parameters are known:
Vo = Position vector of the object
Vg = Direction vector of gravity
Vp = Outward normal of the current slope polygon
Only the following parameter is unknown:
Va = Direction vector of acceleration forces
This can be visualised as follows:

Vp = Outward normal of polygon

\ /
\ /
\ /
\O
\
\\
 \\ Va = Acceleration force
 \
V \
Vg = Gravity

Then the calculation is as follows:
Axis of rotation of a rolling object is given by:
Vt = Vg x Vp
Then the direction vector representing the acceleration force is
given by:
Va = Vt x Vp
This can be implemented using the 3D vector library as follows:

void v3_slope( VECTOR3 *va, VECTOR3 *vr, VECTOR3 *vg, VECTOR3 *vp )
{
v3_cross( &vr, vg, vp );
v3_cross( &va, vt, vp );
}

DEFORMATION PATCHES
===================
Q42. What are deformation patches?

Deformation patches are a means of modifying the shape of an object
while preserving the connectivity of all the geometry. They attempt
to warp the local coordinate system of an object so that straight
lines can become curved lines and vice versa.
Applications of deformation patches includes special effects and
character animation. An inanimate object can be made to twist around,
shrink away from a threatening object and even shuffle or tiptoe
about. For a really trippy effect, a camera can be made to move
through an architectural model, while the geometry of the model is
warped using a deformation patch.
In the real world (using stopgo animation and clay), deformation of
an object can be implemented through the use of reshaping, adding or
removing clay.
However, when animating by computer, using clay is not an option.
Instead, surface are modelled using either polygons defined from
vertices or surfaces defined using spline curves and control points.
By warping the positions of these vertices and control points, it is
possible to deform the shape of the object by modifying the local
coordinate system, while still preserving the connectivity of the
geometry.
Warping or "deforming" of the geometry can be implemented using either
linear or cubic interpolation. Linear interpolation offers considerable
performance advantages over cubic interpolation, at the sacrifice of
control over the way the geometry deforms.
Q43. What are linear deformation patches?

Linear deformation patches are a lowbudget version of cubic
deformation patches. Instead of using cubic interpolation, linear
interpolation only makes use of linear interpolation of vectors.
As a result, only eight control points are required, instead of the
full complement of sixtyfour. However, the control points are still
arranged in the shape of a cube.
Q44. How do I perform linear deformation?

Once the bounding volume and control points have been defined, the
next stage is to evaluate the new coordinates of each vertex.
Each coordinate of the original object is converted into a parametric
form based on the limits of the bounding volume.
If the limits of the bounding volume are defined by:
 Xlo   Xhi 
Min =  Ylo  and Max =  Yhi 
 Zlo   Zhi 
Then a point P can be converted to parametric form:
 X 
P =  Y 
 Z 
Then the parameteric version of P can be calculated from:
 X  Xlo 
  
 Xhi  Xlo 
 
 Y  Ylo 
P' =   
 Yhi  Ylo 
 
 Z  Zlo 
  
 Zhi  Zlo 
This parametric coordinate can then be used as input to the evaluation
stage.
Because the deformation patch exists in three dimensions, this requires
interpolation through three levels of spline curves:
++
 
 Level 1 Level 2 Level 3 
 
 OO ..O.. 
 .. .. . 
 . . . .  . . 
 . . . .  . . . 
 . OO P'.X  ..O.. P'.Y O P'.Z . 
 . . . . =====>   =====> .\ =====> O 
 . . . .   . \ . . 
 . . . .   \. . 
 O.O . ..O..  O 
 . . . . .  . 
 . . . . .  . 
 .. .. . 
 OO ..O.. 
 
++
The first level is defined from four interpolation lines, each of
which is defined from pair of control points in the Xaxis.
Substituting in the Xaxis parametric coordinate from P' generates
a new set of 4 control points.
These are used to generate two interpolation lines in the Yaxis.
Substituting in the Yaxis parameteric coordinate from P' generates
a new set of 2 control points.
These are used to generate a single interpolation line in the Zaxis.
Substituting in the Zaxis parametric coordinate from P' generates
a single coordinate.
This coordinate is in fact the final warped position of the point P.
Each vertex or control point of the model is processed in this manner
until all every coordinate has been processed.
Q45. How do I implement a linear deformation system?

Implementation of a deformation patch system requires three sets of
input parameters. These include the following:
o Model geometry
o Original bounding cube
o Deformation patch (8 control points)
The evaluation function, must then accept a set of vertex data as
input (these might even be control points of a NURBS mesh!), and
produce a modified set of vertex data as output.
For efficiency, the default ordering of the control points of the
deformation patch is Xminor, Zmajor, ie. Vertices on the same
Xaxis row are placed next to each other in memory ie.
 X1 X2 X1 X2 X1 X2 X1 X2 
Mdeform =  Y1 Y1 Y2 Y2 Y1 Y1 Y2 Y2 
 Z1 Z1 Z1 Z1 Z2 Z2 Z2 Z2 
The first stage of linear interpolation will convert each pair of
control points into a single coordinate.
By substituting in the parametric X coordinate and evaluating, a set
of four coordinates are generated:
 Xp Xp Xp Xp 
Mdx =  Y1 Y2 Y1 Y2 
 Z1 Z1 Z2 Z2 
As with the first stage, the parametric Y coordinate is substituted
and evaluated. This generates a pair of coordinates.
 Xp Xp 
Mdy =  Yp Yp 
 Z1 Z2 
Finally, these are converted into a interpolation matrix, and the
parametric Z coordinate is substituted and evaluated. This generates
a single coordinate
 Xp 
Mdz =  Yp 
 Zp 
This is the final processed coordinate.
A complete routine to perform this is as follows:
The following parameters are used:
vnum  number of vertices to be processed
vsrc  source vertex data
vdst  processed vertex data
vlimits  bounding volume for deformation patch
vdeform  control points for deformation patch (64)

void lpatch_evaluate( VECTOR3 *vdst, int vnum, VECTOR3 *vsrc,
VECTOR3 *vlimits, VECTOR3 *vdeform )
{
VECTOR3 v_diff, vparam, v_ymesh[4], v_zmesh[2];
int n, m;
v3_sub( &v_diff, vlimits+1, vlimits ); /* Scale for box */
for ( n = 0; n < vnum; n++ ) /* For each vertex */
{
v3_sub( &vparam, vsrc+n, vlimits ); /* Get parametric */
v3_div( &vparam, &vparam, &v_diff ); /* coordinates */
for ( m = 0; m < 4; m++ ) /* Get Yaxis mesh */
v3_linear( v_ymesh+m, vdeform+m*2, vdeform+m*2+1, vparam.vx );
for ( m = 0; m < 2; m++ ) /* Get Zaxis mesh */
v3_linear( v_zmesh+m, v_ymesh+m*2, v_ymesh+m*2+1, vparam.vy );
v3_linear( vdst+n, v_zmesh, v_zmesh+1, vparam.vz ); /* Final coord. */
}
}

Q46. How do I define a cubic deformation patch?

A cubic deformation patch is defined as a set of spline curve control
points arranged in the shape of a cube. Modification of the cubic
deformation patch is performed by repositioning groups of control points.
Since a minimum of four points are required to define a spline curve,
a cubic deformation patch requires at least sixtyfour control points.
Each control point is represented as a single 3D vector.
It is also necessary to define a bounding volume which contains the
area of coordinate space which is to be deformed.
Thus, a single deformation patch can be defined from less than 70 3D
vectors or less than 1K of memory.
Q47. How do I evaluate a cubic deformation patch?

Once the bounding volume and control points have been defined, the
next stage is to evaluate the new coordinates of each vertex.
Each coordinate of the original object is converted into a
parametric form based on the limits of the original bounding volume.
If the limits of the bounding volume are defined by:
 Xlo   Xhi 
Min =  Ylo  and Max =  Yhi 
 Zlo   Zhi 
Then a point P can be converted to parametric form:
 X 
P =  Y 
 Z 
Then the parameteric version of P can be calculated from:
 X  Xlo 
  
 Xhi  Xlo 
 
 Y  Ylo 
P' =   
 Yhi  Ylo 
 
 Z  Zlo 
  
 Zhi  Zlo 
This parametric coordinate can then be used as input to the evaluation
stage.
Because the deformation patch exists in three dimensions, this requires
interpolation through three levels of spline curves:
++
 
 Level 1 Level 2 Level 3 
 
 oooo 
 .. . . .. 
 . oooo 
 . . . .. . o 
 . oooo . 
 . . . .. .  o 
 . oooo o . o . 
 . . . . . o \ . 
 oooo . P'.X  o . P'.Y o P'.Z . 
 .. .. . .. . o . o \ . 
 . oooo . . o  o o 
 . . .. .. . . ===>  o . ===> \ ===> . 
 . oooo . o . o o . 
 . .. . .. .. . o  
 . oooo o . 
 . . . . . o 
 oooo . o  
 . .. . . . . 
 oooo . o 
 . .. . . . 
 oooo . 
 .. . . .. 
 oooo 
 
++
The first level is defined from sixteen spline curves, each of which
is defined from a row of control points in the Xaxis.
Substituting in the Xaxis parametric coordinate from P' generates
a new set of 16 control points.
These are used to generate four spline curves in the Yaxis.
Substituting in the Yaxis parameteric coordinate from P' generates
a new set of 4 control points.
These are used to generate a single spline path in the Zaxis.
Substituting in the Zaxis parametric coordinate from P' generates
a single coordinate.
This coordinate is in fact the final warped position of the point P.
Each vertex or control point of the model is processed in this manner
until all every coordinate has been processed.
Q48. How do I implement a cubic deformation patch system?

Implementation of a deformation patch system requires three sets of
input parameters. These include the following:
o Model geometry
o Original bounding cube
o Deformation patch (64 control points)
The evaluation function, must then accept a set of vertex data as
input (these might even be control points of a NURBS mesh!), and
produce a modified set of vertex data as output.
For efficiency, the default ordering of the control points of the
deformation patch is Xminor, Zmajor, ie. Vertices on the same
Xaxis row are placed next to each other in memory ie.
 X1 X2 X3 X4 X1 X2 X3 X4 ... X4 
Mdeform =  Y1 Y1 Y1 Y1 Y2 Y2 Y2 Y2 ... Y4 
 Z1 Z1 Z1 Z1 Z1 Z1 Z1 Z1 ... Z4 
The first stage of cubic interpolation will convert each set of four
control points into a cubic interpolation matrix.
By substituting in the parametric X coordinate and evaluating, a set
of 16 coordinates are generated:
 X1 X1 X1 X1 X1 X1 X1 X1 X1 X1 X1 X1 X1 X1 X1 X1 
Mdx =  Y1 Y2 Y3 Y4 Y1 Y2 Y3 Y4 Y1 Y2 Y3 Y4 Y1 Y2 Y3 Y4 
 Z1 Z1 Z1 Z1 Z2 Z2 Z2 Z2 Z3 Z3 Z3 Z3 Z4 Z4 Z4 Z4 
As with the first stage, the parametric Y coordinate is substituted
and evaluated. This generates a set of four coordinates:
 X1 X1 X1 X1 
Mdy =  Y1 Y1 Y1 Y1 
 Z1 Z2 Z3 Z4 
Finally, these are converted into a interpolation matrix, and the
parametric Z coordinate is substituted and evaluated. This generates
a single coordinate
 X1 
Mdz =  Y1 
 Z1 
This is the final processed coordinate.
A complete routine to perform this is as follows:
The following parameters are used:
vnum  number of vertices to be processed
vsrc  source vertex data
vdst  processed vertex data
vlimits  bounding volume for deformation patch
vdeform  control points for deformation patch (64)

typedef VECTOR3 GVECTOR3[4];
void dpatch_evaluate( VECTOR3 *vdst, int vnum, VECTOR3 *vsrc,
VECTOR3 *vlimits, VECTOR3 *vdeform )
{
GVECTOR3 m_xgeom[16], m_ygeom[4], m_zgeom;
VECTOR3 v_diff, vparam, v_ymesh[16], v_zmesh[4];
int n, m;
v3_sub( &v_diff, vlimits+1, vlimits ); /* Scale for box */
for ( m = 0; m < 16; m++ ) /* Imatrix Xaxis */
m4_multspline( m_cubic, vdeform+m*4, m_xgeom[m] );
for ( n = 0; n < vnum; n++ ) /* For each vertex */
{
v3_sub( &vparam, vsrc+n, vlimits ); /* Get parametric */
v3_div( &vparam, &vparam, &v_diff ); /* coordinates */
for ( m = 0; m < 16; m++ ) /* Get Yaxis mesh */
v3_cubic( v_ymesh+m, m_xgeom[m], vparam.vx );
for ( m = 0; m < 4; m++ )
{ /* Imatrix Y axis */
m4_multspline( m_cubic, v_ymesh+m*4, m_ygeom[m] );
v3_cubic( v_zmesh+m, m_ygeom[m], vparam.vy ); /* Get Zaxis mesh */
}
m4_multspline( m_cubic, v_zmesh, m_zgeom ); /* Imatrix Z axis */
v3_cubic( vdst+n, m_zgeom, vparam.vz ); /* New coordinate */
}
}

Q49. How do I use keyframe animation with deformation patches?

Using the algorithm described above, it is only possible to render
a single rendered frame.
In order to implement smooth and continuous animation, it is necessary
to define more than one deformation patch.
However, defining and positioning a single deformation patch for every
keyframe is very timeconsuming. The solution is to add another
dimension to the deformation patch ie. time.
For every two keyframes, it is possible to perform linear interpolation
to generate each frame between the two keyframes.
For every four keyframes, it is possible to perform cubic interpolation
to generate each frame between the four keyframes.
This allows for smooth animation along with efficient use of memory
space.
===========================================================================
Thanks to Hexapod.
