fractalkitty looking for math? fractalkitty.com

cellular automata

Layers of Life

#random#trig#classes#grid#interactive#animation#accumulates#cellular-automata

collectionssizeSqrtnDimensionscolorArraysetCollectionNeighboursthisCellneighboursIndicescolIdxcellPenlivingNeighboursnextLiving

let collections = [];
let sizeSqrt = 50;
let nDimensions = 9;
let colorArray = [
  [182, 204, 213, 10],
  [191, 178, 217, 5],
  [197, 151, 221, 5],
  [200, 121, 224, 5],
  [202, 87, 227, 5],
  [182, 63, 205, 5],
  [143, 58, 161, 5],
  [105, 51, 118, 5],
  [70, 42, 79, 5],
  [36, 31, 42, 5]
];

const setCollectionNeighbours = (collectionIndex) => {
  for (let i = 0; i < sizeSqrt; i++) {
    for (let j = 0; j < sizeSqrt; j++) {
      const thisCell = collections[collectionIndex][i * sizeSqrt + j];
      const neighboursIndices = [
        (i - 1) * sizeSqrt + (j - 1),
        (i - 1) * sizeSqrt + j,
        (i - 1) * sizeSqrt + (j + 1),
        i * sizeSqrt + (j - 1),
        i * sizeSqrt + (j + 1),
        (i + 1) * sizeSqrt + (j - 1),
        (i + 1) * sizeSqrt + j,
        (i + 1) * sizeSqrt + (j + 1)
      ];
      for (const idx of neighboursIndices) {
        if (idx >= 0 && idx < collections[collectionIndex].length) {
          collections[collectionIndex][idx].neighbours.push(thisCell);
        }
      }
    }
  }
};

function setup() {
  createCanvas(600, 600);
  background(36, 31, 42);
  s = width / sizeSqrt;
  collections = [];
  for (let colIdx = 0; colIdx < nDimensions; colIdx++) {
    collections.push([]);
    for (let i = 0; i < sizeSqrt; i++) {
      for (let j = 0; j < sizeSqrt; j++) {
        collections[colIdx].push(new Pen([], i * s, j * s));
      }
    }
    setCollectionNeighbours(colIdx);
  }

  frameRate(5);
  noStroke();
}

function draw() {
  for (let colIdx = 0; colIdx < nDimensions; colIdx++) {
    push();
    scale((colIdx + 1) * 0.5);
    noStroke(1 - colIdx / 10);

    const [r, g, b, a] = colorArray[colIdx];
    for (const cell of collections[colIdx]) {
      if (cell.living) {
        fill(r * 1.5, g * 1.5, b * 1.5, a * 4);
      } else {
        fill(r / 15, g / 15, b / 15, a);
      }
      rect(cell.x + sin(colIdx * 3.14), cell.y + cos(colIdx*3.14), s, s);
      fill(255, 255, 255);
      pop();
    }
    collections[colIdx] = collections[colIdx].map((p) => p.nextGeneration());
    setCollectionNeighbours(colIdx);
  }
}


class Pen {
  constructor(arrayOfNeighbors, x, y, living = random([true, false])) {
    this.neighbours = arrayOfNeighbors;
    this.living = living;
    this.x = x;
    this.y = y;
  }

  nextGeneration() {
    const livingNeighbours = this.neighbours.filter((n) => n.living).length;
    const nextLiving =
      (livingNeighbours == 2 && this.living) || livingNeighbours == 3;
    return new Pen([], this.x, this.y, nextLiving);
  }
}

function keyPressed() {
  if (keyCode === 32) {
    setup();
    draw();
  }
}