"use strict"; /** * 2 Dimensional Vector * @module vector2 */ module.exports = { /** * Creates a new, empty vector2 * * @return {vector2} a new 2D vector */ create: function create() { return [0, 0]; }, /** * Calculates the length of a vector2 * * @param {vector2} v vector to calculate length of * @return {Number} length of v */ length: function length(v) { var x = v[0]; var y = v[1]; return Math.sqrt(x * x + y * y); }, /** * Normalize a vector2 * * @param {vector2} out the receiving vector * @param {vector2} v vector to normalize * @return {vector2} out */ normalize: function normalize(out, v) { var len = this.length(v); if (len === 0) { out[0] = 0; out[1] = 0; } else { out[0] = v[0] / len; out[1] = v[1] / len; } return out; }, /** * Adds two vector2's * * @param {vector2} out the receiving vector * @param {vector2} v1 the first operand * @param {vector2} v2 the second operand * @return {vector2} out */ add: function add(out, v1, v2) { out[0] = v1[0] + v2[0]; out[1] = v1[1] + v2[1]; return out; }, /** * Subtracts vector v2 from vector v1 * * @param {vector2} out the receiving vector * @param {vector2} v1 the first operand * @param {vector2} v2 the second operand * @return {vector2} out */ sub: function sub(out, v1, v2) { out[0] = v1[0] - v2[0]; out[1] = v1[1] - v2[1]; return out; }, /** * Scales a vector2 by a scalar number * * @param {vector2} out the receiving vector * @param {vector2} v the vector to scale * @param {Number} s amount to scale the vector by * @return {vector2} out */ scale: function scale(out, v, s) { out[0] = v[0] * s; out[1] = v[1] * s; return out; }, /** * Calculates the dot product of two vector2's * * @param {vector2} v1 the first operand * @param {vector2} v2 the second operand * @return {Number} dot product of v1 and v2 */ dot: function dot(v1, v2) { return v1[0] * v2[0] + v1[1] * v2[1]; }, /** * Calculates the direction of two vector2's * * @param {vector2} v1 the first operand * @param {vector2} v2 the second operand * @return {Boolean} the direction of v1 and v2 */ direction: function direction(v1, v2) { return v1[0] * v2[1] - v2[0] * v1[1]; }, /** * Calculates the angle of two vector2's * * @param {vector2} v1 the first operand * @param {vector2} v2 the second operand * @return {Number} angle of v1 and v2 */ angle: function angle(v1, v2) { var theta = this.dot(v1, v2) / (this.length(v1) * this.length(v2)); return Math.acos(theta); }, /** * Calculates the angle of two vector2's with direction * * @param {vector2} v1 the first operand * @param {vector2} v2 the second operand * @param {Boolean} direction the direction of two vector2's * @return {Number} angle of v1 and v2 */ angleTo: function angleTo(v1, v2, direction) { var angle = this.angle(v1, v2); var angleLargeThanPI = this.direction(v1, v2) >= 0; if (direction) { if (angleLargeThanPI) { return Math.PI * 2 - angle; } return angle; } if (angleLargeThanPI) { return angle; } return Math.PI * 2 - angle; }, /** * whether a vector2 is zero vector * * @param {vector2} v vector to calculate * @return {Boolean} is or not a zero vector */ zero: function zero(v) { return v[0] === 0 && v[1] === 0; }, /** * Calculates the euclidian distance between two vector2's * * @param {vector2} v1 the first operand * @param {vector2} v2 the second operand * @return {Number} distance between a and b */ distance: function distance(v1, v2) { var x = v2[0] - v1[0]; var y = v2[1] - v1[1]; return Math.sqrt(x * x + y * y); }, /** * Creates a new vector2 initialized with values from an existing vector * * @param {vector2} v vector to clone * @return {Array} a new 2D vector */ clone: function clone(v) { return [v[0], v[1]]; }, /** * Return the minimum of two vector2's * * @param {vector2} out the receiving vector * @param {vector2} v1 the first operand * @param {vector2} v2 the second operand * @return {vector2} out */ min: function min(out, v1, v2) { out[0] = Math.min(v1[0], v2[0]); out[1] = Math.min(v1[1], v2[1]); return out; }, /** * Return the maximum of two vector2's * * @param {vector2} out the receiving vector * @param {vector2} v1 the first operand * @param {vector2} v2 the second operand * @return {vector2} out */ max: function max(out, v1, v2) { out[0] = Math.max(v1[0], v2[0]); out[1] = Math.max(v1[1], v2[1]); return out; }, /** * Transforms the vector2 with a mat2d * * @param {vector2} out the receiving vector * @param {vector2} v the vector to transform * @param {mat2d} m matrix to transform with * @return {vector2} out */ transformMat2d: function transformMat2d(out, v, m) { var x = v[0]; var y = v[1]; out[0] = m[0] * x + m[2] * y + m[4]; out[1] = m[1] * x + m[3] * y + m[5]; return out; } };