diff --git a/sandbox/extraMath.lua b/sandbox/extraMath.lua index 80ac4b8..14138cb 100644 --- a/sandbox/extraMath.lua +++ b/sandbox/extraMath.lua @@ -1,4 +1,6 @@ -function math.lerp (a,b,t) +extraMath = {} + +function extraMath.lerp (a,b,t) -- intended to mirror C++ lerp -- linear interpolation assert(type(a)=="number") @@ -6,7 +8,8 @@ function math.lerp (a,b,t) assert(type(t)=="number") return a + t * (b - a) end -function math.CosineInterpolate(y1,y2,mu) + +function extraMath.CosineInterpolate(y1,y2,mu) -- see http://paulbourke.net/miscellaneous/interpolation/ assert(type(y1)=="number") assert(type(y2)=="number") @@ -15,7 +18,8 @@ function math.CosineInterpolate(y1,y2,mu) assert(type(mu2)=="number") return (y1*(1-mu2)+y2*mu2) end -function math._CosineInterpolateTableInner(tbl,elmt,t) + +function extraMath._CosineInterpolateTableInner(tbl,elmt,t) assert(type(tbl)=="table") assert(type(t)=="number") assert(type(elmt)=="number") @@ -25,20 +29,21 @@ function math._CosineInterpolateTableInner(tbl,elmt,t) return tbl[elmt].y end local t_scaled=(t-tbl[elmt].x)*(1/x_delta) - return math.CosineInterpolate(tbl[elmt].y,tbl[elmt+1].y,t_scaled) + return extraMath.CosineInterpolate(tbl[elmt].y,tbl[elmt+1].y,t_scaled) end -function math.CosineInterpolateTable(tbl,t) + +function extraMath.CosineInterpolateTable(tbl,t) assert(type(tbl)=="table") assert(type(t)=="number") assert(#tbl>1) for i=1,#tbl-1 do if tbl[i+1].x>t then - return math._CosineInterpolateTableInner(tbl,i,t) + return extraMath._CosineInterpolateTableInner(tbl,i,t) end end - return math._CosineInterpolateTableInner(tbl,#tbl-1,t) + return extraMath._CosineInterpolateTableInner(tbl,#tbl-1,t) end -function math.CubicInterpolate(y0,y1,y2,y3,mu) +function extraMath.CubicInterpolate(y0,y1,y2,y3,mu) -- see http://paulbourke.net/miscellaneous/interpolation/ assert(type(y0)=="number") assert(type(y1)=="number") @@ -52,7 +57,7 @@ function math.CubicInterpolate(y0,y1,y2,y3,mu) local a3 = y1; return(a0*mu*mu2+a1*mu2+a2*mu+a3); end -function math.CubicInterpolate2DTable(tbl,t) +function extraMath.CubicInterpolate2DTable(tbl,t) -- this takes an array with 2 elements each (x and y) -- and returns the Cubic interpolation for the (floating point) element t -- it would be tricky and not very useful allowing a table with 3 elements and t==1 @@ -65,21 +70,23 @@ function math.CubicInterpolate2DTable(tbl,t) assert(math.ceil(t)+1<=#tbl,"CubicInterpolate2DTable tbl must have one one more element than the size of t") local i = math.floor(t) local mu = t - i - local x = math.CubicInterpolate(tbl[i].x,tbl[i+1].x,tbl[i+2].x,tbl[i+3].x,mu) - local y = math.CubicInterpolate(tbl[i].y,tbl[i+1].y,tbl[i+2].y,tbl[i+3].y,mu) + local x = extraMath.CubicInterpolate(tbl[i].x,tbl[i+1].x,tbl[i+2].x,tbl[i+3].x,mu) + local y = extraMath.CubicInterpolate(tbl[i].y,tbl[i+1].y,tbl[i+2].y,tbl[i+3].y,mu) return x,y end -function math.lerpTest() - assert(math.lerp(1,2,0)==1) - assert(math.lerp(1,2,1)==2) - assert(math.lerp(2,1,0)==2) - assert(math.lerp(2,1,1)==1) - assert(math.lerp(2,1,.5)==1.5) + +function extraMath:lerpTest() + assert(extraMath.lerp(1,2,0)==1) + assert(extraMath.lerp(1,2,1)==2) + assert(extraMath.lerp(2,1,0)==2) + assert(extraMath.lerp(2,1,1)==1) + assert(extraMath.lerp(2,1,.5)==1.5) -- extrapolation - assert(math.lerp(1,2,-1)==0) - assert(math.lerp(1,2,2)==3) + assert(extraMath.lerp(1,2,-1)==0) + assert(extraMath.lerp(1,2,2)==3) end -function math.clamp(value,lo,hi) + +function extraMath.clamp(value,lo,hi) -- intended to mirror C++ clamp -- clamps value within the range of low and high assert(type(value)=="number") @@ -93,16 +100,18 @@ function math.clamp(value,lo,hi) end return value end -function math.clampTest() - assert(math.clamp(0,1,2)==1) - assert(math.clamp(3,1,2)==2) - assert(math.clamp(1.5,1,2)==1.5) - assert(math.clamp(0,2,3)==2) - assert(math.clamp(4,2,3)==3) - assert(math.clamp(2.5,2,3)==2.5) +function extraMath:clampTest() + assert(extraMath.clamp(0,1,2)==1) + assert(extraMath.clamp(3,1,2)==2) + assert(extraMath.clamp(1.5,1,2)==1.5) + + assert(extraMath.clamp(0,2,3)==2) + assert(extraMath.clamp(4,2,3)==3) + assert(extraMath.clamp(2.5,2,3)==2.5) end -function math.extraTests() - math.lerpTest() - math.clampTest() + +function extraMath:runTests() + extraMath:lerpTest() + extraMath:clampTest() end \ No newline at end of file diff --git a/sandbox/library.lua b/sandbox/library.lua index b5f6a02..b263192 100644 --- a/sandbox/library.lua +++ b/sandbox/library.lua @@ -1096,16 +1096,16 @@ function updateSystem:addEnergyDecayCurve(obj, total_time, curve_x, curve_y) }, update = function (self, obj, delta) self.elapsed_time = self.elapsed_time + delta - local time_ratio = math.clamp(0,1,self.elapsed_time / self.total_time) + local time_ratio = extraMath.clamp(0,1,self.elapsed_time / self.total_time) local curve={-- bah this is bad but until the update edit is better its needed {x = self.curve_x[1], y = self.curve_y[1]}, {x = self.curve_x[2], y = self.curve_y[2]}, {x = self.curve_x[3], y = self.curve_y[3]}, {x = self.curve_x[4], y = self.curve_y[4]} } - local energy_drain_per_second=math.CosineInterpolateTable(curve,time_ratio) + local energy_drain_per_second=extraMath.CosineInterpolateTable(curve,time_ratio) local new_energy=obj:getEnergy()+energy_drain_per_second*delta - obj:setEnergy(math.clamp(0,obj:getMaxEnergy(),new_energy)) + obj:setEnergy(extraMath.clamp(0,obj:getMaxEnergy(),new_energy)) end } self:addUpdate(obj,"energy decay",update_data) @@ -1145,14 +1145,14 @@ function updateSystem:addShieldDecayCurve(obj, total_time, curve_x, curve_y) }, update = function (self, obj, delta) self.elapsed_time = self.elapsed_time + delta - local time_ratio = math.clamp(0,1,self.elapsed_time / self.total_time) + local time_ratio = extraMath.clamp(0,1,self.elapsed_time / self.total_time) local curve={-- bah this is bad but until the update edit is better its needed {x = self.curve_x[1], y = self.curve_y[1]}, {x = self.curve_x[2], y = self.curve_y[2]}, {x = self.curve_x[3], y = self.curve_y[3]}, {x = self.curve_x[4], y = self.curve_y[4]} } - local maxShieldRatio=math.CosineInterpolateTable(curve,time_ratio) + local maxShieldRatio=extraMath.CosineInterpolateTable(curve,time_ratio) local shields = {} for i=0,obj:getShieldCount()-1 do table.insert(shields,math.min((obj:getShieldMax(i)*maxShieldRatio),obj:getShieldLevel(i))) @@ -1194,7 +1194,7 @@ function updateSystem:_addGenericOverclock(obj, overboosted_time, boost_time, ov assert(type(obj)=="table") assert(type(delta)=="number") self.time = self.time - delta - local scale = math.clamp(self.time/self.boost_time,0,1) + local scale = extraMath.clamp(self.time/self.boost_time,0,1) inner_update(self, obj, scale) -- if scale == 0 inner_update has already been called with 0, resulting in overclocks being turned off if scale == 0 then @@ -1243,9 +1243,9 @@ function updateSystem:addBeamBoostOverclock(obj, overboosted_time, boost_time, m -- 16 seems to be the max number of beams (seen via tweak menu) -- if the engine exports max number of beams it should be used rather than mirror all data for index=0,16 do - local beam_range = math.lerp(1,self.max_range_boosted,scale)*self.mirrored_data[index+1].range + local beam_range = extraMath.lerp(1,self.max_range_boosted,scale)*self.mirrored_data[index+1].range compatSetBeamWeaponRange(obj,index,beam_range) - local beam_cycle = math.lerp(1,self.max_cycle_boosted,scale)*self.mirrored_data[index+1].cycle_time + local beam_cycle = extraMath.lerp(1,self.max_cycle_boosted,scale)*self.mirrored_data[index+1].cycle_time compatSetBeamWeaponCycleTime(obj,index,beam_cycle) end end @@ -1275,8 +1275,8 @@ function updateSystem:addEngineBoostUpdate(obj, overboosted_time, boost_time, ma assert(type(self)=="table") assert(type(obj)=="table") assert(type(scale)=="number") - obj:setImpulseMaxSpeed(math.lerp(1,self.max_impulse_boosted,scale)*self.mirrored_data.impulse) - obj:setRotationMaxSpeed(math.lerp(1,self.max_turn_boosted,scale)*self.mirrored_data.turn_rate) + obj:setImpulseMaxSpeed(extraMath.lerp(1,self.max_impulse_boosted,scale)*self.mirrored_data.impulse) + obj:setRotationMaxSpeed(extraMath.lerp(1,self.max_turn_boosted,scale)*self.mirrored_data.turn_rate) end ) end @@ -1309,7 +1309,7 @@ function updateSystem:addOverclockableTractor(obj, spawnFunc) if orbiting:isValid() then local orbiting_update=update_self:getUpdateNamed(orbiting,"orbit target") if orbiting_update ~= nil then - orbiting_update.distance=math.lerp(0,max_dist,scale) + orbiting_update.distance=extraMath.lerp(0,max_dist,scale) end else table.remove(self.orbitingObj,i) @@ -1492,9 +1492,9 @@ function updateSystem:addArtifactCyclicalColorUpdate(obj, red_start, red1, red2, assert(type(self)=="table") assert(type(obj)=="table") assert(type(delta)=="number") - local r = math.lerp(self.red1,self.red2,((getScenarioTime()+self.red_start) % self.red_time)/self.red_time) - local g = math.lerp(self.green1,self.green2,((getScenarioTime()+self.green_start) % self.green_time)/self.green_time) - local b = math.lerp(self.blue1,self.blue2,((getScenarioTime()+self.blue_start) % self.blue_time)/self.blue_time) + local r = extraMath.lerp(self.red1,self.red2,((getScenarioTime()+self.red_start) % self.red_time)/self.red_time) + local g = extraMath.lerp(self.green1,self.green2,((getScenarioTime()+self.green_start) % self.green_time)/self.green_time) + local b = extraMath.lerp(self.blue1,self.blue2,((getScenarioTime()+self.blue_start) % self.blue_time)/self.blue_time) obj:setRadarTraceColor(math.floor(r),math.floor(g),math.floor(b)) end } diff --git a/sandbox/main.lua b/sandbox/main.lua index 6db1b93..a053ac3 100755 --- a/sandbox/main.lua +++ b/sandbox/main.lua @@ -5995,7 +5995,7 @@ function coloredSubspaceRift (x,y,destination_x,destination_y) destination_x = destination_x or 0, destination_y = destination_y or 0, update = function (self, obj, delta) - self.current_radius = math.clamp(self.current_radius+delta*(self.max_radius/self.max_time),0,self.max_radius) + self.current_radius = extraMath.clamp(self.current_radius+delta*(self.max_radius/self.max_time),0,self.max_radius) -- ***techincally*** this is probably wrong - the position of the orbit of the objects is based -- on the previous update, who cares though, but consider this a warning if reusing this code somewhere that matters for i=#all_objs,1,-1 do @@ -6081,7 +6081,7 @@ function gatewayRifts() max_radius = 3000, max_time = 120, update = function (self, obj, delta) - self.current_radius = math.clamp(self.current_radius+delta*(self.max_radius/self.max_time),0,self.max_radius) + self.current_radius = extraMath.clamp(self.current_radius+delta*(self.max_radius/self.max_time),0,self.max_radius) -- ***techincally*** this is probably wrong - the position of the orbit of the objects is based -- on the previous update, who cares though, but consider this a warning if reusing this code somewhere that matters for i=#all_objs,1,-1 do @@ -6374,7 +6374,7 @@ function addChristmasArtifact(waypoints) return end local px,py=obj:getPosition() - local x,y=math.CubicInterpolate2DTable(self.waypoints,self.current) + local x,y=extraMath.CubicInterpolate2DTable(self.waypoints,self.current) if distance(px,py,x,y)>desiredDelta then obj:setPosition(x,y) return @@ -23504,10 +23504,10 @@ function createPlayerShipKindling() update = function (self, obj, delta) -- in a small sign of mercy to players they get their best beams at 90% max heat rather than burning hotel -- it would be kind of cool to give extra damage or something, but given how long ships last this probably wont be seen - local heat=math.clamp(obj:getSystemHeat("beamweapons"),0,0.90) + local heat=extraMath.clamp(obj:getSystemHeat("beamweapons"),0,0.90) heat=heat/0.90 -- scale to that 0.90 = 1 - obj:setBeamWeapon(0, math.lerp(120,15,heat), math.lerp(-90,5,heat), math.lerp(500,1250,heat), 6, 8) - obj:setBeamWeapon(1, math.lerp(120,15,heat), math.lerp(90,-5,heat), math.lerp(500,1250,heat), 6, 8) + obj:setBeamWeapon(0, extraMath.lerp(120,15,heat), extraMath.lerp(-90,5,heat), extraMath.lerp(500,1250,heat), 6, 8) + obj:setBeamWeapon(1, extraMath.lerp(120,15,heat), extraMath.lerp(90,-5,heat), extraMath.lerp(500,1250,heat), 6, 8) end } update_system:addUpdate(playerKindling,"dynamic kindling beams",update_data) @@ -24811,13 +24811,13 @@ function createPlayerShipTorch() local update_data = { update = function (self, obj, delta) local upper_heat = 0.98 - local heat = math.clamp(obj:getSystemHeat("beamweapons"),0,upper_heat) + local heat = extraMath.clamp(obj:getSystemHeat("beamweapons"),0,upper_heat) heat = heat/upper_heat -- Arc, Dir, Range, Cycle Time, Dmg - obj:setBeamWeapon(0, 90, 0, 1000, math.lerp(6,3,heat), 3) - obj:setBeamWeapon(1, 45, -7.5, 900, math.lerp(6,2,heat), 4) - obj:setBeamWeapon(2, 45, 7.5, 900, math.lerp(6,2,heat), 4) - obj:setBeamWeapon(3, 30, 0, 700, math.lerp(6,1,heat), 5) + obj:setBeamWeapon(0, 90, 0, 1000, extraMath.lerp(6,3,heat), 3) + obj:setBeamWeapon(1, 45, -7.5, 900, extraMath.lerp(6,2,heat), 4) + obj:setBeamWeapon(2, 45, 7.5, 900, extraMath.lerp(6,2,heat), 4) + obj:setBeamWeapon(3, 30, 0, 700, extraMath.lerp(6,1,heat), 5) end } update_system:addUpdate(playerTorch,"dynamic heating cycle beams", update_data) @@ -42254,7 +42254,8 @@ function CubicMineObject:updateNow() local last_y = nil if #self.markers>=4 then for t=1,#self.markers-2,delta do - local x,y = math.CubicInterpolate2DTable(pos_tbl,t) + local x,y = extraMath.CubicInterpolate2DTable(pos_tbl,t) + local x,y = extraMath.CubicInterpolate2DTable(pos_tbl,t) if last_x == nil or distance(last_x,last_y,x,y) > min_mine_dist then last_x,last_y=x,y local newArtifact=nil @@ -49402,7 +49403,7 @@ end ------------------------- function runAllTests() getNumberOfObjectsStringTest() - math.extraTests() + extraMath:runTests() updateSystem:create():_test() end -- Probe functions