light-chart
Version:
Charts for mobile visualization.
210 lines (206 loc) • 5.01 kB
JavaScript
/**
* 2 Dimensional Vector
* @module vector2
*/
module.exports = {
/**
* Creates a new, empty vector2
*
* @return {vector2} a new 2D vector
*/
create() {
return [ 0, 0 ];
},
/**
* Calculates the length of a vector2
*
* @param {vector2} v vector to calculate length of
* @return {Number} length of v
*/
length(v) {
const x = v[0];
const 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(out, v) {
const 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(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(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(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(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(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(v1, v2) {
const 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(v1, v2, direction) {
const angle = this.angle(v1, v2);
const 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(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(v1, v2) {
const x = v2[0] - v1[0];
const 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(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(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(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(out, v, m) {
const x = v[0];
const 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;
}
};