• fullscreen
• BML.pde
• bml.pde
• ```//Biham-Middleton-Levine Traffic Model in Processing
//Adapted from the C version I posted on Wikipedia: http://en.wikipedia.org/wiki/User:Purpy_Pupple/BML

boolean one=true;
boolean two=false;
int PERCENT=35;
int H_SIZE=89;//height
int W_SIZE=144;//width
int cellSize=4;
int [] statesone={0,0,0,0,1,1,2,2,2,1,1,1,0,1,1,2,2,2,0,0,0,0,1,1,2,2,2,};//secret sauce
int [] statestwo={0,0,0,1,1,1,0,2,2,0,0,0,1,1,1,0,2,2,2,2,2,1,1,1,0,2,2,};//more secret sauce
int [][] X = new int[H_SIZE][W_SIZE];//to store the current state before it is one's turn to move
int [][] Y = new int[H_SIZE][W_SIZE];//to store the current state before it is two's turn to move
boolean twoorone = one;

int rand(){
return (int)random(99999999);
}

void trafficroll(boolean oneortwo){
//"rolls" traffic depending on whose turn it is.
int a,b,c;//the value of the spot before, at, and after the position you're currently at.
int mobility=0;//mobility
if(oneortwo==one){
for(int i=0;i<H_SIZE;i++){
for(int j=0;j<W_SIZE;j++){
a=X[(i-1+H_SIZE)%H_SIZE][j]; b=X[i][j]; c=X[(i+1)%H_SIZE][j];
Y[i][j]=statesone[c+3*b+9*a];//awesome base three arithmetic!
if(Y[i][j]>X[i][j]) mobility++;
}
}
}else{
for(int i=0;i<H_SIZE;i++){
for(int j=0;j<W_SIZE;j++){
a=Y[i][(j-1+W_SIZE)%W_SIZE]; b=Y[i][j]; c=Y[i][(j+1)%W_SIZE];
X[i][j]=statestwo[c+3*b+9*a];//awesome base three arithmetic!
if(X[i][j]>Y[i][j]) mobility++;
}
}
}
return;
}

void trafficset(){
int n, xn, yn;
for(int j=0;j<H_SIZE;j++){
for(int k=0;k<W_SIZE;k++){
X[j][k]=0;//initialize everything to zero!
}
}
for(int i=0;i<PERCENT*H_SIZE*W_SIZE/200;i++){
do{
n=rand()%(H_SIZE*W_SIZE);
}while(X[n/W_SIZE][n%W_SIZE]!=0);//find a random place that's empty
X[n/W_SIZE][n%W_SIZE]=1;         //set that as a one
do{
n=rand()%(H_SIZE*W_SIZE);
}while(X[n/W_SIZE][n%W_SIZE]!=0);//find a random place that's empty
X[n/W_SIZE][n%W_SIZE]=2;         //set that as a two
}
return;
}

void setup(){
size(W_SIZE*cellSize,(H_SIZE+20)*cellSize);
trafficset();
textFont(createFont("Arial",30,true));
noStroke();
frameRate(60);
}

void draw(){
background(0);
trafficroll(twoorone?one:two);
for(int j=0;j<H_SIZE;j++){
for(int k=0;k<W_SIZE;k++){
if(twoorone){
fill(Y[j][k]==0?#ffffff:(Y[j][k]==1?#ff0000:#0000ff));//two
}else{
fill(X[j][k]==0?#ffffff:(Y[j][k]==1?#ff0000:#0000ff));//one
}
rect(k*cellSize,j*cellSize,cellSize,cellSize);
}
}
twoorone=!twoorone;
fill(#ff0000);
triangle(cellSize*PERCENT*W_SIZE/100,cellSize*(H_SIZE+10),
cellSize*(PERCENT*W_SIZE/100-5),cellSize*(H_SIZE+18),
cellSize*(PERCENT*W_SIZE/100+5),cellSize*(H_SIZE+18));
text(PERCENT,cellSize*(W_SIZE-40),cellSize*(H_SIZE+18));
}

void mouseDragged(){
if(mouseY>H_SIZE*cellSize){
PERCENT=mouseX*100/(W_SIZE*cellSize);
trafficset();
}
}
```
```//Biham-Middleton-Levine Traffic Model in Processing
//Daniel L. Lu

int xsize = 769, ysize = 256, speed = 3, fpsTheoretical = 60,
speedCursor = 160, densityCursor = 346, iterations = 0, mobility = 0, population;

float density = 35;

int []rule = {0,0,0,0,2,2,1,1,1,2,2,2,0,2,2,1,1,1,0,0,0,0,2,2,1,1,1};
int []pixles = new int [xsize*ysize];
int []slexip = new int [xsize*ysize];

int x, y;

int color2state(color c){
return c==#FF0000?1:(c==#0000FF?2:0);
}

color state2color(int s){
return s==1?#FF0000:(s==2?#0000FF:#FFFFFF);
}

void trafficSet(){
background(#FFFFFF);
hud();
population = 0;
for(x=0; x<xsize; x++){
for(y=0; y<ysize; y++){
if(random(100)<density){
if(random(100)<50){
pixels[y*xsize+x] = #FF0000;
population++;
}else{
pixels[y*xsize+x] = #0000FF;
population++;
}
}
}
}
iterations = 0;
mobility = 0;
for(int i = 0; i<xsize*ysize; i++){
pixles[i] = color2state(pixels[i]);
}
updatePixels();
}

void hud(){
fill(#FFFFFF);
rect(0,ysize,xsize,40);
fill(#000000);
text("speed: " + (int)(frameRate*speed),20, ysize+20);
text("density: " + density/100, 276, ysize+20);
text("iter: " + iterations, 532, ysize+20);
if(population!=0){
text("mobility: " + 1000*mobility/population/10.0 + "%", 532, ysize+40);
}

fill(#888888);
text("(" + fpsTheoretical+"*"+speed + ")", 110, ysize+20);
rect(20, ysize+30, 200, 4);
rect(276, ysize+30, 200, 4);
//rect(532, ysize+30, 200, 4);
fill(#444444);
ellipse(speedCursor, ysize+32, 8, 8);
ellipse(densityCursor, ysize+32, 8, 8);
}

void setup(){
frameRate(fpsTheoretical);
textSize(14);
ellipseMode(CENTER);
noStroke();
size(769,306);
trafficSet();
}

void draw(){
for(int i=0; i<speed; i++){
iterations++;
if(iterations%(fpsTheoretical*speed/3)!=0){//mobility calculations are expensive, so we only do it 3 times per second.
for(x = 0; x<xsize; x++){
for(y = 0; y<ysize; y++){
slexip[y*xsize+x] = rule[pixles[y*xsize+(x+1)%xsize]+3*pixles[y*xsize+x]+9*pixles[y*xsize+(x+xsize-1)%xsize]];
}
}
for(x = 0; x<xsize; x++){
for(y = 0; y<ysize; y++){
pixles[y*xsize+x] = rule[slexip[x+((y+1)%ysize)*xsize]+3*slexip[y*xsize+x]+9*slexip[x+((y+ysize-1)%ysize)*xsize]];
}
}
}else{
mobility = 0;
for(x = 0; x<xsize; x++){
for(y = 0; y<ysize; y++){
slexip[y*xsize+x] = rule[pixles[y*xsize+(x+1)%xsize]+3*pixles[y*xsize+x]+9*pixles[y*xsize+(x+xsize-1)%xsize]];
mobility+=(slexip[y*xsize+x]!=0 && pixles[y*xsize+x]==0)?1:0;
}
}
for(x = 0; x<xsize; x++){
for(y = 0; y<ysize; y++){
pixles[y*xsize+x] = rule[slexip[x+((y+1)%ysize)*xsize]+3*slexip[y*xsize+x]+9*slexip[x+((y+ysize-1)%ysize)*xsize]];
mobility+=(pixles[y*xsize+x]!=0 && slexip[y*xsize+x]==0)?1:0;
}
}
}
}
for(int i = 0; i<xsize*ysize; i++){
pixels[i] = state2color(pixles[i]);
}
updatePixels();
hud();
}

void mouseDragged(){
if(mouseY>ysize+10){
if(mouseX>=276 && mouseX<=476){
density = 100.0*(mouseX-276)/200;
trafficSet();
densityCursor = mouseX;
}else if(mouseX>=20 && mouseX<=30){
speed = 0;
fpsTheoretical = 60;
speedCursor = mouseX;
frameRate(fpsTheoretical);
}else if(mouseX>30 && mouseX<=140){
fpsTheoretical = (mouseX-20)/2;
speed = 1;
speedCursor = mouseX;
frameRate(fpsTheoretical);
}else if(mouseX>140 && mouseX<=220){
speed = (mouseX-140+10)/10;
fpsTheoretical = 60;
speedCursor = mouseX;
frameRate(fpsTheoretical);
}
}
}
```

### tweaks (0)

This sketch is running as Java applet, exported from Processing.