# ペナルティ法による複数の円の衝突

```/**
* collision with many particles
*
* @author aa_debdeb
* @date 2017/01/01
*/

float e = 1.0;
float k = 1.0;

ArrayList<Particle> particles;

void setup(){
size(500, 500);
noStroke();
frameRate(30);
particles = new ArrayList<Particle>();
while(particles.size() < 30){
boolean isOverlapping = false;
for(Particle p: particles){
isOverlapping = true;
break;
}
}
if(!isOverlapping){
float velSize = 5.0;
float velAng = random(TWO_PI);
PVector vel = new PVector(velSize * cos(velAng), velSize * sin(velAng));
}
}
}

void draw(){
background(#C7C4A5);
for(Particle p: particles){
p.render();
p.move();
}

for(Particle p1: particles){
for(Particle p2: particles){
if(p1 == p2){continue;}
float d = PVector.dist(p1.loc, p2.loc);
PVector p12 = PVector.sub(p2.loc, p1.loc);
PVector n = PVector.div(p12, p12.mag());
PVector v12 = PVector.sub(p2.vel, p1.vel);
PVector vn1 = PVector.mult(n, PVector.dot(p1.vel, n));
PVector vt1 = PVector.sub(p1.vel, vn1);
PVector t = PVector.div(vt1, vt1.mag());
float j = (1 + e) * (p1.mass * p2.mass / (p1.mass + p2.mass)) * PVector.dot(v12, n);
PVector impulse = PVector.mult(n, j + spring);
}
}
}

for(Particle p: particles){
p.updateVel();
}

}

class Particle{

PVector loc, vel, nvel;
color c;

Particle(PVector loc, PVector vel, float radius){
this.loc = loc;
this.vel = vel;
this.nvel = new PVector(vel.x, vel.y);
this.mass = 1.0;
c = color(#9B2C6B);
c =color(#197993);
} else {
c = color(#6C4787);
}
}

void move(){
PVector mouse = new PVector(mouseX, mouseY);
PVector acc = PVector.sub(mouse, loc);
acc.limit(0.5);
vel.limit(5.0);
nvel = new PVector(vel.x, vel.y);