Vector Library

As we move forward in game programming, it would be very useful to have a library for working with vectors and vector-like objects. Particularly, functionality like normalizing, dot product, addition and subtraction, all are commonly used in game math.

To implement such a library we would like to place all the related code in a module by itself, say Vector, which we could include in other files. Let's place this module in its own JavaScript file, vector.js, and export it with the CommonJS Module pattern:

module.exports = exports = { add: add, subtract: subtract, dotProduct: dotProduct, magnitude: magnitude, normalize: normalize, rotate: rotate, perpendicular: perpendicular }

We populate our exported object with functions as our properties, thus when we include the file in another one, i.e.:

const Vector = require('./vector');

We can use these functions by referencing the property names:

var a = {x: 10, y: 10} var b = {x: 5, y: -5} var c = Vector.add(a, b)

The vector c is the result of the addition of vectors a and b, and will be {x: 15, y: 5}.

In most programming languages, we'd also want to define a vector class that would have properties x and y, but as a dynamically-typed programming language, we can supply any object to our functions and, provided it has an x and y property, everything will work.

All that is left is to implement the various vector operations.

Vector Addition and Subtraction

Adding and subtracting vectors is simply a matter of adding or subtracting their x and y components:

function add(a, b) { return { x: a.x + b.x, y: a.y + b.y } } function subtract(a, b) { return { x: a.x - b.x, y: a.y - b.y } }

Vector Dot Product

The dot product is the sum of the products of the vector's x and y components:

function dotProduct(a, b) { return a.x * b.x + a.y + b.y; }

Vector magnitude

The magnitude (or length) of the vector is calculated using Pythagoras's theorem:

function magnitude(a) { return Math.sqrt(a.x * a.x + b.x * b.x); }

Vector Normalization

Normalizing (scaling to magnitude 1) a vector is a simple matter of dividing its components by the magnitude:

function normalize(a) { var mag = magnitude(a); return { x: a.x / mag, y: a.y / mag } }

Rotation about Z

Rotation about the z-axis is accomplished by multiplying the vector by a rotation matrix. This can be expressed by extrapolating the matrix mulptiplication into two equations, one to calculate x and one to calculate y:

function rotate(a) { return { x: a.x * Math.cos(angle) - a.y * Math.sin(angle), y: a.x * Math.sin(angle) + a.y * Math.cos(angle) } }

Finding a Perpendicular Vector

Another useful ability is finding a perpendicular vector. We can do this by flipping the x and y axis, and inverting one of their signs:

function perpendicular(a) { return { x: -a.y, y: a.x } }