(function(){ var vec2 = function (a,b){ this.a = a this.b = b } vec2.prototype.magnitude = function(){ return this.b-this.a } vec2.prototype.length = function(){ return abs(this.b-this.a) } vec2.prototype.dist = function(){ return dist(0,this.a,0,this.b) } vec2.prototype.clone = function(){ return new vec2(this.a, this.b) } vec2.prototype.abs = function(){ if (this.b < this.a) { this.invert() } return this } vec2.prototype.invert = function(){ this.a = this.a ^ this.b this.b = this.a ^ this.b this.a = this.a ^ this.b return this } vec2.prototype.midpoint = function(){ return lerp(0.5, this.a, this.b) } vec2.prototype.eq = function(v){ return this.a == v.a && this.b == v.b } vec2.prototype.add = function(n){ this.a += n this.b += n return this } vec2.prototype.sub = function(n){ this.a -= n this.b -= n return this } vec2.prototype.mul = function(n){ this.a *= n this.b *= n return this } vec2.prototype.div = function(n){ this.a /= n this.b /= n return this } vec2.prototype.setPosition = function(n){ var len = this.length() this.a = n this.b = n + len } vec2.prototype.setLength = function(n){ this.b = this.a + n } vec2.prototype.normalize = function(){ var dim = max(this.a, this.b) this.a = this.a/dim this.b = this.b/dim return this } vec2.prototype.contains = function(n){ return this.a <= n && n <= this.b } vec2.prototype.containsCenter = function(n){ return this.a < n && n < this.b } vec2.prototype.containsDisc = function(n,r){ return this.a <= n-r && n+r <= this.b } vec2.prototype.clamp = function(n){ return clamp(n, this.a, this.b) } vec2.prototype.clampDisc = function(n,r){ return clamp(n, this.a+r, this.b-r) } vec2.prototype.intersects = function(v){ if (this.a == v.a || this.b == v.b || this.a == v.b || this.b == v.a) { return true } else if (this.a < v.a) { return (v.a < this.b && this.b <= v.b) || (this.a < v.b && v.b <= this.b) } else if (this.a > v.a) { return (this.a < v.b && v.b <= this.b) || (v.a < this.b && this.b <= v.b) } } vec2.prototype.adjacent = function(v){ if (this.a == v.a || this.b == v.b || this.a == v.b || this.b == v.a) { return true } return false } vec2.prototype.union = function(v){ if (this.intersects(v)) { return new vec2( min(this.a,v.a), max(this.b, v.b) ) } } vec2.prototype.intersection = function(v){ if (this.intersects(v)) { return new vec2( max(this.a,v.a), min(this.b, v.b) ) } } // given two vectors, test how they overlap // return the set of overlapping segments in the initial vector, labelled with sides vec2.prototype.split = function(v, left, right){ var intervals = [], _len if (this.eq(v)) { intervals.push([ new vec2( this.a, this.b ), left | right ]) } // a---A===b---B (rightways overlap) else if (this.contains(v.a) && v.contains(this.b)) { intervals.push([ new vec2( this.a, v.a ), left ]) intervals.push([ new vec2( v.a, this.b ), right ]) } // A---a===B---b (leftways overlap) else if (v.contains(this.a) && this.contains(v.b)) { intervals.push([ new vec2( this.a, v.b ), left ]) intervals.push([ new vec2( v.b, this.b ), right ]) } // a---A===B---b (contains v) else if (this.contains(v.a) && this.contains(v.b)) { intervals.push([ new vec2( this.a, v.a ), left ]) intervals.push([ new vec2( v.a, v.b ), 0 ]) intervals.push([ new vec2( v.b, this.b ), right ]) } // A---a===b---B (contained in v) else { // if (v.contains(this.a) && v.contains(v.b)) { intervals.push([ new vec2( this.a, this.b ), left | right ]) } // cull empty vectors _len = intervals.length if (_len > 1) { if (intervals[0][0].magnitude() == 0) { intervals[1][1] |= intervals[0][1] intervals.shift() } else if (intervals[_len-1][0].magnitude() == 0) { intervals[_len-2][1] |= intervals[_len-1][1] intervals.pop() } } return intervals } vec2.prototype.toString = function(){ return "[" + ~~this.a + " " + ~~this.b + "]" } vec2.prototype.serialize = function(){ return [ ~~this.a, ~~this.b ] } vec2.prototype.quantize = function(n){ n = n || 10 this.a = quantize(this.a, n) this.b = quantize(this.b, n) } if ('window' in this) { window.vec2 = vec2 } else { module.exports = vec2 } })()