Code

//////////////////////////////////
//  Exercise 050
//  Leonardo Covarrubias
//
//  a particle emitter with rate, speed and gravity controls
//  magnet in progress
//
//  sliders addapted from Max Kaufmann
//  particle, particleManager, vec2d addapted from zachary lieberman 
//
///////////////////////////////////

vec2d gravity;

Slider gravitySlider;
Slider rateSlider;
Slider attrSlider;
Slider distSlider;
Slider speedSlider;

emitter emit;
magnet mag;


//---------------------------------------------------------
void setup(){

  smooth();

  size(400,400);

  emit = new emitter();
  mag = new magnet();

  gravitySlider = new Slider(80, 25, 100, 20,10);
  gravitySlider.setColors(color(230), color(0,150,200));
  rateSlider = new Slider(80, 60, 100, 20,10);
  rateSlider.setColors(color(230), color(200,150,0));
  speedSlider = new Slider(80, 95, 100, 20,10);
  speedSlider.setColors(color(230), color(100,150,20));
  attrSlider = new Slider(320, 25, 100, 20,10);
  attrSlider.setColors(color(230), color(150,200,0));
  distSlider = new Slider(320, 60, 100, 20,10);
  distSlider.setColors(color(230), color(200,0,150));

  gravity = new vec2d(0, .98);


}

//---------------------------------------------------------
void draw(){
  colorMode(RGB,255);
  background(240);

  emit.setRate(ceil(rateSlider.value()*10));
  emit.setSpeed(ceil(speedSlider.value()*10));

  gravity.set(0, gravitySlider.value());



  emit.draw();
  //mag.draw();
  gravitySlider.draw();
  rateSlider.draw();
  //attrSlider.draw();
  //distSlider.draw();
  speedSlider.draw();

}


void mousePressed()  {
  emit.mousePressed();
  mag.mousePressed();
  gravitySlider.mousePressed();
  rateSlider.mousePressed();
  attrSlider.mousePressed();
  distSlider.mousePressed();
  speedSlider.mousePressed();
  
}
void mouseReleased() {
  emit.mouseReleased();
  mag.mouseReleased();
  gravitySlider.mouseReleased();
  rateSlider.mouseReleased();
  attrSlider.mouseReleased();
  distSlider.mouseReleased();
  speedSlider.mouseReleased();
  
}
void mouseDragged()  {
  emit.mouseDragged();
  mag.mouseDragged();
  gravitySlider.mouseDragged();
  rateSlider.mouseDragged();
  attrSlider.mouseDragged();
  distSlider.mouseDragged();
  speedSlider.mouseDragged();
  
}



//---------------------------------------------------------

class emitter
{

  private vec2d curMousePos;
  private vec2d randomVector;
  private vec2d emitterPos;

  private vec2d lastPos;

  private boolean state;
  private boolean draggingState = false;
  private int i;
  private int j;
  private int rate;
  private int ptCount;
  private int diameter;
  private int speed;

  private particleManager PM;

  emitter (){
    ptCount = 1000;
    i = 0;
    j = 0;
    rate = 1;
    diameter = 16;
    speed = 0;

    curMousePos = new vec2d(width/2,height/2);
    emitterPos = new vec2d(width/2,height/2);

    lastPos = new vec2d(20,30);
    randomVector = new vec2d(0,0);

    PM = new particleManager(ptCount);

    state = true;
    lastPos.set(curMousePos);
  }

  void setRate (int r){
    rate = r;
  }
  
  void setSpeed (int sp){
    speed = sp;
  }
  
  boolean getState(){
    return state;
  }

  void setState(boolean s){
    state = s;
  }

  boolean insideEmitter(){
    if(mouseX < emitterPos.getX()+(diameter/2) && mouseX > emitterPos.getX()-(diameter/2) &&
      mouseY < emitterPos.getY()+(diameter/2) && mouseY > emitterPos.getY()-(diameter/2)){
      return true;
    }
    else{
      return false;
    }
  }

  void mousePressed()
    //Must be called in processing's corresponding method
  {
    if(insideEmitter()){
      draggingState = true;

    }
  }

  void mouseReleased()
  {
    draggingState = false;
    emitterPos = lastPos;
  }

  void mouseDragged()
  {
    if (draggingState)
    {
      emitterPos = curMousePos;
      lastPos.set(curMousePos);        
    }
  }

  void draw(){


    curMousePos.set(mouseX,mouseY);
    //emitterPos.set(curMousePos);
    randomVector.set(random(-speed,speed),random(-speed,speed));

    if(i>=ptCount){
      i = 0;
    }

    if(state){
      for(j = i; j < i+rate && j < ptCount; j++){  
        randomVector.set(random(-speed,speed),random(-speed,speed));
        PM.PRTS[j].setPropertiesAndTurnOn(emitterPos, randomVector);

      }

      i = j+1;
    }//end if state

    PM.idle();
    PM.draw();



    colorMode(RGB);
    fill(210,60,20);
    stroke(0);
    ellipseMode(CENTER);
    ellipse(emitterPos.getX(), emitterPos.getY(), diameter, diameter);
  }
}




//--------------------------- making things move
//--------------------------- example 06 _ 02
//--------------------------- zachary lieberman / zlieb@parsons.edu

/*
   
 I know my own position and velocity 
 and move on my own
 you set up my initial conditions
 and I move --- idle() is one time step...
 
 */

//---------------
class particle {

  vec2d      pos;
  vec2d      vel;
  vec2d vbX = new vec2d (1,-1);
  vec2d vbY = new vec2d (-1,1);
  int c = 0;
  //vbX.set(1,-1);
  //vbY.set(-1,1);
  boolean    bAlive;
  float      slowDownRate;
  //---------------
  particle(){
    bAlive = false;  
    pos = new vec2d(0,0);
    vel = new vec2d(0,0);

  }

  //---------------
  void setPropertiesAndTurnOn(vec2d posIn, vec2d velIn){
    bAlive = true;
    pos.set(posIn);
    vel.set(velIn);
    slowDownRate = 0.98;
  }

  //---------------
  void killParticle(){
    bAlive = true;
  }
  
  //---------------
  
  float getX(){
    return pos.x;
  }
  float getY(){
    return pos.y;
  }
  void bounceX(){
    
    vel.mult(vbX);
  }
  void bounceY(){
  
    vel.mult(vbY);
  }
  vec2d getVel(){
    return vel;
  }
  void setVel(vec2d v) {
    vel.set(v);
  }

  //---------------
  void idle(){ 

    if (bAlive == true){
      // if I'm alive, take a time step forward and slow down!
      pos.add(vel);
      vel.mult(slowDownRate);
    }
  }

  //---------------
  void draw(){
    smooth();
    if (bAlive == true){
      
      colorMode(HSB,1,255,255);
            
      float h = degrees(vel.angle())/360;
      
      c = ceil(abs(vel.getX()*vel.getY()/2))*50+20;
      
      fill(h, c, c);
      noStroke();
      ellipseMode(CENTER);
      ellipse(pos.x, pos.y, 7,7);
    }
  }
}




//--------------------------- making things move
//--------------------------- example 06 _ 02
//--------------------------- zachary lieberman / zlieb@parsons.edu


class particleManager {

  int numParticles;
  particle PRTS [];
  int ptCount;

  //---------------------
  particleManager(int nP){
    ptCount = 0;
    numParticles = nP;
    PRTS = new particle[numParticles];
    for (int i = 0; i < numParticles; i ++){
      PRTS[i] = new particle();
    }
  }
  
  //---------------------
  void idle(){
    
    calculateForces();
    
    for (int i = 0; i < numParticles; i ++){
      PRTS[i].idle();
    }
  }
 
 void calculateForces(){
     for (int i = 0; i < numParticles; i ++){
      if(PRTS[i].getX() > width-6 || PRTS[i].getX() < 6){
        //PRTS[i].killParticle();
        PRTS[i].bounceY();
      }
      if(PRTS[i].getY() > height-6 || PRTS[i].getY() < 6){
        PRTS[i].bounceX();
      }
      if(PRTS[i].getY() < height-6 || PRTS[i].getY() < 6){
        PRTS[i].vel.add(gravity);
      }
      
    }
 }
 
 //---------------------
  void draw(){
    
    for (int i = 0; i < numParticles; i ++){
      PRTS[i].draw();
    }
  }
   





}

class Slider
{
  private int x;
  private int y;
  private int w;
  private int h;
  private int sw;
  private int value;
  private color c1;
  private color c2;
  private boolean draggingState = false;
  
  Slider(int x0, int y0, int w0, int h0, int sw0)
  //Standard Constructor - set's colors to b/w
  {
    x = x0;
    y = y0;
    w = w0;
    h = h0;
    sw = sw0;
    value = 0;
    c1 = color(255,255,255);
    c2 = color(0,0,0);
  }
  
  void setColors(color a, color b)
  //Change bar and slider colors
  {
    c1 = a;
    c2 = b;
  }
  
  void draw()
  //Draw it to the screen
  {
    noStroke();
    rectMode(CENTER);
    fill(c1);
    rect(x,y,w,(h>>2));
    fill(c2);
    rect(x+value,y,sw,h);
  }
  
  void mousePressed()
  //Must be called in processing's corresponding method
  {
    draggingState = (mouseX == constrain(mouseX,x+value-(sw>>1),x+value+(sw>>1)) && 
                     mouseY == constrain(mouseY,y-(h>>1),y+(h>>1)));
  }
  
  void mouseReleased()
  {
    draggingState = false;
  }
  
  void mouseDragged()
  {
    if (draggingState)
    {
      value = constrain(mouseX-x,-(w>>1),(w>>1));        
    }
  }
  
  float value()
  //Retrieve the slider percent, use with "lerp"
  {
    return float(value+(w>>1))/float(w);
  }
}


// General vector class for 2D vectors
// from unlekker.net / many thanks to marius watz who is dope

class vec2d {
  float x,y;

  vec2d(float _x,float _y) {
    x=_x;
    y=_y;
  }

  vec2d(vec2d v) {
    x=v.x;
    y=v.y;
  }

  void set(float _x,float _y) {
    x=_x;
    y=_y;
  }

  void set(vec2d v) {
    x=v.x;
    y=v.y;
  }
  
  float getX () {
    return x;
  }
  
  float getY () {
    return y;
  }

  void add(float _x,float _y) {
    x+=_x;
    y+=_y;
  }

  void add(vec2d v) {
    x+=v.x;
    y+=v.y;
  }

  void sub(float _x,float _y) {
    x-=_x;
    y-=_y;
  }

  void sub(vec2d v) {
    x-=v.x;
    y-=v.y;
  }
  
  void mult(vec2d v){
    x*=v.x;
    y*=v.y;
  }

  void mult(float m) {
    x*=m;
    y*=m;
  }

  void div(float m) {
    x/=m;
    y/=m;
  }

  float length() {
    return (float)Math.sqrt(x*x+y*y);
  }

  float angle() {
    return (float)Math.atan2(y,x);
  }

  void normalise() {
    float l=length();
    if(l!=0) {
      x/=l;
      y/=l;
    }
  }

  vec2d tangent() {
    return new vec2d(-y,x);
  }

  void rotate(float val) {
    // Due to float not being precise enough, double is used for the calculations
    double cosval=Math.cos(val);
    double sinval=Math.sin(val);
    double tmpx=x*cosval - y*sinval;
    double tmpy=x*sinval + y*cosval;

    x=(float)tmpx;
    y=(float)tmpy;
  }
}

050 -- Dynamic Simulations I: Individual Particles: Due 11/1

Statement:Create an interactive system in which multiple instances of a single type of unconnected particles are influenced by forces that are (at least partially) governed by user input. By "unconnected", I mean that there are no interparticle forces of any kind, e.g. no springs, interparticle collisions, flocking forces, etc. However, you can have particles influenced by forces from features of their environment, such as the cursor, walls, static objects, or a priori gradient fields.

For some possible inspiration, you could look into some projects by Look into works by Casey Reas, Lia, and Marius Watz; but you need not make works which are specifically accretive, as many of their examples are.

For assignments numbered 05x, you are welcome to use code from the examples that I showed in class. You may also find the following examples helpful:
-- magnet forces
-- wall collisions

a particle emitter with rate, speed and gravity controls

hide statement