diff options
author | William Wilgus <me.theuser@yahoo.com> | 2018-05-28 17:56:06 +0200 |
---|---|---|
committer | William Wilgus <me.theuser@yahoo.com> | 2018-07-22 18:05:02 +0200 |
commit | 2daec3d3c3d84e7176a22bc073ca5530e8e44c6d (patch) | |
tree | 0f7e64ed5abd305fe80a7fbfabf79d2a9374ed4f /apps/plugins/lua/include_lua/math_ex.lua | |
parent | 19b2964d78b2ad6624a0e7cddd0ac6a49082cca4 (diff) | |
download | rockbox-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.lua | 158 |
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 | |||
35 | local _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 | ||
156 | end -- missing math functions | ||
157 | |||
158 | return _math | ||