summaryrefslogtreecommitdiff
path: root/apps/plugins/lua/include_lua/math_ex.lua
diff options
context:
space:
mode:
authorWilliam Wilgus <me.theuser@yahoo.com>2018-05-28 17:56:06 +0200
committerWilliam Wilgus <me.theuser@yahoo.com>2018-07-22 18:05:02 +0200
commit2daec3d3c3d84e7176a22bc073ca5530e8e44c6d (patch)
tree0f7e64ed5abd305fe80a7fbfabf79d2a9374ed4f /apps/plugins/lua/include_lua/math_ex.lua
parent19b2964d78b2ad6624a0e7cddd0ac6a49082cca4 (diff)
downloadrockbox-2daec3d3c3d84e7176a22bc073ca5530e8e44c6d.tar.gz
rockbox-2daec3d3c3d84e7176a22bc073ca5530e8e44c6d.zip
Rocklua -- Extend / Fix rliImage
Some devices(1-bit / 2-bit displays) have packed bit formats that need to be unpacked in order to work on them at a pixel level. This caused a few issues on 1 & 2-bit devices: Greatly Oversized data arrays for bitmaps Improper handling of native image data Framebuffer data was near unusable without jumping through hoops Conversion between native addressing and per pixel addressing incurs extra overhead but it is much faster to do it on the 'C' side rather than in lua. Not to mention the advantage of a unified interface for the end programer ------------------------------------------------------------------- Adds a sane way to access each pixel of image data Adds: -------------------------------------------------------------------- img:clear([color],[x1],[y1],[x2],[y2]) (set whole image or a portion to a particular value) -------------------------------------------------------------------- img:invert([x1],[y1],[x2],[y2]) (inverts whole image or a portion) -------------------------------------------------------------------- img:marshal([x1],[y1],[x2],[y2],[funct]) (calls funct for each point defined by rect of x1,y1 x2,y2 returns value and allows setting value of each point return nil to terminate early) -------------------------------------------------------------------- img:points([x1],[y1],[x2],[y2],[dx],[dy]) (returns iterator function that steps delta-x and delta-y pixels each call returns value of pixel each call but doesn't allow setting to a new value compare to lua pairs method) -------------------------------------------------------------------- img:copy(src,[x1],[y1],[x2],[y2],[w],[h],[clip][operation][clr/funct]) (copies all or part of an image -- straight copy or special ops optionally calls funct for each point defined by rect of x1, y1, w, h and x2, y2, w, h for dest and src images returns value of dst and src and allows setting value of each point return nil to terminate early) -------------------------------------------------------------------- img:line(x1, y1, x2, y2, color) -------------------------------------------------------------------- img:ellipse(x1, y1, x2, y2, color, [fillcolor] -------------------------------------------------------------------- Fixed handling of 2-bit vertical integrated screens Added direct element access for saving / restoring native image etc. Added more data to tostring() handler and a way to access individual items Added equals method to see if two variables reference the same image address (doesn't check if two separate images contain the same 'picture') Optimized get and set routines Fixed out of bound x coord access shifting to next line Added lua include files to expose new functionality Finished image saving routine Static allocation of set_viewport struct faster + saves ram over dynamic Cleaned up code Fixed pixel get/set for 1/2 bit devices ------------------------------------------------------------------------- Example lua script to follow on forums ------------------------------------------------------------------------- Change-Id: I7b9c1fd699442fb683760f781021091786c18509
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 0000000000..c0bf55c1ad
--- /dev/null
+++ b/apps/plugins/lua/include_lua/math_ex.lua
@@ -0,0 +1,158 @@
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