// bluemath.js // This library adds advanced math objects function deg2rad (deg) { return ((Math.PI*2)/360)*deg; } function rad2deg (rad) { return (1/deg2rad(1))*rad; } class vector { constructor(dimentions=[0]) { var me = this; this.d = Array.isArray(dimentions) ? dimentions.map(d => !isNaN(d)) : [0]; if (me.d.length == 2) { this.getRadAngle = function (vec) { vec = vec instanceof vector ? vec : new vector([0,0]); var xydims = vec.d.length == 2 ? vec.d : [...me.d.map((d,i) => vec[i] ? vec[i] : 0)]; return Math.atan2(xydims[1] - me.d[1], xydims[0] - me.d[0]); } this.getDegAngle = function (vec) { return rad2deg(me.getRadAngle(vec)); } this.resize = function (newLength) { var angle = me.getDegAngle(); var soh = Math.sin(angle) * newLength; var cah = Math.cos(angle) * newLength; me.d = [cah,soh]; } } } add(vec=new vector([...this.d.map(d => 0)]) { vec = vec instanceof vector ? vec : new vector([0]); var longest = vec.d.length > this.d.length ? vec.d : this.d; var shortest = vec.d.length < this.d.length ? vec.d : this.d; return new vector([...longest.map(function (value,index) { var small = shortest[index]; if !isNaN(small) { return value + small; } else { return value; } })]); } mult(vec=new vector([...this.d.map(d => 1)])) { vec = vec instanceof vector ? vec : new vector([0]); var longest = vec.d.length > this.d.length ? vec.d : this.d; var shortest = vec.d.length < this.d.length ? vec.d : this.d; return new vector([...longest.map(function (value,index) { var small = shortest[index]; if (!isNaN(small) { return value * small; } else { value; } })]); } mag(mult=1) { mult = !isNaN(mult) ? mult : 1; return this.mult(new vector([...this.d.map(d => mult)])); } square() { return this.mult(this); } getDistance(origin = new vector([...this.d.map(d => 0)])) { origin = origin instanceof vector ? origin : new vector([...this.d.map(d => 0)]); return Math.sqrt(this.d.map(function (value, index) { var ori = !isNaN(origin.d[index]) ? origin.d[index] : 0; return Math.pow(ori - value, 2); }).reduce((a,b) => a + b)); } } function rad2vec (rad) { var x = Math.cos(rad); var y = Math.sin(rad); return new vector([x,y]); } function deg2vec (deg) { //abstraction, really just for sanity return rad2vec(deg2rad(deg)); } function getAngle(ax,ay,bx,by) { var deltaX = bx - ax; var deltaY = by - ay; return rad2deg(Math.atan2(deltaY,deltaX)); } function reflect(inAngle,surfaceAngle) { var normal = surfaceAngle+90; var theta1 = normal - inAngle; var theta2 = normal + theta1; return theta2; } class bound { constructor (min=[-Infinity],max=[Infinity]) { // Insure both inputs are arrays with valid numbers min = Array.isArray(min) ? min.map(value => !isNaN(value) ? value : -Infinity) : [-Infinity]; max = Array.isArray(max) ? max.map(value => !isNaN(value) ? value : -Infinity) : [Infinity]; // Insure both arrays are equal in size while( min.length != max.length ) { if (min.length > max.length) { max.push(Infinity); } else { min.push(-Infinity); } } // Accept filtered bounds this.min = min; this.max = max; } inbounds(valueArray=[...this.min.map(v => 0)]) { if (valueArray.length != this.min.length) { return false } return valueArray.map((value,index) => (value >= this.min[index]) && (value <= this.max[index])).reduce((a,b) => a && b); } normalize(valueArray=[...this.min.map(v => 0)]) { if (valueArray.length != this.min.length) { return [...this.min.map(v => 0)]; } return valueArray.map((value,index) => (value - this.min[index])/(this.max[index] - this.min[index])); } clamp(valueArray=[...this.min.map(v => 0)]) { if (valueArray.length != this.min.length) { return [...this.min.map((v,i) => Math.min(Math.max(0, v), this.max[i]))]; } return valueArray.map((value,index) => Math.min(Math.max(value,this.min[index]),this.max[index])); } }