summaryrefslogtreecommitdiff
path: root/apps/plugins/lua/include_lua/math_ex.lua
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/lua/include_lua/math_ex.lua')
-rw-r--r--apps/plugins/lua/include_lua/math_ex.lua158
1 files changed, 158 insertions, 0 deletions
diff --git a/apps/plugins/lua/include_lua/math_ex.lua b/apps/plugins/lua/include_lua/math_ex.lua
new file mode 100644
index 0000000..c0bf55c
--- /dev/null
+++ b/apps/plugins/lua/include_lua/math_ex.lua
@@ -0,0 +1,158 @@
+--[[ Lua Missing Math functions
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2017 William Wilgus
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+]]
+
+--[[ Exposed Functions
+
+ _math.clamp
+ _math.clamp_roll
+ _math.d_sin
+ _math.d_cos
+ _math.d_tan
+ _math.i_sqrt
+
+]]
+
+local _math = {} do
+
+ -- internal constants
+ local _NIL = nil -- _NIL placeholder
+
+ -- clamps value to >= min and <= max
+ local function clamp(iVal, iMin, iMax)
+ if iMin > iMax then
+ local swap = iMin
+ iMin, iMax = iMax, swap
+ end
+
+ if iVal < iMin then
+ return iMin
+ elseif iVal < iMax then
+ return iVal
+ end
+
+ return iMax
+ end
+
+ -- clamps value to >= min and <= max rolls over to opposite
+ local function clamp_roll(iVal, iMin, iMax)
+ if iMin > iMax then
+ local swap = iMin
+ iMin, iMax = iMax, swap
+ end
+
+ if iVal < iMin then
+ iVal = iMax
+ elseif iVal > iMax then
+ iVal = iMin
+ end
+
+ return iVal
+ end
+
+ local function i_sqrt(n)
+ -- Newtons square root approximation
+ if n < 2 then return n end
+ local g = n / 2
+ local l = 1
+
+ for c = 1, 25 do -- if l,g haven't converged after 25 iterations quit
+
+ l = (n / g + g)/ 2
+ g = (n / l + l)/ 2
+
+ if g == l then return g end
+ end
+
+ -- check for period-two cycle between g and l
+ if g - l == 1 then
+ return l
+ elseif l - g == 1 then
+ return g
+ end
+
+ return _NIL
+ end
+
+ local function d_sin(iDeg, bExtraPrecision)
+ --[[ values are returned multiplied by 10000
+ II | I 180-90 | 90-0
+ ---(--)--- -------(--)-------
+ III | IV 180-270 | 270-360
+
+ sine is only positive in quadrants I , II => 0 - 180 degrees
+ sine 180-360 degrees is a reflection of sine 0-180
+ Bhaskara I's sine approximation formula isn't overly accurate
+ but it is close enough for rough image work.
+ ]]
+ local sign, x
+ -- no negative angles -10 degrees = 350 degrees
+ if iDeg < 0 then
+ x = 360 + (iDeg % 360)
+ else --keep rotation in 0-360 range
+ x = iDeg % 360
+ end
+
+ -- reflect II & I onto III & IV
+ if x > 180 then
+ sign = -1
+ x = x % 180
+ else
+ sign = 1
+ end
+
+ local x1 = x * (180 - x)
+
+ if bExtraPrecision then -- ~halves the largest errors
+ if x <= 22 or x >= 158 then
+ return sign * 39818 * x1 / (40497 - x1)
+ elseif (x >= 40 and x <= 56) or (x > 124 and x < 140) then
+ return sign * 40002 * x1 / (40450 - x1)
+ elseif (x > 31 and x < 71) or (x > 109 and x < 150) then
+ return sign * 40009 * x1 / (40470 - x1)
+ end
+ end
+
+ --multiplied by 10000 so no decimal in results (RB LUA is integer only)
+ return sign * 40000 * x1 / (40497 - x1)
+ end
+
+ local function d_cos(iDeg, bExtraPrecision)
+ --cos is just sine shifed by 90 degrees CCW
+ return d_sin(90 - iDeg, bExtraPrecision)
+ end
+
+ local function d_tan(iDeg, bExtraPrecision)
+ --tan = sin0 / cos0
+ return (d_sin(iDeg, bExtraPrecision) * 10000 / d_sin(90 - iDeg, bExtraPrecision))
+ end
+
+ --expose functions to the outside through _math table
+ _math.clamp = clamp
+ _math.clamp_roll = clamp_roll
+ _math.i_sqrt = i_sqrt
+ _math.d_sin = d_sin
+ _math.d_cos = d_cos
+ _math.d_tan = d_tan
+end -- missing math functions
+
+return _math