circles-3
2012. 06. 04.

Click on the screen to generate random patterns of tiled circles.

Although named circles-3, this sketch is actually another varition of tiles-1. Initially inspired by a slide full of colorful circles from a TED talk, Beware online "filter bubbles", which is a great talk by the way, the sketch ended up being this schizophrenic-circle-madness.

» launch circles-3

rint = (a, b) -> parseInt random(a, b)
Array::sample  = -> this[rint(0, this.length)]
Object::keys   = -> _(this).keys()
String::sample = -> this.substr(rint(0, this.length), 1)
Object::each   = (f) ->
  for k, v of this
    f(k, v) if this.hasOwnProperty(k)
  null
Array::each    = (f) -> _(this).each(f)

p5       = processing
sizes    = {}
grids    = {}
shapes   = 5
sr       = 0.4
sparsity = 2
srange   = [10, 180]
opacity  = 3

pick_slot = (sz) ->
  sz = parseInt sz
  x  = grids[sz].keys().sample()

  if x?
    y = grids[sz][x].keys().sample()
    if y?
      x = parseInt x
      y = parseInt y
      occupy sz, x, y
      return { x: x, y: y }

occupy = (sz, x, y) ->
  sizes.each (s, cnt) ->
    s = parseInt s
    step = parseInt s * sr

    sx = floor((x - s) / step) * step
    sy = floor((y - s) / step) * step

    for xx in [sx...(x + sz)] by step
      for yy in [sy...(y + sz)] by step
        if grids[s][xx]? and xx > sx and yy > sy
          delete grids[s][xx][yy]
          if grids[s][xx].keys().length == 0
            delete grids[s][xx]
  null

setup = ->
  colorMode HSB, 1.0
  ellipseMode CENTER
  noLoop()
  mousePressed()

drawCircle = (x, y, sz, col) ->
  stroke 1, 0.5
  fill hue(col), saturation(col), brightness(col), opacity / sz
  pushMatrix()
  translate x + sz / 2, y + sz / 2
  for s in [0..sz] by 2
    rotate random TWO_PI
    ellipse(
      random(-1, 1) * sz * 0.2,
      random(-1, 1) * sz * 0.2,
      s * random(0.7, 1.3),
      s * random(0.7, 1.3)
    )
  popMatrix()

mousePressed = ->
  size       $(window).width(), $(window).height()
  background 0

  colors = for i in [0...rint(5, 10)]
      color(random(1.0), random(0.8, 1.0), random(0.7, 1.0))

  grids = {}
  sizes = {}
  for i in [0...shapes]
    sz = rint(srange[0], srange[1])
    sizes[sz] = parseInt(p5.width * p5.height /
                         (shapes + sparsity) / pow(sz, 2))
  sizes.each (sz, count) ->
    sz = parseInt sz
    step = parseInt sz * sr

    grids[sz] = {}
    for x in [0..p5.width - sz] by step
      grids[sz][x] = {}
      for y in [0..p5.height - sz] by step
        grids[sz][x][y] = 1

  rsizes = _(sizes.keys()).sortBy((e) -> -parseInt(e))
  _(rsizes).each (sz) ->
    sz = parseInt sz
    count = sizes[sz]
    for i in [0...count]
      p = pick_slot sz
      if p?
        drawCircle p.x, p.y, sz, colors.sample()
      else
        break
» capture | close