Skip to content

Instantly share code, notes, and snippets.

@bohnacker

bohnacker/add.js

Last active Sep 4, 2017
Embed
What would you like to do?
Vector utility functions
/**
* Adds two (or more) vectors.
*
* @function add
* @param {Array|Object} vector1 The first vector
* @param {Array|Object} vector2 The second vector
* @param {Array|Object} [vector3] The third vector, ...
* @return {Object} The resulting vector
*/
function add(v1, v2) {
var x = (v1[0] || v1.x || 0) + (v2[0] || v2.x || 0);
var y = (v1[1] || v1.y || 0) + (v2[1] || v2.y || 0);
var z = (v1[2] || v1.z || 0) + (v2[2] || v2.z || 0);
var w = (v1[3] || v1.w || 0) + (v2[3] || v2.w || 0);
// if there are more than two vectors given
if (arguments.length > 2) {
for (var i = 2; i < arguments.length; i++) {
x += (arguments[i][0] || arguments[i].x || 0);
y += (arguments[i][1] || arguments[i].y || 0);
z += (arguments[i][2] || arguments[i].z || 0);
w += (arguments[i][3] || arguments[i].w || 0);
}
}
return {x:x, y:y, z:z, w:w};
}
/**
* Calculates the average angle of an array of vectors. A vector
* could be any object, that has x, y, [z] and [w] properties or an
* array with 2, 3 or 4 numbers.
*
* @function average
* @param {Array|Object} vector(s) The vectors or one vector
* @param {Array|Object} [vector] The second vector, ...
* @return {Object} The normalized average vector
* @dependency normalize(), add()
*/
function average(vectors) {
var res = {x:0, y:0, z:0, w:0};
if (arguments.length == 1) {
for (var i = 0; i < vectors.length; i++) {
var v = normalize(vectors[i]);
res = add(res, v);
}
} else {
for (var i = 0; i < arguments.length; i++) {
var v = normalize(arguments[i]);
res = add(res, v);
}
}
return normalize(res);
}
/**
* Normalizes a vector.
*
* @function averageVector
* @param {Array|Object|Number} vectors The vector or the x coordinate
* @param {Number} [y] The y coordinate
* @param {Number} [z] The z coordinate
* @param {Number} [w] The w coordinate
* @return {Object} The normalized vector
*/
function normalize(vector) {
var x = vector[0] || vector.x || arguments[0] || 0;
var y = vector[1] || vector.y || arguments[1] || 0;
var z = vector[2] || vector.z || arguments[2] || 0;
var w = vector[3] || vector.w || arguments[3] || 0;
var l = Math.sqrt(x*x + y*y + z*z + w*w);
if (l != 0) {
x /= l;
y /= l;
z /= l;
w /= l;
}
return {x:x, y:y, z:z, w:w};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment