ArrayList<Particle> particles;
particles = new ArrayList<Particle>();
while(particles.size() < 30){
float radius = random(10, 30);
PVector loc = new PVector(random(radius, width - radius), random(radius, height - radius));
boolean isOverlapping = false;
for(Particle p: particles){
if(PVector.dist(loc, p.loc) <= radius + p.radius){
float velAng = random(TWO_PI);
PVector vel = new PVector(velSize * cos(velAng), velSize * sin(velAng));
particles.add(new Particle(loc, vel, radius));
for(Particle p: particles){
for(Particle p1: particles){
for(Particle p2: particles){
float d = PVector.dist(p1.loc, p2.loc);
if(d <= p1.radius + p2.radius){
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 spring = -k * (p1.radius + p2.radius - d);
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){
Particle(PVector loc, PVector vel, float radius){
this.nvel = new PVector(vel.x, vel.y);
PVector mouse = new PVector(mouseX, mouseY);
PVector acc = PVector.sub(mouse, loc);
nvel = new PVector(vel.x, vel.y);
ellipse(loc.x, loc.y, radius * 2, radius * 2);
nvel = new PVector(vel.x, vel.y);