Cellular Automata without Animation

I’ve been following along with Daniel Shiffman’s Cellular Automata tutorials (the code is here: noc-examples-processing/chp07_CA at master · arianatri/noc-examples-processing · GitHub).

And I’ve noticed that most CA seems to work in a similar way - by enacting the process in real-time.

I’m wondering how hard it would be to take something like the simplest example (https://github.com/arianatri/noc-examples-processing/tree/master/chp07_CA/NOC_7_01_WolframCA_simple) and have it do the computation first and then display the fully-rendered image.

I have no idea how to do this in Processing or whether it is even possible.

Thanks!

I may not be correctly understanding your question, but first create a Processing app with the following source code, then create a Tab titled ‘CA’ and copy/paste the class code in there:

CA ca;   // An instance object to describe the Wolfram basic Cellular Automata

void setup() {
  size(800, 400);
  background(255);
  ca = new CA();                 // Initialize CA
}

void draw() {
  ca.display();    // Draw the CA
  if (ca.generation < height/ca.w) {
    ca.generate();
  }  
}

Class code goes under the tab shown by the arrow:

Output:

Hi @svan, I do think you might be misunderstanding me…
The issue is that this process works by drawing one line at a time, until the full screen is filled up.
I’m wondering if there is a way to render the full image before displaying it.

this process works by drawing one line at a time

I see. Processing function createGraphics() uses an offscreen graphics buffer and perhaps might work; you’d have to try it. The idea being to do all the drawing offscreen and then send it to the screen when it’s all done, which sounds like what you are trying to do.

The following works on my system using createGraphics(). Also have to modify the display() function of the CA class to use PGraphics which is shown below that.

CA ca;   // An instance object to describe the Wolfram basic Cellular Automata
PGraphics pg;

void setup() {
  size(800, 400);
  background(255);
  ca = new CA();                 // Initialize CA
  pg = createGraphics(800, 400);
  for (int x = 0; x < height/ca.w; x++) {
    ca.display();    // Draw the CA line by line
    ca.generate();
  }
}

void draw() {
  image(pg, 0, 0);
}

Modified display() function of CA class:

  void display() {
   pg.beginDraw();
    for (int i = 0; i < cells.length; i++) {      
      if (cells[i] == 1) {
        pg.fill(0);
      } else { 
      pg.fill(255);
     }
      pg.noStroke();      
      pg.rect(i*w, generation*w, w, w);     
    }
    pg.endDraw();
  }
1 Like

Thanks, Svan - that should get me where I’m trying to go. Is it difficult to substitute PShape for PGraphic, though?

Is it difficult to substitute PShape for PGraphic, though?

One way would be to use createGraphics() to create an SVG, then load that image into a PShape. See https://processing.org/reference/libraries/svg/index.html. The code below should allow you to create an SVG which you can then use to create a PShape.

import processing.svg.*;

CA ca;   // An instance object to describe the Wolfram basic Cellular Automata

PGraphics pg;
PShape s;

void setup() {
  size(800, 400);
  background(255);
  noLoop();
  ca = new CA();                 // Initialize CA
  pg = createGraphics(800,400);
  for (int x = 0; x < height/ca.w; x++) {
    ca.display();    // Draw the CA line by line
    ca.generate();
  }  
  beginRecord(SVG, "data/serp.svg");
}

void draw() {
  image(pg,0,0);
  endRecord();
  s = loadShape("serp.svg");
  println(s);
}
1 Like