ArrayList<Particle> particles;
particles = new ArrayList<Particle>();
translate(width / 2, height * 3.0 / 4, -300);
rotateX(map(mouseY, 0, height, PI / 2 - PI / 6, PI / 2 + PI / 6));
rotateZ(map(mouseX, 0, width, -PI / 4, PI / 4));
rect(-width / 2, -height / 2, width, height);
for(int w = -width / 2; w <= width / 2; w += 50){
line(w, -height / 2, 0, w, height / 2, 0);
for(int h = -height / 2; h <= height / 2; h += 50){
line(-width / 2, h, 0, width / 2, h, 0);
ArrayList<Particle> nextParticles = new ArrayList<Particle>();
for(Particle particle: particles){
if(particle.isDivided()){
for(Particle p: particle.divide()){
nextParticles.add(particle);
particles = nextParticles;
particles.add(new Particle());
float x = random(-width / 2, width / 2);
float y = random(-height / 2, height / 2);
float z = random(500, 800);
pos = new PVector(x, y, z);
vel = new PVector(0, 0, 0);
Particle(PVector pos, PVector vel, float size){
translate(pos.x, pos.y, pos.z);
return size >= 2 && pos.z == size / 2;
return !(-width / 2 <= pos.x && pos.x <= width / 2 && -height / 2 <= pos.y && pos.y <= height / 2);
ArrayList<Particle> divide(){
ArrayList<Particle> children = new ArrayList<Particle>();
for(int i = 0; i < 4; i++){
PVector cpos = new PVector(pos.x, pos.y, pos.z);
PVector cvel = new PVector(vel.x + random(-3, 3), vel.y + random(-3, 3), vel.z);
float csize = pow(size, 0.5);
Particle child = new Particle(cpos, cvel, csize);