float MAX_RADIOUS = 100;
float MAX_SPEED = 20;
float EXPLOSION_NUM = 10;
ArrayList<Particle> particles;
void setup(){
size(500, 500);
smooth();
frameRate(24);
noStroke();
particles = new ArrayList<Particle>();
particles.add(new Particle());
particles.add(new Particle());
particles.add(new Particle());
}
void draw(){
background(255);
for(Particle particle: particles){
particle.draw();
}
for(Particle particle: particles){
particle.update();
}
ArrayList<Particle> deleteParticles = new ArrayList<Particle>();
for(int i = 0; i < particles.size() - 1; i++){
Particle p1 = particles.get(i);
for(int j = i + 1; j < particles.size(); j++){
Particle p2 = particles.get(j);
if(!p1.absorbed && !p2.absorbed && p1.timeAfterExplosion >= 10 && p2.timeAfterExplosion >= 10 && p1.isContactWith(p2)){
if(p1.radious >= p2.radious){
p1.absorb(p2);
deleteParticles.add(p2);
p2.absorbed = true;
} else{
p2.absorb(p1);
deleteParticles.add(p1);
p1.absorbed = true;
}
}
}
}
for(Particle p: deleteParticles){
particles.remove(p);
}
ArrayList<Particle> appendParticles = new ArrayList<Particle>();
deleteParticles = new ArrayList<Particle>();
for(Particle p: particles){
if(p.radious >= MAX_RADIOUS - 5.0){
ArrayList<Particle> childrens = p.explode();
for(Particle c: childrens){
appendParticles.add(c);
}
deleteParticles.add(p);
}
}
for(Particle p: appendParticles){
particles.add(p);
}
for(Particle p: deleteParticles){
particles.remove(p);
}
}
class Particle{
PVector position;
PVector velocity;
float radious;
boolean absorbed;
int timeAfterExplosion;
Particle(){
position = new PVector(width / 2, height / 2);
float radian = random(PI * 2);
float speed = random(MAX_SPEED);
velocity = new PVector(speed * cos(radian), speed * sin(radian));
radious = MAX_RADIOUS;
absorbed = false;
timeAfterExplosion = 0;
}
Particle(Particle p){
position = new PVector(p.position.x, p.position.y);
float radian = random(PI * 2);
float speed = random(MAX_SPEED);
velocity = new PVector(speed * cos(radian), speed * sin(radian));
radious = p.radious * sqrt(1.0 / EXPLOSION_NUM);
absorbed = false;
timeAfterExplosion = 0;
}
void draw(){
fill(0);
arc(position.x, position.y, radious * 2, radious * 2, 0, TWO_PI);
}
void update(){
position.add(velocity);
if(position.x < radious){
position.x = radious;
velocity.x *= -1;
} else if(position.x >= width - radious){
position.x = width - radious;
velocity.x *= -1;
}
if(position.y < radious){
position.y = radious;
velocity.y *= -1;
} else if(position.y >= height - radious){
position.y = height - radious;
velocity.y *= -1;
}
timeAfterExplosion += 1;
}
void absorb(Particle p){
radious = sqrt(sq(radious) + sq(p.radious));
}
ArrayList<Particle> explode(){
ArrayList<Particle> childrens = new ArrayList<Particle>();
for(int i = 0; i < EXPLOSION_NUM; i++){
childrens.add(new Particle(this));
}
return childrens;
}
boolean isContactWith(Particle p){
if(position.dist(p.position) <= radious + p.radious){
return true;
} else {
return false;
}
}
}