This is a very old article, included for historical interest only!
Before I get into the meat of my ray-tracing experiment, I need to present a tiny bit of maths so I don’t need to explain in the main articles. I’m not going to try to prove anything here; this is all going to be math-as-technology, not math-as-theory. If you’re happy with operations such as vector dot products, cross products, and normalization, you can skip this article.
A scalar is what a C# coder would call a float or a double – it’s just a number. Scalars are usually represented as plain lowercase letters such as t or x.
A vector is a collection of scalars that define a direction and magnitude in space - for the purposes of ray-tracing, that will be three components: x, y, and z. Vectors are usually represented as bold letters (n or p), or letters with a bar above.
I use vectors both for “directional” concepts, and also for “positional” concepts – a point in space can be represented by a vector from the origin.
A vector v is (x, y, z).
For this series of articles, considered from the point of view of you looking at your computer screen, positive x is to the right, positive y is upwards, and positive z is directly into the screen.
A normal is a vector pointing perpendicularly away from a surface. For example, assuming your desk is horizontal, the normal to its surface will be directly upwards: (0, 1, 0). The normal from a point on a sphere points directly away from the center, and so forth. Normals are almost always used as normalized vectors (see below).
Two vectors a and b can be added together to give a new vector
(a.x + b.x, a.y + b.y, a.z + b.z).
A Vector v may be multiplied by a scalar k giving a new vector (v.x * k, v.y * k, v.z * k). Multiplying a vector by a scalar changes only the magnitude of the vector, not the direction. For example, multiplying a vector by 2 doubles the length. Similarly, dividing a vector by a scalar is the same as multiplying by the inverse of the scalar – i.e., v / f is the same as v * (1 / f).
The magnitude of a vector v is simply its length (a scalar): Sqrt( v.x * v.x + v.y * v.y + v.z * v.z ). Vector magnitude is often represented by |v|.
A vector is said to be normalized if its length (or magnitude) is one. Given a vector v, its normalized form is given by v / |v|.
Vector Dot Product
Given two vectors v and w, the dot product is a scalar, calculated as v.x * w.x + v.y * w.y + v.z * w.z. This may seem a pointless computation, until we see that:
|v dot w =||v||*||w||* Cos( theta )|
…where theta is the angle between the two vectors. This can be easily re-arranged to compute theta, if required.
Vector Cross Product
Given two vectors v and w, the cross product is a vector:
(-v.Z * w.Y + v.Y * w.Z, v.Z * w.X - v.X * w.Z, -v.Y * w.X + v.X * w.Y )
Again, this looks like nonsense, until we discover that the cross product gives a vector which is perpendicular to both v and w.