ArrayList psystems; Spring2D s1, s2, s3, s4, s5, s6, s7, s8, s9, s10; float gravity = 5.0; float mass = 3.0; void setup() { size(500, 500); frameRate(30); colorMode(RGB,255,255,255,100); psystems = new ArrayList(); smooth(); fill(255,91.0); background(0); s1 = new Spring2D(0.0, width/2, mass, gravity); s2 = new Spring2D(0.0, width/2, mass, gravity); s3 = new Spring2D(0.0, width/2, mass, gravity); s4 = new Spring2D(0.0, width/2, mass, gravity); s5 = new Spring2D(0.0, width/2, mass, gravity); s6 = new Spring2D(0.0, width/2, mass, gravity); s7 = new Spring2D(0.0, width/2, mass, gravity); s8 = new Spring2D(0.0, width/2, mass, gravity); s9 = new Spring2D(0.0, width/2, mass, gravity); s10 = new Spring2D(0.0, width/2, mass, gravity); } void draw() { for (int i = psystems.size()-1; i >= 0; i--) { ParticleSystem psys = (ParticleSystem) psystems.get(i); psys.run(); if (psys.dead()) { psystems.remove(i); background(0); } { s1.update(mouseX, mouseY); s1.display(mouseX, mouseY); s2.update(s1.x, s1.y); s2.display(s1.x, s1.y); s3.update(s2.x, s2.y); s3.display(s2.x, s2.y); s4.update(s3.x, s3.y); s4.display(s3.x, s3.y); s5.update(s4.x, s4.y); s5.display(s4.x, s4.y); s6.update(s5.x, s5.y); s6.display(s5.x, s5.y); s7.update(s6.x, s6.y); s7.display(s6.x, s6.y); s8.update(s7.x, s7.y); s8.display(s7.x, s7.y); s9.update(s8.x, s8.y); s9.display(s8.x, s8.y); s10.update(s9.x, s9.y); s10.display(s9.x, s9.y); } } } void mousePressed() { psystems.add(new ParticleSystem(int(random(5,25)),new Vector3D(mouseX,mouseY))); } class CrazyParticle extends Particle { float theta; CrazyParticle(Vector3D l) { super(l); theta = 1.0; } void update() { super.update(); float theta_vel = (vel.x * vel.magnitude()) / 10.0f; theta += theta_vel; } void timer() { timer -= 0.5; } void render() { super.render(); fill(255,91,0); pushMatrix(); translate(loc.x,loc.y); rotate(theta); stroke(255,timer); popMatrix(); } } class Particle { Vector3D loc; Vector3D vel; Vector3D acc; float r; float timer; Particle(Vector3D a, Vector3D v, Vector3D l, float r_) { acc = a.copy(); vel = v.copy(); loc = l.copy(); r = r_; timer = 100.0; } Particle(Vector3D l) { acc = new Vector3D(0,0.05,0); vel = new Vector3D(random(-1,1),random(-2,0),0); loc = l.copy(); r = 10.0; timer = 100.0; } void run() { update(); render(); } void update() { vel.add(acc); loc.add(vel); timer -= 1.0; } void render() { ellipseMode(CENTER); noStroke(); fill(255,timer); ellipse(loc.x,loc.y,r,r); } boolean dead() { if (timer <= 0.0) { return true; } else { return false; } } } class ParticleSystem { ArrayList particles; Vector3D origin; ParticleSystem(int num, Vector3D v) { particles = new ArrayList(); origin = v.copy(); for (int i = 0; i < num; i++) { particles.add(new CrazyParticle(origin)); } } void run() { for (int i = particles.size()-1; i >= 0; i--) { Particle p = (Particle) particles.get(i); p.run(); if (p.dead()) { particles.remove(i); } } } void addParticle() { particles.add(new Particle(origin)); } void addParticle(Particle p) { particles.add(p); } boolean dead() { if (particles.isEmpty()) { return true; } else { return false; } } } public class Vector3D { public float x; public float y; public float z; Vector3D(float x_, float y_, float z_) { x = x_; y = y_; z = z_; } Vector3D(float x_, float y_) { x = x_; y = y_; z = 0f; } Vector3D() { x = 0f; y = 0f; z = 0f; } void setX(float x_) { x = x_; } void setY(float y_) { y = y_; } void setZ(float z_) { z = z_; } void setXY(float x_, float y_) { x = x_; y = y_; } void setXYZ(float x_, float y_, float z_) { x = x_; y = y_; z = z_; } void setXYZ(Vector3D v) { x = v.x; y = v.y; z = v.z; } public float magnitude() { return (float) Math.sqrt(x*x + y*y + z*z); } public Vector3D copy() { return new Vector3D(x,y,z); } public Vector3D copy(Vector3D v) { return new Vector3D(v.x, v.y,v.z); } public void add(Vector3D v) { x += v.x; y += v.y; z += v.z; } public void sub(Vector3D v) { x -= v.x; y -= v.y; z -= v.z; } public void mult(float n) { x *= n; y *= n; z *= n; } public void div(float n) { x /= n; y /= n; z /= n; } public void normalize() { float m = magnitude(); if (m > 0) { div(m); } } public void limit(float max) { if (magnitude() > max) { normalize(); mult(max); } } public float heading2D() { float angle = (float) Math.atan2(-y, x); return -1*angle; } public Vector3D add(Vector3D v1, Vector3D v2) { Vector3D v = new Vector3D(v1.x + v2.x,v1.y + v2.y, v1.z + v2.z); return v; } public Vector3D sub(Vector3D v1, Vector3D v2) { Vector3D v = new Vector3D(v1.x - v2.x,v1.y - v2.y,v1.z - v2.z); return v; } public Vector3D div(Vector3D v1, float n) { Vector3D v = new Vector3D(v1.x/n,v1.y/n,v1.z/n); return v; } public Vector3D mult(Vector3D v1, float n) { Vector3D v = new Vector3D(v1.x*n,v1.y*n,v1.z*n); return v; } public float distance (Vector3D v1, Vector3D v2) { float dx = v1.x - v2.x; float dy = v1.y - v2.y; float dz = v1.z - v2.z; return (float) Math.sqrt(dx*dx + dy*dy + dz*dz); } } class Spring2D { float vx, vy; float x, y; float gravity; float mass; float radius = 10; float stiffness = 0.3; float damping = 0.65; Spring2D(float xpos, float ypos, float m, float g) { x = xpos; y = ypos; mass = m; gravity = g; } void update(float targetX, float targetY) { float forceX = (targetX - x) * stiffness; float ax = forceX / mass; vx = damping * (vx + ax); x += vx; float forceY = (targetY - y) * stiffness; forceY += gravity; float ay = forceY / mass; vy = damping * (vy + ay); y += vy; } void display(float nx, float ny) { smooth(); noStroke(); fill(255,178,0); ellipse(x, y, radius*1, radius*1); stroke(255); } }