読者です 読者をやめる 読者になる 読者になる

Daily Creative Coding

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

追うパーティクル、追われるパーティクル

パーティクル
/**
* Following Particles, Followed Particles
*
* @author aa_debdeb
* @date 2016/02/29
*/

int PARTICLE_NUM = 1000;
float PARTICLE_RADIOUS = 1.5;
float PARTICLE_MAX_SPEED = 10.0;
float PARTICLE_MAX_ACCELERATION = 1.0;
float PARTICLE_SPEED_VARIANT = 0.1;

ArrayList<Particle> preies;
ArrayList<Particle> predators;

void setup(){
  size(640, 640);
  frameRate(30);
  preies = new ArrayList<Particle>();
  for(int i = 0; i < 2000; i++){
    preies.add(new Particle());
  }
  predators = new ArrayList<Particle>();  
  for(int i = 0; i < 10; i++){
    predators.add(new Particle());
  }
}

void draw(){
  background(0);
  for(Particle prey: preies){
    Particle nearest = null;
    float nearestDist = 10000;
    for(Particle predator: predators){
      float dist = PVector.dist(prey.position, predator.position);
      if(dist < nearestDist){
        nearest = predator;
        nearestDist = dist;
      }
    }
    
    prey.display(color(0, 255, 0, 180), 3);
    prey.update(nearest.position, false);
  }
  for(Particle predator: predators){
    Particle nearest = null;
    float nearestDist = 10000;
    for(Particle prey: preies){
      float dist = PVector.dist(prey.position, predator.position);
      if(dist < nearestDist){
        nearest = prey;
        nearestDist = dist;
      }
    }
    predator.display(color(255, 0, 0), 3);
    predator.update(nearest.position, true);
  }
}

class Particle{
  
  PVector position;
  PVector velocity;
  
  Particle(){
    position = new PVector(random(width), random(height));
    setRandomVelocity();
  }
  
  void setRandomVelocity(){
    velocity = new PVector(random(2) - 1.0, random(2) - 1.0);
    velocity.normalize();
    velocity.mult(random(PARTICLE_MAX_SPEED * 2) - PARTICLE_MAX_SPEED);
  }
  
  void display(color c, float diameter){
    noStroke();
    fill(c);
    ellipse(position.x, position.y, diameter, diameter);
  }
  
  void update(PVector target, boolean isAttracted){
    PVector direction = isAttracted ? PVector.sub(target, position): PVector.sub(position, target);
    direction.normalize();
    PVector acceleration = PVector.mult(direction, PARTICLE_MAX_ACCELERATION);
    velocity.add(acceleration);
    PVector velocityVariant = new PVector(random(2) - 1.0, random(2) - 1.0);
    velocityVariant.normalize();
    velocityVariant.mult(PARTICLE_SPEED_VARIANT);
    velocity.add(velocityVariant);
    velocity.limit(PARTICLE_MAX_SPEED);
    position.add(velocity);
    
    if(position.x < 0){
      position.x += width;
    }
    if(position.x >= width){
      position.x -= width;
    }
    if(position.y < 0){
      position.y += height;
    }
    if(position.y >= height){
      position.y -= height;
    }
  }
  
}