diff --git a/libs/bluemath.js b/libs/bluemath.js index 7ee90b1..5280786 100644 --- a/libs/bluemath.js +++ b/libs/bluemath.js @@ -1,15 +1,127 @@ // 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(components) { - this.components = components; + 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)); } } -class tensor { - contructor(dimentions,rank) { - this.componants = Math.pow(rank,dimentions); - this.baseVectors = dimentions; +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])); } }