This program is best run in Processing on a computer. The above video is compressed, thus losing much of the complexity of the program. Code for running locally can be found below.
The program creates an interesting amount of complexity and quickly reaches a dynamic (cells are always changing and unpredictable), but stable (some patterns emerge, but it never become a solid color) state. It is easy to tweak the rules and variable to create new configurations.
RULES:
- if the average brightness of a cell's two neighbors (left and right) is above 50%, the cell becomes slightly dimmer
- if the average brightness of a cell's two neighbors is below 50%, the cell becomes slightly brighter
- if the average brightness of a cell's two neighbors is very high, the cell becomes significantly brighter
- if the average brightness of a cell's two neighbors is very low, the cell becomes significantly dimmer
CODE (TO RUN IN PROCESSING):
int vwidth = 720;
int vheight = 480;
void setup(){
size(vwidth,vheight);
colorMode(HSB,360,100,250);
setPixels();
frameRate(30);
}
void draw(){
changePixels();
}
void changePixels() {
loadPixels();
for (int i = 1; i < vwidth*vheight-1; i++){
color c = pixels[i];
color cprev = pixels[i-1];
color cnext = pixels[i+1];
c = int(brightness(c));
cprev = int(brightness(cprev));
cnext = int(brightness(cnext));
if (cprev + cnext > 250) {
pixels[i] = color(220,100,c-5);
} else if (cprev + cnext < 250) {
pixels[i] = color(220,100,c+5);
}
if (cprev + cnext > 460){
pixels[i] = color(220,100,c+50);
}
if (cprev + cnext < 40){
pixels[i] = color(220,100,c-50);
}
}
updatePixels();
}
void setPixels() {
loadPixels();
for (int i = 0; i < vwidth*vheight; i++){
color setColor = color(220,100,random(0,250));
pixels[i] = setColor;
}
updatePixels();
}
CODE (FOR CREATING A .MOV FILE):
import processing.video.*;
MovieMaker mm;
PImage img;
int vwidth = 720;
int vheight = 480;
void setup(){
size(vwidth,vheight);
colorMode(HSB,360,100,250);
setPixels();
frameRate(30);
mm = new MovieMaker(this,vwidth,vheight,"ca.mov", 30, MovieMaker.ANIMATION, MovieMaker.BEST);
for (int i = 0; i < 480; i++){
changePixels();
if (i % 10 == 0) {
println(i);
}
mm.addFrame();
}
mm.finish();
}
void draw(){
}
void changePixels() {
loadPixels();
for (int i = 1; i < vwidth*vheight-1; i++){
color c = pixels[i];
color cprev = pixels[i-1];
color cnext = pixels[i+1];
c = int(brightness(c));
cprev = int(brightness(cprev));
cnext = int(brightness(cnext));
if (cprev + cnext > 250) {
pixels[i] = color(220,100,c-5);
} else if (cprev + cnext < 250) {
pixels[i] = color(220,100,c+5);
}
if (cprev + cnext > 460){
pixels[i] = color(220,100,c+50);
}
if (cprev + cnext < 40){
pixels[i] = color(220,100,c-50);
}
}
updatePixels();
}
void setPixels() {
loadPixels();
for (int i = 0; i < vwidth*vheight; i++){
color setColor = color(220,100,random(0,250));
pixels[i] = setColor;
}
updatePixels();
}