Daily Creative Coding

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

円同士の衝突と反射

/**
* collision of circles
*
* @author aa_debdeb
* @date 2016/09/10
*/

float e = 1.0;
ArrayList<Particle> particles;

void setup(){
  size(640, 640);
  fill(255, 105, 180);
  stroke(255, 153, 204);
  strokeWeight(3);
  particles = new ArrayList<Particle>();
  while(particles.size() < 10){
    float radious = random(10, 50);
    PVector loc = new PVector(random(radious, width - radious), random(radious, height - radious));
    boolean canMade = true;
    for(Particle p: particles){
      if(PVector.dist(loc, p.loc) < radious + p.radious){
        canMade = false;
        break;
      }
    }
    if(canMade){
      particles.add(new Particle(loc, radious));
    }
  }
}

void draw(){
  background(90);
  for(Particle p: particles){
    p.display();
  }
  for(Particle p: particles){
    p.collide();
  }
  for(Particle p: particles){
    p.update();
  }
}

class Particle{
  
  PVector loc, vel, nvel;
  float radious;
  float mass;
  
  Particle(PVector _loc, float _radious){
    loc = _loc;
    float velSize = random(0.5, 3);
    float velAngle = random(TWO_PI);
    vel = new PVector(velSize * cos(velAngle), velSize * sin(velAngle));
    radious = _radious;
    mass = sq(radious) * PI;
  }
  
  void display(){
    ellipse(loc.x, loc.y, radious * 2, radious * 2);
  }
  
  void collide(){
    nvel = new PVector(vel.x, vel.y);
    for(Particle p: particles){
      if(p != this && PVector.dist(loc, p.loc) < radious + p.radious){
        nvel = PVector.sub(loc, p.loc);
        nvel.normalize();
        nvel.mult(PVector.dot(PVector.sub(p.vel, vel), nvel));
        nvel.mult(1 + e);
        nvel.mult(p.mass / (mass + p.mass));
        nvel.add(vel);
        break;
      }
    }  
  }
  
  void update(){
    vel = nvel;
    loc.add(vel);
    if(loc.x < radious){
      vel.x *= -1;
      loc.x += vel.x;
    }
    if(loc.x > width - radious){
      vel.x *= -1;
      loc.x += vel.x;
    }
    if(loc.y < radious){
      vel.y *= -1;
      loc.y += vel.y;
    }
    if(loc.y > height - radious){
      vel.y *= -1;
      loc.y += vel.y;
    }
  }
  
}
f:id:aa_debdeb:20160907182352j:plain