tiles-0
2012. 05. 31.

Filling canvas with randomly-positioned elements is a no-brainer. However, doing so with non-overlapping elements, and making it look good, required a little more work.

Click on the screen to regenerate the tiles. (There's no clever algorithm behind this, so every click should take a while.)

» launch tiles-0

Array::sample = -> this[parseInt(random(this.length))]
Object::keys  = -> _(this).keys()

Object::each = (f) ->
  for k, v of this
    f(k, v) if this.hasOwnProperty(k)
  null

p5       = processing
sizes    = {}
grids    = {}
no_space = -1
shapes   = 5

pick = (sz) ->
  sz = parseInt sz
  x = grids[sz].keys().sample()
  return no_space unless x?

  y = grids[sz][x].keys().sample()

  if y?
    x = parseInt x
    y = parseInt y
    sizes.each (s, cnt) ->
      s = parseInt s
      step = s

      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]
    { x: x, y: y }

setup = ->
  noLoop()
  rectMode CENTER
  mousePressed()

mousePressed = ->
  size         $(window).width(), $(window).height()
  colorMode    HSB, 1.0
  background   1
  stroke       0
  strokeWeight 1

  colors = for i in [0...parseInt(random(5, 10))]
      color(random(1.0), random(0.0, 0.7), random(0.6, 1.0))

  grids = {}
  sizes = {}
  for i in [0...shapes]
    sz = parseInt random(10, 120)
    sizes[sz] = parseInt(p5.width * p5.height /
                         (shapes + 1) / pow(sz, 2))
  sizes.each (sz, count) ->
    sz = parseInt sz

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

  rsizes = _(sizes.keys()).sortBy((e) -> -parseInt(e))
  _(rsizes).each (sz) ->
    count = sizes[sz]
    for i in [0...count]
      p = pick(sz)
      if p?
        break if p == no_space
        fill colors.sample()
        pushMatrix()
        translate(p.x + sz * 0.5, p.y + sz * 0.5)
        rotate(0.015 * random(-PI, PI))
        rect 0, 0, sz, sz
        popMatrix()
» capture | close