Hi all, had is whacky idea last night which involved the algorithm I made for creating polygons in my paint app, it basically iterates through all points finding the mid point and returns the closest midpoint there is then inserts that point between the two. Someone else may have thought of this before but I haven’t seen it yet. I thought to myself what if I make a spiral and use this algorithm? Well I had some interesting results and most of them aren’t spirals because course changed direction. I like to just sit and watch the shapes evolve for a few minutes then tweak the values, but I’ve made 10 interesting tests to start you guys off.
Here’s the code:
-- Spiral
-- Use this function to perform your initial setup
function setup()
n = 0
l = 0
verts = {vec2(WIDTH/2,HEIGHT/2)}
test = {}
test[1] = {{15,20},0.2,0.01,70} --Broken Glass
test[2] = {{45,45},0.2,0.01,70} --Constantly evolving spiral
test[3] = {{50,4},0.5,0.1,70} --Electric field
test[4] = {{5,50},0,0.04,70} --Square
test[5] = {{10,0.1},0.4,0.01,70} --One To Another
test[6] = {{10,10.1},0,0.01,70} --Crystallizing Twist
test[7] = {{100,0.01},2.5,0.01,200} --Loops
test[8] = {{0.02,0.01},2.5,0.01,200} --No contact
test[9] = {{3,1},0.1,0.1,100} --Order out of chaos
test[10] = {{0.5,0.5},0.2,0.01,100} --Constantly evolving spiral 2 (try changing 0.5 to 0.6)
b = 1
parameter.integer("b",1,#test,#test,function() n=0 l=0 verts = {vec2(WIDTH/2,HEIGHT/2)}
nd,lt,ti,si = test[b][1],test[b][2],test[b][3],test[b][4] end)
spiralu()
end
function spiralu()
n = n + 6
l = l + lt
local ang = vec2(math.sin(n/nd[1]),math.cos(n/nd[2]))*(si)--(math.sin(l)*0.5+0.5)+70)
plotPoint(ang+vec2(WIDTH/2,HEIGHT/2))
tween.delay(ti,spiralu)
end
function cPoint(p)
local cent = ""
local d = math.huge
for i=1,#verts do
local pt = verts[i]
if pt:dist(p)<d then
d = pt:dist(p)
cent = i.."; "..(p.x)..","..(p.y)
end
end
return cent
end
function plotPoint(p)
local pt = verts
local d = {math.huge,pt[1]}
if #pt > 1 then
for i=1,#pt do
if i > 1 then
if d[1] > p:dist((pt[i]+pt[i-1])/2) then
d = {p:dist((pt[i]+pt[i-1])/2),i}
end
else
if d[1] > p:dist((pt[i]+pt[#pt])/2) then
d = {p:dist((pt[i]+pt[#pt])/2),i}
end
end
end
table.insert(verts,d[2],p)
else
table.insert(verts,p)
end
end
function touched(t)
if t.state == BEGAN then
cp = cPoint(vec2(t.x,t.y))
print(cp)
end
end
-- This function gets called once every frame
function draw()
-- This sets a dark background color
background(40, 40, 50)
-- This sets the line thickness
strokeWidth(2)
stroke(200,255)
lineCapMode(ROUND)
-- Do your drawing here
local cent=vec2(WIDTH/2,HEIGHT/2)
if #verts>4 then
verts[1]=vec2(WIDTH/2,HEIGHT/2)
end
for i=1,#verts do
if i>1 and verts[i] then
local p1,p2
p1 = verts[i-1]
p2 = verts[i]
verts[i] = verts[i]+(verts[i]-cent):normalize()*-lt
if verts[i]:dist(cent)<2 then table.remove(verts,i) end
line(p1.x,p1.y,p2.x,p2.y)
end
end
end
Some of them really have some interesting shapes. It’s not the algorithm itself that makes the different shapes but the way sine and cosine are handled along with the algorithm.
All I have to say is it is mesmerizing.
The way to make your own tests:
Test format is nd,lt,ti,si
Nd is the sin/cos setter to plot points at positions
Lt is the draw in (gravity) a minus sends it outwards
Ti is the time step
Si is the size.
I might change to meshes if it is fast enough but I fear the calculation of midpoints lengths and angles for hundreds of lines every step will slow things down a lot.