UNPKG

processing-js

Version:

For the project website, visit http://processingjs.org

245 lines (230 loc) • 5.8 kB
module.exports = function(options, undef) { var PConstants = options.PConstants; function PVector(x, y, z) { this.x = x || 0; this.y = y || 0; this.z = z || 0; } PVector.fromAngle = function(angle, v) { if (v === undef || v === null) { v = new PVector(); } v.x = Math.cos(angle); v.y = Math.sin(angle); return v; }; PVector.random2D = function(v) { return PVector.fromAngle(Math.random() * PConstants.TWO_PI, v); }; PVector.random3D = function(v) { var angle = Math.random() * PConstants.TWO_PI; var vz = Math.random() * 2 - 1; var mult = Math.sqrt(1 - vz * vz); var vx = mult * Math.cos(angle); var vy = mult * Math.sin(angle); if (v === undef || v === null) { v = new PVector(vx, vy, vz); } else { v.set(vx, vy, vz); } return v; }; PVector.dist = function(v1, v2) { return v1.dist(v2); }; PVector.dot = function(v1, v2) { return v1.dot(v2); }; PVector.cross = function(v1, v2) { return v1.cross(v2); }; PVector.sub = function(v1, v2) { return new PVector(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z); }; PVector.angleBetween = function(v1, v2) { return Math.acos(v1.dot(v2) / Math.sqrt(v1.magSq() * v2.magSq())); }; PVector.lerp = function(v1, v2, amt) { // non-static lerp mutates object, but this version returns a new vector var retval = new PVector(v1.x, v1.y, v1.z); retval.lerp(v2, amt); return retval; }; // Common vector operations for PVector PVector.prototype = { set: function(v, y, z) { if (arguments.length === 1) { this.set(v.x || v[0] || 0, v.y || v[1] || 0, v.z || v[2] || 0); } else { this.x = v; this.y = y; this.z = z; } }, get: function() { return new PVector(this.x, this.y, this.z); }, mag: function() { var x = this.x, y = this.y, z = this.z; return Math.sqrt(x * x + y * y + z * z); }, magSq: function() { var x = this.x, y = this.y, z = this.z; return (x * x + y * y + z * z); }, setMag: function(v_or_len, len) { if (len === undef) { len = v_or_len; this.normalize(); this.mult(len); } else { var v = v_or_len; v.normalize(); v.mult(len); return v; } }, add: function(v, y, z) { if (arguments.length === 1) { this.x += v.x; this.y += v.y; this.z += v.z; } else if (arguments.length === 2) { // 2D Vector this.x += v; this.y += y; } else { this.x += v; this.y += y; this.z += z; } }, sub: function(v, y, z) { if (arguments.length === 1) { this.x -= v.x; this.y -= v.y; this.z -= v.z; } else if (arguments.length === 2) { // 2D Vector this.x -= v; this.y -= y; } else { this.x -= v; this.y -= y; this.z -= z; } }, mult: function(v) { if (typeof v === 'number') { this.x *= v; this.y *= v; this.z *= v; } else { this.x *= v.x; this.y *= v.y; this.z *= v.z; } }, div: function(v) { if (typeof v === 'number') { this.x /= v; this.y /= v; this.z /= v; } else { this.x /= v.x; this.y /= v.y; this.z /= v.z; } }, rotate: function(angle) { var prev_x = this.x; var c = Math.cos(angle); var s = Math.sin(angle); this.x = c * this.x - s * this.y; this.y = s * prev_x + c * this.y; }, dist: function(v) { var dx = this.x - v.x, dy = this.y - v.y, dz = this.z - v.z; return Math.sqrt(dx * dx + dy * dy + dz * dz); }, dot: function(v, y, z) { if (arguments.length === 1) { return (this.x * v.x + this.y * v.y + this.z * v.z); } return (this.x * v + this.y * y + this.z * z); }, cross: function(v) { var x = this.x, y = this.y, z = this.z; return new PVector(y * v.z - v.y * z, z * v.x - v.z * x, x * v.y - v.x * y); }, lerp: function(v_or_x, amt_or_y, z, amt) { var lerp_val = function(start, stop, amt) { return start + (stop - start) * amt; }; var x, y; if (arguments.length === 2) { // given vector and amt amt = amt_or_y; x = v_or_x.x; y = v_or_x.y; z = v_or_x.z; } else { // given x, y, z and amt x = v_or_x; y = amt_or_y; } this.x = lerp_val(this.x, x, amt); this.y = lerp_val(this.y, y, amt); this.z = lerp_val(this.z, z, amt); }, normalize: function() { var m = this.mag(); if (m > 0) { this.div(m); } }, limit: function(high) { if (this.mag() > high) { this.normalize(); this.mult(high); } }, heading: function() { return (-Math.atan2(-this.y, this.x)); }, heading2D: function() { return this.heading(); }, toString: function() { return "[" + this.x + ", " + this.y + ", " + this.z + "]"; }, array: function() { return [this.x, this.y, this.z]; } }; function createPVectorMethod(method) { return function(v1, v2) { var v = v1.get(); v[method](v2); return v; }; } for (var method in PVector.prototype) { if (PVector.prototype.hasOwnProperty(method) && !PVector.hasOwnProperty(method)) { PVector[method] = createPVectorMethod(method); } } return PVector; };