public void setup() {
   size(displayWidth, displayHeight - 100);
   frameRate(50);
   controllers(); // comment this line out once force coefficients are determined
   tspsReceiver = new TSPS(this, 12000); // set up UDP port for TSPS
   physics = new VerletPhysics2D(); // set up physics "world"
   wind = 0;
   grav = new Vec2D(wind, gravY); // set up gravity vector for gravityForce
   gravityForce = new GravityBehavior(grav); // sets up the gravity force
   physics.addBehavior(gravityForce); // adds gravity force to particle system
   attractors = new ArrayList<Attractor>(); // create arraylist of attractors
   circles = new ArrayList<Circle>(); // create the ArrayList of circles
   for (int i = 0; i < numCircles; i++) {
     circles.add(new Circle(new Vec2D(random(0, width), random(-height, height))));
   }
 }
  public void draw() {
    background(255);
    fill(cp.getColorValue());
    rect(0, 0, width, height);
    windUpdate();
    gravityForce.setForce(grav.set(wind, gravY)); // update gravityForce
    physics.setDrag(drag); // update drag
    physics.update(); // update the physics world

    // update and display circles
    for (Circle c : circles) {
      c.circUpdate();
      c.display();
      if (c.y > (height + 20)) {
        c.lock();
        c.set(random(width), random(-height, -40));
        c.unlock();
      } else if (c.age > deathAge) {
        c.lock();
        c.set(random(width), random(-height, -40));
        c.unlock();
      }
    }

    // -------------------- person tracking section ---------------------

    // set up array of people from TSPS
    TSPSPerson[] people = tspsReceiver.getPeopleArray();

    Vec2D personLoc = new Vec2D(0, 0);
    peopleLength = people.length;

    // add attractors
    for (int i = attractors.size(); i < people.length; i++) {
      TSPSPerson person = people[i];
      personLoc = new Vec2D(person.centroid.x * width, (person.centroid.y * height + yOff));
      attractors.add(new Attractor(personLoc, width, attStrength));
    }

    // add behaviors
    for (int i = 0; i < attractors.size(); i++) {
      Attractor a = attractors.get(i);
      physics.addBehavior(a.att());
    }

    // update and display attractors
    for (int i = 0; i < people.length; i++) {
      TSPSPerson person = people[i];
      Attractor a = attractors.get(i);
      a.update(person.centroid.x * width, (person.centroid.y * height + yOff));
      // a.display();          //comment out this line for display
    }

    // remove attractors
    for (int i = attractors.size() - 1; i > people.length; i--) {
      Attractor a = attractors.get(i);
      a.killBurst();
      attractors.remove(a);
    }

    // remove behaviors
    for (int i = physics.behaviors.size() - 1; i > people.length; i--) {
      ParticleBehavior2D b = physics.behaviors.get(i);
      physics.removeBehavior(b);
    }

    // playing it safe and removing everything if people array is empty
    if (people.length == 0) {
      for (int i = physics.behaviors.size() - 1; i > 0; i--) {
        ParticleBehavior2D b = physics.behaviors.get(i);
        physics.removeBehavior(b);
      }
      attractors.clear();
    }

    // debugging
    println("people: " + people.length);
    println("behaviors" + physics.behaviors.size());
    println("framerate: " + frameRate);

    hideControls();
  }