Simulation of Theo Jansen’s Strandbeest (http://www.strandbeest.com). I first wanted to use the new physics engine for this, but decided against it after I discovered an instance can not change it’s dimensions (which is the main purpose of this simulation).
`
-- Strandbeest Mechanism Simulation
-- invented by Theo Jansen
-- http://www.strandbeest.com/
-- Herwig Van Marck
-- Use this function to perform your initial setup
function setup()
print("Pinch to Zoom the view")
print("Set clear to 1 to clear path")
print("Reduce step to slow down")
touches = {}
lastPinchDist = 0
pinchDelta = 1.0
pinchCenter = vec2(WIDTH/2,HEIGHT/2)
offset = vec2(0,0)
zoom = 1
T=0
parameter("step",0,0.3,0.12)
iparameter("clear",0,1,0)
parameter("a",10,200, 38*3)
parameter("b", 10, 200, 41.5*3)
parameter("c", 10, 200, 39.3*3)
parameter("d", 10, 200, 40.1*3)
parameter("e", 10, 200, 55.8*3)
parameter("f", 10, 200, 39.4*3)
parameter("g", 10, 200, 36.7*3)
parameter("h", 10, 200, 65.7*3)
parameter("i", 10, 200, 49*3)
parameter("j", 10, 200, 50*3)
parameter("k", 10, 200, 61.9*3)
parameter("l", 10, 200, 7.8*3)
parameter("m", 10, 200, 15*3)
img=image(WIDTH,HEIGHT)
spriteMode(CORNER)
end
function touched(touch)
if touch.state == ENDED then
touches[touch.id] = nil
else
touches[touch.id] = touch
end
end
function processTouches()
touchArr = {}
for k,touch in pairs(touches) do
-- push touches into array
table.insert(touchArr,touch)
end
if #touchArr == 2 then
t1 = vec2(touchArr[1].x,touchArr[1].y)
t2 = vec2(touchArr[2].x,touchArr[2].y)
dist = t1:dist(t2)
if lastPinchDist > 0 then
pinchDelta = dist/lastPinchDist
else
offset= offset + ((t1 + t2)/2-pinchCenter)/zoom
end
pinchCenter = (t1 + t2)/2
lastPinchDist = dist
else
pinchDelta = 1.0
lastPinchDist = 0
end
end
function draw()
if (clear==1) then
img=image(WIDTH,HEIGHT)
clear=0
end
-- This sets the background color to black
background(0, 0, 0)
font("Arial-BoldMT")
fontSize(50)
fill(0, 19, 255, 255)
text("Theo Jansen's",WIDTH/2,HEIGHT -60)
text("Strandbeest Mechanism",WIDTH/2,HEIGHT -120)
-- compute pinch delta
processTouches()
-- scale by pinch delta
zoom = math.max( zoom*pinchDelta, 0.2 )
translate(pinchCenter.x-offset.x*zoom,pinchCenter.y-offset.y*zoom)
scale(zoom,zoom)
sprite(img,-WIDTH/2,-HEIGHT/2)
--translate(pinchCenter.x,pinchCenter.y)
pinchDelta = 1.0
-- This sets the line thickness
strokeWidth(4)
font("AmericanTypewriter-Condensed")
fontSize(24)
fill(248, 248, 248, 255)
-- Draw mechanism
x1=0
y1=0
x2=a
y2=l
stroke(255, 0, 0, 255)
line(x1,y1,x2,y1)
text("a",(x2-x1)/2,y1-8)
line(x2,y1,x2,y2)
text("l",x2+8,(y2-y1)/2)
x3=x2+m*math.cos(T)
y3=y2+m*math.sin(T)
stroke(251, 255, 0, 255)
pushStyle()
fill(0, 0, 0, 0)
ellipse(x2,y2,m*2,m*2)
fill(251,255,0,255)
text("m",x2+m,y2+m+8)
popStyle()
line(x2,y2,x3,y3)
tmp=math.acos((j^2-b^2-x3^2-y3^2)/(-2*b*math.sqrt(x3^2+y3^2)))+math.atan(y3/x3)
x4=b*math.cos(tmp)
y4=b*math.sin(tmp)
stroke(255, 255, 255, 255)
line(x1,y1,x4,y4)
text("b",(x1+x4)/2+8,(y1+y4)/2)
line(x3,y3,x4,y4)
text("j",(x3+x4)/2,(y3+y4)/2+16)
tmp2=math.atan(y3/x3)-math.acos((k^2-c^2-x3^2-y3^2)/(-2*c*math.sqrt(x3^2+y3^2)))
x7=c*math.cos(tmp2)
y7=c*math.sin(tmp2)
line(x1,y1,x7,y7)
text("c",(x1+x7)/2-8,(y1+y7)/2)
line(x3,y3,x7,y7)
text("k",(x3+x7)/2+8,(y3+y7)/2-4)
tmp3=math.acos((e^2-b^2-d^2)/(-2*b*d))+tmp
x5=d*math.cos(tmp3)
y5=d*math.sin(tmp3)
line(x1,y1,x5,y5)
text("d",(x1+x5)/2,(y1+y5)/2+8)
line(x4,y4,x5,y5)
text("e",(x4+x5)/2+8,(y4+y5)/2)
n=math.sqrt(c^2+d^2-2*math.cos(2*math.pi-tmp3+tmp2)*c*d)
tmp4=math.acos((n^2-f^2-g^2)/(-2*f*g))
tmp5=math.acos((f^2-n^2-g^2)/(-2*n*g))+math.acos((d^2-n^2-c^2)/(-2*n*c))
o=math.sqrt(c^2+g^2-2*math.cos(tmp5)*c*g)
tmp6=math.acos((g^2-o^2-c^2)/(-2*o*c))
x6=o*math.cos(tmp2-tmp6)
y6=o*math.sin(tmp2-tmp6)
line(x5,y5,x6,y6)
text("f",(x5+x6)/2-8,(y5+y6)/2)
line(x7,y7,x6,y6)
text("g",(x6+x7)/2,(y6+y7)/2-8)
tmp7=math.acos((h^2-i^2-g^2)/(-2*i*g))+tmp5
p=math.sqrt(c^2+i^2-2*math.cos(tmp7)*c*i)
tmp8=tmp2-math.asin(i*math.sin(tmp7)/p)
x8=p*math.cos(tmp8)
y8=p*math.sin(tmp8)
line(x6,y6,x8,y8)
text("h",(x6+x8)/2-8,(y6+y8)/2-4)
line(x7,y7,x8,y8)
text("i",(x7+x8)/2+8,(y7+y8)/2)
if (math.abs(x8)<WIDTH/2 and math.abs(y8)<HEIGHT/2) then
img:set(x8+WIDTH/2,y8+HEIGHT/2,0,0,255,255)
end
T=T+step
end
`