fractalkitty looking for math? fractalkitty.com

100 days of code

lifeMeditation

#random#grid#interactive#animation#math#geometry#symmetry#cellular-automata

rulesdArrayrandomDeadswitchDead


let rules = 0;//this is the counter for different sets of rules
let cnt = 0;//counter for dead alive array in loops below
let n;
let dArray = [];//array for each cell for dead/alive status
let r = 20;//radius size - change this for different looks (this doesn't change based on canvas size)

function setup() {
  createCanvas(windowWidth, windowHeight );//canvas size seet to window
  co = floor(width / (2 * r));
  ro = co
  randomDead();//this sets a random dead/alive for each cell
  background(20);//almost black
  noStroke();//no lines
  frameRate(5)//slow frame rate to see progression of automata
}
function draw() {
  background(20);
  translate(width / 2, height / 2);
  s=0.28;
  if(width>1000){
    s=0.2;//scale factor to adjust for larger screens
  }
  scale(s, s)//set scale
  v = 12
  for (let m = 0; m < v; m++) {//loop to create separate points on the star
    push();//translations and rotations between push and pop only apply between push/pop
      rotate(m * TWO_PI / v)//rotate the canvas to create each point
      cnt = 0;//this is the counter for the alive/dead array to loop through
      for (let j = 0; j <= co; j++) {
        for (let i = ro; i >= 0; i--) {
          x = r * j * 1.5;
          y = -r * 12 + r * sqrt(3) * i + r * j / 1.15;
          if (dArray[cnt] === 0) {//change fill for dead
            noFill();
            noStroke();
          }
          if (dArray[cnt] === 1) {//change fill/stroke for alive with a gradient based on row/column
            fill(j * 4 + i * 5, 200 + i * 5, 255 - j * 2, 200 - m * 7);
            stroke(j * 4 + i * 5, 200 + i * 5, 255 - j * 2, 200 - m * 7);
          }
          circle(x, y, r*1.4 );//place circle in the hexgrid
          fill(20);//set fill back to background
          cnt = cnt + 1;
        }
      }
    pop();//end push/pop transformations
  }
  switchDead()//next round of alive/dead caculatiions 
}

function randomDead() {//initializes random dead/alive status of cells
  n = (co + 1) * (ro + 1);//n is the size of the grid
  dArray = []//dead-alive array is cleared
  for (let i = 0; i < n; i++) {//loop through the array and fill with random dead/alive
    tmp = random(-1, 1);//base dead/alive on positive/negative numbers
    if (tmp <= 0) {
      dArray[i] = 1;
    }
    if (tmp > 0) {
      dArray[i] = 0;
    }
  }
}

function switchDead() {//loops through and changes dead/alive status bases on neighbors
  cnt1 = 0
  for (let j = 0; j <= co; j++) {
    for (let i = ro; i >= 0; i--) {
      if (j != 0 && i != 0 && i != ro && j != co) {//if a cell is not in the corner of the grid
        sumd = dArray[cnt1 + co + 1] + dArray[cnt1 + co + 2] + dArray[cnt1 - co - 1] + dArray[cnt1 - co - 2] + dArray[cnt1 + 1] + dArray[cnt1 - 1];
      }
      if (i === 0 && j != 0 && j != co) {//for left side of array (but not a corner)
        sumd = dArray[cnt1 + co + 1] + dArray[cnt1 - co - 1] + dArray[cnt1 - co - 2] + dArray[cnt1 - 1];//find the sum of neighbors that are alive
      }
      if (i === ro && j != 0 && j != co) {//for right side of array (but not a corner)
        sumd = dArray[cnt1 + co + 1] + dArray[cnt1 - co - 1] + dArray[cnt1 + co + 2] + dArray[cnt1 + 1];//find the sum of neighbors that are alive
      }
      if (j === co && i != 0 && i != ro) {//for top side of array (but not a corner)
        sumd = dArray[cnt1 - co - 1] + dArray[cnt1 - co - 2] + dArray[cnt1 + 1] + dArray[cnt1 - 1];//find the sum of neighbors that are alive
      }
      if (j === 0 && i != 0 && i != co) {//for bottom side of array (but not a corner)
        sumd = dArray[cnt1 + co + 1] + dArray[cnt1 + co + 2] + dArray[cnt1 + 1] + dArray[cnt1 - 1];//find the sum of neighbors that are alive
      }
      if (i === 0 && j === 0) {//for corner lower left
        sumd = dArray[cnt1 + co + 1] + dArray[cnt1 + 1];//find the sum of neighbors that are alive
      }
      if (i === 0 && j === co) {//for corner upper left
        sumd = dArray[cnt1 - 1] + dArray[cnt1 - co - 1] + dArray[cnt1 - co - 2];//find the sum of neighbors that are alive
      }
      if (i === ro && j === 0) {//for corner lower right
        sumd = dArray[cnt1 + 1] + dArray[cnt1 + co + 1] + dArray[cnt1 + co + 2];
      }
      if (i === ro && j === co) {//for corner upper right
        sumd = dArray[cnt1 + 1] + dArray[cnt1 - co - 1];
      }
      if (rules===0){
          if (dArray[cnt1] === 1 && (sumd === 6 || sumd === 5 || sumd === 1 || sumd === 0)) {
          dArray[cnt1] = 0;
        } else if (dArray[cnt1] === 0 && (sumd === 4)) {
          dArray[cnt1] = 1;
        }
      }
      if (rules===1){
          if (dArray[cnt1] === 1 && (sumd === 6 || sumd === 5 || sumd === 2 || sumd === 1 || sumd === 0)) {
          dArray[cnt1] = 0;
        } else if (dArray[cnt1] === 0 && ( sumd === 3 ||sumd===4||sumd===5)) {
          dArray[cnt1] = 1;
        }
      }
      if (rules===2){
          if (dArray[cnt1] === 1 && (sumd === 6 || sumd === 5 ))   {
          dArray[cnt1] = 0;
        } else if (dArray[cnt1] === 0 && (sumd === 3)) {
          dArray[cnt1] = 1;
        }
      }
      if (rules===3){
          if (dArray[cnt1] === 1 && (sumd === 1 || sumd === 2 || sumd === 3))   {
          dArray[cnt1] = 0;
        } else if (dArray[cnt1] === 0 && (sumd === 3||sumd===4)) {
          dArray[cnt1] = 1;
        }
      }
      if (rules===4){
          if (dArray[cnt1] === 1 && (sumd === 3 ||sumd === 4 || sumd === 5 || sumd === 6))   {
          dArray[cnt1] = 0;
        } else if (dArray[cnt1] === 0 && (sumd===0||sumd===1||sumd===2)) {
          dArray[cnt1] = 1;
        }
      }
      if (rules===5){
          if (dArray[cnt1] === 1 && (sumd === 2 ||sumd === 3 ||sumd === 4 || sumd === 5 || sumd === 6))   {
          dArray[cnt1] = 0;
        } else if (dArray[cnt1] === 0 && (sumd===0||sumd===1||sumd===2)) {
          dArray[cnt1] = 1;
        }
      }
      if (rules===6){
          if (dArray[cnt1] === 1 && (sumd === 4 || sumd === 5 || sumd === 6))   {
          dArray[cnt1] = 0;
        } else if (dArray[cnt1] === 0 && (sumd===3||sumd===4)) {
          dArray[cnt1] = 1;
        }
      }
      cnt1 = cnt1 + 1
    }
  }
  stroke(255);
  noFill()
  push()//change scale for rule counter only between push/pop
    scale(3,3)//scale change
    for(let i=0;i<=6;i++){
      circle(-width/2+20,-height/2+30*i+5,20)//rule circles
    }
    fill(100)
    circle(-width/2+20,-height/2+30*rules+5,20)//current rule
  pop()
}

function mousePressed() {//randomize dead alive again when the mouse is clicked
  randomDead();
}

function keyPressed() {//use arrow keys to change the rules
  if (keyCode === 32 || keyCode===40) {
    rules = rules+1;
    if (rules>6 ){
      rules=0;
    }
    randomDead();  
  }
  if (keyCode === 38){//move up with up arrow
  rules = rules-1;
    if (rules<0 ){
      rules=6;
    }
    randomDead(); 
  } 
}