Processing: Cellular Automata

CELLULAR AUTOMATA
A cellular automaton (pl. cellular automata, abbrev. CA) is a discrete model studied in computability theory, mathematics, physics, complexity science, theoretical biology and microstructure modeling. It consists of a regular grid of cells, each in one of a finite number of states, such as “On” and “Off” (in contrast to a coupled map lattice). The grid can be in any finite number of dimensions. For each cell, a set of cells called its neighborhood (usually including the cell itself) is defined relative to the specified cell. For example, the neighborhood of a cell might be defined as the set of cells a distance of 2 or less from the cell. An initial state (time t=0) is selected by assigning a state for each cell. A new generation is created (advancing t by 1), according to some fixed rule (generally, a mathematical function) that determines the new state of each cell in terms of the current state of the cell and the states of the cells in its neighborhood. For example, the rule might be that the cell is “On” in the next generation if exactly two of the cells in the neighborhood are “On” in the current generation, otherwise the cell is “Off” in the next generation. Typically, the rule for updating the state of cells is the same for each cell and does not change over time, and is applied to the whole grid simultaneously, though exceptions are known.
For further reading on CAs try:

EXAMPLE 01: ONE-DIMENSIONAL CELLULAR AUTOMATA
…coming soon…

EXAMPLE 02: TWO-DIMENSIONAL CELLULAR AUTOMATA
SKETCH COMPONENT 01: CA CELL
The CA cell itself, here we functions to assign neighbours to each cell, and write the behaviours that the cell will use to check those neighbours, and based on the results apply a rule set to update itself.
class SuperCell{ /*------------------------------------------------------------------------------------------------------------------------------ *** CLASS VARIABLES *** ------------------------------------------------------------------------------------------------------------------------------*/ PVector pos; float sizeXX, sizeYY; boolean currState, nextState; int cellCol, indexI, indexJ; String myID; SuperCell[] neighbours; /*------------------------------------------------------------------------------------------------------------------------------ *** CLASS CONSTRUCTOR *** ------------------------------------------------------------------------------------------------------------------------------*/ SuperCell( String _ID, boolean _S, PVector _P, float _SX, float _SY, int _II, int _JJ ){ pos = _P; indexI = _II; indexJ = _JJ; myID = _ID; currState = _S; sizeXX = _SX; sizeYY = _SY; cellCol = 250; //------------------------------------Neighbourhood neighbours = new SuperCell[8]; } /*------------------------------------------------------------------------------------------------------------------------------ *** CLASS BEHAVIORS *** ------------------------------------------------------------------------------------------------------------------------------*/ //------------------------------------ draw the cell void render(){ if( this.getCurrentState() ){ stroke(0,0,cellCol); fill(0,0,cellCol,95); ellipse(pos.x, pos.y, sizeXX/3, sizeYY/3); } else{ stroke(0,0,cellCol/5); fill(0,0,cellCol/5,70); ellipse(pos.x, pos.y, sizeXX/6, sizeYY/6); } } //------------------------------------ update current state to the next state void updateCell(){ int counter = 0; for(int i = 0; i < neighbours.length; i++){ boolean bVal = neighbours[i].getCurrentState(); if( bVal ) counter++; } this.applyRules(counter); } //------------------------------------ apply rules of life void applyRules(int C){ if( C < 2 ) setNextState(false); // loneliness if( C > 3 ) setNextState(false); // overpopulation if( C == 3 ) setNextState(true); // reproduce } //------------------------------------ toggle cell state void toggleCellState(){ boolean bVal = nextState; currState = bVal; //setCurrentState(bVal); } //------------------------------------ applyRules void assignNeighbours(){ // println("assigning neighbours!"); // BELOW neighbours[0] = cellPop[ (indexI+COLS-1) % COLS ] [ (indexJ+ROWS-1) % ROWS ]; neighbours[1] = cellPop[ indexI ] [ (indexJ+ROWS-1) % ROWS ]; neighbours[2] = cellPop[ (indexI+1) % COLS ] [ (indexJ+ROWS-1) % ROWS ]; // LEFT & RIGHT neighbours[3] = cellPop[ (indexI+COLS-1) % COLS ] [ indexJ ]; neighbours[4] = cellPop[ (indexI+1) % COLS ] [ indexJ ]; // ABOVE neighbours[5] = cellPop[ (indexI+COLS-1) % COLS ] [ (indexJ+1) % ROWS ]; neighbours[6] = cellPop[ indexI ] [ (indexJ+1) % ROWS ]; neighbours[7] = cellPop[ (indexI+1) % COLS ] [ (indexJ+1) % ROWS ]; } //------------------------------------ set cell states void setCurrentState(boolean B){ currState = B; } void setNextState(boolean B){ nextState = B; } //------------------------------------ retrieve cell states boolean getCurrentState(){ return currState; } boolean getNextState(){ return nextState; } }
SKETCH COMPONENT 02: SETUP
All the upfront initialization methods to create a Processing sketch. Plus we have parameters relating to the CA setup itself; size, number of cells, etc….
/*------------------------------------------------------------------------------------------------------------------------------ *** GLOBAL VARIABLES*** ------------------------------------------------------------------------------------------------------------------------------*/ //--------------------------- Applet int ENVX = 500; int ENVY = 500; int COLS = 100; int ROWS = 100; float colStep, rowStep; //--------------------------- CA Cells SuperCell[][] cellPop; float PERCENT = 0.25; // percent to be alive at start of sim /*------------------------------------------------------------------------------------------------------------------------------ *** GLOBAL INIT *** ------------------------------------------------------------------------------------------------------------------------------*/ void setup(){ background(0); size(ENVX, ENVY); frameRate(2); rectMode(CENTER); //-----------------------------------------make cells cellPop = new SuperCell[COLS][ROWS]; makeCells(); } /*------------------------------------------------------------------------------------------------------------------------------ *** GLOBAL MAIN *** ------------------------------------------------------------------------------------------------------------------------------*/ void draw(){ background(0); //----------------------------------------- RUN CELLS for(int i = 0; i < COLS; i++){ for(int j = 0; j < ROWS; j++){ // cellPop[i][j].printCell(); // use text labels cellPop[i][j].render(); } } //----------------------------------------- check cells for(int i = 0; i < COLS; i++){ for(int j = 0; j < ROWS; j++){ cellPop[i][j].updateCell(); } } //----------------------------------------- toggle cell states for(int i = 0; i < COLS; i++){ for(int j = 0; j < ROWS; j++){ cellPop[i][j].toggleCellState(); } } } /*------------------------------------------------------------------------------------------------------------------------------ *** UTILITIES *** ------------------------------------------------------------------------------------------------------------------------------*/ void makeCells(){ boolean blnSwitch; colStep = float(ENVX)/COLS; rowStep = float(ENVY)/ROWS; //----------------------------------------- make cells for(int i = 0; i < COLS; i++){ for(int j = 0; j < ROWS; j++){ if(random(1) < PERCENT) blnSwitch = true; else blnSwitch = false; cellPop[i][j] = new SuperCell( str(i) + "_" + str(j), blnSwitch, new PVector( (colStep/2) + colStep*i, (rowStep/2) + rowStep*j ), colStep, rowStep, i, j ); } } //----------------------------------------- assign neighbours to each cells for(int i = 0; i < COLS; i++){ for(int j = 0; j < ROWS; j++){ cellPop[i][j].assignNeighbours(); } } }
You’re currently reading “Processing: Cellular Automata”, an entry on supermanoeuvre
- Published:
- 15.06.09 / 9am
- Category:
- Processing, Tutorials, Uncategorized
- Tags:
Comments are closed
Comments are currently closed on this entry.