lua optimize poly_draw add draw_number, poly_points modules
Change-Id: Id36e765f18234f5a4f3092d090c0adffa3da1612
This commit is contained in:
parent
9f551b09f6
commit
b99d4d7fa9
4 changed files with 297 additions and 43 deletions
115
apps/plugins/lua/include_lua/draw_num.lua
Normal file
115
apps/plugins/lua/include_lua/draw_num.lua
Normal file
|
@ -0,0 +1,115 @@
|
|||
--[[ Lua draw number function
|
||||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2019 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
|
||||
_draw_nums.print; binary (base = 2) , octal (base = 8), hexadecimal (base = 16)
|
||||
_draw_nums.nums; table of number characters
|
||||
]]
|
||||
|
||||
if not rb.lcd_framebuffer then rb.splash(rb.HZ, "No Support!") return nil end
|
||||
|
||||
local _draw_nums = {} do
|
||||
local _poly = require "draw_poly"
|
||||
|
||||
-- every 2 elements is an x, y coord pair
|
||||
-- n[?] = {x,y,x,y,x,y}
|
||||
local nums = {
|
||||
["b"] = {0,1,0,7,0,5,1,4,1,4,2,4,3,5,3,6,2,7,1,7,0,6,0,5},
|
||||
["o"] = {1,4,0,5,0,6,1,7,2,7,3,6,3,5,2,4,1,4},
|
||||
["x"] = {0,3,4,7,2,5,4,3,0,7},
|
||||
[-1] = {1,4, 3,4},
|
||||
[0] = {1,2,1,6,2,7,3,7,4,6,4,2,3,1,2,1,1,2},
|
||||
[1] = {3,1,3,7},
|
||||
[2] = {1,1,3,1,4,2,4,3,3,4,1,5,1,7,4,7},
|
||||
[3] = {1,1,3,1,4,2,4,3,3,4,2,4,3,4,4,5,4,6,3,7,1,7},
|
||||
[4] = {1,1,1,3,2,4,4,4,4,1,4,7},
|
||||
[5] = {1,1,4,1,1,1,1,4,3,4,4,5,4,7,1,7},
|
||||
[6] = {1,2,1,4,1,6,2,7,3,7,4,6,4,4,1,4,1,2,2,1,4,1},
|
||||
[7] = {1,1,4,1,4,2,1,7},
|
||||
[8] = {1,2,1,6,2,7,3,7,4,6,4,4,1,4,4,4,4,2,3,1,2,1,1,2},
|
||||
[9] = {4,6,4,4,4,2,3,1,2,1,1,2,1,4,4,4,4,6,3,7,1,7},
|
||||
[10] = {1,7,1,4,4,4,4,7,4,2,3,1,2,1,1,2,1,4},
|
||||
[11] = {1,1,1,7,3,7,4,6,4,5,3,4,1,4,3,4,4,3,4,2,3,1,1,1},
|
||||
[12] = {4,2,3,1,2,1,1,2,1,6,2,7,3,7,4,6},
|
||||
[13] = {1,1,1,7,3,7,4,6,4,2,3,1,1,1},
|
||||
[14] = {4,1,1,1,1,4,3,4,1,4,1,7,4,7},
|
||||
[15] = {4,1,1,1,1,4,3,4,1,4,1,7},
|
||||
}
|
||||
_draw_nums.nums = nums
|
||||
|
||||
|
||||
_draw_nums.print = function(img, num, x, y, chrw, color, base, prefix, bClip, scale_x, scale_y, t_nums)
|
||||
scale_x = scale_x or 1
|
||||
scale_y = scale_y or 1
|
||||
chrw = chrw * scale_x
|
||||
prefix = (prefix == nil or prefix == true) and true or false
|
||||
t_nums = t_nums or nums
|
||||
local max_x, max_y, digits = 0, 0, {}
|
||||
|
||||
if num <= 0 then
|
||||
if num < 0 then
|
||||
digits[-3] = -1
|
||||
num = -num
|
||||
else
|
||||
digits[0] = 0
|
||||
end
|
||||
end
|
||||
|
||||
if not prefix and (base == 2 or base == 8 or base == 16) then
|
||||
-- no prefix
|
||||
elseif base == 2 then
|
||||
digits[-1] = "b"
|
||||
elseif base == 8 then
|
||||
digits[-1] = "o"
|
||||
elseif base == 10 then
|
||||
-- no prefix
|
||||
elseif base == 16 then
|
||||
digits[-2] = 0
|
||||
digits[-1] = "x"
|
||||
elseif base == nil then -- default
|
||||
base = 10
|
||||
else
|
||||
error("unknown number base: " .. base)
|
||||
return nil
|
||||
end
|
||||
|
||||
while num > 0 do -- get each digit (LeastSignificant)
|
||||
digits[#digits + 1] = num % base;
|
||||
num=num/base;
|
||||
end
|
||||
|
||||
digits[#digits + 1] = digits[0] -- zero
|
||||
digits[#digits + 1] = digits[-1] -- base prefix
|
||||
digits[#digits + 1] = digits[-2] -- base prefix (hex)
|
||||
digits[#digits + 1] = digits[-3] -- neg sign
|
||||
|
||||
for i = #digits, 1, -1 do
|
||||
max_x, max_y = _poly.polyline(img, x, y, t_nums[digits[i]],
|
||||
color, false, bClip, scale_x, scale_y)
|
||||
x = x + chrw
|
||||
end
|
||||
|
||||
return x, y + max_y, chrw
|
||||
end
|
||||
end
|
||||
return _draw_nums
|
|
@ -25,7 +25,11 @@
|
|||
_poly.polygon
|
||||
_poly.polyline
|
||||
]]
|
||||
|
||||
--[[
|
||||
every 2 elements in t_pts is an x, y coord pair
|
||||
p[?] = {x,y,x,y,x,y}
|
||||
lines get drawn between the coords
|
||||
]]
|
||||
if not rb.lcd_framebuffer then rb.splash(rb.HZ, "No Support!") return nil end
|
||||
|
||||
local _poly = {} do
|
||||
|
@ -39,66 +43,83 @@ local _poly = {} do
|
|||
local _copy = rocklib_image.copy
|
||||
local _line = rocklib_image.line
|
||||
local _newimg = rb.new_image
|
||||
local flood_fill = require("draw_floodfill")
|
||||
local flood_fill
|
||||
|
||||
-- draws a non-filled figure based on points in t-points
|
||||
local function polyline(img, x, y, t_points, color, bClosed, bClip)
|
||||
if #t_points < 2 then error("not enough points", 3) end
|
||||
local function polyline(img, x, y, t_pts, color, bClosed, bClip, scale_x, scale_y)
|
||||
scale_x = scale_x or 1
|
||||
scale_y = scale_y or 1
|
||||
|
||||
local pt_first_last
|
||||
local pt_first_last, pt1, pt2
|
||||
local max_x, max_y = 0, 0
|
||||
local len = #t_pts
|
||||
if len < 4 then error("not enough points", 3) end
|
||||
|
||||
if bClosed then
|
||||
pt_first_last = t_points[1]
|
||||
pt_first_last = {t_pts[1] * scale_x, t_pts[2] * scale_y}
|
||||
else
|
||||
pt_first_last = t_points[#t_points]
|
||||
pt_first_last = {t_pts[len - 1] * scale_x, t_pts[len] * scale_y}
|
||||
end
|
||||
|
||||
for i = 1, #t_points, 1 do
|
||||
local pt1 = t_points[i]
|
||||
|
||||
local pt2 = t_points[i + 1] or pt_first_last-- first and last point
|
||||
pt2 = {t_pts[1] * scale_x, t_pts[2] * scale_y}
|
||||
for i = 3, len + 2, 2 do
|
||||
pt1 = pt2
|
||||
if t_pts[i + 1] == nil then
|
||||
pt2 = pt_first_last
|
||||
else
|
||||
pt2 = {t_pts[i] * scale_x, t_pts[i + 1] * scale_y}
|
||||
end-- first and last point
|
||||
|
||||
_line(img, pt1[1] + x, pt1[2] + y, pt2[1] + x, pt2[2] + y, color, bClip)
|
||||
if pt1[1] > max_x then max_x = pt1[1] end
|
||||
if pt1[2] > max_y then max_y = pt1[2] end
|
||||
end
|
||||
|
||||
if pt2[1] > max_x then max_x = pt2[1] end
|
||||
if pt2[2] > max_y then max_y = pt2[2] end
|
||||
return max_x + x, max_y + y
|
||||
end
|
||||
|
||||
-- draws a closed figure based on points in t_points
|
||||
_poly.polygon = function(img, x, y, t_points, color, fillcolor, bClip)
|
||||
if #t_points < 2 then error("not enough points", 3) end
|
||||
-- draws a closed figure based on points in t_pts
|
||||
_poly.polygon = function(img, x, y, t_pts, color, fillcolor, bClip, scale_x, scale_y)
|
||||
scale_x = scale_x or 1
|
||||
scale_y = scale_y or 1
|
||||
if #t_pts < 2 then error("not enough points", 3) end
|
||||
|
||||
if fillcolor then
|
||||
local x_min, x_max = 0, 0
|
||||
local y_min, y_max = 0, 0
|
||||
local w, h = 0, 0
|
||||
-- find boundries of polygon
|
||||
for i = 1, #t_points, 1 do
|
||||
local pt = t_points[i]
|
||||
if pt[1] < x_min then x_min = pt[1] end
|
||||
if pt[1] > x_max then x_max = pt[1] end
|
||||
if pt[2] < y_min then y_min = pt[2] end
|
||||
if pt[2] > y_max then y_max = pt[2] end
|
||||
end
|
||||
w = _abs(x_max) + _abs(x_min)
|
||||
h = _abs(y_max) + _abs(y_min)
|
||||
x_min = x_min - 2 -- leave a border to use flood_fill
|
||||
y_min = y_min - 2
|
||||
flood_fill = flood_fill or require("draw_floodfill")
|
||||
local x_min, x_max = 0, 0
|
||||
local y_min, y_max = 0, 0
|
||||
local w, h = 0, 0
|
||||
local pt1, pt2
|
||||
-- find boundries of polygon
|
||||
for i = 1, #t_pts, 2 do
|
||||
if t_pts[i] < x_min then x_min = t_pts[i] end
|
||||
if t_pts[i] > x_max then x_max = t_pts[i] end
|
||||
|
||||
local fill_img = _newimg(w + 3, h + 3)
|
||||
_clear(fill_img, 0x1)
|
||||
if t_pts[i+1] < y_min then y_min = t_pts[i+1] end
|
||||
if t_pts[i+1] > y_max then y_max = t_pts[i+1] end
|
||||
end
|
||||
x_max = x_max * scale_x
|
||||
x_min = x_min * scale_x
|
||||
y_max = y_max * scale_y
|
||||
y_min = y_min * scale_y
|
||||
w = _abs(x_max) + _abs(x_min)
|
||||
h = _abs(y_max) + _abs(y_min)
|
||||
x_min = -(x_min - 2) -- leave a border to use flood_fill
|
||||
y_min = -(y_min - 2)
|
||||
|
||||
for i = 1, #t_points, 1 do
|
||||
local pt1 = t_points[i]
|
||||
local pt2 = t_points[i + 1] or t_points[1]-- first and last point
|
||||
_line(fill_img, pt1[1] - x_min, pt1[2] - y_min,
|
||||
pt2[1]- x_min, pt2[2] - y_min, 0)
|
||||
local fill_img = _newimg(w + 3, h + 3)
|
||||
_clear(fill_img, 0x1)
|
||||
|
||||
end
|
||||
polyline(fill_img, x_min, y_min, t_pts,
|
||||
0x0, true, bClip, scale_x, scale_y)
|
||||
-- flood the outside of the figure with 0 the inside will be fillcolor
|
||||
flood_fill(fill_img, fill_img:width(), fill_img:height() , 0x1, 0x0)
|
||||
_copy(img, fill_img, x - 1, y - 1, _NIL, _NIL, _NIL, _NIL, bClip, BSAND, fillcolor)
|
||||
_copy(img, fill_img, x - 1, y - 1,
|
||||
_NIL, _NIL, _NIL, _NIL, bClip, BSAND, fillcolor)
|
||||
end
|
||||
|
||||
polyline(img, x, y, t_points, color, true, bClip)
|
||||
polyline(img, x, y, t_pts, color, true, bClip, scale_x, scale_y)
|
||||
end
|
||||
|
||||
-- expose internal functions to the outside through _poly table
|
||||
|
|
118
apps/plugins/lua/include_lua/poly_points.lua
Normal file
118
apps/plugins/lua/include_lua/poly_points.lua
Normal file
|
@ -0,0 +1,118 @@
|
|||
--PolyPoints.lua
|
||||
--[[
|
||||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* 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.
|
||||
*
|
||||
****************************************************************************/
|
||||
]]
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- decodes ascii string back to t_pts
|
||||
function points_from_ascii(encstr, scale)
|
||||
scale = scale or 1
|
||||
local t_pts = {}
|
||||
encstr = encstr or "00000008"
|
||||
local chroffset = tonumber(string.sub(encstr, 1, 3)) or 0
|
||||
local chrlen = tonumber(string.sub(encstr, 4, 8)) or 0
|
||||
|
||||
if string.len(encstr) ~= chrlen then
|
||||
error("Invalid Points String" .. string.len(encstr), 2)
|
||||
end
|
||||
|
||||
for i = 9, string.len(encstr) - 1, 2 do
|
||||
local x = string.byte(encstr, i, i) - chroffset
|
||||
local y = string.byte(encstr, i + 1, i + 1) - chroffset
|
||||
t_pts[#t_pts + 1] = x * scale
|
||||
t_pts[#t_pts + 1] = y * scale
|
||||
end
|
||||
return t_pts
|
||||
end
|
||||
--------------------------------------------------------------------------------
|
||||
-- encodes t_pts as a ascii string non print chars are excluded so
|
||||
-- size is limited to approx ~ 90x90
|
||||
function points_to_ascii(t_pts)
|
||||
if not t_pts then return "" end
|
||||
local chroffset = 33
|
||||
local maxoffset = 126 - 33
|
||||
local t_enc = {[1] = string.format("%03d%05d", chroffset, #t_pts + 8)}
|
||||
local max_n, min_n = 0, 0
|
||||
for i = 1, #t_pts, 2 do
|
||||
if t_pts[i] > max_n then max_n = t_pts[i] end
|
||||
if t_pts[i] < min_n then min_n = t_pts[i] end
|
||||
if t_pts[i+1] > max_n then max_n = t_pts[i+1] end
|
||||
if t_pts[i+1] < min_n then min_n = t_pts[i+1] end
|
||||
if max_n > maxoffset or min_n < 0 then break; end
|
||||
t_enc[#t_enc + 1] = string.char(t_pts[i] + chroffset)
|
||||
t_enc[#t_enc + 1] = string.char(t_pts[i+1] + chroffset)
|
||||
end
|
||||
if min_n >= 0 and (max_n - min_n) <= maxoffset then
|
||||
return table.concat(t_enc)
|
||||
else
|
||||
return "00000008"
|
||||
end
|
||||
end
|
||||
--------------------------------------------------------------------------------
|
||||
-- scales t_pts by percentage (x/y)
|
||||
function points_scale_pct(t_pts, x_pct, y_pct)
|
||||
for i = 1, #t_pts, 2 do
|
||||
local t_pt = {t_pts[i], t_pts[i + 1]}
|
||||
t_pt = t_pt or {0, 0}
|
||||
t_pts[i] = (t_pt[1] * x_pct) / 100
|
||||
t_pts[i+1] = (t_pt[2] * y_pct) / 100
|
||||
end
|
||||
return t_pts
|
||||
end
|
||||
--------------------------------------------------------------------------------
|
||||
-- scales t_pts by (x/y)
|
||||
function points_scale(t_pts, width, height)
|
||||
local max_x, max_y = 0, 0
|
||||
for i = 1, #t_pts, 2 do
|
||||
if t_pts[i] > max_x then max_x = t_pts[i] end
|
||||
if t_pts[i+1] > max_y then max_y = t_pts[i+1] end
|
||||
end
|
||||
|
||||
local x_pct = (width * 100) / max_x
|
||||
local y_pct = (height * 100) / max_y
|
||||
|
||||
return points_scale_pct(t_pts, x_pct, y_pct)
|
||||
end
|
||||
--------------------------------------------------------------------------------
|
||||
--[[
|
||||
function scaleup(t_pts, scale_x, scale_y)
|
||||
local t_coord
|
||||
for key,value in pairs(t_pts) do
|
||||
t_coord = t_pts[key]
|
||||
t_coord[1] = t_coord[1] * scale_x
|
||||
t_coord[2] = t_coord[2] * scale_y
|
||||
t_pts[key] = t_coord
|
||||
end
|
||||
end
|
||||
|
||||
function scaledn(t_pts, scale_x, scale_y)
|
||||
local t_coord
|
||||
for key,value in pairs(t_pts) do
|
||||
t_coord = t_pts[key]
|
||||
t_coord[1] = t_coord[1] / scale_x
|
||||
t_coord[2] = t_coord[2] / scale_y
|
||||
t_pts[key] = t_coord
|
||||
end
|
||||
end
|
||||
]]
|
|
@ -17,9 +17,9 @@ OTHER_SRC += $(LUA_SRC)
|
|||
|
||||
LUA_INCLUDEDIR := $(LUA_SRCDIR)/include_lua
|
||||
LUA_INCLUDELIST := $(addprefix $(LUA_BUILDDIR)/,audio.lua blit.lua color.lua draw.lua draw_floodfill.lua draw_poly.lua \
|
||||
draw_text.lua image.lua image_save.lua lcd.lua math_ex.lua print.lua \
|
||||
timer.lua playlist.lua pcm.lua sound.lua \
|
||||
rbcompat.lua printtable.lua)
|
||||
draw_num.lua draw_text.lua image.lua image_save.lua lcd.lua math_ex.lua \
|
||||
print.lua timer.lua playlist.lua pcm.lua sound.lua \
|
||||
rbcompat.lua poly_points.lua printtable.lua)
|
||||
|
||||
|
||||
ifndef APP_TYPE
|
||||
|
|
Loading…
Reference in a new issue