sink-1
2013. 01. 10.

My attempt to simulate a hyperbolic funnel (gone a bit crazy). Drag on the screen and see the marbles spinning. Press enter key to invert the colors.

```p5    = processing
balls = []
g     = 1
cx    = null
cy    = null
bg    = 255
fg    = 0
rtn   = if typeof(window.devicePixelRatio) != 'undefined'
window.devicePixelRatio
else
1

setup = ->
size      \$(window).width() * rtn, \$(window).height() * rtn
frameRate 60
stroke    fg
cx = p5.width / 2
cy = p5.height / 2

angle = (x, y) ->
atan2 cy - y, cx - x

dying = (x, y, vx, vy) ->
dist(cx, cy, x, y) < 10 and mag(vx, vy) < 10

class Ball
constructor: (@x, @y, @vx, @vy) ->
@sw = 1 + random() * 30
@life = 20

tick: ->
ang = angle(@x, @y)
@vx += g * cos(ang)
@vy += g * sin(ang)

@vx *= 0.99
@vy *= 0.99

@x += @vx
@y += @vy

strokeWeight @sw
point @x, @y

@life -= 1 if dying(@x, @y, @vx, @vy)
@life > 0

keyPressed = ->
if keyCode() == ENTER || keyCode() == RETURN
[fg, bg] = [bg, fg]
stroke fg

draw = ->
if __mousePressed()
mx = p5.mouseX * rtn
my = p5.mouseY * rtn
ang = angle(mx, my)
for i in [0...3]
a = ang + 0.4 * PI + 0.2 * random() * PI
f = random() * 50
balls.push new Ball(mx, my, f * cos(a), f * sin(a))

background bg
balls = (b for b in balls when b.tick())```
» capture | close