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. If we are using the ES6 syntax, we simply need to export each function (note the absence of a default):

export function add(a, b) { return { x: a.x + b.x, y: a.y + b.y}; }

We can then include the file in another one, i.e.:

import * as Vector from './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:

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

Vector Scaling

Multiplying a vector by a scalar value means multiplying both the x and y component.

export function scale(a, s) { return { x: a.x * s, y: a.y * s } }

Vector Dot Product

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

export 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:

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

Vector Normalization

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

export 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:

export function rotate(a, angle) { 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:

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