3dAutomata
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);
}
}