Daily Creative Coding

元「30 min. Processing」。毎日、Creative Codingします。

拡散律速凝集 Diffusion Limited Aggregation (DLA)

/**
* Diffusion Limited Aggregation (DLA)
*
* @author aa_debdeb
* @date 2016/07/09
*/

int num = 10000;
ArrayList<Walker> nonwalkers;
ArrayList<Walker> walkers;
int[][] moves = {{0, -1}, // up
                 {1, 0}, //right 
                 {0, 1}, // down
                 {-1, 0}}; //left

void setup(){
  size(300, 300);
  frameRate(300);
  colorMode(HSB, 360, 100, 100);
  nonwalkers = new ArrayList<Walker>();
  nonwalkers.add(new Walker(int(width / 2), int(height / 2)));
  walkers = new ArrayList<Walker>();
  for(int i = 0; i < num; i++){
    walkers.add(new Walker());
  }
}

void draw(){
  background(0, 0, 0);
 
  for(Walker walker: nonwalkers){
    stroke(walker.hue, 70, 100);
    point(walker.x, walker.y);
  }
  
  for(Walker walker: walkers){
    stroke(walker.hue, 70, 100);
    point(walker.x, walker.y);
  }
  
  int minx, maxx, miny, maxy;
  minx = width;
  maxx = -1;
  miny = height;
  maxy = -1;
  for(Walker walker: nonwalkers){
    if(walker.x < minx){minx = walker.x;}
    if(walker.x > maxx){maxx = walker.x;}
    if(walker.y < miny){miny = walker.y;}
    if(walker.y > maxy){maxy = walker.y;}
  }
  
  ArrayList<Walker> nextWalkers = new ArrayList<Walker>();
  for(Walker w: walkers){
    boolean isTrapped = false;
    if(minx - 1 <= w.x && w.x <= maxx + 1 &&
       miny - 1 <= w.y && w.y <= maxy + 1 ){
      for(int i = 0; i < 4; i++){
        int mx = w.x + moves[i][0];
        int my = w.y + moves[i][1];
        for(Walker nonw: nonwalkers){  
          if(nonw.x == mx && nonw.y == my){
            nonwalkers.add(w);
            isTrapped = true;
            break;    
          }
        }
        if(isTrapped){
          break;
        }
      }
    }
    if(!isTrapped){
      w.update();
      nextWalkers.add(w);
    }    
  }
  walkers = nextWalkers;
}

class Walker{
  int x, y;
  float hue;
  
  Walker(){
    x = int(random(width));
    y = int(random(height));
    hue = 1.0;
  } 
  
  Walker(int x_, int y_){
    x = x_;
    y = y_;
  } 
  
  void update(){
    while(true){
      int mi = int(random(4));
      int nx = x + moves[mi][0];
      int ny = y + moves[mi][1];
      if(0 <= nx && nx < width && 0 <= ny && ny < height){
        x = nx;
        y = ny;
        break;
      }
    }  
    hue += 0.03;
    if(hue >= 360){hue -= 360;} 
  }
}