Experiments in Ray-Tracing, Part 2

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).

Vector Addition

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).

Vector-Scalar Multiplication

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).

Vector Magnitude

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|.

Vector Normalization

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.

Published: Sunday, July 13, 2008

Hacker News

You may be interested in...

Hackification.io is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to amazon.com. I may earn a small commission for my endorsement, recommendation, testimonial, and/or link to any products or services from this website.

Comments? Questions?