Diamond Lattice

to generate a new and unique variation

Source Code

Every variart piece is a small program. This is the one that drew what you're looking at.

var background = '#EFEEEA';
var colors = ['#D9852F', '#5B3A92', '#3E8E46', '#B3242B', '#E8D25A'];
var margin = 60;

var count = intVariable('Squares', 12, 45);

// Grow a cluster on a diamond lattice, half-steps allowed so squares overlap.
var cells = [{i: 0, j: 0}];
var taken = {'0,0': true};
while (cells.length < count) {
  var from = cells[getRandomInt(0, cells.length - 1)];
  var step = getRandomInt(0, 3) == 0 ? 0.5 : 1;
  var dirs = [[step, 0], [-step, 0], [0, step], [0, -step]];
  var d = dirs[getRandomInt(0, 3)];
  var cell = {i: from.i + d[0], j: from.j + d[1]};
  if (!taken[cell.i + ',' + cell.j]) {
    taken[cell.i + ',' + cell.j] = true;
    cells.push(cell);
  }
}

// Fit the cluster inside the margin.
var minX = 1e9, maxX = -1e9, minY = 1e9, maxY = -1e9;
cells.forEach(function(c) {
  var x = c.i - c.j, y = c.i + c.j;
  minX = Math.min(minX, x - 1); maxX = Math.max(maxX, x + 1);
  minY = Math.min(minY, y - 1); maxY = Math.max(maxY, y + 1);
});
var unit = Math.min(70, (width - margin * 2) / Math.max(maxX - minX, maxY - minY));
var offsetX = width / 2 - (minX + maxX) / 2 * unit;
var offsetY = height / 2 - (minY + maxY) / 2 * unit;
var stroke = Math.max(2, unit / 16);

s.rect(0, 0, width, height).attr({fill: background});

// Inner squares keep their distance, so half-step neighbours don't pile them up.
var inners = [];
function crowded(x, y) {
  return inners.some(function(p) {
    return Math.abs(p.x - x) + Math.abs(p.y - y) < unit * 1.5;
  });
}

cells.forEach(function(c) {
  var x = offsetX + (c.i - c.j) * unit;
  var y = offsetY + (c.i + c.j) * unit;
  var color = colors[getRandomInt(0, colors.length - 1)];
  s.polygon(x, y - unit, x + unit, y, x, y + unit, x - unit, y)
    .attr({fill: 'none', stroke: color, strokeWidth: stroke, strokeLinejoin: 'miter'});

  if (getRandomInt(0, 2) > 0 && !crowded(x, y)) {
    inners.push({x: x, y: y});
    var inner = unit * getRandomArbitary(0.5, 0.75);
    var innerColor = colors[getRandomInt(0, colors.length - 1)];
    s.rect(x - inner / 2, y - inner / 2, inner, inner)
      .attr({fill: 'none', stroke: innerColor, strokeWidth: stroke / 2});
  }
});