float G = 1.0;
ArrayList<Particle> particles;
ArrayList<Attractor> attractors;
void setup(){
size(640, 640);
frameRate(120);
particles = new ArrayList<Particle>();
for(int i = 0; i < 300; i++){
particles.add(new Particle());
}
attractors = new ArrayList<Attractor>();
for(int i = 0; i < 100; i++){
attractors.add(new Attractor());
}
strokeWeight(1);
stroke(0, 10);
background(255);
}
void draw(){
for(Particle particle: particles){
for(Attractor attractor: attractors){
PVector force = attractor.calcForce(particle);
particle.addForce(force);
}
particle.update();
if(random(1) < 0.005){
particle.setRandomPosVel();
}
}
}
class Particle {
PVector pos, vel, force;
float mass;
Particle(){
setRandomPosVel();
force = new PVector(0, 0);
mass = map(random(1), 0, 1, 0.05, 0.1);
}
void setRandomPosVel(){
pos = new PVector(random(width), random(height));
float velSize = map(random(1), 0, 1, 1, 3);
float velAng = random(TWO_PI);
vel = new PVector(velSize * cos(velAng), velSize * sin(velAng));
}
void addForce(PVector f){
force.add(f);
}
void update(){
force.limit(1);
PVector acc = PVector.mult(force, mass);
acc.limit(1);
vel.add(acc);
vel.limit(3);
PVector nPos = PVector.add(pos, vel);
line(pos.x, pos.y, nPos.x, nPos.y);
if(nPos.x >= 0 && nPos.x < width && nPos.y >= 0 && nPos.y < height){
pos = nPos;
} else {
setRandomPosVel();
}
force = new PVector(0, 0);
}
}
class Attractor {
PVector pos;
float mass;
float radious;
boolean isAttract;
Attractor(){
pos = new PVector(random(width), random(height));
mass = map(random(1), 0, 1, 50, 500);
radious = map(random(1), 0, 1, 100, 500);
isAttract = random(1) < 0.5 ? true: false;
}
PVector calcForce(Particle particle){
float distance = PVector.dist(pos, particle.pos);
if(distance < radious){
float forceSize = (G * (mass * particle.mass)) / sq(map(distance, 0, radious, 0.00000001, 1));
PVector forceAng = isAttract ? PVector.sub(particle.pos, pos) : PVector.sub(particle.pos, pos);
forceAng.normalize();
PVector force = PVector.mult(forceAng, forceSize);
return force;
} else {
return new PVector(0, 0);
}
}
}