Daily Creative Coding

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

波の干渉

/**
* wave interference
*
* @author aa_debdeb
* @date 2016/08/03
*/

float step = 5;
float maxAmp = 100;
float minAmp = 20;
float maxDistance = 300;
float minDistance = 50;
float maxSpeed = 0.2;
float minSpeed = 0.01;
float maxInterval = PI / 32;
float minInterval = PI / 256;
ArrayList<Oscillator> oscillators;
color[] c = {color(255, 20, 147),
                color(0, 0, 0),
                color(20, 255, 247)};              

void setup(){
  size(500, 500);
  noStroke();
  oscillators = new ArrayList<Oscillator>();
}

void draw(){
  for(float x = 0; x < width; x += step){
    for(float y = 0; y < height; y += step){
      PVector p = new PVector(x + step / 2.0, y + step / 2.0);
      float v = 0;
      for(Oscillator osc: oscillators){
        v += osc.getValue(p);
      }
      if(v <= 0){
        fill(map(v, -200, 0, red(c[0]), red(c[1])),
             map(v, -200, 0, green(c[0]), green(c[1])),
             map(v, -200, 0, blue(c[0]), blue(c[1])));
      } else {
        fill(map(v, 0, 200, red(c[1]), red(c[2])),
             map(v, -0, 200, green(c[1]), green(c[2])),
             map(v, -0, 200, blue(c[1]), blue(c[2])));    
      }
      rect(x, y, step, step);
    }
  }
  
  for(Oscillator osc: oscillators){
    osc.update();
  }
  ArrayList<Oscillator> nextOscillators = new ArrayList<Oscillator>();
  for(Oscillator osc: oscillators){
    if(osc.energy >= 0.01){
      nextOscillators.add(osc);
    }
  }
  oscillators = nextOscillators;
}

void mousePressed(){
  oscillators.add(new Oscillator(new PVector(mouseX, mouseY)));
}

class Oscillator{
  
  PVector loc;
  float time;
  float energy;
  float distance;
  float amp;
  float speed;
  float interval;
  
  Oscillator(PVector _loc){
    loc = _loc;
    time = frameCount;
    energy = 1.0;
    distance = random(minDistance, maxDistance);
    amp = random(minAmp, maxAmp);
    speed = random(minSpeed, maxSpeed);
    interval = random(minInterval, maxInterval);
  }
  
  void update(){
    energy *= 0.995;
  }
  
  float getValue(PVector p){
    float d = loc.dist(p);
    float a = amp * energy * ((distance - d) / distance);
    return map(cos(d * interval - (frameCount - time) * speed), -1, 1, -a, a);
  }
  
}