Chances are that if you’re a game developer (aspiring or otherwise), you’ve probably heard some mention of the dot product somewhere along the line. What is it? What’s it for? What does it tell you? Lets find out!
We’ll start off by stating what the formula for the dot product actually is:
This is using some mathematical symbols that we haven’t used before, so lets spell it out in English instead:
The dot product of the vector named U and the vector named V is equal to the magnitude of U multiplied by the magnitude of V multiplied by the cosine of the angle between them.
The name of this curious operation derives from the fact that a dot symbol (·) is used in math to represent a multiplication (where using an X might otherwise be confusing) and that a Product is the value you get when you multiply two numbers together.
The formula itself is derived some some algebraic manipulation of both the Law of Cosines and Vector Subtraction. More specifically, if you treat the two vectors as the sides of a triangle, and you arrange their tails so that they overlap, then the third side of the triangle is the subtraction of one vector from the other. Check the page on the topic of vector subtraction if you need a refresher on why that is the case.
The calculation of the dot product is done by adding together the products of the x and y components of the vectors. Specifically:
This makes calculating the dot product the first “strange” vector operation we’ve come across, because the result you get is a number (technically, a scalar; math nerds sometimes refer to the dot product as the scalar product for this reason). Up until now, when we’ve done an operation on two vectors (addition, subtraction or negation) the result was always another vector.
The dot product is a number that is related to the cosine of the angle between two vectors (vectors contain no position information blah blah blah, you know the drill by now). However, it is the multiplication of not only the cosine of that angle but ALSO their lengths; vectors can have any length at all, so you may be having a hard time trying to decide why this is even useful.
Lets say you made sure that the magnitude of your vectors was always 1 when you calculated the dot product. If you did that, then this:
Thus the dot product of two vectors that have a magnitude of 1 is the cosine of the angle between them! Any vector can be turned into a vector with a magnitude of 1 by scaling it, which we also talked about on the basic vector math page. It’s almost as if I had some plan in mind when I came up with the order of these topics or something! This operation is called Normalizing and the result is referred to as a Unit Vector (because its length is 1 unit long).
Normalizing a vector is something that we already know how to do, even if we don’t realize it. Remember that a vector can be thought of as the hypotenuse of a right triangle and that its length is tied to the length of the other two sides of the triangle (here the X and Y components of the vector). As outlined in the discussion on simple vector operations, if you scale both components of the vector by the same value, the direction remains the same but the magnitude changes.
Dividing anything by itself results in the value being 1, so simply dividing each individual component in the vector by its length makes the overall length 1. I’ve visualized that here with a 3-4-5 triangle because that’s how I roll:
Note however that this is not strictly needed; remember our good old friend algebraic manipulation, who always shows up to parties unannounced and eats all of the corn chips because he’s a hog. You can manipulate the dot product equation to look like this:
If you do this, you can get the cosine of the angle of any two vectors you want, even if they’re not unit vectors.; the cost being that you need to know the magnitude of both vectors as well. That requires you to calculate two square roots, which could conceivably slow things down for you if you do it a lot (always make sure to check such things, never assume!) so that’s something to think about. If you already had the magnitudes laying around from some other operation that required them, this might not be so bad.
The good thing about the normalized vector approach is that you only need to calculate the magnitude once, and once that’s done you can always assume that it’s 1.
Now all the pieces are in place; We know how to:
- Normalize any vector to turn it into a unit vector (vector with a length of 1 that retains the direction of the initial vector)
- Calculate the dot product of two such vectors, which ultimately gives us the cosine of the angle between the two
Of course, the profit here is some stunningly cool game action, but what about step #3? There are a variety of reasons that you might want to know the angle between two different vectors.
Example idea #1
Lets say that you have a top down game where each player has a vector that indicates what direction they’re facing. The players are all armed with bows, but they also have shields in place that they could use to block an arrow that was shot at them. You could calculate the dot product of the vectors representing the facing of the shooter and the target to see if the shield is in a position where it can block the arrow or not.
Example idea #2
Completely different top down game where each player has a vector that indicates what direction they’re facing. This time the players are armed with guns (just to be different from the first example) AND they can walk in one direction while facing another direction entirely. The dot product between the direction they’re facing and the direction they’re moving could be used to make the player walk slower when walking backwards..
To be more rigorously mathematical about things, here are some things to think about:
- The cosine of 90° is 0, so if the dot product is 0, the two vectors are perpendicular to each other. (a math nerd term for this is orthogonal)
- Fun fact! A consequence of the mathemagics of multiplying by 0 is that if all you want to check for is that two vectors are perpendicular to each other, you don’t need to bother normalizing them first; no matter what their lengths are, the dot product is still 0 because the cosine is 0.
- The cosine of 0° is 1, so the closer the dot product is to 1, the closer the two vectors are to pointing in the same direction; when it’s 1 they are facing the same direction. (math nerds might refer to this as being parallel)
- The cosine of 180° is -1, so the closer the dot product is to -1, the closer the two vectors are to pointing in opposite directions; when it’s -1 they are facing opposite directions. (to be honest I’m not sure if there’s a math nerd term for this. I feel ashamed, so ashamed. They’re still parallel though!)
That’s all for this article! Now go forth and multiply those vector components!