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.lua159
1 files changed, 159 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 0000000000..bd4cc58765
--- /dev/null
+++ b/apps/plugins/lua/include_lua/math_ex.lua
@@ -0,0 +1,159 @@
1--[[ Lua Missing Math functions
2/***************************************************************************
3 * __________ __ ___.
4 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
5 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
6 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
7 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 * \/ \/ \/ \/ \/
9 * $Id$
10 *
11 * Copyright (C) 2017 William Wilgus
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22]]
23
24--[[ Exposed Functions
25
26 _math.clamp
27 _math.clamp_roll
28 _math.d_sin
29 _math.d_cos
30 _math.d_tan
31 _math.i_sqrt
32
33]]
34
35local _math = {} do
36
37 -- internal constants
38 local _NIL = nil -- _NIL placeholder
39
40 -- clamps value to >= min and <= max
41 local function clamp(iVal, iMin, iMax)
42 if iMin > iMax then
43 local swap = iMin
44 iMin, iMax = iMax, swap
45 end
46
47 if iVal < iMin then
48 return iMin
49 elseif iVal < iMax then
50 return iVal
51 end
52
53 return iMax
54 end
55
56 -- clamps value to >= min and <= max rolls over to opposite
57 local function clamp_roll(iVal, iMin, iMax)
58 if iMin > iMax then
59 local swap = iMin
60 iMin, iMax = iMax, swap
61 end
62
63 if iVal < iMin then
64 iVal = iMax
65 elseif iVal > iMax then
66 iVal = iMin
67 end
68
69 return iVal
70 end
71
72 local function i_sqrt(n)
73 -- Newtons square root approximation
74 if n < 2 then return n end
75 local g = n / 2
76 local l = 1
77
78 for c = 1, 25 do -- if l,g haven't converged after 25 iterations quit
79
80 l = (n / g + g)/ 2
81 g = (n / l + l)/ 2
82
83 if g == l then return g end
84 end
85
86 -- check for period-two cycle between g and l
87 if g - l == 1 then
88 return l
89 elseif l - g == 1 then
90 return g
91 end
92
93 return _NIL
94 end
95
96 local function d_sin(iDeg, bExtraPrecision)
97 --[[ values are returned multiplied by 10000
98 II | I 180-90 | 90-0
99 ---(--)--- -------(--)-------
100 III | IV 180-270 | 270-360
101
102 sine is only positive in quadrants I , II => 0 - 180 degrees
103 sine 180-360 degrees is a reflection of sine 0-180
104 Bhaskara I's sine approximation formula isn't overly accurate
105 but it is close enough for rough image work.
106 ]]
107 local sign, x
108 -- no negative angles -10 degrees = 350 degrees
109 if iDeg < 0 then
110 x = 360 + (iDeg % 360)
111 else --keep rotation in 0-360 range
112 x = iDeg % 360
113 end
114
115 -- reflect II & I onto III & IV
116 if x > 180 then
117 sign = -1
118 x = x % 180
119 else
120 sign = 1
121 end
122
123 local x1 = x * (180 - x)
124
125 if bExtraPrecision then -- ~halves the largest errors
126 if x <= 22 or x >= 158 then
127 return sign * 39818 * x1 / (40497 - x1)
128 elseif (x >= 40 and x <= 56) or (x > 124 and x < 140) then
129 return sign * 40002 * x1 / (40450 - x1)
130 elseif (x > 31 and x < 71) or (x > 109 and x < 150) then
131 return sign * 40009 * x1 / (40470 - x1)
132 end
133 end
134
135 --multiplied by 10000 so no decimal in results (RB LUA is integer only)
136 return sign * 40000 * x1 / (40497 - x1)
137 end
138
139 local function d_cos(iDeg, bExtraPrecision)
140 --cos is just sine shifed by 90 degrees CCW
141 return d_sin(90 - iDeg, bExtraPrecision)
142 end
143
144 local function d_tan(iDeg, bExtraPrecision)
145 --tan = sin0 / cos0
146 return (d_sin(iDeg, bExtraPrecision) * 10000 / d_sin(90 - iDeg, bExtraPrecision))
147 end
148
149 --expose functions to the outside through _math table
150 _math.clamp = clamp
151 _math.clamp_roll = clamp_roll
152 _math.i_sqrt = i_sqrt
153 _math.d_sin = d_sin
154 _math.d_cos = d_cos
155 _math.d_tan = d_tan
156end -- missing math functions
157
158return _math
159