Processing: Particle System and Attractive Forces

05Oct10

Another simple enough sketch I have been working on while trying to learn more about vectors and simulating forces in processing. It consists of a particle system in which all the particles that come into close contact become magnetised to each other. This results in some interesting emergent patterns, such as spirals, circular shapes that travel one-dimensionally, and explosions as the particles begin to die out.

Daniel Shiffman’s Nature of Code website was very helpful in building the sketch and for learning about some of the basic theory behind vectors and natural algorithms.

Play with the applet here.

Commented sourcecode posted below:

ParticleSystem ps;
PFont font;
 
void setup(){
  size(800, 500, JAVA2D);
  background(0);
  ps = new ParticleSystem(1, new PVector(width/2, height/2, 0), 2, 5, 0.1, 255); //create new particle system ArrayList
  smooth();
   
  font = loadFont("Monaco-12.vlw");
  textFont(font, 12);
}
 
void draw(){
  fill(0, 3);
  rect(0, 0, width, height); //show particle trails
  
  ps.run();
   
  if(mousePressed){
    ps.addParticle(mouseX, mouseY, 2, 5, 0.1, 255);
  }
}

//Another class to handle the addition and removal of the individual particle objects from the ArrayList
class ParticleSystem{
  ArrayList parts;
  PVector origin;
   
  //Constructor
  ParticleSystem(int num, PVector v, float r, float mass, float grav, float timer){
    parts = new ArrayList();
    origin = v.get();
    for(int i=0; i<num; i++){
      parts.add(new Particle(origin, r, mass, grav, timer));
    }
  }
 
  void run(){
    for(int i=parts.size()-1; i>=0; i--){
      Particle p = (Particle) parts.get(i);
      p.run(parts); //run all the main actions for every particle in the ArrayList
      if(p.dead()){ //if particle p timer is = 0, remove it from the ArrayList
        parts.remove(i);
      }
    }
     
    //display how many particles are alive
    fill(0);
    rect(width-120, height-40, width, height);
    fill(255);
    text("Particles: "+parts.size(), width-100, height-16);
  }
 
  //Add a new particle
  void addParticle(float x, float y, float r, float mass, float grav, float timer){
    parts.add(new Particle(new PVector(x, y), r, mass, grav, timer));
  }
}

//Set up individual particle object
class Particle{
  PVector loc;   //2d vector storing x and y locations
  PVector acc;   //rate of acceleration
  PVector vel;   //controlling direction
  float r;       //radius of particle
  float timer;   //particle lifetime
  float mass;    //"weight" of particle, need for attraction algorithm
  float velLim;  //limit the speed at which the particles can travel
  float g;       //gravity constant
  ArrayList parts;
 
  Particle(PVector l, float _r, float _mass, float _grav, float _timer){
    loc = l.get(); //x and y values
    acc = new PVector(random(0, 2), random(0, 2), 0);  //set initial acceleration
    vel = new PVector(random(-2, 2), random(-1, 1), 0); //set initial velocity
    r = _r;
    mass = _mass;
    g = _grav;
    timer = _timer;
    velLim = 5.0;
  }
 
  void applyAttraction(ArrayList parts){
    //compare location values between different particles in the arraylist
    for(int i=0; i<parts.size();i++){
      Particle p1 = (Particle)parts.get(i);
      for(int j=i+1;j<parts.size();j++){
        Particle p2 = (Particle)parts.get(j);
 
        PVector dir = PVector.sub(p1.loc, p2.loc);
        float d = dir.mag();
        dir.normalize();
         
        //calculate strength of attraction
        float force = (g * p1.mass * p2.mass) / (d*d);
        dir.mult(force);
       
        p2.applyForce(dir);
        dir.mult(-1.0);
        p1.applyForce(dir);
      }
    }
  }
   
  //used to apply the attraction force
  void applyForce(PVector force){
    force.div(mass);
    acc.add(force);
  }
   
  //main
  void run(ArrayList parts){
    bounds();
    applyAttraction(parts);
    update();
    render();
  }
   
  //update vector values
  void update(){
    vel.add(acc);
    vel.limit(velLim);
    loc.add(vel);
    acc.mult(0);
    timer -= 1.0;
  }
 
  //bounces particles off canvas edge
  void bounds(){
    if(loc.y > height || loc.y < 0){
      vel.y *= -1;
    }
    if(loc.x > width || loc.x < 0){
      vel.x *= -1;
    }
  }
   
  //set the visual characteristics of the individual particles here
  void render(){
    ellipseMode(CENTER);
    noStroke();
    fill(255,  timer);
    ellipse(loc.x, loc.y, r, r);
  }
   
  //check if the particle's timer is 0
  boolean dead(){
    if(timer <= 0.0){
      return true;
    }
    else{
      return false;
    }
  }
}
Advertisements


No Responses Yet to “Processing: Particle System and Attractive Forces”

  1. Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s


%d bloggers like this: