Daily Creative Coding

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

瞬くメタボール

/**
* flash of metaballs
*
* @author aa_debdeb
* @date 2016/07/30
*/

int cellNum = 200;
float cellSize = 2;
float[][] cells;
ArrayList<Ball> balls;

void setup(){
  size(int(cellNum * cellSize), int(cellNum * cellSize));
  noStroke();
  cells = new float[cellNum][cellNum];
  balls = new ArrayList<Ball>();
}

void draw(){
  background(0);
  for(int x = 0; x < cellNum; x++){
    for(int y = 0;  y < cellNum; y++){
      PVector pos = new PVector(x * cellSize + cellSize / 2, y * cellSize + cellSize / 2);
      cells[x][y] = 0.0;
      for(Ball ball: balls){
        cells[x][y] += (ball.getRadious() / PVector.dist(pos, ball.pos)) * ball.energy;
      }
    }
  }
  for(int x = 0; x < cellNum; x++){
    for(int y = 0; y < cellNum; y++){
      float alpha = map(cells[x][y], 0.5, 3.0, 0, 255);
      fill(255, alpha);
      rect(x * cellSize, y * cellSize, cellSize, cellSize);
    }
  }
  
  ArrayList<Ball> nextBalls = new ArrayList<Ball>();
  for(Ball ball: balls){
    ball.update();
    if(ball.energy > 0.1){
      nextBalls.add(ball);
    }
  }
  if(random(1) < 0.03){
    balls.add(new Ball());
  }
}

class Ball{
  
  PVector pos;
  float energy;
  float maxRadious;
  
  Ball(){
    pos = new PVector(random(width), random(height));
    energy = 1.0;
    maxRadious = random(300, 800);
  }
  
  void update(){
    energy *= 0.98;
  }
  
  float getRadious(){
    return map(sqrt(energy), 0, 1, maxRadious, 0);
  }
  
}
f:id:aa_debdeb:20160725093549j:plain