diff --git a/drift.lua b/drift.lua index 2a9ebac..646f12d 100644 --- a/drift.lua +++ b/drift.lua @@ -1,13 +1,13 @@ -- drift - dust motes in flight -- --- v0.3.0 @echophon +-- v0.4 @echophon -- -- KEY1 shift -- KEY2 cycles param focus -- KEY3 cycles focus -- ENC1 transpose --- ENC2 motivate x-axis --- ENC3 motivate y-axis +-- ENC2 param 1 +-- ENC3 param 2 -- shift + KEY2 randomizes all -- shift + KEY3 randomizes focus @@ -18,29 +18,29 @@ local viewport = { width = 128, height = 64 } local frame = 0 local txt = 'hello' -local drift_max = 40 +local drift_max = 4 local connect_distance = 24 local focus = 1 local param_focus = 1 -local param_count = 5 -local param_txt = {"move", "pos", "connect distance", "boundary", "random"} +local param_count = 7 +local param_txt = {"move", "pos", "xboundary", "yboundary", "connect distance", "boundary", "random"} local shift = false local dot_count = 8 local boundary_ops = 1 local boundary_count = 4 -local boundary_txt = {"wrap", "wrap half", "bounce", "random"} +local boundary_txt = {"wrap", "wrap random", "bounce", "bounce random"} local random_ops = 1 -local random_count = 7 -local random_txt = {"default", "xpos", "ypos", "xypos", "xmove", "ymove", "xymove"} - -local dots= {{x=0,y=0,move_x=0,move_y=0,dirty={0,0,0,0,0,0,0,0}} - ,{x=0,y=0,move_x=0,move_y=0,dirty={0,0,0,0,0,0,0,0}} - ,{x=0,y=0,move_x=0,move_y=0,dirty={0,0,0,0,0,0,0,0}} - ,{x=0,y=0,move_x=0,move_y=0,dirty={0,0,0,0,0,0,0,0}} - ,{x=0,y=0,move_x=0,move_y=0,dirty={0,0,0,0,0,0,0,0}} - ,{x=0,y=0,move_x=0,move_y=0,dirty={0,0,0,0,0,0,0,0}} - ,{x=0,y=0,move_x=0,move_y=0,dirty={0,0,0,0,0,0,0,0}} - ,{x=0,y=0,move_x=0,move_y=0,dirty={0,0,0,0,0,0,0,0}}} +local random_count = 10 +local random_txt = {"default", "xpos", "ypos", "xypos", "xmove", "ymove", "xymove", "xboundary", "yboundary", "xyboundary"} + +local dots= {{x=0,y=0,move_x=0,move_y=0,x1_bound=1,x2_bound=viewport.width,y1_bound=1,y2_bound=viewport.height,dirty={0,0,0,0,0,0,0,0}} + ,{x=0,y=0,move_x=0,move_y=0,x1_bound=1,x2_bound=viewport.width,y1_bound=1,y2_bound=viewport.height,dirty={0,0,0,0,0,0,0,0}} + ,{x=0,y=0,move_x=0,move_y=0,x1_bound=1,x2_bound=viewport.width,y1_bound=1,y2_bound=viewport.height,dirty={0,0,0,0,0,0,0,0}} + ,{x=0,y=0,move_x=0,move_y=0,x1_bound=1,x2_bound=viewport.width,y1_bound=1,y2_bound=viewport.height,dirty={0,0,0,0,0,0,0,0}} + ,{x=0,y=0,move_x=0,move_y=0,x1_bound=1,x2_bound=viewport.width,y1_bound=1,y2_bound=viewport.height,dirty={0,0,0,0,0,0,0,0}} + ,{x=0,y=0,move_x=0,move_y=0,x1_bound=1,x2_bound=viewport.width,y1_bound=1,y2_bound=viewport.height,dirty={0,0,0,0,0,0,0,0}} + ,{x=0,y=0,move_x=0,move_y=0,x1_bound=1,x2_bound=viewport.width,y1_bound=1,y2_bound=viewport.height,dirty={0,0,0,0,0,0,0,0}} + ,{x=0,y=0,move_x=0,move_y=0,x1_bound=1,x2_bound=viewport.width,y1_bound=1,y2_bound=viewport.height,dirty={0,0,0,0,0,0,0,0}}} local useMidi = 0 local channel = 1 @@ -58,10 +58,10 @@ params:set_action("drift_max", function(x) drift_max = x end) params:add_number("connect_distance","connect_distance",4,48,24) params:set_action("connect_distance", function(x) connect_distance = x end) -params:add_option("boundary_ops","boundary_ops",{"wrap", "wrap half", "bounce", "random"},1) +params:add_option("boundary_ops","boundary_ops",{"wrap", "wrap random", "bounce", "bounce random"},1) params:set_action("boundary_ops", function(x) boundary_ops = x end) -params:add_option("random_ops","random_ops",{"default", "xpos", "ypos", "xypos", "xmove", "ymove", "xymove"},1) +params:add_option("random_ops","random_ops",{"default", "xpos", "ypos", "xypos", "xmove", "ymove", "xymove", "xboundary", "yboundary", "xyboundary"},1) params:set_action("random_ops", function(x) random_ops = x end) params:add_trigger("randomize", "randomize") @@ -94,19 +94,29 @@ function enc(id,delta) elseif id == 3 and param_focus == 1 then dots[focus].move_y = tonumber(string.format("%.2f", util.clamp(dots[focus].move_y + (delta*0.01),-drift_max,drift_max))) elseif id == 2 and param_focus == 2 then - dots[focus].x = tonumber(string.format("%.1f", util.clamp(dots[focus].x + (delta*0.1),0,viewport.width))) + dots[focus].x = tonumber(string.format("%.1f", util.clamp(dots[focus].x + (delta*1),0,viewport.width))) elseif id == 3 and param_focus == 2 then - dots[focus].y = tonumber(string.format("%.1f", util.clamp(dots[focus].y + (delta*0.1),0,viewport.height))) + dots[focus].y = tonumber(string.format("%.1f", util.clamp(dots[focus].y + (delta*1),0,viewport.height))) + elseif id == 2 and param_focus == 3 then - connect_distance = tonumber(string.format("%.1f", util.clamp(connect_distance + (delta*0.1),1,48))) + dots[focus].x1_bound = tonumber(string.format("%.1f", util.clamp(dots[focus].x1_bound + (delta*1),0,dots[focus].x2_bound))) + elseif id == 3 and param_focus == 3 then + dots[focus].x2_bound = tonumber(string.format("%.1f", util.clamp(dots[focus].x2_bound + (delta*1),dots[focus].x1_bound,viewport.width))) + elseif id == 2 and param_focus == 4 then - boundary_ops = util.clamp(boundary_ops + (delta*1),1,4) + dots[focus].y1_bound = tonumber(string.format("%.1f", util.clamp(dots[focus].y1_bound + (delta*1),0,dots[focus].y2_bound))) + elseif id == 3 and param_focus == 4 then + dots[focus].y2_bound = tonumber(string.format("%.1f", util.clamp(dots[focus].y2_bound + (delta*1),dots[focus].y1_bound,viewport.height))) + elseif id == 2 and param_focus == 5 then - random_ops = util.clamp(random_ops + (delta*1),1,7) + connect_distance = tonumber(string.format("%.1f", util.clamp(connect_distance + (delta*0.1),1,48))) + elseif id == 2 and param_focus == 6 then + boundary_ops = util.clamp(boundary_ops + (delta*1),1,boundary_count) + elseif id == 2 and param_focus == 7 then + random_ops = util.clamp(random_ops + (delta*1),1,random_count) elseif id == 1 then for i=1,dot_count do - -- dots[i].x = tonumber(string.format("%.0f", util.clamp(dots[i].x + (delta*1),-1,viewport.width))) dots[i].x = tonumber(string.format("%.0f", util.clamp(dots[i].x + (delta*1),-20,viewport.width))) end end @@ -145,6 +155,17 @@ function randomize_dot() elseif random_ops == 7 then dots[focus].move_x = drift_calc() dots[focus].move_y = drift_calc() + elseif random_ops == 8 then + dots[focus].x1_bound = math.random(viewport.width) + dots[focus].x2_bound = math.random(dots[focus].x1_bound, viewport.width) + elseif random_ops == 9 then + dots[focus].y1_bound = math.random(viewport.height) + dots[focus].y2_bound = math.random(dots[focus].y1_bound, viewport.height) + elseif random_ops == 10 then + dots[focus].x1_bound = math.random(viewport.width) + dots[focus].x2_bound = math.random(dots[focus].x1_bound, viewport.width) + dots[focus].y1_bound = math.random(viewport.height) + dots[focus].y2_bound = math.random(dots[focus].y1_bound, viewport.height) end end @@ -169,6 +190,17 @@ function randomize_dots() elseif random_ops == 7 then dots[i].move_x = drift_calc() dots[i].move_y = drift_calc() + elseif random_ops == 8 then + dots[i].x1_bound = math.random(viewport.width) + dots[i].x2_bound = math.random(dots[i].x1_bound, viewport.width) + elseif random_ops == 9 then + dots[i].y1_bound = math.random(viewport.height) + dots[i].y2_bound = math.random(dots[i].y1_bound, viewport.height) + elseif random_ops == 10 then + dots[i].x1_bound = math.random(viewport.width) + dots[i].x2_bound = math.random(dots[i].x1_bound, viewport.width) + dots[i].y1_bound = math.random(viewport.height) + dots[i].y2_bound = math.random(dots[i].y1_bound, viewport.height) end end end @@ -183,17 +215,23 @@ end function move_dots_wrap() for i=1, dot_count do - dots[i].x = dots[i].x % viewport.width - dots[i].y = dots[i].y % viewport.height - if dots[i].x < 0 then - dots[i].x = viewport.width + + if dots[i].x > viewport.width or dots[i].x > dots[i].x2_bound then + dots[i].x = dots[i].x1_bound end - if dots[i].y < 0 then - dots[i].y = viewport.height + if dots[i].y > viewport.height or dots[i].y > dots[i].y2_bound then + dots[i].y = dots[i].y1_bound + end + if dots[i].x < 0 or dots[i].x < dots[i].x1_bound then + dots[i].x = dots[i].x2_bound + end + if dots[i].y < 0 or dots[i].y < dots[i].y1_bound then + dots[i].y = dots[i].y2_bound end end end +-- TODO no longer needed function move_dots_wrap_perc(n,m) for i=1, dot_count do if dots[i].x > viewport.width then @@ -213,20 +251,20 @@ end function move_dots_bounce() for i=1, dot_count do - if dots[i].x < 0 then - dots[i].x = -dots[i].x + if dots[i].x < dots[i].x1_bound then + dots[i].x = dots[i].x1_bound dots[i].move_x = -dots[i].move_x end - if dots[i].x > viewport.width then - dots[i].x = viewport.width + (viewport.width - dots[i].x) + if dots[i].x > dots[i].x2_bound then + dots[i].x = dots[i].x2_bound dots[i].move_x = -dots[i].move_x end - if dots[i].y < 0 then - dots[i].y = -dots[i].y + if dots[i].y < dots[i].y1_bound then + dots[i].y = dots[i].y1_bound dots[i].move_y = -dots[i].move_y end - if dots[i].y > viewport.height then - dots[i].y = viewport.height + (viewport.height - dots[i].y) + if dots[i].y > dots[i].y2_bound then + dots[i].y = dots[i].y2_bound dots[i].move_y = -dots[i].move_y end end @@ -234,15 +272,27 @@ end function move_dots_random() for i=1, dot_count do - if dots[i].x < 0 or dots[i].x > viewport.width then - dots[i].x = math.random(0,viewport.width) + if dots[i].x < dots[i].x1_bound or dots[i].x > dots[i].x2_bound then + dots[i].x = math.random(dots[i].x1_bound,dots[i].x1_bound) end - if dots[i].y < 0 or dots[i].y > viewport.height then - dots[i].y = math.random(0,viewport.height) + if dots[i].y < dots[i].y1_bound or dots[i].y > dots[i].y2_bound then + dots[i].y = math.random(dots[i].y1_bound,dots[i].y2_bound) end end end +function move_dots_random_bounce() + for i=1, dot_count do + if dots[i].x < dots[i].x1_bound or dots[i].x > dots[i].x2_bound then + dots[i].x = math.random(dots[i].x1_bound,dots[i].x2_bound) + dots[i].move_x = -dots[i].move_x + end + if dots[i].y < dots[i].y1_bound or dots[i].y > dots[i].y2_bound then + dots[i].y = math.random(dots[i].y1_bound,dots[i].y2_bound) + dots[i].move_y = -dots[i].move_y + end + end +end function distance( x1, y1, x2, y2 ) return math.sqrt( (x2-x1)^2 + (y2-y1)^2 ) @@ -317,16 +367,26 @@ function draw_line(x1, y1, x2, y2, l) screen.stroke() end +function draw_bounds() + screen.level(1) + screen.rect(dots[focus].x1_bound, dots[focus].y1_bound, dots[focus].x2_bound - dots[focus].x1_bound, dots[focus].y2_bound - dots[focus].y1_bound) + screen.stroke() + end + function draw_text() if param_focus == 1 then txt = param_txt[param_focus] .. focus .. ":" .. string.format("%.2f",dots[focus].move_x) .. "," .. string.format("%.2f",dots[focus].move_y) elseif param_focus == 2 then txt = param_txt[param_focus] .. focus .. ":" .. string.format("%.2f",dots[focus].x) .. "," .. string.format("%.2f",dots[focus].y) elseif param_focus == 3 then - txt = param_txt[param_focus] .. ":" .. string.format("%.1f",connect_distance) + txt = param_txt[param_focus] .. focus .. ":" .. string.format("%.1f",dots[focus].x1_bound) .. "," .. string.format("%.1f",dots[focus].x2_bound) elseif param_focus == 4 then - txt = param_txt[param_focus] .. ":" .. boundary_txt[boundary_ops] + txt = param_txt[param_focus] .. focus .. ":" .. string.format("%.1f",dots[focus].y1_bound) .. "," .. string.format("%.1f",dots[focus].y2_bound) elseif param_focus == 5 then + txt = param_txt[param_focus] .. ":" .. string.format("%.1f",connect_distance) + elseif param_focus == 6 then + txt = param_txt[param_focus] .. ":" .. boundary_txt[boundary_ops] + elseif param_focus == 7 then txt = param_txt[param_focus] .. ":" .. random_txt[random_ops] end screen.level(1) @@ -337,9 +397,11 @@ end function redraw() screen.clear() + draw_bounds() draw_dots() draw_connections() draw_text() + screen.update() end @@ -351,11 +413,11 @@ re.event = function() if boundary_ops == 1 then move_dots_wrap() elseif boundary_ops == 2 then - move_dots_wrap_perc(0.5,0.5) + move_dots_random() elseif boundary_ops == 3 then move_dots_bounce() elseif boundary_ops == 4 then - move_dots_random() + move_dots_random_bounce() end if useMidi == 1 then