Created
February 16, 2017 15:54
-
-
Save luastoned/d0561b5691fd71e2a6b5d33edf11eb11 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local nw = require("nw") | |
local app = nw:app() -- get the app singleton | |
local win = app:window({ -- create a new window | |
w = 1280, h = 720, -- specify window"s frame size | |
title = "SndVis", -- specify window"s title | |
visible = false, -- dont show it yet | |
resizeable = false, | |
maximizable = false, | |
fullscreenable = false, | |
--transparent = true, | |
--frame = "none", | |
--corner_radius = 5, | |
}) | |
function win:click(button, count) -- this is one way to bind events | |
if button == "left" and count == 3 then -- triple click | |
app:quit() | |
end | |
end | |
-- this is another way to bind events which allows setting multiple | |
-- handlers for the same event type. | |
win:on("keydown", function(self, key) | |
if key == "F11" then | |
self:fullscreen(not self:fullscreen()) -- toggle fullscreen state | |
end | |
end) | |
--[[ | |
function getCurvePoints(pts, tension, isClosed, numOfSegments) { | |
-- use input value if provided, or use a default value | |
tension = (typeof tension != 'undefined') ? tension : 0.5; | |
isClosed = isClosed ? isClosed : false; | |
numOfSegments = numOfSegments ? numOfSegments : 16; | |
var _pts = [], res = [], -- clone array | |
x, y, -- our x,y coords | |
t1x, t2x, t1y, t2y, -- tension vectors | |
c1, c2, c3, c4, -- cardinal points | |
st, t, i; -- steps based on num. of segments | |
-- clone array so we don't change the original | |
-- | |
_pts = pts.slice(0); | |
-- The algorithm require a previous and next point to the actual point array. | |
-- Check if we will draw closed or open curve. | |
-- If closed, copy end points to beginning and first points to end | |
-- If open, duplicate first points to befinning, end points to end | |
if (isClosed) { | |
_pts.unshift(pts[pts.length - 1]); | |
_pts.unshift(pts[pts.length - 2]); | |
_pts.unshift(pts[pts.length - 1]); | |
_pts.unshift(pts[pts.length - 2]); | |
_pts.push(pts[0]); | |
_pts.push(pts[1]); | |
} | |
else { | |
_pts.unshift(pts[1]); --copy 1. point and insert at beginning | |
_pts.unshift(pts[0]); | |
_pts.push(pts[pts.length - 2]); --copy last point and append | |
_pts.push(pts[pts.length - 1]); | |
} | |
-- ok, lets start.. | |
-- 1. loop goes through point array | |
-- 2. loop goes through each segment between the 2 pts + 1e point before and after | |
for (i=2; i < (_pts.length - 4); i+=2) { | |
for (t=0; t <= numOfSegments; t++) { | |
-- calc tension vectors | |
t1x = (_pts[i+2] - _pts[i-2]) * tension; | |
t2x = (_pts[i+4] - _pts[i]) * tension; | |
t1y = (_pts[i+3] - _pts[i-1]) * tension; | |
t2y = (_pts[i+5] - _pts[i+1]) * tension; | |
-- calc step | |
st = t / numOfSegments; | |
-- calc cardinals | |
c1 = 2 * Math.pow(st, 3) - 3 * Math.pow(st, 2) + 1; | |
c2 = -(2 * Math.pow(st, 3)) + 3 * Math.pow(st, 2); | |
c3 = Math.pow(st, 3) - 2 * Math.pow(st, 2) + st; | |
c4 = Math.pow(st, 3) - Math.pow(st, 2); | |
-- calc x and y cords with common control vectors | |
x = c1 * _pts[i] + c2 * _pts[i+2] + c3 * t1x + c4 * t2x; | |
y = c1 * _pts[i+1] + c2 * _pts[i+3] + c3 * t1y + c4 * t2y; | |
--store points in array | |
res.push(x); | |
res.push(y); | |
} | |
} | |
return res; | |
} | |
]] | |
local function cardinalSpline(points, tension, numOfSeg, isClosed) | |
tension = tension or 0.5 | |
numOfSeg = numOfSeg or 12 | |
isClosed = isClosed or false | |
local pts, res = {}, {} | |
local x, y | |
local t1x, t2x, t1y, t2y -- tension | |
local c1, c2, c3, c4 -- cardinal points | |
local step, t, i | |
local length = #points | |
for k, point in pairs(points) do | |
table.insert(pts, point) | |
end | |
if (isClosed) then | |
-- add start to end and vice versa | |
table.insert(pts, 1, points[length]) | |
table.insert(pts, points[1]) | |
else | |
-- duplicate start and end | |
table.insert(pts, 1, points[1]) | |
table.insert(pts, points[length]) | |
end | |
local cache = {} | |
-- cache inner-loop calculations as they are based on t alone | |
for i = 0, numOfSeg - 1 do | |
step = i / numOfSeg | |
local st2 = step * step | |
local st3 = st2 * step | |
local st23 = st2 * 3 | |
local st32 = st3 * 2 | |
cache[i * 4 + 1] = st32 - st23 + 1 -- c1 | |
cache[i * 4 + 2] = st23 - st32 -- c2 | |
cache[i * 4 + 3] = st3 - 2 * st2 + step -- c3 | |
cache[i * 4 + 4] = st3 - st2 -- c4 | |
end | |
-- 1. loop goes through points | |
-- 2. loop goes through each segment between two points and 1 point before and after | |
for i = 2, length do | |
-- calc tension vectors | |
t1x = (pts[i + 1].x - pts[i - 1].x) * tension | |
t1y = (pts[i + 1].y - pts[i - 1].y) * tension | |
t2x = (pts[i + 2].x - pts[i].x) * tension | |
t2y = (pts[i + 2].y - pts[i].y) * tension | |
for t = 0, numOfSeg - 1 do | |
c1 = cache[t * 4 + 1] | |
c2 = cache[t * 4 + 2] | |
c3 = cache[t * 4 + 3] | |
c4 = cache[t * 4 + 4] | |
x = c1 * pts[i].x + c2 * pts[i + 1].x + c3 * t1x + c4 * t2x | |
y = c1 * pts[i].y + c2 * pts[i + 1].y + c3 * t1y + c4 * t2y | |
table.insert(res, {x = x, y = y}) | |
end | |
end | |
table.insert(res, points[length]) | |
return res | |
end | |
local t = {} | |
for i = 1, 3 do | |
local p = {x = i * 20, y = math.floor(math.random() * 20)} | |
print(i .. " -> (" .. p.x .. ", " .. p.y .. ")") | |
table.insert(t, p) | |
end | |
local tbl = cardinalSpline(t, 0.5, 3, false) | |
for k, p in pairs(tbl) do | |
print(k .. " -> (" .. p.x .. ", " .. p.y .. ")") | |
end | |
local sleepTime = 0.2 | |
local deg_add = 0 | |
function win:repaint() -- called when window needs repainting | |
local bmp = win:bitmap() -- get the window"s bitmap | |
bmp:clear() | |
local cr = bmp:cairo() -- get a cairo drawing context | |
local w, h = win:client_size() | |
-- draw red line | |
cr:rgba(1, 0, 0, 1) | |
cr:line_width(2) | |
cr:new_path() | |
cr:move_to(10, 10) | |
cr:line_to(w - 10, 10) | |
cr:close_path() | |
cr:stroke() | |
local fftTable = {} | |
for i = 1, 16 do | |
table.insert(fftTable, math.random()) | |
end | |
cr:push_group() | |
cr:rgba(1, 1, 1, 1) | |
cr:line_width(2) | |
cr:new_path() | |
cr:move_to(400, 100) | |
--cr:rel_curve_to(0, 0, 0, -50, 100, 0) | |
cr:rel_quad_curve_to(50, 50, 100, 0) | |
--cr:curve_to(i * 50, h - 50 - off, i * 50, h - 50 - off, i * 50, h - 50 - off) | |
--cr:rel_curve_to(0, 0, 0, 0, 0, math.random() * 100) | |
cr:stroke() | |
cr:pop_group_to_source() | |
cr:paint() | |
cr:push_group() | |
cr:rgba(1, 1, 1, 1) | |
cr:line_width(2) | |
cr:new_path() | |
cr:move_to(50, h - 50) | |
for i = 1, 16 - 1 do | |
local x = i * 50 + 25 | |
local y = (fftTable[i] + fftTable[i + 1]) / 2 | |
cr:quad_curve_to(i * 50, h - 50 - fftTable[i] * 300, x, h - 50 - y * 300) | |
--cr:rectangle(i * 50, h - 50 - fftTable[i] * 200, 10, fftTable[i] * 200) | |
--cr:curve_to(i * 50, h - 50 - off, i * 50, h - 50 - off, i * 50, h - 50 - off) | |
--cr:rel_curve_to(0, 0, 0, 0, 0, math.random() * 100) | |
end | |
cr:quad_curve_to(16 * 50, h - 50 - fftTable[16] * 300, 16 * 50, h - 50) | |
--cr:line_to(16 * 50, h - 50) | |
--cr:close_path() | |
cr:stroke() | |
cr:pop_group_to_source() | |
cr:paint() | |
cr:push_group() | |
cr:rgba(0, 0, 1, 1) | |
cr:new_path() | |
for i = 1, 16 do | |
cr:rectangle(i * 50, h - 50 - fftTable[i] * 200, 10, fftTable[i] * 200) | |
end | |
cr:fill() | |
cr:rgba(1, 0, 0, 1) | |
cr:new_path() | |
for i = 1, 16 do | |
cr:rectangle(i * 50, h - 50 - fftTable[i] * 300, 10, 10) | |
end | |
cr:fill() | |
cr:pop_group_to_source() | |
cr:paint() | |
cr:push_group() | |
deg_add = deg_add + 15 | |
cr:new_path() | |
cr:rotate_around(200, 200, math.rad(deg_add)) | |
cr:rectangle(100, 100, 200, 200) | |
cr:rgba(0, 1, 0, 0.2) | |
cr:fill() | |
cr:pop_group_to_source() | |
cr:paint() | |
cr:rgba(0, 0, 1, 0.5) | |
cr:line_width(2) | |
cr:new_path() | |
cr:move_to(50, 50) | |
cr:line_to(w - 50, 50) | |
cr:close_path() | |
cr:stroke() | |
app:runafter(sleepTime, function() | |
win:invalidate() | |
end) | |
end | |
win:show() -- show it now that it was properly set up | |
app:run() -- start the event loop |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment