SoCoder -> Article Home -> Advanced Techniques
Created : 19 September 2013
Maths 101 - Episode 2: VectorsIn this article, we'll look at vectors and some things you can do with them.
I was originally going to matrices in this tutorial, but it then occurred to me that we should probably cover vectors first. As ever, unless otherwise stated, angles are in degrees for simplicity.
Scalars and VectorsIn everyday arithmetic, you usually scalar numbers - numbers that have simply have a magnitude. 1, 2, 10.3, -52 and 0 are all scalar quantities.
A vector is a quantity that exists in a multi-dimensional vector space, with the vector having a scalar quantity in each dimension of the space. You don't really need to know about vector spaces to use vectors, other than than vectors can only interact with other vectors in the same vector space (so you can't [directly] do stuff to 2D and 3D vectors at once, for instance). Typically in programming we will consider a 2 or 3 dimensional vector space, since our games will (probably) be in either a 2 or 3 dimensional world.
There are two ways of representing vectors. The Cartesian representation is the easiest to use in programming: we give the scalar quantities in each dimension as a list; for instance (2, 3) is a 2D vector signifying 2 units in the X dimension and 3 units in the Y dimension; or (-4, 8, 2) is a 3D vector signifying -4 units in the X dimension, 8 in the Y, and 2 in the Z.
The other representation is the Polar representation. In this, we give the magnitude of the vector and its direction. Unlike in the Cartesian representation, where all quantities that make up the representation are scalar, the direction component of the Polar representation will only be scalar when dealing with 2 dimensions. The magnitude is always scalar.
For the most part we will deal with the Cartesian representation, because it is easier to handle when programming. It is fairly easy, if you know trigonometry, to derive conversion formulae for 2D vectors to get between the Cartesian and Polar representations:
Cartesian -> Polar
r = sqrt(x * x + y * y)
theta = atan2(y, x)
Polar -> Cartesian
x = r * cos(theta)
y = r * sin(theta)
So, what can we do with vectors?
Addition and SubtractionVectors can be added and subtracted easily: just take the sum (or difference) of the quantities in the same dimension. This is why Cartesian is easier - to do this to Polar vectors, you would first need to convert them to Cartesian.
(2, 8) + (-3, 6) = (-1, 14)
(0, 5, 10) + (8, -2, 2) = (8, 3, 12)
Scalar MultiplicationYou cannot directly multiply two vectors together (but we can do something else, which we shall come on to in a moment), but you can multiply (or divide) a vector by a scalar. Just multiply each quantity by the scalar multiple!
Scalar multiplication can be easily applied to Polar vectors as well - the magnitude is multiplied by the scalar multiple, while the direction remains unchanged.
5 * (6, 10) = (30, 50)
0.1 * (100, 12, -18) = (10, 1.2, -1.8)
LengthThe length of any vector is the square root of the sum of the squares of each dimension, which you may have encountered in 2D as Pythagoras' Theorem. Obviously when dealing with Polar vectors, the length is already one of the values you have.
We often write |x| to mean 'the length of the vector x'.
|(3, 4)| = sqrt(3*3 + 4*4) = sqrt(25) = 5
|(3, 4, -8)| = sqrt(3*3 + 4*4 + (-8)*(-8)) = sqrt(89)
NormalisationA vector is said to be 'normalised' if its length is equal to 1. When we looked at scalar multiplication, we noted that scalar multiplication of a Polar vector only affects the length, so it should be fairly easy to see that scalar dividing a vector by its length will make it of length 1.
So, to normalise a Cartesian vector, just divide each of its dimensional quantities by the length of the whole vector!
Safety Warning: You cannot normalise the zero vector! The zero vector [(0, 0) in 2D, (0, 0, 0) in 3D, etc] is the only vector with length 0, and division by zero is not allowed!
(3, 4) normalises to (3/5, 4/5)
(1, 2, -2) normalises to (1/3, 2/3, -2/3)
The Dot ProductThe dot product is a special operation that can be applied to two vectors. Remember how we said before that vectors cannot be multiplied together? Well, instead, we can take their dot product.
The dot product takes two vectors of the same dimension, and returns a scalar quantity. It can be defined in two ways: one for Cartesian, and one for Polar. In programming, it is of course easier to dot together two Cartesian vectors, however the Polar version tells us some interesting things.
The Cartesian Definition
Let (a1, a2, ..., aN) and (b1, b2, ..., bN) be N-dimensional vectors. Then their dot product is:
(a1, a2, ..., aN) . (b1, b2, ..., bN) = a1*b1 + a2*b2 + ... + aN*bN
(2, 3) . (-1, 8) = 2*-1 + 3*8 = -2 + 24 = 22
(-1, -4, 12) . (8, -6, -4) = -1*8 + -4*-6 + 12*-4 = -8 + 24 + -48 = -32
The Polar Definition
Let (r1, d1) and (r2, d2) be N-dimensional vectors with magnitude r and direction d. Let theta be the angle between the two vectors.
Note: theta is only the difference between d1 and d2 in TWO dimensions - in higher dimensions, the angles are not scalar, but theta is, since it is the angle separating the vectors along the plane they are both on. If that doesn't quite make sense, just take my word for it!
Their dot product is:
r1 * r2 * cos(theta)
So what can we use the Dot Product for?The usefulness of the dot product actually comes from the Polar definition. Note the cos(theta) term. The cosine of any angle is equal to zero only when that angle is 90 + 180n degrees, where n is any integer (so -90, 90, 270, etc are values with cosine zero). This tells us that the dot product of any two perpendicular vectors is zero! This is a handy way of testing if two vectors form a 90 angle.
More usefully, we can use the dot product to calculate the angle between two vectors, in any dimension, in a single line using only one trigonometric function! Remember, if you have both vectors available in both Cartesian and Polar forms, then the two dot product formulae above will give the same results. So, if you have two vectors v and w, it follows that:
|v| * |w| * cos(theta) = v . w
...now divide through by (|v| * |w|)...
cos(theta) = (v . w) / (|v| * |w|)
...and take the arccosine of both sides...
theta = arccos((v . w) / (|v| * |w|))
(again, this won't work if one of the vectors is the zero vector)
The dot product can of course be calculated easily with the Cartesian version of the formula, so there you go: in a single line, we can find the angle between two vectors in any dimension!
I suspect a lot of this won't really be news to most people, but the dot product is an interesting and useful piece of maths that can reduce the amount of trig you need to do with vectors.
Next time, we'll consider the next step up from vectors: matrices, which we will later learn how to apply to vectors to transform them.