Daily Creative Coding

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

光の伝播

隣接している円が点灯していると自分も光る. ブーリアンネットワークみたいな感じ. ときたま,周期的に光り続ける状態に陥る.

/**
* Propagation of Lights
*
* @autor aa_debdeb
* @date 2015/09/12
*/


int LIGHT_NUM = 100;
float MAX_LIGHT_RADIOUS = 50;
float MIN_LIGHT_RADIOUS = 20;

ArrayList<Light> lights;

void setup(){
  size(500, 500);
  smooth();
  frameRate(30);
  
  lights = new ArrayList<Light>();
  for(int i = 0; i < LIGHT_NUM; i++){
    lights.add(new Light(i));
  }
  for(Light light : lights){
    light.findNeighbors();
  }

}

void draw(){
  if(random(1) < 0.05){
    Light light = lights.get(int(random(lights.size())));
    if(!light.isCooling){
      light.isOn = true;
    }
  }
  
  background(100);
  for(Light light : lights){
    light.draw();
  }
  for(Light light : lights){
    light.setNextState();
  }
  for(Light light : lights){
    light.update();
  }
  
}

class Light{

  int id;
  float x;
  float y;
  float radious;
  boolean isOn;
  boolean nextState;
  boolean isCooling;
  ArrayList<Light> neighbors;
  
  Light(int id){
    this.id = id;
    this.radious = random(MAX_LIGHT_RADIOUS - MIN_LIGHT_RADIOUS) + MIN_LIGHT_RADIOUS; 
    this.x = random(width - radious * 2) + radious;
    this.y = random(height - radious * 2) + radious;
    isOn = false;
    nextState = false;
    isCooling = false;
    neighbors = new ArrayList<Light>();
  }
  
  void findNeighbors(){
    for(Light light : lights){
      if(light.id == this.id){
        continue;
      } else {
        float distance = sqrt(sq(this.x - light.x) + sq(this.y - light.y));
        if(distance <= this.radious + light.radious){
          this.neighbors.add(light);
        }
      }
    } 
  }
  
  void setNextState(){
    this.nextState = false;
    if(!this.isCooling){
      for(Light neighbor: this.neighbors){
        if(neighbor.isOn){
          this.nextState = true;
          break;
        }
      }
    }
  }
  
  void update(){
    if(isCooling){
      this.isCooling = false;
    }
    if(this.isOn){
      this.isCooling = true;
    }
    this.isOn = this.nextState;
  }
  
  void draw(){
    noStroke();
    if(isOn){
      fill(255, 100);
    } else {
      fill(0, 100);
    }
    arc(this.x, this.y, this.radious * 2, this.radious * 2, 0, PI * 2);
  }
}