Sweet little lines

http://www.youtube.com/watch?v=gPVC5W0lpRI

Above video just shows playing about with the code, it starts with a fixed segment size. I won’t go in to detail as it’s easy to play with, it also makes cool lightning, the code is below:

-- Linedrawer

-- Use this function to perform your initial setup
function setup()
    lines = {}
    lines[1] = {}
    lines[1].a = vec2(WIDTH/2,HEIGHT/2)
    lines[1].b = vec2(WIDTH/2,HEIGHT/2)
    lines[1].col = color(-10,10,-15)
    lines[1].marked = 0
    lm = mesh()
    lines[1].r = lm:addRect(-1,-1,1,1)
    t = 0
    MarkAmount = 5
    AddSize = 0
    SegmentSize = 5
    RandomColors = true
    Colors = color(255, 44, 0, 255)
    FixedSegmentSize = false
    at = 0
    SizeChange = false
    ChangeSpeed = 2
    Speed = 1
    SizeX = 100
    SizeY = 100
    SpeedX = 10
    SpeedY = 10
    AddX = 0
    AddY = 0
    parameter.boolean("SizeChange",false,function() clear() end)
    parameter.integer("ChangeSpeed",0,40,2,function() clear() end)
    parameter.integer("AddSize",0,200,0,function() clear() end)
    parameter.integer("SizeX",0,300,100,function() clear() end)
    parameter.integer("SizeY",0,300,100,function() clear() end)
    parameter.integer("Speed",0,10,0,function() clear() end)
    parameter.integer("SpeedX",0,50,10,function() clear() end)
    parameter.integer("SpeedY",0,50,10,function() clear() end)
    parameter.integer("AddX",0,50,0,function() clear() end)
    parameter.integer("AddY",0,50,0,function() clear() end)
    parameter.boolean("FixedSegmentSize",false,function() clear() end)
    parameter.integer("SegmentSize",0,50,5,function() clear() end)
    parameter.boolean("RandomColors",true,function()  end)
    parameter.color("Colors",Colors,function() lm:setColors(Colors.r,Colors.g,Colors.b,255) end)
    parameter.integer("MarkAmount",0,10,5,function() clear() end)
end

function angle(dir)
    local ang = math.atan2(dir.y,dir.x)
    return ang
end

function clear()
    lm:clear()
    lines = {}
    lines[1] = {}
    lines[1].a = vec2(WIDTH/2,HEIGHT/2)
    lines[1].b = vec2(WIDTH/2,HEIGHT/2)
    lines[1].col = color(-5,5,-3)
    lines[1].marked = 0
    makeLine(1,lines[1].a,lines[1].b,1)
end

function sign(x)
    if x>0 then return 1 elseif x<0 then return -1 else return 0 end
end

function clamp(x,min,max)
    return math.max(math.min(x,max),min)
end

function makeLine(k,pos1,pos2,cent)
    lines[k].a = pos1
    lines[k].b = pos2
    lines[k].col = lines[cent].col
    lines[k].marked = 0
    if lm.size>0 and lm.size<13 then
        for i=1,6 do
            lm:color(i,color(0,0,125,0))
        end
    end
    local md = (pos1+pos2)/2
    local ds = (pos1-pos2)
    local ln = ds:len()
    local ang = angle(ds)
    if k>1 then
        lines[k].r = lm:addRect(md.x,md.y,ln,1,ang)
        local lc = lines[cent].col
        local col = lm:color(clamp(cent*6-6,1,lm.size)) 
        col = color(col.r+lc.r,col.g+lc.g,col.b+lc.b,255)
        if col.r<0 then
            --lines[k].col.r = math.random(1,5)*5
            lines[cent].col.r = math.random(30,40)
        elseif col.r>255 then
            --lines[k].col.r = -math.random(1,5)*5
            lines[cent].col.r = -math.random(30,40)
        end
        if col.g<0 then
            --lines[k].col.g = math.random(1,5)*5
            lines[cent].col.g = math.random(30,40)
        elseif col.r>255 then
            --lines[k].col.g = -math.random(1,5)*5
            lines[cent].col.g = -math.random(30,40)
        end
        if col.b<0 then
            --lines[k].col.b = math.random(1,5)*5
            lines[cent].col.b = math.random(30,40)
        elseif col.b>255 then
            --lines[k].col.b = -math.random(1,5)*5
            lines[cent].col.b = -math.random(30,40)
        end
        if RandomColors then
            for i=0,5 do
                lm:color(lm.size-i,col)
            end
        else
            for i=0,5 do
                lm:color(lm.size-i,Colors)
            end
        end
        lines[cent].marked = lines[cent].marked + 1
    end
end

function cpol(p,a,b)
	local c = p - a;	
	local v = (b - a):normalize()	
	local d = (b - a):len();
	local t = v:dot(c)
	if t < 0 then return a end
	if t > d then return b end
	v = v * t
	return a + v;
end

function addLine(pos)
    local cent = {math.huge,1,lines[1].b}
    for k,v in pairs(lines) do
        if v.marked <MarkAmount then
        local lpos = cpol(pos,v.a,v.b)
        if pos:dist(lpos)<cent[1] then
            cent = {pos:dist(lpos),k,lpos}
        end
        end
    end
    if cent[3] and cent[1]>2.5 then
        local tbl = {}
        tbl.a = nil
        tbl.b = nil
        tbl.r = nil
        table.insert(lines,tbl)
        if FixedSegmentSize then
            makeLine(#lines,cent[3],cent[3]+(pos-cent[3]):normalize()*SegmentSize,cent[2])
        else
            makeLine(#lines,cent[3],pos,cent[2])
        end
    end
end

-- This function gets called once every frame
function draw()
    -- This sets a dark background color 
    background(0, 0, 0, 255)
    local rnd = math.random(0,100)
    t = t + DeltaTime*Speed+rnd*0.0001
    if SizeChange then
        at = at + DeltaTime*Speed+rnd*0.0001
    end
    fill(255, 255, 255, 255)
    -- This sets the line thickness
    local x,y 
    local sx = (math.cos(at*ChangeSpeed+math.pi/2)*1)
    local sy = (math.sin(at*ChangeSpeed+math.pi/2)*1)
    x = WIDTH/2+math.sin(t*(SpeedX/5)+math.cos(t)*AddX*0.5)*SizeX+sx*AddSize
    y = HEIGHT/2+math.cos(t*(SpeedY/5)+math.sin(t)*AddY*0.5)*SizeY+sy*AddSize
    ellipse(x,y,5)
    addLine(vec2(x,y))
    -- Do your drawing here
    text(#lines.." x:"..math.ceil(x).." y:"..math.ceil(y).." FPS:"..math.ceil(1/DeltaTime),100,100)
    lm:draw()
end


Very interesting, nice code.

Neat - at around 20sec’s in the video I thought you’d generated a road layout for a procedurally generated city :slight_smile:

Nice to use for a breaking glass effect