sink-0
2012. 09. 17.

Drag on the screen to spawn particles, press enter key to reset.

» launch sink-0

p5          = processing
sources     = []
sinks       = []
objects     = []
random2     = (r) -> random(-r, r)
min_dist    = 100
force       = 20
friction    = 0.1
num_sinks   = 10
num_objects = 10

class Sink
  constructor: (@x, @y) ->
    @f = force
    @c = color random(255), random(255), random(255), random(100)

  pull: (obj) ->
    d = max(min_dist, dist(@x, @y, obj.x, obj.y))
    f = @f / pow(d, 2)

    obj.ax += f * (@x - obj.x)
    obj.ay += f * (@y - obj.y)

    f

  draw: (f) ->
    noStroke()
    fill @c, 1
    ellipse @x, @y, f, f

class Particle
  constructor: (x, y) ->
    @x  = x or random(p5.width)
    @y  = y or random(p5.height)
    vr  = 0
    @vx = random(-vr, vr)
    @vy = random(-vr, vr)
    @ax = 0
    @ay = 0
    @a  = random(50, 150)
    @c  = color random(255), random(0, 150), random(100, 255)
    @f  = force
    @friction = friction

  pull: (obj) ->
    d = max(min_dist, dist(@x, @y, obj.x, obj.y))
    f = @f * 1 / pow(d, 2)

    obj.ax += f * (@x - obj.x) / d
    obj.ay += f * (@y - obj.y) / d

  draw: ->
    [px, py] = [@x, @y]

    @x  += @vx += @ax
    @y  += @vy += @ay
    @vx *= @friction
    @vy *= @friction

    @a -= 0.1
    stroke @c, @a
    #line px, py, @x, @y
    for i in [0...2]
      point @x + random2(2), @y + random2(2)

  visible: ->
    @x > 0 and @y > 0 and @x < p5.width and @y < p5.height

setup = ->
  colorMode HSB
  background 255
  frameRate 30
  size $(window).width(), $(window).height()
  noFill()
  strokeWeight 2
  stroke 0

  initialize()

initialize = ->
  sinks   = []
  objects = []
  for t in [0...num_sinks]
    sinks.push new Sink(random(p5.width), random(p5.height))
  for t in [0...num_objects]
    objects.push new Particle()

  background random(255), random(0, 150), random(50, 200)

keyPressed = ->
  if keyCode() == ENTER || keyCode() == RETURN
    initialize()

draw = ->
  if __mousePressed()
    if objects.length < 50
      objects.push new Particle(p5.mouseX + random2(100), p5.mouseY + random2(100))

  for s in sinks
    f = 0
    for o in objects
      f += s.pull(o)
      o.draw()
    s.draw(f)

  objects =
    for o in objects when o.a > 0 and
                          o.x > -p5.width and o.y > -p5.height and
                          o.x < p5.width * 2 and o.y < p5.height * 2
      o
» capture | close