fractalkitty looking for math? fractalkitty.com

early works

3dAutomata

#random#trig#classes#3d#interactive#animation#math#cellular-automata#mathober

draft of some ideas with 3d cellular automata

rulenodeArrayedgeArrayneighborArraynRulesnodeSinitializeNodesinitializeEdgesrandomBoolplotEdgesapplyRuleslivingNeighborsruleDots

let n = 50;
let r = 200;
let rule = 6;
let nodeArray = [];
let edgeArray = [];
let neighborArray = [];
let nRules = 8;
function setup() {
  createCanvas(windowWidth, windowHeight, WEBGL);
  r = min(width, height) / 2.5;
  angleMode(DEGREES);
  initializeNodes();
  initializeEdges();
  background(100);
  fill(191, 214, 212);
  plotEdges();
  ruleDots();
  for (let i = 0; i < n; i++) {
    nodeArray[i].display();
  }
}

function draw() {
  background(100);
  orbitControl();
  rotateX(frameCount / 10);
  rotateX(frameCount / 10);
  ruleDots();
  plotEdges();
  applyRules();
  noStroke();
  for (let i = 0; i < n; i++) {
    nodeArray[i].display();
  }
  livingNeighbors();
}
class nodeS {
  constructor(nId, a) {
    this.x = r * sin((nId * 360) / n) * sin((nId * 180) / n);
    this.y = r * cos((nId * 180) / n);
    this.z = r * sin((nId * 180) / n) * cos((nId * 360) / n);
    this.alive = a;
  }
  display() {
    if (this.alive) {
      fill(255);
    } else {
      fill(20);
    }
    push();
    noStroke();
    translate(this.x, this.y, this.z);
    sphere(5, 5, 5);
    pop();
  }
}
function initializeNodes() {
  for (let i = 0; i < n; i++) {
    nodeArray.push(new nodeS(i, randomBool()));
  }
}
function initializeEdges() {
  for (let i = 0; i < n; i++) {
    edgeArray[i] = [];
    for (let j = 0; j < i; j++) {
      edgeArray[i][i] = false;
      if (i !== j) {
        edgeArray[i][j] = randomBool();
      }
    }
  }
}
function randomBool() {
  a = random(0, 1);
  if (round(a) === 1) {
    return true;
  } else {
    return false;
  }
}
function plotEdges() {
  for (let i = 0; i < n; i++) {
    for (let j = 0; j < i; j++) {
      if (i != j && edgeArray[i][j]) {
        if (nodeArray[i].alive && nodeArray[j].alive) {
          stroke(255);
          strokeWeight(1);
        } else {
          stroke(0);
          strokeWeight(0.1);
        }
        line(
          nodeArray[i].x,
          nodeArray[i].y,
          nodeArray[i].z,
          nodeArray[j].x,
          nodeArray[j].y,
          nodeArray[j].z
        );
      }
    }
  }
}

function applyRules() {
  if (rule === 0) {
    t = floor(n / 50);
    for (let i = 0; i < n; i++) {
      if (neighborArray[i] < t || neighborArray[i] > t) {
        nodeArray[i].alive = false;
      }
      if (neighborArray[i] === t || neighborArray[i] != 0) {
        nodeArray[i].alive = true;
      }
    }
  }
  if (rule === 1) {
    t = 3;
    for (let i = 0; i < n; i++) {
      if (neighborArray[i] < t || neighborArray[i] > t) {
        nodeArray[i].alive = false;
      }
      if (neighborArray[i] === t || neighborArray[i] === 0) {
        nodeArray[i].alive = true;
      }
    }
  }
  if (rule === 2) {
    t = 5;
    for (let i = 0; i < n; i++) {
      if (neighborArray[i] < t || neighborArray[i] > t) {
        nodeArray[i].alive = false;
      }
      if (neighborArray[i] === t || neighborArray[i] === 0) {
        nodeArray[i].alive = true;
      }
    }
  }
  if (rule === 3) {
    for (let i = 0; i < n; i++) {
      if (neighborArray[i] % 2 === 0) {
        nodeArray[i].alive = true;
      } else {
        nodeArray[i].alive = false;
      }
    }
  }
  if (rule === 4) {
    for (let i = 0; i < n; i++) {
      if (neighborArray[i] % 2 === 0 && neighborArray[i] !== 0) {
        nodeArray[i].alive = false;
      } else {
        nodeArray[i].alive = true;
      }
    }
  }
  if (rule === 5) {
    t = 2;
    for (let i = 0; i < n; i++) {
      if (neighborArray[i] < t || neighborArray[i] > t) {
        nodeArray[i].alive = false;
      }
      if (neighborArray[i] === t || neighborArray[i] === 0) {
        nodeArray[i].alive = true;
      }
    }
  }
  if (rule === 6) {
    for (let i = 0; i < n; i++) {
      if (neighborArray[i] > 1) {
        nodeArray[i].alive = true;
      } else if (i % 2 === 0) {
        nodeArray[i].alive = false;
      }
    }
  }
  if (rule === 7) {
    t = 2;
    for (let i = 0; i < n; i++) {
      nodeArray[i].alive = false;
    }
  }
}

function livingNeighbors() {
  for (let i = 0; i < n; i++) {
    neighborArray[i] = 0;
    for (let j = 0; j < n; j++) {
      if (i !== j && nodeArray[j].alive && edgeArray[i][j]) {
        neighborArray[i] = neighborArray[i] + 1;
      }
    }
  }
}

function keyPressed() {
  if (keyCode === 38) {
    if (rule === 0) {
      rule = nRules - 1;
    } else {
      rule--;
    }
  }
  if (keyCode === 40) {
    if (rule === nRules - 1) {
      rule = 0;
    } else {
      rule = rule + 1;
    }
  }
  if (keyCode === 32) {
    if (n < 120) {
      n = n + 10;
    } else {
      n = 30;
    }
  }
  nodeArray = [];
  edgeArray = [];
  neighborArray = [];
  setup();
}

function ruleDots() {
  for (let i = 0; i < nRules; i++) {
    stroke(255);
    strokeWeight(1);
    if (rule === i) {
      fill(255);
    } else {
      fill(255, 255, 255, 50);
    }
    circle(-width / 2 + 20, -height / 2 + 20 * (i + 1), 15);
  }
}