diff --git a/java/examples/Topics/Simulate/Flocking/Boid.pde b/java/examples/Topics/Simulate/Flocking/Boid.pde index e887c1d3f..2aec12bd3 100644 --- a/java/examples/Topics/Simulate/Flocking/Boid.pde +++ b/java/examples/Topics/Simulate/Flocking/Boid.pde @@ -2,31 +2,36 @@ class Boid { - PVector loc; - PVector vel; - PVector acc; + PVector location; + PVector velocity; + PVector acceleration; float r; float maxforce; // Maximum steering force float maxspeed; // Maximum speed - Boid(PVector l, float ms, float mf) { - acc = new PVector(0,0); - vel = new PVector(random(-1,1), random(-1,1)); - loc = l.get(); + Boid(float x, float y) { + acceleration = new PVector(0,0); + velocity = new PVector(random(-1,1),random(-1,1)); + location = new PVector(x,y); r = 2.0; - maxspeed = ms; - maxforce = mf; + maxspeed = 2; + maxforce = 0.03; } - void run(ArrayList boids) { + void run(ArrayList boids) { flock(boids); update(); borders(); render(); } + void applyForce(PVector force) { + // We could add mass here if we want A = F / M + acceleration.add(force); + } + // We accumulate a new acceleration each time based on three rules - void flock(ArrayList boids) { + void flock(ArrayList boids) { PVector sep = separate(boids); // Separation PVector ali = align(boids); // Alignment PVector coh = cohesion(boids); // Cohesion @@ -35,60 +40,42 @@ class Boid { ali.mult(1.0); coh.mult(1.0); // Add the force vectors to acceleration - acc.add(sep); - acc.add(ali); - acc.add(coh); + applyForce(sep); + applyForce(ali); + applyForce(coh); } // Method to update location void update() { // Update velocity - vel.add(acc); + velocity.add(acceleration); // Limit speed - vel.limit(maxspeed); - loc.add(vel); + velocity.limit(maxspeed); + location.add(velocity); // Reset accelertion to 0 each cycle - acc.mult(0); + acceleration.mult(0); } - void seek(PVector target) { - acc.add(steer(target,false)); - } - - void arrive(PVector target) { - acc.add(steer(target,true)); - } - - // A method that calculates a steering vector towards a target - // Takes a second argument, if true, it slows down as it approaches the target - PVector steer(PVector target, boolean slowdown) { - PVector steer; // The steering vector - PVector desired = PVector.sub(target,loc); // A vector pointing from the location to the target - float d = desired.mag(); // Distance from the target is the magnitude of the vector - // If the distance is greater than 0, calc steering (otherwise return zero vector) - if (d > 0) { - // Normalize desired - desired.normalize(); - // Two options for desired vector magnitude (1 -- based on distance, 2 -- maxspeed) - if ((slowdown) && (d < 100.0)) desired.mult(maxspeed*(d/100.0)); // This damping is somewhat arbitrary - else desired.mult(maxspeed); - // Steering = Desired minus Velocity - steer = PVector.sub(desired,vel); - steer.limit(maxforce); // Limit to maximum steering force - } - else { - steer = new PVector(0,0); - } + // A method that calculates and applies a steering force towards a target + // STEER = DESIRED MINUS VELOCITY + PVector seek(PVector target) { + PVector desired = PVector.sub(target,location); // A vector pointing from the location to the target + // Normalize desired and scale to maximum speed + desired.normalize(); + desired.mult(maxspeed); + // Steering = Desired minus Velocity + PVector steer = PVector.sub(desired,velocity); + steer.limit(maxforce); // Limit to maximum steering force return steer; } - + void render() { // Draw a triangle rotated in the direction of velocity - float theta = vel.heading2D() + PI/2; + float theta = velocity.heading2D() + radians(90); fill(200,100); stroke(255); pushMatrix(); - translate(loc.x,loc.y); + translate(location.x,location.y); rotate(theta); beginShape(TRIANGLES); vertex(0, -r*2); @@ -100,26 +87,25 @@ class Boid { // Wraparound void borders() { - if (loc.x < -r) loc.x = width+r; - if (loc.y < -r) loc.y = height+r; - if (loc.x > width+r) loc.x = -r; - if (loc.y > height+r) loc.y = -r; + if (location.x < -r) location.x = width+r; + if (location.y < -r) location.y = height+r; + if (location.x > width+r) location.x = -r; + if (location.y > height+r) location.y = -r; } // Separation // Method checks for nearby boids and steers away - PVector separate (ArrayList boids) { - float desiredseparation = 20.0; + PVector separate (ArrayList boids) { + float desiredseparation = 25.0f; PVector steer = new PVector(0,0,0); int count = 0; // For every boid in the system, check if it's too close - for (int i = 0 ; i < boids.size(); i++) { - Boid other = (Boid) boids.get(i); - float d = PVector.dist(loc,other.loc); + for (Boid other : boids) { + float d = PVector.dist(location,other.location); // If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself) if ((d > 0) && (d < desiredseparation)) { // Calculate vector pointing away from neighbor - PVector diff = PVector.sub(loc,other.loc); + PVector diff = PVector.sub(location,other.location); diff.normalize(); diff.div(d); // Weight by distance steer.add(diff); @@ -136,7 +122,7 @@ class Boid { // Implement Reynolds: Steering = Desired - Velocity steer.normalize(); steer.mult(maxspeed); - steer.sub(vel); + steer.sub(velocity); steer.limit(maxforce); } return steer; @@ -144,52 +130,48 @@ class Boid { // Alignment // For every nearby boid in the system, calculate the average velocity - PVector align (ArrayList boids) { - float neighbordist = 25.0; - PVector steer = new PVector(0,0,0); + PVector align (ArrayList boids) { + float neighbordist = 50; + PVector sum = new PVector(0,0); int count = 0; - for (int i = 0 ; i < boids.size(); i++) { - Boid other = (Boid) boids.get(i); - float d = PVector.dist(loc,other.loc); + for (Boid other : boids) { + float d = PVector.dist(location,other.location); if ((d > 0) && (d < neighbordist)) { - steer.add(other.vel); - count++; - } - } - if (count > 0) { - steer.div((float)count); - } - - // As long as the vector is greater than 0 - if (steer.mag() > 0) { - // Implement Reynolds: Steering = Desired - Velocity - steer.normalize(); - steer.mult(maxspeed); - steer.sub(vel); - steer.limit(maxforce); - } - return steer; - } - - // Cohesion - // For the average location (i.e. center) of all nearby boids, calculate steering vector towards that location - PVector cohesion (ArrayList boids) { - float neighbordist = 25.0; - PVector sum = new PVector(0,0); // Start with empty vector to accumulate all locations - int count = 0; - for (int i = 0 ; i < boids.size(); i++) { - Boid other = (Boid) boids.get(i); - float d = loc.dist(other.loc); - if ((d > 0) && (d < neighbordist)) { - sum.add(other.loc); // Add location + sum.add(other.velocity); count++; } } if (count > 0) { sum.div((float)count); - return steer(sum,false); // Steer towards the location + sum.normalize(); + sum.mult(maxspeed); + PVector steer = PVector.sub(sum,velocity); + steer.limit(maxforce); + return steer; + } else { + return new PVector(0,0); + } + } + + // Cohesion + // For the average location (i.e. center) of all nearby boids, calculate steering vector towards that location + PVector cohesion (ArrayList boids) { + float neighbordist = 50; + PVector sum = new PVector(0,0); // Start with empty vector to accumulate all locations + int count = 0; + for (Boid other : boids) { + float d = PVector.dist(location,other.location); + if ((d > 0) && (d < neighbordist)) { + sum.add(other.location); // Add location + count++; + } + } + if (count > 0) { + sum.div(count); + return seek(sum); // Steer towards the location + } else { + return new PVector(0,0); } - return sum; } } diff --git a/java/examples/Topics/Simulate/Flocking/Flock.pde b/java/examples/Topics/Simulate/Flocking/Flock.pde index 9ec1001c7..cea728a78 100644 --- a/java/examples/Topics/Simulate/Flocking/Flock.pde +++ b/java/examples/Topics/Simulate/Flocking/Flock.pde @@ -1,15 +1,14 @@ // The Flock (a list of Boid objects) class Flock { - ArrayList boids; // An arraylist for all the boids + ArrayList boids; // An ArrayList for all the boids Flock() { - boids = new ArrayList(); // Initialize the arraylist + boids = new ArrayList(); // Initialize the ArrayList } void run() { - for (int i = 0; i < boids.size(); i++) { - Boid b = (Boid) boids.get(i); + for (Boid b : boids) { b.run(boids); // Passing the entire list of boids to each boid individually } } diff --git a/java/examples/Topics/Simulate/Flocking/Flocking.pde b/java/examples/Topics/Simulate/Flocking/Flocking.pde index 5703caa0b..ac7302217 100644 --- a/java/examples/Topics/Simulate/Flocking/Flocking.pde +++ b/java/examples/Topics/Simulate/Flocking/Flocking.pde @@ -16,7 +16,7 @@ void setup() { flock = new Flock(); // Add an initial set of boids into the system for (int i = 0; i < 150; i++) { - flock.addBoid(new Boid(new PVector(width/2,height/2), 3.0, 0.05)); + flock.addBoid(new Boid(width/2,height/2)); } } @@ -27,5 +27,5 @@ void draw() { // Add a new boid into the System void mousePressed() { - flock.addBoid(new Boid(new PVector(mouseX,mouseY), 2.0, 0.05)); + flock.addBoid(new Boid(mouseX,mouseY)); } diff --git a/java/examples/Topics/Simulate/MultipleParticleSystems/MultipleParticleSystems.pde b/java/examples/Topics/Simulate/MultipleParticleSystems/MultipleParticleSystems.pde index 9ef4e5802..9ab20cdef 100644 --- a/java/examples/Topics/Simulate/MultipleParticleSystems/MultipleParticleSystems.pde +++ b/java/examples/Topics/Simulate/MultipleParticleSystems/MultipleParticleSystems.pde @@ -9,32 +9,31 @@ * with Particles and CrazyParticles (a subclass of Particle) * Note use of Inheritance and Polymorphism here. */ - -ArrayList psystems; + +ArrayList systems; void setup() { size(640, 360); - colorMode(RGB, 255, 255, 255, 100); - psystems = new ArrayList(); + systems = new ArrayList(); + smooth(); } void draw() { background(0); - - // Cycle through all particle systems, run them and delete old ones - for (int i = psystems.size()-1; i >= 0; i--) { - ParticleSystem psys = (ParticleSystem) psystems.get(i); - psys.run(); - if (psys.dead()) { - psystems.remove(i); - } + for (ParticleSystem ps: systems) { + ps.run(); + ps.addParticle(); } + if (systems.isEmpty()) { + fill(255); + textAlign(CENTER); + text("click mouse to add particle systems", width/2, height/2); + } } -// When the mouse is pressed, add a new particle system void mousePressed() { - psystems.add(new ParticleSystem(int(random(5,25)),new PVector(mouseX,mouseY))); + systems.add(new ParticleSystem(1, new PVector(mouseX, mouseY))); } @@ -46,4 +45,3 @@ void mousePressed() { - diff --git a/java/examples/Topics/Simulate/MultipleParticleSystems/Particle.pde b/java/examples/Topics/Simulate/MultipleParticleSystems/Particle.pde index f06feae24..b519208ca 100644 --- a/java/examples/Topics/Simulate/MultipleParticleSystems/Particle.pde +++ b/java/examples/Topics/Simulate/MultipleParticleSystems/Particle.pde @@ -1,57 +1,44 @@ // A simple Particle class class Particle { - PVector loc; - PVector vel; - PVector acc; - float r; - float timer; + PVector location; + PVector velocity; + PVector acceleration; + float lifespan; - // One constructor - Particle(PVector a, PVector v, PVector l, float r_) { - acc = a.get(); - vel = v.get(); - loc = l.get(); - r = r_; - timer = 100.0; - } - - // Another constructor (the one we are using here) Particle(PVector l) { - acc = new PVector(0,0.05,0); - vel = new PVector(random(-1,1),random(-2,0),0); - loc = l.get(); - r = 10.0; - timer = 100.0; + acceleration = new PVector(0,0.05); + velocity = new PVector(random(-1,1),random(-2,0)); + location = l.get(); + lifespan = 255.0; } - void run() { update(); - render(); + display(); } // Method to update location void update() { - vel.add(acc); - loc.add(vel); - timer -= 1.0; + velocity.add(acceleration); + location.add(velocity); + lifespan -= 2.0; } // Method to display - void render() { - ellipseMode(CENTER); - stroke(255,timer); - fill(100,timer); - ellipse(loc.x,loc.y,r,r); + void display() { + stroke(255,lifespan); + fill(255,lifespan); + ellipse(location.x,location.y,8,8); } // Is the particle still useful? - boolean dead() { - if (timer <= 0.0) { + boolean isDead() { + if (lifespan < 0.0) { return true; } else { return false; } } } + diff --git a/java/examples/Topics/Simulate/MultipleParticleSystems/ParticleSystem.pde b/java/examples/Topics/Simulate/MultipleParticleSystems/ParticleSystem.pde index 9322a70af..1088f5c85 100644 --- a/java/examples/Topics/Simulate/MultipleParticleSystems/ParticleSystem.pde +++ b/java/examples/Topics/Simulate/MultipleParticleSystems/ParticleSystem.pde @@ -2,29 +2,25 @@ class ParticleSystem { - ArrayList particles; // An arraylist for all the particles - PVector origin; // An origin point for where particles are birthed + ArrayList particles; // An arraylist for all the particles + PVector origin; // An origin point for where particles are birthed ParticleSystem(int num, PVector v) { - particles = new ArrayList(); // Initialize the arraylist + particles = new ArrayList(); // Initialize the arraylist origin = v.get(); // Store the origin point for (int i = 0; i < num; i++) { - // We have a 50% chance of adding each kind of particle - if (random(1) < 0.5) { - particles.add(new CrazyParticle(origin)); - } else { - particles.add(new Particle(origin)); - } + particles.add(new Particle(origin)); // Add "num" amount of particles to the arraylist } } void run() { - // Cycle through the ArrayList backwards b/c we are deleting - for (int i = particles.size()-1; i >= 0; i--) { - Particle p = (Particle) particles.get(i); + // Cycle through the ArrayList using Iterator we are deleting + Iterator it = particles.iterator(); + while (it.hasNext()) { + Particle p = it.next(); p.run(); - if (p.dead()) { - particles.remove(i); + if (p.isDead()) { + it.remove(); } } } @@ -41,11 +37,9 @@ class ParticleSystem { boolean dead() { if (particles.isEmpty()) { return true; - } - else { + } else { return false; } } } - diff --git a/java/examples/Topics/Simulate/SimpleParticleSystem/Particle.pde b/java/examples/Topics/Simulate/SimpleParticleSystem/Particle.pde index f9395c066..44a592d66 100644 --- a/java/examples/Topics/Simulate/SimpleParticleSystem/Particle.pde +++ b/java/examples/Topics/Simulate/SimpleParticleSystem/Particle.pde @@ -1,67 +1,44 @@ // A simple Particle class class Particle { - PVector loc; - PVector vel; - PVector acc; - float r; - float timer; - - // Another constructor (the one we are using here) + PVector location; + PVector velocity; + PVector acceleration; + float lifespan; + Particle(PVector l) { - acc = new PVector(0,0.05,0); - vel = new PVector(random(-1,1),random(-2,0),0); - loc = l.get(); - r = 10.0; - timer = 100.0; + acceleration = new PVector(0,0.05); + velocity = new PVector(random(-1,1),random(-2,0)); + location = l.get(); + lifespan = 255.0; } void run() { update(); - render(); + display(); } // Method to update location void update() { - vel.add(acc); - loc.add(vel); - timer -= 1.0; + velocity.add(acceleration); + location.add(velocity); + lifespan -= 1.0; } // Method to display - void render() { - ellipseMode(CENTER); - stroke(255,timer); - fill(100,timer); - ellipse(loc.x,loc.y,r,r); - displayVector(vel,loc.x,loc.y,10); + void display() { + stroke(255,lifespan); + fill(255,lifespan); + ellipse(location.x,location.y,8,8); } // Is the particle still useful? - boolean dead() { - if (timer <= 0.0) { + boolean isDead() { + if (lifespan < 0.0) { return true; } else { return false; } } - - void displayVector(PVector v, float x, float y, float scayl) { - pushMatrix(); - float arrowsize = 4; - // Translate to location to render vector - translate(x,y); - stroke(255); - // Call vector heading function to get direction (note that pointing up is a heading of 0) and rotate - rotate(v.heading2D()); - // Calculate length of vector & scale it to be bigger or smaller if necessary - float len = v.mag()*scayl; - // Draw three lines to make an arrow (draw pointing up since we've rotate to the proper direction) - line(0,0,len,0); - line(len,0,len-arrowsize,+arrowsize/2); - line(len,0,len-arrowsize,-arrowsize/2); - popMatrix(); - } - } diff --git a/java/examples/Topics/Simulate/SimpleParticleSystem/ParticleSystem.pde b/java/examples/Topics/Simulate/SimpleParticleSystem/ParticleSystem.pde index 3d6829d83..4c4f02ab5 100644 --- a/java/examples/Topics/Simulate/SimpleParticleSystem/ParticleSystem.pde +++ b/java/examples/Topics/Simulate/SimpleParticleSystem/ParticleSystem.pde @@ -2,49 +2,26 @@ // An ArrayList is used to manage the list of Particles class ParticleSystem { + ArrayList particles; + PVector origin; - ArrayList particles; // An arraylist for all the particles - PVector origin; // An origin point for where particles are born - - ParticleSystem(int num, PVector v) { - particles = new ArrayList(); // Initialize the arraylist - origin = v.get(); // Store the origin point - for (int i = 0; i < num; i++) { - particles.add(new Particle(origin)); // Add "num" amount of particles to the arraylist - } - } - - void run() { - // Cycle through the ArrayList backwards b/c we are deleting - for (int i = particles.size()-1; i >= 0; i--) { - Particle p = (Particle) particles.get(i); - p.run(); - if (p.dead()) { - particles.remove(i); - } - } + ParticleSystem(PVector location) { + origin = location.get(); + particles = new ArrayList(); } void addParticle() { particles.add(new Particle(origin)); } - - void addParticle(float x, float y) { - particles.add(new Particle(new PVector(x,y))); - } - void addParticle(Particle p) { - particles.add(p); - } - - // A method to test if the particle system still has particles - boolean dead() { - if (particles.isEmpty()) { - return true; - } else { - return false; + void run() { + Iterator it = particles.iterator(); + while (it.hasNext()) { + Particle p = it.next(); + p.run(); + if (p.isDead()) { + it.remove(); + } } } - } - diff --git a/java/examples/Topics/Simulate/SimpleParticleSystem/SimpleParticleSystem.pde b/java/examples/Topics/Simulate/SimpleParticleSystem/SimpleParticleSystem.pde index b714ab6a0..5b55db150 100644 --- a/java/examples/Topics/Simulate/SimpleParticleSystem/SimpleParticleSystem.pde +++ b/java/examples/Topics/Simulate/SimpleParticleSystem/SimpleParticleSystem.pde @@ -11,16 +11,15 @@ ParticleSystem ps; void setup() { - size(640, 360); - colorMode(RGB, 255, 255, 255, 100); - ps = new ParticleSystem(1, new PVector(width/2,height/2,0)); + size(640,360); + smooth(); + ps = new ParticleSystem(new PVector(width/2,50)); } void draw() { background(0); + ps.addParticle(); ps.run(); - ps.addParticle(mouseX,mouseY); } - diff --git a/java/examples/Topics/Simulate/SmokeParticleSystem/Particle.pde b/java/examples/Topics/Simulate/SmokeParticleSystem/Particle.pde index 5e9ba9b5f..a8802c2f2 100644 --- a/java/examples/Topics/Simulate/SmokeParticleSystem/Particle.pde +++ b/java/examples/Topics/Simulate/SmokeParticleSystem/Particle.pde @@ -5,26 +5,16 @@ class Particle { PVector loc; PVector vel; PVector acc; - float timer; + float lifespan; PImage img; - // One constructor - Particle(PVector a, PVector v, PVector l, PImage img_) { - acc = a.get(); - vel = v.get(); - loc = l.get(); - timer = 100.0; - img = img_; - } - - // Another constructor (the one we are using here) Particle(PVector l,PImage img_) { - acc = new PVector(0.0,0.0,0.0); - float x = (float) generator.nextGaussian()*0.3f; - float y = (float) generator.nextGaussian()*0.3f - 1.0f; - vel = new PVector(x,y,0); + acc = new PVector(0,0); + float vx = (float) generator.nextGaussian()*0.3; + float vy = (float) generator.nextGaussian()*0.3 - 1.0; + vel = new PVector(vx,vy); loc = l.get(); - timer = 100.0; + lifespan = 100.0; img = img_; } @@ -35,7 +25,7 @@ class Particle { // Method to apply a force vector to the Particle object // Note we are ignoring "mass" here - void add_force(PVector f) { + void applyForce(PVector f) { acc.add(f); } @@ -43,20 +33,20 @@ class Particle { void update() { vel.add(acc); loc.add(vel); - timer -= 2.5; - acc.mult(0); + acc.mult(0); // clear Acceleration + lifespan -= 2.5; } // Method to display void render() { - imageMode(CORNER); - tint(255,timer); - image(img,loc.x-img.width/2,loc.y-img.height/2); + imageMode(CENTER); + tint(255,lifespan); + image(img,loc.x,loc.y); } // Is the particle still useful? boolean dead() { - if (timer <= 0.0) { + if (lifespan <= 0.0) { return true; } else { return false; diff --git a/java/examples/Topics/Simulate/SmokeParticleSystem/ParticleSystem.pde b/java/examples/Topics/Simulate/SmokeParticleSystem/ParticleSystem.pde index a937d2efe..b0e2ed439 100644 --- a/java/examples/Topics/Simulate/SmokeParticleSystem/ParticleSystem.pde +++ b/java/examples/Topics/Simulate/SmokeParticleSystem/ParticleSystem.pde @@ -3,12 +3,12 @@ class ParticleSystem { - ArrayList particles; // An arraylist for all the particles + ArrayList particles; // An arraylist for all the particles PVector origin; // An origin point for where particles are birthed PImage img; ParticleSystem(int num, PVector v, PImage img_) { - particles = new ArrayList(); // Initialize the arraylist + particles = new ArrayList(); // Initialize the arraylist origin = v.get(); // Store the origin point img = img_; for (int i = 0; i < num; i++) { @@ -17,21 +17,21 @@ class ParticleSystem { } void run() { - // Cycle through the ArrayList backwards b/c we are deleting - for (int i = particles.size()-1; i >= 0; i--) { - Particle p = (Particle) particles.get(i); + Iterator it = particles.iterator(); + while (it.hasNext()) { + Particle p = it.next(); p.run(); if (p.dead()) { - particles.remove(i); + it.remove(); } } } // Method to add a force vector to all particles currently in the system - void add_force(PVector dir) { - for (int i = particles.size()-1; i >= 0; i--) { - Particle p = (Particle) particles.get(i); - p.add_force(dir); + void applyForce(PVector dir) { + // Enhanced loop!!! + for (Particle p: particles) { + p.applyForce(dir); } } @@ -55,3 +55,4 @@ class ParticleSystem { } + diff --git a/java/examples/Topics/Simulate/SmokeParticleSystem/SmokeParticleSystem.pde b/java/examples/Topics/Simulate/SmokeParticleSystem/SmokeParticleSystem.pde index cef2c4ddd..97be74377 100644 --- a/java/examples/Topics/Simulate/SmokeParticleSystem/SmokeParticleSystem.pde +++ b/java/examples/Topics/Simulate/SmokeParticleSystem/SmokeParticleSystem.pde @@ -8,48 +8,42 @@ // @pjs preload must be used to preload media if the program is // running with Processing.js -/* @pjs preload="texture.gif"; */ +/* @pjs preload="texture.png"; */ ParticleSystem ps; Random generator; void setup() { - size(640, 360); - colorMode(RGB, 255, 255, 255, 100); - - // Using a Java random number generator for Gaussian random numbers + size(640,360); generator = new Random(); - - // Create an alpha masked image to be applied as the particle's texture - PImage msk = loadImage("texture.gif"); - PImage img = createImage(msk.width, msk.height, RGB); - for (int i = 0; i < img.pixels.length; i++) { - img.pixels[i] = color(255); - } - img.mask(msk); - ps = new ParticleSystem(0, new PVector(width/2, height-20), img); - + PImage img = loadImage("texture.png"); + ps = new ParticleSystem(0,new PVector(width/2,height-60),img); + smooth(); } void draw() { - background(75); - + background(0); + // Calculate a "wind" force based on mouse horizontal position - float dx = (mouseX - width/2) / 1000.0; - PVector wind = new PVector(dx,0,0); - displayVector(wind,width/2,50,500); - ps.add_force(wind); + float dx = map(mouseX,0,width,-0.2,0.2); + PVector wind = new PVector(dx,0); + ps.applyForce(wind); ps.run(); for (int i = 0; i < 2; i++) { ps.addParticle(); } + + // Draw an arrow representing the wind force + drawVector(wind, new PVector(width/2,50,0),500); + } -void displayVector(PVector v, float x, float y, float scayl) { +// Renders a vector object 'v' as an arrow and a location 'loc' +void drawVector(PVector v, PVector loc, float scayl) { pushMatrix(); float arrowsize = 4; // Translate to location to render vector - translate(x,y); + translate(loc.x,loc.y); stroke(255); // Call vector heading function to get direction (note that pointing up is a heading of 0) and rotate rotate(v.heading2D());