<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>jasonmcdermott &#187; jasonmcdermott</title>
	<atom:link href="http://www.jasonmcdermott.net/author/jasonmcdermott/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jasonmcdermott.net</link>
	<description>architecture interaction design</description>
	<lastBuildDate>Sun, 22 Aug 2010 01:28:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>faking gravity</title>
		<link>http://www.jasonmcdermott.net/2010/08/faking-gravity/</link>
		<comments>http://www.jasonmcdermott.net/2010/08/faking-gravity/#comments</comments>
		<pubDate>Sat, 21 Aug 2010 14:44:02 +0000</pubDate>
		<dc:creator>jasonmcdermott</dc:creator>
				<category><![CDATA[teaching]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[forces]]></category>
		<category><![CDATA[gravity]]></category>
		<category><![CDATA[particles]]></category>
		<category><![CDATA[processing]]></category>

		<guid isPermaLink="false">http://www.jasonmcdermott.net/?p=1389</guid>
		<description><![CDATA[<img src="http://www.jasonmcdermott.net/blog/wp-content/uploads/media/screengrab-2010-08-22-11-20-06.tif" class="attachment-medium wp-post-image" alt="screengrab 2010-08-22 11-20-06" title="screengrab 2010-08-22 11-20-06" />This time we&#8217;ll be faking gravity on our particles. Each time we redraw, we&#8217;ll add a velocity vector of (0,1,0), pushing the particles down the screen. I&#8217;ve drawn the force vectors for both particle and boundary interactions, as well as the boundary objects themselves, to  &#8230;]]></description>
			<content:encoded><![CDATA[<img src="http://www.jasonmcdermott.net/blog/wp-content/uploads/media/screengrab-2010-08-22-11-20-06.tif" class="attachment-medium wp-post-image" alt="screengrab 2010-08-22 11-20-06" title="screengrab 2010-08-22 11-20-06" /><p></p><br /><p>This time we&#8217;ll be faking gravity on our particles.  Each time we redraw, we&#8217;ll add a velocity vector of (0,1,0), pushing the particles down the screen.  I&#8217;ve drawn the force vectors for both particle and boundary interactions, as well as the boundary objects themselves, to (hopefully) make things a little bit clearer.</p>
<p><a href="http://dl.dropbox.com/u/3801794/faking_gravity.pde" onclick="javascript: pageTracker._trackPageview('/downloads/source'); ">Source Code</a></p>
<p><script type="application/processing">

int Resolution;
ParticleController pC;
PVec mousey;
boolean gridded = false;
boolean back;
int W;
int H;
boolean online;
float timed;

void setup() {
  if (online == false) {
    W = 800;
    H = 300;
  } 
  else {
    W = 600;
    H = 200;
  }
  size(W,H);
  smooth();
  //  frameRate(30);
  Resolution = 75;
  pC = new ParticleController();
  background(0);
}

void draw() {
  if (back == true) {
    tint(0,10);
    fill(0,1);
    noStroke();
    rect(0,0,W,H);
  } 
  else {
    background(0);
  }
  pC.update();
  timed++;
  if (timed > 2000) {
    println(frameRate + " " + pC.pSize());
    noLoop();
  }
}

class ParticleController {
  // an arraylist to hold all of our particles
  ArrayList particles = new ArrayList();
  ArrayList boundaries = new ArrayList();
  // these variables were originally used to dictate the spacing of a grid
  // we're not really using them anymore, but we'll keep them for posterity
  // besides, we might later on want to reintroduce the grid
  int mXRes, mYRes;
  // this we'll use to give each particle a unique identifier
  int counting = 0;

  ParticleController() {
    // we'll assign a new random point to push away from.
    mousey = new PVec(random(0,W),random(0,H),0);
    // when we were putting the particles into a grid, this part made more sense
    // step through the grid resolution, assign a new particle for each x/y position on the grid
    // although this time and most times in future we'll ignore the grid
    // and insert particles randomly
    if (gridded) {    
      mXRes = W/Resolution; 
      mYRes = H/Resolution;
      for( int y=mYRes; y>0; y-- ) {
        for( int x=mXRes; x>0; x-- ) {
          addParticle( x, y-1, Resolution,counting );
          counting++;
        }
      }
    } 
    else {
      for (int i=Resolution; i > 0 ; i--) {
        addParticle( i, i-1, Resolution,counting );
        counting++;
      }
    }
    float gridBounds = 10;
    for (int i=W;i> 0;i--) { 
      for (int j=H;j> 0;j--) {
        if (i == W-150 && j % gridBounds ==0) {
          if (j > H-H/2) {
            addBoundary(i,j,Resolution);
          }
        } 
        else if (i == 150 && j % gridBounds ==0) {
          if (j > H-H/2) {
            addBoundary(i,j,Resolution);
          }
        } 
        //        else if (i % gridBounds ==0 && j ==1) {
        //          addBoundary(i,j,Resolution);
        //        } 
        else if (i % gridBounds ==0 && j ==H-10) {
          if (i > 150  && i < W-150) {
            addBoundary(i,j,Resolution);
          }
        }
      }
    }
  }

  void update() {
    for (int i=0;i<particles.size();i++) {
      Particle p = (Particle) particles.get(i);
      p.render(0);
      p.update(particles,boundaries);
      if (p.dead) {
        particles.remove(i);
        println(frameRate + " " + pC.pSize());
      }
    }
    for (int i=0;i<boundaries.size();i++) {
      Particle b = (Particle) boundaries.get(i);
      b.render(1);
    }
  }

  void addParticle(float x_, float y_, int Resolution_, int Num_) {
    float offSet = 150;
    particles.add(new Particle(new PVec(random(offSet,W-offSet),random(offSet/2,H-offSet),0), Num_));
  }

  void addBoundary(float x_, float y_,int Resolution_) {
    boundaries.add(new Particle(new PVec(x_,y_,0),0));
  }

  float pSize() {
    return particles.size();
  }
}

class Particle {
  PVec mLoc, newLoc;
  PVec mDirToCursor;
  PVec loc, vel, acc, steer, sepp, bounds, attracts;
  float time, sinOffset, distance, mDistanceToCursor,mRadius;
  float distTicker = 50, drag = 0.96; 
  boolean dead;

  Particle(PVec loc_, int num_) {
    mLoc = loc_;
    mRadius = Resolution;
    newLoc = mLoc;
    loc = new PVec(0,0,0);
    vel = new PVec(0,1,0);
    acc = new PVec(0,0,0);
    steer = new PVec(0,0,0);
    sepp = new PVec(0,0,0);
    bounds = new PVec(0,0,0);
    attracts =  new PVec(0,0,0);
    dead = false;
  }

  void update(ArrayList particles_, ArrayList boundaries_) {
    newLoc.add(vel);
    if (frameCount > 1) {
      sepp = interact(particles_,1.5,false,-1,20);
      //      attracts = interact(particles_,0,false,1,30);
      bounds = interact(boundaries_,0.25,true,-1,40);
      //      attracts.mult(drag);
      sepp.mult(drag);
      //      newLoc.add(attracts);
      newLoc.add(sepp);
      newLoc.add(bounds);
    }
    //    newLoc.mult(drag);
    if (newLoc.x > W || newLoc.x < 0) {
      dead = true;
    } 
    else if (newLoc.y > H || newLoc.y < 0) {
      dead = true;
    }
  }

  void render (int mode) {
    noStroke();
    if (mode == 1) {
      fill(255,125);
      ellipse(newLoc.x,newLoc.y,3,3);
    } 
    else {
      fill(255);
      ellipse(newLoc.x,newLoc.y,20,20);
    }
  }

  // here we have a neat little function which can tell us the 
  // distance between each particle object
  // and then act on it
  PVec interact(ArrayList particles_, float multFact_, boolean drawMe_, int pushPull_, int separation_) {
    float pushPull = pushPull_;
    float multFact = multFact_;
    float desiredseparation = separation_;
    for (int i = 0 ; i < particles_.size()-1; i++) {
      Particle other = (Particle) particles_.get(i);
      PVec ot = other.getLocation();
      float p = Dist(ot);
      if ((p > 0) && (p < desiredseparation)) {
        if (drawMe_) {
          strokeWeight(desiredseparation/(p*5));
          stroke(255-p);
          fill(255-p*4);
          line(newLoc.x,newLoc.y,ot.x,ot.y);
        }
        PVec diff = Sub(newLoc,other.newLoc, null);
        float diffMag = (float)sqrt(diff.x * diff.x + diff.y * diff.y + diff.z * diff.z);
        if ((diffMag != 0.0) && (diffMag != 1.0)) {
          diff.div(diffMag);
        }
        if (pushPull < 0 ) {
          diff.div(p);
          diff.mult(multFact);
          steer.add(diff);
        } 
        else {
          diff.mult(0.1);
          diff.mult(multFact);
          steer.sub(diff);
        }
      }
    }
    return steer;
  }

  // this function returns the current location of our particle
  PVec getLocation() {
    PVec tempLoc = newLoc;
    return tempLoc;
  }
  // this function tells us the distance between the location and a pvec
  float Dist(PVec v) {
    float dx = mLoc.x - v.x;
    float dy = mLoc.y - v.y;
    float dz = mLoc.z - v.z;
    return (float)Math.sqrt(dx * dx + dy * dy + dz * dz);
  }

  // this is lifted straight out of the pvector class.
  // it returns a new pvec object which represents the 
  // distance (direction and length) between two PVec objects
  PVec Sub(PVec v1, PVec v2, PVec target) {
    if (target == null) {
      target = new PVec(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
    } 
    else {
      target.set(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
    }
    return target;
  }
}



// all of this PVec code is taken from theh PVector class written by Daniel Shiffman
// I've merely pulled out the bits we need to have a working PVec class which will run in a web browser window
// It's a bit of a hack, but it's worth demonstrating the way we can interact with java classes
class PVec {
  float x;
  float y;
  float z;

  PVec(float x_, float y_, float z_) {
    x = x_;
    y = y_;
    z = z_;
  }
  void add(PVec v) {
    x += v.x;
    y += v.y;
    z += v.z;
  }
  void div(float n) {
    x /= n;
    y /= n;
    z /= n;
  }
  void mult(float n) {
    x *= n;
    y *= n;
    z *= n;
  }
  void set(float x_, float y_, float z_) {
    x = x_;
    y = y_;
    z = z_;
  }
  void sub(PVec v)
  {
    x -= v.x;
    y -= v.y;
    z -= v.z;
  }
}

</script></script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jasonmcdermott.net/2010/08/faking-gravity/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>particle interaction</title>
		<link>http://www.jasonmcdermott.net/2010/08/particle-interaction/</link>
		<comments>http://www.jasonmcdermott.net/2010/08/particle-interaction/#comments</comments>
		<pubDate>Sat, 21 Aug 2010 14:19:16 +0000</pubDate>
		<dc:creator>jasonmcdermott</dc:creator>
				<category><![CDATA[teaching]]></category>
		<category><![CDATA[attraction]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[interaction]]></category>
		<category><![CDATA[particles]]></category>
		<category><![CDATA[processing]]></category>
		<category><![CDATA[repulsion]]></category>

		<guid isPermaLink="false">http://www.jasonmcdermott.net/?p=1381</guid>
		<description><![CDATA[<img src="http://www.jasonmcdermott.net/blog/wp-content/uploads/media/screengrab-2010-08-22-00-15-11.tif" class="attachment-medium wp-post-image" alt="screengrab 2010-08-22 00-15-11" title="screengrab 2010-08-22 00-15-11" />Here we&#8217;ll see some chaotic interaction happening between our particles &#8211; we can tweak the interaction parameters (e.g. interact(particles_,1,false,-1,40) is where all the magic happens) to allow for different attraction and repulsion forces between each of the particles and their environment. Source Code int Resolution;  &#8230;]]></description>
			<content:encoded><![CDATA[<img src="http://www.jasonmcdermott.net/blog/wp-content/uploads/media/screengrab-2010-08-22-00-15-11.tif" class="attachment-medium wp-post-image" alt="screengrab 2010-08-22 00-15-11" title="screengrab 2010-08-22 00-15-11" /><p></p><br /><p>Here we&#8217;ll see some chaotic interaction happening between our particles &#8211; we can tweak the interaction parameters (e.g. interact(particles_,1,false,-1,40) is where all the magic happens) to allow for different attraction and repulsion forces between each of the particles and their environment.</p>
<p><a href="http://dl.dropbox.com/u/3801794/particle_interaction.pde" onclick="javascript: pageTracker._trackPageview('/downloads/source'); ">Source Code</a></p>
<p><script type="application/processing">

int Resolution;
ParticleController pC;
PVec mousey;
boolean gridded = false;
boolean back = true;
int W;
int H;
boolean online;
float timed;

void setup() {
  // this is one of the more useful pieces of code i've used to date
  // firstly we check if we're offline
  if (online == false) {
    // if so, we know we're in a processing window
    // so we set our height/width variables accordingly
    W = 800;
    H = 300;
  } 
  // if online is true, we know we're in a browser window
  // so we make the sketch smaller
  // this way I can sketch out the same sketch but with dynamic size properties
  else {
    W = 600;
    H = 200;
  }
  size(W,H);
  smooth();
  frameRate(30);
  // how closely packed our particles might be
  Resolution = 20;
  // our particle controller class object
  pC = new ParticleController();
  background(0);
}

void draw() {
  if (back == true) {
    tint(0,1);
    fill(0,5);
    noStroke();
    rect(0,0,W,H);
  } else {
    background(0);
  }
  pC.update();
  timed++;
  if (timed > 2000) {
    println(frameRate + " " + pC.pSize());
    noLoop();
  }
}

class ParticleController {
  // an arraylist to hold all of our particles
  ArrayList particles = new ArrayList();
  ArrayList boundaries = new ArrayList();
  // these variables were originally used to dictate the spacing of a grid
  // we're not really using them anymore, but we'll keep them for posterity
  // besides, we might later on want to reintroduce the grid
  int mXRes, mYRes;
  // this we'll use to give each particle a unique identifier
  int counting = 0;

  ParticleController() {
    // we'll assign a new random point to push away from.
    mousey = new PVec(random(0,W),random(0,H),0);
    // when we were putting the particles into a grid, this part made more sense
    // step through the grid resolution, assign a new particle for each x/y position on the grid
    // although this time and most times in future we'll ignore the grid
    // and insert particles randomly
    if (gridded) {    
      mXRes = W/Resolution; 
      mYRes = H/Resolution;
      for( int y=mYRes; y>0; y-- ) {
        for( int x=mXRes; x>0; x-- ) {
          addParticle( x, y-1, Resolution,counting );
          counting++;
        }
      }
    } 
    else {
      for (int i=Resolution; i > 0 ; i--) {
        addParticle( i, i-1, Resolution,counting );
        counting++;
      }
    }

    // for our pressure exerting walls we'll create 'boundary' particle objects
    // how closely do we want to space these boundary objects?
    float gridBounds = 5;
    // then we'll step through each of the boundary conditions
    // if (x == 1 && y % gridBounds == 0) simply means every 2 vertical pixels on the left side of the window
    // likewise
    // if (x % gridBounds == 0 && y == 1) simply means every 2 horizontal pixels on the top of the window
    for (int i=W;i> 0;i--) { 
      for (int j=H;j> 0;j--) {
        if (i == W && j % gridBounds ==0) {
          addBoundary(i,j,Resolution);
        } 
        else if (i == 1 && j % gridBounds ==0) {
          addBoundary(i,j,Resolution);
        } 
        else if (i % gridBounds ==0 && j ==1) {
          addBoundary(i,j,Resolution);
        } 
        else if (i % gridBounds ==0 && j ==H) {
          addBoundary(i,j,Resolution);
        }
      }
    }
  }

  void update() {
    // stock standard routine for looping through each particle and updating them.
    for (int i=0;i<particles .size();i++) {
      Particle p = (Particle) particles.get(i);
      // in this case we also pass through the entire particles arraylist to each particle
      // we use this method to then compare each particle to its neighbour
      p.render(0);
      p.update(particles,boundaries);
      if (p.dead) {
        particles.remove(i);
        println(frameRate + " " + pC.pSize());
      }
    }
  }

  void addParticle(float x_, float y_, int Resolution_, int Num_) {
    float x = ( x_ + 0.5f ) * (float)Resolution_;
    float y = ( y_ + 0.5f ) * (float)Resolution_;
    float offSet = 80;
    particles.add(new Particle(new PVec(random(offSet,W-offSet),random(offSet,H-offSet),0), Num_));
  }

  void addBoundary(float x_, float y_,int Resolution_) {
    boundaries.add(new Particle(new PVec(x_,y_,0),0));
  }
  
  float pSize() {
    return particles.size();
  }
}

class Particle {
  // our position pvec objects, which hold the starting loc, our updated newloc and directionto cursor data
  // the direction to cursor really should be re-named, as it mainly points to a random point in space now
  PVec mLoc, newLoc;
  PVec mDirToCursor;
  // these are different pvec variables which we will use to store the
  // location, momentum and velocity values
  // these may well supersede the mLoc and newLoc variables, we'll see.
  PVec loc, vel, acc, steer, sepp, bounds, attracts;
  // time is incrementally increased
  // sinOffset is the sin function variable
  // distance is a temporary distance variable, which scales our distance to cursor pvec
  // mRadius sets the radius of our circle
  float time, sinOffset, distance, mDistanceToCursor,mRadius;
  // these we'll temporarily use to draw lines between objects
  // the first will increase the distance allowed between objects
  // the first will control the direction of increase (so we could be increasing the ticker in a negative direction)
  // i.e. if the ticker is less than a certain upper limit, increase until it reaches that limit, then increase negagively
  float distTicker = 50, drag = 0.999; 
  boolean dead;

  Particle(PVec loc_, int num_) {
    // we'll start by giving the particle a home
    mLoc = loc_;
    // and a size
    mRadius = Resolution;
    // initiate the newlocation pvec
    newLoc = mLoc;
    loc = new PVec(0,0,0);
    vel = new PVec(random(-0.3,0.3),random(0.1,1.5),0);
    acc = new PVec(0,0,0);
    steer = new PVec(0,0,0);
    sepp = new PVec(0,0,0);
    bounds = new PVec(0,0,0);
    attracts =  new PVec(0,0,0);
    dead = false;
  }

  void update(ArrayList particles_, ArrayList boundaries_) {
    // we'll wait for the 3rd frame to start calculating and drawing lines
//    newLoc.add(vel);
    if (frameCount > 1) {
      sepp = interact(particles_,1,false,-1,40);
      attracts = interact(particles_,.5,true,1,80);
      bounds = interact(boundaries_,2,false,-1,40);
      attracts.mult(drag);
      sepp.mult(drag);
      newLoc.add(attracts);
      newLoc.add(sepp);
      newLoc.add(bounds);
    }
//    newLoc.mult(drag);
    if (newLoc.x > W || newLoc.x < 0) {
      dead = true;
    } else if (newLoc.y > H || newLoc.y < 0) {
      dead = true;
    }
  }

  void render (int mode) {
    noStroke();
    if (mode == 1) {
      fill(255,0,0);
      ellipse(newLoc.x,newLoc.y,Resolution*0.3,Resolution*0.3);
    } 
    else {
      fill(255);
      ellipse(newLoc.x,newLoc.y,3,3);
    }
  }

  // here we have a neat little function which can tell us the 
  // distance between each particle object
  // and then act on it
  PVec interact(ArrayList particles_, float multFact_, boolean drawMe_, int pushPull_, int separation_) {
    // we first set our upper limit
//    bio drawMe = drawMe_;
    float pushPull = pushPull_;
    float multFact = multFact_;
    float desiredseparation = separation_;
    // then for each particle
    for (int i = 0 ; i < particles_.size()-1; i++) {
      // get it, we'll call the temp particle 'other'
      Particle other = (Particle) particles_.get(i);
      // grab the location of the other particle
      PVec ot = other.getLocation();
      // let's see how far away it is from us
      float p = Dist(ot);
      // if it's further than 0 units away and less than 20 units away
      if ((p > 0) && (p < desiredseparation)) {
        // draw a line between this object and that one
        // but only between our particles, not between the particles and the boundaries
        if (drawMe_) {
          strokeWeight(desiredseparation/(p*5));
          stroke(255-p);
          fill(255-p*4);
          line(newLoc.x,newLoc.y,ot.x,ot.y);
        }
        PVec diff = Sub(newLoc,other.newLoc, null);
        float diffMag = (float)sqrt(diff.x * diff.x + diff.y * diff.y + diff.z * diff.z);
        if ((diffMag != 0.0) && (diffMag != 1.0)) {
          diff.div(diffMag);
        }
        if (pushPull < 0 ) {
          diff.div(p);
          diff.mult(multFact);
          steer.add(diff);
        } else {
          diff.mult(0.1);
          diff.mult(multFact);
          steer.sub(diff);
        }
      }
    }
    return steer;
  }

//  PVec converge(ArrayList particles_, float multFact_, int drawMe_, int pushPull_, int separation) {
//    // we first set our upper limit
//    float drawMe = drawMe_;
//    float multFact = multFact_;
//    float influence = separation;
//    // then for each particle
//    for (int i = 0 ; i < particles_.size()-1; i++) {
//      // get it, we'll call the temp particle 'other'
//      Particle other = (Particle) particles_.get(i);
//      // grab the location of the other particle
//      PVec ot = other.getLocation();
//      // let's see how far away it is from us
//      float p = Dist(ot);
//      // if it's further than 0 units away and less than 20 units away
//      if ((p > 0) && (p < influence)) {
//        // draw a line between this object and that one
//        // but only between our particles, not between the particles and the boundaries
//        if (drawMe == 1) {
//          strokeWeight(influence/(p*5));
//          stroke(255-p);
//          fill(255-p*4);
//          line(newLoc.x,newLoc.y,ot.x,ot.y);
//        }
//        PVec diff = Sub(newLoc,other.newLoc, null);
//        float diffMag = (float)sqrt(diff.x * diff.x + diff.y * diff.y + diff.z * diff.z);
//        if ((diffMag != 0.0) && (diffMag != 1.0)) {
//          diff.div(diffMag);
//        }
//        diff.mult(0.1);
//        diff.mult(multFact);
//        steer.sub(diff);
//      }
//    }
//    return steer;
//  }
  // this function returns the current location of our particle
  PVec getLocation() {
    PVec tempLoc = newLoc;
    return tempLoc;
  }
  // this function tells us the distance between the location and a pvec
  float Dist(PVec v) {
    float dx = mLoc.x - v.x;
    float dy = mLoc.y - v.y;
    float dz = mLoc.z - v.z;
    return (float)Math.sqrt(dx * dx + dy * dy + dz * dz);
  }

  // this is lifted straight out of the pvector class.
  // it returns a new pvec object which represents the 
  // distance (direction and length) between two PVec objects
  PVec Sub(PVec v1, PVec v2, PVec target) {
    if (target == null) {
      target = new PVec(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
    } 
    else {
      target.set(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
    }
    return target;
  }
}



// all of this PVec code is taken from theh PVector class written by Daniel Shiffman
// I've merely pulled out the bits we need to have a working PVec class which will run in a web browser window
// It's a bit of a hack, but it's worth demonstrating the way we can interact with java classes
class PVec {
  float x;
  float y;
  float z;

  PVec(float x_, float y_, float z_) {
    x = x_;
    y = y_;
    z = z_;
  }
  void add(PVec v) {
    x += v.x;
    y += v.y;
    z += v.z;
  }
  void div(float n) {
    x /= n;
    y /= n;
    z /= n;
  }
  void mult(float n) {
    x *= n;
    y *= n;
    z *= n;
  }
  void set(float x_, float y_, float z_) {
    x = x_;
    y = y_;
    z = z_;
  }
  void sub(PVec v)
  {
    x -= v.x;
    y -= v.y;
    z -= v.z;
  }
}


</script></particles></script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jasonmcdermott.net/2010/08/particle-interaction/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>particle attraction</title>
		<link>http://www.jasonmcdermott.net/2010/08/particle-attraction/</link>
		<comments>http://www.jasonmcdermott.net/2010/08/particle-attraction/#comments</comments>
		<pubDate>Sat, 21 Aug 2010 13:19:18 +0000</pubDate>
		<dc:creator>jasonmcdermott</dc:creator>
				<category><![CDATA[teaching]]></category>
		<category><![CDATA[attraction]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[forces]]></category>
		<category><![CDATA[particles]]></category>
		<category><![CDATA[processing]]></category>

		<guid isPermaLink="false">http://www.jasonmcdermott.net/?p=1368</guid>
		<description><![CDATA[<img src="http://www.jasonmcdermott.net/blog/wp-content/uploads/media/screengrab-2010-08-21-23-18-35.tif" class="attachment-medium wp-post-image" alt="screengrab 2010-08-21 23-18-35" title="screengrab 2010-08-21 23-18-35" />This time round we&#8217;ll add an attraction force into the mix. Each particle has repulsion and attraction interactions with all other particles, which result in &#8216;path of least resistance&#8217; geometric configurations. In this example we&#8217;ll be drawing both the particles and the forces. Source Code  &#8230;]]></description>
			<content:encoded><![CDATA[<img src="http://www.jasonmcdermott.net/blog/wp-content/uploads/media/screengrab-2010-08-21-23-18-35.tif" class="attachment-medium wp-post-image" alt="screengrab 2010-08-21 23-18-35" title="screengrab 2010-08-21 23-18-35" /><p></p><br /><p>This time round we&#8217;ll add an attraction force into the mix.  Each particle has repulsion and attraction interactions with all other particles, which result in &#8216;path of least resistance&#8217; geometric configurations.  In this example we&#8217;ll be drawing both the particles and the forces.</p>
<p><a href="http://dl.dropbox.com/u/3801794/particle_attraction.pde" onclick="javascript: pageTracker._trackPageview('/downloads/source'); ">Source Code</a></p>
<p><script type="application/processing">

int Resolution;
ParticleController pC;
PVec mousey;
boolean gridded = false;
boolean back;
int W;
int H;
boolean online;
float timed;

void setup() {
  // this is one of the more useful pieces of code i've used to date
  // firstly we check if we're offline
  if (online == false) {
    // if so, we know we're in a processing window
    // so we set our height/width variables accordingly
    W = 800;
    H = 300;
  } 
  // if online is true, we know we're in a browser window
  // so we make the sketch smaller
  // this way I can sketch out the same sketch but with dynamic size properties
  else {
    W = 600;
    H = 200;
  }
  size(W,H);
  smooth();
  frameRate(30);
  // how closely packed our particles might be
  Resolution = 30;
  // our particle controller class object
  pC = new ParticleController();
  background(0);
}

void draw() {
  if (back == true) {
    tint(0,10);
    fill(0,1);
    noStroke();
    rect(0,0,W,H);
  } else {
    background(0);
  }
  pC.update();
  timed++;
  if (timed > 500) {
    println(frameRate + " " + pC.pSize());
    noLoop();
  }
}

class ParticleController {
  // an arraylist to hold all of our particles
  ArrayList particles = new ArrayList();
  ArrayList boundaries = new ArrayList();
  // these variables were originally used to dictate the spacing of a grid
  // we're not really using them anymore, but we'll keep them for posterity
  // besides, we might later on want to reintroduce the grid
  int mXRes, mYRes;
  // this we'll use to give each particle a unique identifier
  int counting = 0;

  ParticleController() {
    // we'll assign a new random point to push away from.
    mousey = new PVec(random(0,W),random(0,H),0);
    // when we were putting the particles into a grid, this part made more sense
    // step through the grid resolution, assign a new particle for each x/y position on the grid
    // although this time and most times in future we'll ignore the grid
    // and insert particles randomly
    if (gridded) {    
      mXRes = W/Resolution; 
      mYRes = H/Resolution;
      for( int y=mYRes; y>0; y-- ) {
        for( int x=mXRes; x>0; x-- ) {
          addParticle( x, y-1, Resolution,counting );
          counting++;
        }
      }
    } 
    else {
      for (int i=Resolution; i > 0 ; i--) {
        addParticle( i, i-1, Resolution,counting );
        counting++;
      }
    }

    // for our pressure exerting walls we'll create 'boundary' particle objects
    // how closely do we want to space these boundary objects?
    float gridBounds = 10;
    // then we'll step through each of the boundary conditions
    // if (x == 1 && y % gridBounds == 0) simply means every 2 vertical pixels on the left side of the window
    // likewise
    // if (x % gridBounds == 0 && y == 1) simply means every 2 horizontal pixels on the top of the window
    for (int i=W;i> 0;i--) { 
      for (int j=H;j> 0;j--) {
        if (i == W && j % gridBounds ==0) {
          addBoundary(i,j,Resolution);
        } 
        else if (i == 1 && j % gridBounds ==0) {
          addBoundary(i,j,Resolution);
        } 
        else if (i % gridBounds ==0 && j ==1) {
          addBoundary(i,j,Resolution);
        } 
        else if (i % gridBounds ==0 && j ==H) {
          addBoundary(i,j,Resolution);
        }
      }
    }
  }

  void update() {
    // stock standard routine for looping through each particle and updating them.
    for (int i=0;i<particles .size();i++) {
      Particle p = (Particle) particles.get(i);
      // in this case we also pass through the entire particles arraylist to each particle
      // we use this method to then compare each particle to its neighbour
      p.render(0);
      p.update(particles,boundaries);
      if (p.dead) {
        particles.remove(i);
        println(frameRate + " " + pC.pSize());
      }
    }
    //    for (int i=0;i<boundaries.size();i++) {
    //      Particle b = (Particle) boundaries.get(i);
    //      b.render(1);
    //    }
  }

  void addParticle(float x_, float y_, int Resolution_, int Num_) {
    float x = ( x_ + 0.5f ) * (float)Resolution_;
    float y = ( y_ + 0.5f ) * (float)Resolution_;
    float offSet = 80;
    //    particles.add(new Particle(new PVec(x,y,0),Num_));
    particles.add(new Particle(new PVec(random(offSet,W-offSet),random(offSet,H-offSet),0), Num_));
  }

  void addBoundary(float x_, float y_,int Resolution_) {
    boundaries.add(new Particle(new PVec(x_,y_,0),0));
  }
  
  float pSize() {
    return particles.size();
  }
}

class Particle {
  // our position pvec objects, which hold the starting loc, our updated newloc and directionto cursor data
  // the direction to cursor really should be re-named, as it mainly points to a random point in space now
  PVec mLoc, newLoc;
  PVec mDirToCursor;
  // these are different pvec variables which we will use to store the
  // location, momentum and velocity values
  // these may well supersede the mLoc and newLoc variables, we'll see.
  PVec loc, vel, acc, steer, sepp, bounds, attracts;
  // time is incrementally increased
  // sinOffset is the sin function variable
  // distance is a temporary distance variable, which scales our distance to cursor pvec
  // mRadius sets the radius of our circle
  float time, sinOffset, distance, mDistanceToCursor,mRadius;
  // these we'll temporarily use to draw lines between objects
  // the first will increase the distance allowed between objects
  // the first will control the direction of increase (so we could be increasing the ticker in a negative direction)
  // i.e. if the ticker is less than a certain upper limit, increase until it reaches that limit, then increase negagively
  float distTicker = 50, drag = 0.97; 
  boolean dead;

  Particle(PVec loc_, int num_) {
    // we'll start by giving the particle a home
    mLoc = loc_;
    // and a size
    mRadius = Resolution;
    // initiate the newlocation pvec
    newLoc = mLoc;
    loc = new PVec(0,0,0);
    vel = new PVec(random(-0.3,0.3),random(0.1,1.5),0);
    acc = new PVec(0,0,0);
    steer = new PVec(0,0,0);
    sepp = new PVec(0,0,0);
    bounds = new PVec(0,0,0);
    attracts =  new PVec(0,0,0);
    dead = false;
  }

  void update(ArrayList particles_, ArrayList boundaries_) {
    // we'll wait for the 3rd frame to start calculating and drawing lines
//    newLoc.add(vel);
    if (frameCount > 1) {
      sepp = interact(particles_,0.49,false,-1,20);
      attracts = interact(particles_,0.2,true,1,25);
      bounds = interact(boundaries_,0.2,false,-1,20);
      attracts.mult(drag);
      sepp.mult(drag);
      newLoc.add(attracts);
      newLoc.add(sepp);
      newLoc.add(bounds);
    }
//    newLoc.mult(drag);
    if (newLoc.x > W || newLoc.x < 0) {
      dead = true;
    } else if (newLoc.y > H || newLoc.y < 0) {
      dead = true;
    }
  }

  void render (int mode) {
    noStroke();
    if (mode == 1) {
      fill(255,0,0);
      ellipse(newLoc.x,newLoc.y,Resolution*0.3,Resolution*0.3);
    } 
    else {
      fill(255);
      ellipse(newLoc.x,newLoc.y,3,3);
    }
  }

  // here we have a neat little function which can tell us the 
  // distance between each particle object
  // and then act on it
  PVec interact(ArrayList particles_, float multFact_, boolean drawMe_, int pushPull_, int separation_) {
    // we first set our upper limit
//    bio drawMe = drawMe_;
    float pushPull = pushPull_;
    float multFact = multFact_;
    float desiredseparation = separation_;
    // then for each particle
    for (int i = 0 ; i < particles_.size()-1; i++) {
      // get it, we'll call the temp particle 'other'
      Particle other = (Particle) particles_.get(i);
      // grab the location of the other particle
      PVec ot = other.getLocation();
      // let's see how far away it is from us
      float p = Dist(ot);
      // if it's further than 0 units away and less than 20 units away
      if ((p > 0) && (p < desiredseparation)) {
        // draw a line between this object and that one
        // but only between our particles, not between the particles and the boundaries
        if (drawMe_) {
          strokeWeight(desiredseparation/(p*5));
          stroke(255-p);
          fill(255-p*4);
          line(newLoc.x,newLoc.y,ot.x,ot.y);
        }
        PVec diff = Sub(newLoc,other.newLoc, null);
        float diffMag = (float)sqrt(diff.x * diff.x + diff.y * diff.y + diff.z * diff.z);
        if ((diffMag != 0.0) && (diffMag != 1.0)) {
          diff.div(diffMag);
        }
        if (pushPull < 0 ) {
          diff.div(p);
          diff.mult(multFact);
          steer.add(diff);
        } else {
          diff.mult(0.1);
          diff.mult(multFact);
          steer.sub(diff);
        }
      }
    }
    return steer;
  }

//  PVec converge(ArrayList particles_, float multFact_, int drawMe_, int pushPull_, int separation) {
//    // we first set our upper limit
//    float drawMe = drawMe_;
//    float multFact = multFact_;
//    float influence = separation;
//    // then for each particle
//    for (int i = 0 ; i < particles_.size()-1; i++) {
//      // get it, we'll call the temp particle 'other'
//      Particle other = (Particle) particles_.get(i);
//      // grab the location of the other particle
//      PVec ot = other.getLocation();
//      // let's see how far away it is from us
//      float p = Dist(ot);
//      // if it's further than 0 units away and less than 20 units away
//      if ((p > 0) && (p < influence)) {
//        // draw a line between this object and that one
//        // but only between our particles, not between the particles and the boundaries
//        if (drawMe == 1) {
//          strokeWeight(influence/(p*5));
//          stroke(255-p);
//          fill(255-p*4);
//          line(newLoc.x,newLoc.y,ot.x,ot.y);
//        }
//        PVec diff = Sub(newLoc,other.newLoc, null);
//        float diffMag = (float)sqrt(diff.x * diff.x + diff.y * diff.y + diff.z * diff.z);
//        if ((diffMag != 0.0) && (diffMag != 1.0)) {
//          diff.div(diffMag);
//        }
//        diff.mult(0.1);
//        diff.mult(multFact);
//        steer.sub(diff);
//      }
//    }
//    return steer;
//  }
  // this function returns the current location of our particle
  PVec getLocation() {
    PVec tempLoc = newLoc;
    return tempLoc;
  }
  // this function tells us the distance between the location and a pvec
  float Dist(PVec v) {
    float dx = mLoc.x - v.x;
    float dy = mLoc.y - v.y;
    float dz = mLoc.z - v.z;
    return (float)Math.sqrt(dx * dx + dy * dy + dz * dz);
  }

  // this is lifted straight out of the pvector class.
  // it returns a new pvec object which represents the 
  // distance (direction and length) between two PVec objects
  PVec Sub(PVec v1, PVec v2, PVec target) {
    if (target == null) {
      target = new PVec(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
    } 
    else {
      target.set(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
    }
    return target;
  }
}



// all of this PVec code is taken from theh PVector class written by Daniel Shiffman
// I've merely pulled out the bits we need to have a working PVec class which will run in a web browser window
// It's a bit of a hack, but it's worth demonstrating the way we can interact with java classes
class PVec {
  float x;
  float y;
  float z;

  PVec(float x_, float y_, float z_) {
    x = x_;
    y = y_;
    z = z_;
  }
  void add(PVec v) {
    x += v.x;
    y += v.y;
    z += v.z;
  }
  void div(float n) {
    x /= n;
    y /= n;
    z /= n;
  }
  void mult(float n) {
    x *= n;
    y *= n;
    z *= n;
  }
  void set(float x_, float y_, float z_) {
    x = x_;
    y = y_;
    z = z_;
  }
  void sub(PVec v)
  {
    x -= v.x;
    y -= v.y;
    z -= v.z;
  }
}


</script></particles></script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jasonmcdermott.net/2010/08/particle-attraction/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>particle forces</title>
		<link>http://www.jasonmcdermott.net/2010/08/particle-forces/</link>
		<comments>http://www.jasonmcdermott.net/2010/08/particle-forces/#comments</comments>
		<pubDate>Sat, 21 Aug 2010 02:50:33 +0000</pubDate>
		<dc:creator>jasonmcdermott</dc:creator>
				<category><![CDATA[teaching]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[forces]]></category>
		<category><![CDATA[particles]]></category>
		<category><![CDATA[processing]]></category>

		<guid isPermaLink="false">http://www.jasonmcdermott.net/?p=1361</guid>
		<description><![CDATA[<img src="http://www.jasonmcdermott.net/blog/wp-content/uploads/media/screengrab-2010-08-21-12-44-23.tif" class="attachment-medium wp-post-image" alt="screengrab 2010-08-21 12-44-23" title="screengrab 2010-08-21 12-44-23" />Here&#8217;s a subtle variant on the last post &#8211; this time focussing more on the forces between the particles than the particles themselves. To do this, we&#8217;ll only make a few changes &#8211; firstly turn off the background(0); line, and make our particles smaller. Essentially  &#8230;]]></description>
			<content:encoded><![CDATA[<img src="http://www.jasonmcdermott.net/blog/wp-content/uploads/media/screengrab-2010-08-21-12-44-23.tif" class="attachment-medium wp-post-image" alt="screengrab 2010-08-21 12-44-23" title="screengrab 2010-08-21 12-44-23" /><p></p><br /><p>Here&#8217;s a subtle variant on the last post &#8211; this time focussing more on the forces between the particles than the particles themselves.  To do this, we&#8217;ll only make a few changes &#8211; firstly turn off the background(0); line, and make our particles smaller.  </p>
<p>Essentially what we&#8217;re drawing here are the particle motion paths, along with the repulsion forces acting on all of the particles.</p>
<p><a href="http://dl.dropbox.com/u/3801794/particle_forces.pde" onclick="javascript: pageTracker._trackPageview('/downloads/source'); ">Source Code</a></p>
<p><script type="application/processing">

int Resolution;
ParticleController pC;
PVec mousey;
int W;
int H;
boolean online;
float timed;

void setup() {
  // this is one of the more useful pieces of code i've used to date
  // firstly we check if we're offline
  if (online == false) {
    // if so, we know we're in a processing window
    // so we set our height/width variables accordingly
    W = 800;
    H = 300;
  } 
  // if online is true, we know we're in a browser window
  // so we make the sketch smaller
  // this way I can sketch out the same sketch but with dynamic size properties
  else {
    W = 600;
    H = 200;
  }
  size(W,H);
  smooth();
  frameRate(30);
  // how closely packed our particles might be
  Resolution = 100;
  // our particle controller class object
  pC = new ParticleController();
  background(0);
}

void draw() {
//  background(0);
  // we don't do much in draw, merely call the particle controllers' update() function
  pC.update();
  timed++;
  if (timed > 1000) {
    noLoop();
  }
}

class ParticleController {
  // an arraylist to hold all of our particles
  ArrayList particles = new ArrayList();
  ArrayList boundaries = new ArrayList();
  // these variables were originally used to dictate the spacing of a grid
  // we're not really using them anymore, but we'll keep them for posterity
  // besides, we might later on want to reintroduce the grid
  int mXRes, mYRes;
  // this we'll use to give each particle a unique identifier
  int counting = 0;

  ParticleController() {
    // we'll assign a new random point to push away from.
    mousey = new PVec(random(0,W),random(0,H),0);
    // when we were putting the particles into a grid, this part made more sense
    // step through the grid resolution, assign a new particle for each x/y position on the grid
    // although this time and most times in future we'll ignore the grid
    // and insert particles randomly
    mXRes = W/Resolution; 
    mYRes = H/Resolution;
    for( int y=mYRes; y>0; y-- ) {
      for( int x=mXRes; x>0; x-- ) {
        addParticle( x, y-1, Resolution,counting );
        counting++;
      }
    }
    
    // for our pressure exerting walls we'll create 'boundary' particle objects
    // how closely do we want to space these boundary objects?
    float gridBounds = 15;
    // then we'll step through each of the boundary conditions
    // if (x == 1 && y % gridBounds == 0) simply means every 2 vertical pixels on the left side of the window
    // likewise
    // if (x % gridBounds == 0 && y == 1) simply means every 2 horizontal pixels on the top of the window
    for (int i=W;i> 0;i--) { 
      for (int j=H;j> 0;j--) {
        if (i == W && j % gridBounds ==0) {
          addBoundary(i,j,Resolution);
        } 
        else if (i == 1 && j % gridBounds ==0) {
          addBoundary(i,j,Resolution);
        } 
        else if (i % gridBounds ==0 && j ==1) {
          addBoundary(i,j,Resolution);
        } 
        else if (i % gridBounds ==0 && j ==H) {
          addBoundary(i,j,Resolution);
        }
      }
    }
  }

  void update() {
    // stock standard routine for looping through each particle and updating them.
    for (int i=0;i<particles .size();i++) {
      Particle p = (Particle) particles.get(i);
      // in this case we also pass through the entire particles arraylist to each particle
      // we use this method to then compare each particle to its neighbour
      p.render(0);
      p.update(particles,boundaries);

    }
//    for (int i=0;i<boundaries.size();i++) {
//      Particle b = (Particle) boundaries.get(i);
//      b.render(1);
//    }
  }

  void addParticle(float x_, float y_, int Resolution_, int Num_) {
    float x = ( x_ + 0.5f ) * (float)Resolution_;
    float y = ( y_ + 0.5f ) * (float)Resolution_;
    float offSet = 50;
    //    particles.add(new Particle(new PVec(x,y,0),Num_));
    particles.add(new Particle(new PVec(random(offSet,W-offSet),random(offSet,H-offSet),0), Num_));
  }

  void addBoundary(float x_, float y_,int Resolution_) {
    boundaries.add(new Particle(new PVec(x_,y_,0),0));
  }
}

class Particle {
  // our position pvec objects, which hold the starting loc, our updated newloc and directionto cursor data
  // the direction to cursor really should be re-named, as it mainly points to a random point in space now
  PVec mLoc, newLoc;
  PVec mDirToCursor;
  // these are different pvec variables which we will use to store the
  // location, momentum and velocity values
  // these may well supersede the mLoc and newLoc variables, we'll see.
  PVec loc, vel, acc, steer, sepp, bounds;
  // time is incrementally increased
  // sinOffset is the sin function variable
  // distance is a temporary distance variable, which scales our distance to cursor pvec
  // mRadius sets the radius of our circle
  // desired separation is the float to store our 'line drawing' separation length
  float time, sinOffset, distance, mDistanceToCursor,mRadius, desiredseparation;
  // these we'll temporarily use to draw lines between objects
  // the first will increase the distance allowed between objects
  // the first will control the direction of increase (so we could be increasing the ticker in a negative direction)
  // i.e. if the ticker is less than a certain upper limit, increase until it reaches that limit, then increase negagively
  float distTicker = 50; 

  Particle(PVec loc_, int num_) {
    // we'll start by giving the particle a home
    mLoc = loc_;
    // and a size
    mRadius = Resolution;
    // initiate the newlocation pvec
    newLoc = mLoc;
    loc = new PVec(0,0,0);
    vel = new PVec(0,0,0);
    acc = new PVec(0,0,0);
    steer = new PVec(0,0,0);
    sepp = new PVec(0,0,0);
    bounds = new PVec(0,0,0);
  }

  void update(ArrayList particles_, ArrayList boundaries_) {
    // we'll wait for the 3rd frame to start calculating and drawing lines
    if (frameCount > 2) {
      // run the entire particles arraylist through the separation function
      // first of all between each particle
      sepp = separate(particles_,0.5,1);
      newLoc.add(sepp);
      // then between particles and boundaries
      bounds = separate(boundaries_,0.3,0);
      newLoc.add(bounds);
    }
    newLoc = mLoc;
  }

  void render (int mode) {
    noStroke();
    if (mode == 1) {
      fill(255,0,0);
      ellipse(newLoc.x,newLoc.y,Resolution*0.3,Resolution*0.3);
    } 
    else {
      fill(255);
      ellipse(newLoc.x,newLoc.y,Resolution*0.01,Resolution*0.01);
    }
  }

  // here we have a neat little function which can tell us the 
  // distance between each particle object
  // and then act on it
  PVec separate(ArrayList particles_, float multFact_, int drawMe_) {
    // we first set our upper limit
    float drawMe = drawMe_;
    float multFact = multFact_;
    desiredseparation = 50;
    // then for each particle
    for (int i = 0 ; i < particles_.size()-1; i++) {
      // get it, we'll call the temp particle 'other'
      Particle other = (Particle) particles_.get(i);
      // grab the location of the other particle
      PVec ot = other.getLocation();
      // let's see how far away it is from us
      float p = Dist(ot);
      // if it's further than 0 units away and less than 20 units away
      if ((p > 0) && (p < desiredseparation)) {
        // draw a line between this object and that one
        // but only between our particles, not between the particles and the boundaries
        if (drawMe == 1) {
          strokeWeight(desiredseparation/(p*2));
          stroke(255-p*4);
          fill(255-p*4);
          line(newLoc.x,newLoc.y,ot.x,ot.y);
        }
        // here we check the difference vector between us and them
        PVec diff = Sub(newLoc,other.newLoc, null);
        // then get the magnitude of the vector
        float diffMag = (float)sqrt(diff.x * diff.x + diff.y * diff.y + diff.z * diff.z);
        // if the magnitude is greater than zero and not equal to 1
        if ((diffMag != 0.0) && (diffMag != 1.0)) {
          // divide the difference vector by it's magnitude
          // which normalises the vector to a length of 1
          diff.div(diffMag);
        }
        // then divide the difference vector by the distance between it and the other object
        diff.div(p);
        // we multiply particle forces differently to boundary forces
        diff.mult(multFact);
        // then we add all of this to a new steering vector, which we can add to our location vector
        steer.add(diff);
      }
    }
    return steer;
  }
  // this function returns the current location of our particle
  PVec getLocation() {
    PVec tempLoc = newLoc;
    return tempLoc;
  }
  // this function tells us the distance between the location and a pvec
  float Dist(PVec v) {
    float dx = mLoc.x - v.x;
    float dy = mLoc.y - v.y;
    float dz = mLoc.z - v.z;
    return (float)Math.sqrt(dx * dx + dy * dy + dz * dz);
  }

  // this is lifted straight out of the pvector class.
  // it returns a new pvec object which represents the 
  // distance (direction and length) between two PVec objects
  PVec Sub(PVec v1, PVec v2, PVec target) {
    if (target == null) {
      target = new PVec(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
    } 
    else {
      target.set(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
    }
    return target;
  }
}



// all of this PVec code is taken from theh PVector class written by Daniel Shiffman
// I've merely pulled out the bits we need to have a working PVec class which will run in a web browser window
// It's a bit of a hack, but it's worth demonstrating the way we can interact with java classes
class PVec {
  float x;
  float y;
  float z;

  PVec(float x_, float y_, float z_) {
    x = x_;
    y = y_;
    z = z_;
  }
  void add(PVec v) {
    x += v.x;
    y += v.y;
    z += v.z;
  }
  void div(float n) {
    x /= n;
    y /= n;
    z /= n;
  }
  void mult(float n) {
    x *= n;
    y *= n;
    z *= n;
  }
  void set(float x_, float y_, float z_) {
    x = x_;
    y = y_;
    z = z_;
  }
}



</script></particles></script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jasonmcdermott.net/2010/08/particle-forces/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>push</title>
		<link>http://www.jasonmcdermott.net/2010/08/push/</link>
		<comments>http://www.jasonmcdermott.net/2010/08/push/#comments</comments>
		<pubDate>Fri, 20 Aug 2010 14:22:40 +0000</pubDate>
		<dc:creator>jasonmcdermott</dc:creator>
				<category><![CDATA[teaching]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[forces]]></category>
		<category><![CDATA[particle]]></category>
		<category><![CDATA[processing]]></category>
		<category><![CDATA[vector]]></category>

		<guid isPermaLink="false">http://www.jasonmcdermott.net/?p=1307</guid>
		<description><![CDATA[<img src="http://www.jasonmcdermott.net/blog/wp-content/uploads/media/screengrab-2010-08-21-00-34-24.tif" class="attachment-medium wp-post-image" alt="screengrab 2010-08-21 00-34-24" title="screengrab 2010-08-21 00-34-24" />This time round we&#8217;ll assert some basic forces on our particles. First of all we&#8217;ll add a repulsion force between all particles, pushing them away from each other. Secondly we&#8217;ll insert some boundaries for the particles to remain within, with the walls of the sketch  &#8230;]]></description>
			<content:encoded><![CDATA[<img src="http://www.jasonmcdermott.net/blog/wp-content/uploads/media/screengrab-2010-08-21-00-34-24.tif" class="attachment-medium wp-post-image" alt="screengrab 2010-08-21 00-34-24" title="screengrab 2010-08-21 00-34-24" /><p></p><br /><p>This time round we&#8217;ll assert some basic forces on our particles.  First of all we&#8217;ll add a repulsion force between all particles, pushing them away from each other.  Secondly we&#8217;ll insert some boundaries for the particles to remain within, with the walls of the sketch forming a boundary pressure keeping the particles constrained.</p>
<p><a href="http://dl.dropbox.com/u/3801794/particle_push.pde" onclick="javascript: pageTracker._trackPageview('/downloads/source'); ">Source Code</a></p>
<p><script type="application/processing">

int Resolution;
ParticleController pC;
PVec mousey;
int W;
int H;
boolean online;
float timed = 0;

void setup() {
  // this is one of the more useful pieces of code i've used to date
  // firstly we check if we're offline
  if (online == false) {
    // if so, we know we're in a processing window
    // so we set our height/width variables accordingly
    W = 800;
    H = 300;
  } 
  // if online is true, we know we're in a browser window
  // so we make the sketch smaller
  // this way I can sketch out the same sketch but with dynamic size properties
  else {
    W = 600;
    H = 200;
  }
  size(W,H);
  smooth();
  frameRate(30);
  // how closely packed our particles might be
  Resolution = 50;
  // our particle controller class object
  pC = new ParticleController();
  background(0);
}

void draw() {
  background(0);
  pC.update();  
  timed++;
  if (timed > 200) {
    exit();
  }
}

void mousePressed() {
  exit(); 
}

class ParticleController {
  ArrayList particles = new ArrayList();
  ArrayList boundaries = new ArrayList();
  int mXRes, mYRes;
  int counting = 0;

  ParticleController() {
    mousey = new PVec(random(0,W),random(0,H),0);
    mXRes = W/Resolution; 
    mYRes = H/Resolution;
    for( int y=mYRes; y>0; y-- ) {
      for( int x=mXRes; x>0; x-- ) {
        addParticle( x, y-1, Resolution,counting );
        counting++;
      }
    }
    float gridBounds = 10;

    for (int i=W;i> 0;i--) { 
      for (int j=H;j> 0;j--) {
        if (i == W && j % gridBounds ==0) {
          addBoundary(i,j,Resolution);
        } 
        else if (i == 1 && j % gridBounds ==0) {
          addBoundary(i,j,Resolution);
        } 
        else if (i % gridBounds ==0 && j ==1) {
          addBoundary(i,j,Resolution);
        } 
        else if (i % gridBounds ==0 && j ==H) {
          addBoundary(i,j,Resolution);
        }
      }
    }
  }

  void update() {
    for (int i=0;i<particles .size();i++) {
      Particle p = (Particle) particles.get(i);
      p.update(particles,boundaries);
      p.render(0);
    }
    //    for (int i=0;i<boundaries.size();i++) {
    //      Particle b = (Particle) boundaries.get(i);
    //      b.render(1);
    //    }
  }

  void addParticle(float x_, float y_, int Resolution_, int Num_) {
    float x = ( x_ + 0.5f ) * (float)Resolution_;
    float y = ( y_ + 0.5f ) * (float)Resolution_;
    float offSet = 50;
    //    particles.add(new Particle(new PVec(x,y,0),Num_));
    particles.add(new Particle(new PVec(random(offSet,W-offSet),random(offSet,H-offSet),0), Num_));
  }

  void addBoundary(float x_, float y_,int Resolution_) {
    boundaries.add(new Particle(new PVec(x_,y_,0),0));
  }
}




class Particle {
  PVec mLoc, newLoc;
  PVec mDirToCursor;
  PVec loc, vel, acc, steer, sepp, bounds;
  float time, sinOffset, distance, mDistanceToCursor,mRadius, desiredseparation;
  float distTicker = 50; 

  Particle(PVec loc_, int num_) {
    mLoc = loc_;
    mRadius = Resolution;
    newLoc = mLoc;
    loc = new PVec(0,0,0);
    vel = new PVec(0,0,0);
    acc = new PVec(0,0,0);
    steer = new PVec(0,0,0);
    sepp = new PVec(0,0,0);
    bounds = new PVec(0,0,0);
  }

  void update(ArrayList particles_, ArrayList boundaries_) {
    if (frameCount > 2) {
      sepp = separate(particles_,0.5,1);
      newLoc.add(sepp);
      bounds = separate(boundaries_,1,0);
      newLoc.add(bounds);
    }
    newLoc = mLoc;
  }

  void render (int mode) {
    noStroke();
    if (mode == 1) {
      fill(255,0,0);
      ellipse(newLoc.x,newLoc.y,Resolution*0.3,Resolution*0.3);
    } 
    else {
      fill(255);
      ellipse(newLoc.x,newLoc.y,Resolution*0.1,Resolution*0.1);
    }
  }

  PVec separate(ArrayList particles_, float multFact_, int drawMe_) {
    float drawMe = drawMe_;
    float multFact = multFact_;
    desiredseparation = 50;
    for (int i = 0 ; i < particles_.size()-1; i++) {
      Particle other = (Particle) particles_.get(i);
      PVec ot = other.getLocation();
      float p = Dist(ot);
      if ((p > 0) && (p < desiredseparation)) {
        if (drawMe == 1) {
          strokeWeight(desiredseparation/(p*4));
          stroke(255-p*4);
          fill(255);
          line(newLoc.x,newLoc.y,ot.x,ot.y);
        }
        PVec diff = Sub(newLoc,other.newLoc, null); 
        float diffMag = (float)sqrt(diff.x * diff.x + diff.y * diff.y + diff.z * diff.z);
        if ((diffMag != 0.0) && (diffMag != 1.0)) {
          diff.div(diffMag);
        }
        diff.div(p);
        diff.mult(multFact);
        steer.add(diff);
      }
    }
    return steer;
  }

  PVec getLocation() {
    PVec tempLoc = newLoc;
    return tempLoc;
  }

  float Dist(PVec v) {
    float dx = mLoc.x - v.x;
    float dy = mLoc.y - v.y;
    float dz = mLoc.z - v.z;
    return (float)Math.sqrt(dx * dx + dy * dy + dz * dz);
  }

  PVec Sub(PVec v1, PVec v2, PVec target) {
    if (target == null) {
      target = new PVec(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
    } 
    else {
      target.set(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
    }
    return target;
  }
}



// all of this PVec code is taken from theh PVector class written by Daniel Shiffman
// I've merely pulled out the bits we need to have a working PVec class which will run in a web browser window
// It's a bit of a hack, but it's worth demonstrating the way we can interact with java classes
class PVec {
  float x;
  float y;
  float z;

  PVec(float x_, float y_, float z_) {
    x = x_;
    y = y_;
    z = z_;
  }
  void add(PVec v) {
    x += v.x;
    y += v.y;
    z += v.z;
  }
  void div(float n) {
    x /= n;
    y /= n;
    z /= n;
  }
  void mult(float n) {
    x *= n;
    y *= n;
    z *= n;
  }
  void set(float x_, float y_, float z_) {
    x = x_;
    y = y_;
    z = z_;
  }
}


</script></particles></script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jasonmcdermott.net/2010/08/push/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>distance</title>
		<link>http://www.jasonmcdermott.net/2010/08/distance/</link>
		<comments>http://www.jasonmcdermott.net/2010/08/distance/#comments</comments>
		<pubDate>Fri, 20 Aug 2010 07:59:15 +0000</pubDate>
		<dc:creator>jasonmcdermott</dc:creator>
				<category><![CDATA[teaching]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[particle]]></category>
		<category><![CDATA[processing]]></category>
		<category><![CDATA[sketch]]></category>
		<category><![CDATA[vector]]></category>

		<guid isPermaLink="false">http://www.jasonmcdermott.net/?p=1280</guid>
		<description><![CDATA[<img src="http://www.jasonmcdermott.net/blog/wp-content/uploads/media/screengrab-2010-08-20-17-46-02.tif" class="attachment-medium wp-post-image" alt="screengrab 2010-08-20 17-46-02" title="screengrab 2010-08-20 17-46-02" />Now we&#8217;re going to begin doing more interesting things with our particles. Since we have a decent (yet small) PVec class to maintain details about location and motion, we&#8217;ll begin to map out interactions between particles. For this to work, we need to be able  &#8230;]]></description>
			<content:encoded><![CDATA[<img src="http://www.jasonmcdermott.net/blog/wp-content/uploads/media/screengrab-2010-08-20-17-46-02.tif" class="attachment-medium wp-post-image" alt="screengrab 2010-08-20 17-46-02" title="screengrab 2010-08-20 17-46-02" /><p></p><br /><p>Now we&#8217;re going to begin doing more interesting things with our particles.  Since we have a decent (yet small) PVec class to maintain details about location and motion, we&#8217;ll begin to map out interactions between particles.<br />
For this to work, we need to be able to pass the entire arraylist of particles to each particle, which we then use to compare a local particle with a remote particle, one by one each time we redraw.<br />
This first example will loop through all available particles, drawing lines between particles within a particular distance (in this case, ~100 pixels).</p>
<p><a href="http://dl.dropbox.com/u/3801794/particle_distance.pde" onclick="javascript: pageTracker._trackPageview('/downloads/source'); ">Source Code</a></p>
<p><script type="application/processing">

int Resolution;
ParticleController pC;
PVec mousey;
int W;
int H;
boolean online;

void setup() {
  // this is one of the more useful pieces of code i've used to date
  // firstly we check if we're offline
  if (online == false) {
    // if so, we know we're in a processing window
    // so we set our height/width variables accordingly
    W = 800;
    H = 300;
  } 
  // if online is true, we know we're in a browser window
  // so we make the sketch smaller
  // this way I can sketch out the same sketch but with dynamic size properties
  else {
    W = 600;
    H = 200;
  }
  size(W,H);
  smooth();
  frameRate(30);
  // how closely packed our particles might be
  Resolution = 35;
  // our particle controller class object
  pC = new ParticleController();
  background(0);
}

float timed = 0;
void draw() {
  background(0);
  // we don't do much in draw, merely call the particle controllers' update() function
  pC.update();
  timed++;
  if (timed > 150) {
    exit();
  }
}

class ParticleController {
  // an arraylist to hold all of our particles
  ArrayList particles = new ArrayList();
  // these variables were originally used to dictate the spacing of a grid
  // we're not really using them anymore, but we'll keep them for posterity
  // besides, we might later on want to reintroduce the grid
  int mXRes, mYRes;
  // this we'll use to give each particle a unique identifier
  int counting = 0;

  ParticleController() {
    // we'll assign a new random point to push away from.
    mousey = new PVec(random(0,W),random(0,H),0);
    // when we were putting the particles into a grid, this part made more sense
    // step through the grid resolution, assign a new particle for each x/y position on the grid
    for( int y=H/Resolution; y>0; y-- ) {
      for( int x=W/Resolution; x>0; x-- ) {
        // Resolution is also useful for determining size
        addParticle( x, y-1, Resolution, counting );
        // increment counting by 1 so we can uniquely identify each particle
        counting++;
      }
    }
  }

  void update() {
    // stock standard routine for looping through each particle and updating them.
    for (int i=0;i<particles .size();i++) {
      Particle p = (Particle) particles.get(i);
      // in this case we also pass through the entire particles arraylist to each particle
      // we use this method to then compare each particle to its neighbour
      p.update(particles);
    }
  }

  void addParticle(float x_, float y_, int Resolution_, int Num_) {
    particles.add(new Particle(new PVec(random(0,W),random(0,H),0), Num_));
  }
}



class Particle {
  // our position pvec objects, which hold the starting loc, our updated newloc and directionto cursor data
  // the direction to cursor really should be re-named, as it mainly points to a random point in space now
  PVec mLoc, newLoc;
  PVec mDirToCursor;
  // these are different pvec variables which we will use to store the
  // location, momentum and velocity values
  // these may well supersede the mLoc and newLoc variables, we'll see.
  PVec loc, vel, acc;
  // time is incrementally increased
  // sinOffset is the sin function variable
  // distance is a temporary distance variable, which scales our distance to cursor pvec
  // mRadius sets the radius of our circle
  // desired separation is the float to store our 'line drawing' separation length
  float time, sinOffset, distance, mDistanceToCursor,mRadius, desiredseparation;
  // these we'll temporarily use to draw lines between objects
  // the first will increase the distance allowed between objects
  // the first will control the direction of increase (so we could be increasing the ticker in a negative direction)
  // i.e. if the ticker is less than a certain upper limit, increase until it reaches that limit, then increase negagively
  float distTicker; 
  float direction = 0.5;

  Particle(PVec loc_, int num_) {
    // we'll start by giving the particle a home
    mLoc = loc_;
    // and a size
    mRadius = Resolution;
    // initiate the newlocation pvec
    newLoc = mLoc;
    loc = new PVec(0,0,0);
    vel = new PVec(0,0,0);
    acc = new PVec(0,0,0);
  }

  void update(ArrayList particles_) {
    // we'll wait for the 3rd frame to start calculating and drawing lines
    if (frameCount > 2) {
      // run the entire particles arraylist through the separation function
      separate(particles_);
    }

    //    //  at this point, these bits aren't even being used
    //    // Update velocity
    //    vel.add(acc);
    //    // Limit speed
    //    vel.limit(maxspeed);
    //    loc.add(vel);
    //    // Reset accelertion to 0 each cycle
    //    acc.mult(0);

    distTicker = distTicker + direction;
    if (distTicker > 150) {
      direction = 0;
    } 
    else if (distTicker < 0) {
      direction = 0.5;
    }
    newLoc = mLoc;
    render();
  }

  void render () {
    noStroke();
    ellipse(newLoc.x,newLoc.y,100/Resolution,100/Resolution);
  }

  //  boolean slowdown = true;
  //  float maxspeed = 10;
  //  float maxforce = 2;

  //  void seek(PVec target) {
  //    acc.add(steer(target,false));
  //  }
  //
  //  PVec steer(PVec target, boolean slowdown) {
  //    PVec steer;  // The steering vector
  //    PVec desired = Sub(target,mLoc,null);  // A vector pointing from the location to the target
  //    float d = desired.mag();
  //    if (d > 0) {
  //      // Normalize desired
  //      desired.normalize();
  //      // Two options for desired vector magnitude (1 -- based on distance, 2 -- maxspeed)
  //      if ((slowdown) && (d < 100.0f)) desired.mult(maxspeed*(d/100.0f)); // This damping is somewhat arbitrary
  //      else desired.mult(maxspeed);
  //      // Steering = Desired minus Velocity
  //      steer = Sub(desired,vel, null);
  //      steer.limit(maxforce);  // Limit to maximum steering force
  //    } 
  //    else {
  //      steer = new PVec(0,0,0);
  //    }
  //    return steer;
  //  }

  //  void attraction(ArrayList particles_) {
  //  }

  // here we have a neat little function which can tell us the 
  // distance between each particle object
  // and then act on it
  void separate(ArrayList particles_) {
    // we first set our upper limit
    desiredseparation = distTicker;
    // then for each particle
    for (int i = 0 ; i < particles_.size()-1; i++) {
      // get it, we'll call the temp particle 'other'
      Particle other = (Particle) particles_.get(i);
      // grab the location of the other particle
      PVec ot = other.getLocation();
      // let's see how far away it is from us
      float p = Dist(ot);
      // if it's further than 0 units away and less than 20 units away
      if ((p > 0) && (p < desiredseparation)) {
        // draw a line between this object and that one
        strokeWeight(0.2);
        stroke(255,255-p*2);
        fill(255-p*2,255-p*2);
        line(newLoc.x,newLoc.y,ot.x,ot.y);
      }
    }
  }
  // this function returns the current location of our particle
  PVec getLocation() {
    PVec tempLoc = newLoc;
    return tempLoc;
  }
  // this function tells us the distance between the location and a pvec
  float Dist(PVec v) {
    float dx = mLoc.x - v.x;
    float dy = mLoc.y - v.y;
    float dz = mLoc.z - v.z;
    return (float)Math.sqrt(dx * dx + dy * dy + dz * dz);
  }

  // this is lifted straight out of the pvector class.
  // it returns a new pvec object which represents the 
  // distance (direction and length) between two PVec objects
  PVec Sub(PVec v1, PVec v2, PVec target) {
    if (target == null) {
      target = new PVec(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
    } 
    else {
      target.set(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z);
    }
    return target;
  }
}




// all of this PVec code is taken from theh PVector class written by Daniel Shiffman
// I've merely pulled out the bits we need to have a working PVec class which will run in a web browser window
// It's a bit of a hack, but it's worth demonstrating the way we can interact with java classes
class PVec {
  float x;
  float y;
  float z;

  PVec(float x_, float y_, float z_) {
    x = x_;
    y = y_;
    z = z_;
  }
  void add(PVec v) {
    x += v.x;
    y += v.y;
    z += v.z;
  }
  void div(float n) {
    x /= n;
    y /= n;
    z /= n;
  }
  float mag() {
    return (float)sqrt(x * x + y * y + z * z);
  }
  void mult(float n) {
    x *= n;
    y *= n;
    z *= n;
  }
  void set(float x_, float y_, float z_) {
    x = x_;
    y = y_;
    z = z_;
  }
}
</script></particles></script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jasonmcdermott.net/2010/08/distance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>particle vectors</title>
		<link>http://www.jasonmcdermott.net/2010/08/particle-vectors/</link>
		<comments>http://www.jasonmcdermott.net/2010/08/particle-vectors/#comments</comments>
		<pubDate>Thu, 19 Aug 2010 13:02:17 +0000</pubDate>
		<dc:creator>jasonmcdermott</dc:creator>
				<category><![CDATA[teaching]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[particle]]></category>
		<category><![CDATA[processing]]></category>
		<category><![CDATA[sketch]]></category>
		<category><![CDATA[vector]]></category>

		<guid isPermaLink="false">http://www.jasonmcdermott.net/?p=1269</guid>
		<description><![CDATA[<img src="http://www.jasonmcdermott.net/blog/wp-content/uploads/media/screengrab-2010-08-19-23-03-57.tif" class="attachment-medium wp-post-image" alt="screengrab 2010-08-19 23-03-57" title="screengrab 2010-08-19 23-03-57" />Now that we have animated particles, moving on sin waves, we can test each one to see how far away it&#8217;s neighbours are. In this example, we&#8217;ll use the PVec class again to check the distance (by finding the square root of the squares of  &#8230;]]></description>
			<content:encoded><![CDATA[<img src="http://www.jasonmcdermott.net/blog/wp-content/uploads/media/screengrab-2010-08-19-23-03-57.tif" class="attachment-medium wp-post-image" alt="screengrab 2010-08-19 23-03-57" title="screengrab 2010-08-19 23-03-57" /><p></p><br /><p>Now that we have animated particles, moving on sin waves, we can test each one to see how far away it&#8217;s neighbours are.  In this example, we&#8217;ll use the PVec class again to check the distance (by finding the square root of the squares of each distance direction, x-y-z).  Once we know the distance between two particles, we can use that to check if two are between an upper distance limit &#8211; if so, we&#8217;ll draw a line between them.</p>
<p><a href="http://dl.dropbox.com/u/3801794/particle_vectors.pde" onClick="javascript: pageTracker._trackPageview('/downloads/source'); ">Source Code</a></p>
<p><script type="application/processing">

int Resolution;
ParticleController pC;
PVec mousey;
int W;
int H;
boolean online;

void setup() {
  if (online == false) {
    W = 800;
    H = 300;
  } 
  else {
    W = 600;
    H = 200;
  }
  size(W,H);
  smooth();
  frameRate(30);
  Resolution = 40;
  pC = new ParticleController();
  background(0);
}

void draw() {
  background(0);
  pC.update();
}

class ParticleController {
  ArrayList particles = new ArrayList();
  int mXRes, mYRes;
  int counting;

  ParticleController() {
    mXRes = W/Resolution; 
    mYRes = H/Resolution;
    mousey = new PVec(random(0,W),random(0,H),0);
    counting = 0;
    for( int y=mYRes; y>0; y-- ) {
      for( int x=mXRes; x>0; x-- ) {
        addParticle( x, y-1, Resolution, counting );
        counting++;
      }
    }
  }

  void update() {
    for (int i=0;i<particles .size();i++) {
      Particle p = (Particle) particles.get(i);
      p.update(particles);
    }
  }

  void addParticle(float x_, float y_, int Resolution_, int Num_) {
    particles.add(new Particle(new PVec(random(0,W),random(0,H),0), Num_));
  }
}

class Particle {
  PVec mLoc, newLoc, mDirToCursor;
  float time, sinOffset, distance, mDistanceToCursor,mRadius, desiredseparation;
  ArrayList connections = new ArrayList();
  int Number;

  Particle(PVec loc_, int num_) {
    mLoc = loc_;
    mRadius = Resolution;
    newLoc = new PVec(0,0,0);
    Number = num_;
  }
  void update(ArrayList particles_) {
    if (frameCount > 2) {
      separate(particles_);
    }
    
    float dx = mLoc.x - mousey.x;
    float dy = mLoc.x - mousey.y;
    float dz = mLoc.z - mousey.z;
    mDistanceToCursor = (float)Math.sqrt(dx * dx + dy * dy + dz * dz);
    mDirToCursor = new PVec(mLoc.x - mousey.x, mLoc.y - mousey.y, mLoc.z - mousey.z);
    float m = (float)Math.sqrt(mDirToCursor.x * mDirToCursor.x + mDirToCursor.y * mDirToCursor.y + mDirToCursor.z * mDirToCursor.z);

    if ((m != 0.0) && (m != 1.0)) {
      mDirToCursor.x = mDirToCursor.x / m;
      mDirToCursor.y = mDirToCursor.y / m;
      mDirToCursor.z = mDirToCursor.z / m;
    }
    time += 10;
    distance = mDistanceToCursor * 0.025;
    sinOffset = (sin(distance-(time/100))+1); 
    mDirToCursor.x = mDirToCursor.x * (sinOffset * 20);
    mDirToCursor.y = mDirToCursor.y * (sinOffset * 20);
    mDirToCursor.z = mDirToCursor.z * (sinOffset * 20);

    newLoc = new PVec(mLoc.x + mDirToCursor.x, mLoc.y + mDirToCursor.y, mLoc.z + mDirToCursor.z);
    render();
  }

  PVec getLocation() {
    PVec tempLoc = newLoc;
    return tempLoc;
  }

  void render () {
    fill(255);
    noStroke();
    ellipse(newLoc.x,newLoc.y,100/Resolution,100/Resolution);
  }


  void separate(ArrayList particles_) {
    desiredseparation = 20;
    for (int i = 0 ; i < particles_.size()-1; i++) {
      Particle other = (Particle) particles_.get(i);
      PVec ot = other.getLocation();

      float px = ot.x - mLoc.x;
      float py = ot.y - mLoc.y;
      float pz = 0;
      float p = (float)Math.sqrt(px * px + py * py + pz * pz);

      if ((p > 0) && (p < desiredseparation)) {
        strokeWeight(0.2);
        stroke(255);
        line(newLoc.x,newLoc.y,ot.x,ot.y);
      }
    }
  }
}

class PVec {
  float x;
  float y;
  float z;

  PVec(float x_, float y_, float z_) {
    x = x_;
    y = y_;
    z = z_;
  }
}


</script></particles></script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jasonmcdermott.net/2010/08/particle-vectors/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>particle patterns</title>
		<link>http://www.jasonmcdermott.net/2010/08/particle-patterns/</link>
		<comments>http://www.jasonmcdermott.net/2010/08/particle-patterns/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 12:39:02 +0000</pubDate>
		<dc:creator>jasonmcdermott</dc:creator>
				<category><![CDATA[teaching]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[particles]]></category>
		<category><![CDATA[processing]]></category>
		<category><![CDATA[PVec]]></category>
		<category><![CDATA[sketch]]></category>

		<guid isPermaLink="false">http://www.jasonmcdermott.net/?p=1192</guid>
		<description><![CDATA[<img src="http://www.jasonmcdermott.net/blog/wp-content/uploads/media/screengrab-2010-08-17-23-44-17.tif" class="attachment-medium wp-post-image" alt="screengrab 2010-08-17 23-44-17" title="screengrab 2010-08-17 23-44-17" />We&#8217;ll be using our little PVec class to form the basis of some more interesting animated interactions between particles. In this case, all we&#8217;re doing is moving particles based on a grid relationship, but already we can see some &#8216;macro&#8217; behaviours popping up through the  &#8230;]]></description>
			<content:encoded><![CDATA[<img src="http://www.jasonmcdermott.net/blog/wp-content/uploads/media/screengrab-2010-08-17-23-44-17.tif" class="attachment-medium wp-post-image" alt="screengrab 2010-08-17 23-44-17" title="screengrab 2010-08-17 23-44-17" /><p></p><br /><p>We&#8217;ll be using our little PVec class to form the basis of some more interesting animated interactions between particles. In this case, all we&#8217;re doing is moving particles based on a grid relationship, but already we can see some &#8216;macro&#8217; behaviours popping up through the iteration of localised calculations.</p>
<p><a href="http://dl.dropbox.com/u/3801794/particle_patterns.pde" onclick="javascript: pageTracker._trackPageview('/downloads/source'); ">Source Code</a></p>
<p><script type="application/processing">

int Resolution;
ParticleController pC;
PVec mousey;

void setup() {
  size(595,200); 
  smooth();
  frameRate(30);
  Resolution = 20;
  pC = new ParticleController();
}

void draw() {
  background(0);
  pC.update();
}

class ParticleController {
  ArrayList particles = new ArrayList();
  int mXRes, mYRes;

  ParticleController() {
    mXRes = 595/Resolution; 
    mYRes = 200/Resolution;
    for( int y=mYRes; y>0; y-- ) {
      for( int x=mXRes; x>0; x-- ) {
        addParticle( x, y, Resolution );
      }
    }
  }

  void update() {
    mousey = new PVec(595,200,0);
    for (int i=0;i<particles .size();i++) {
      Particle p = (Particle) particles.get(i);
      p.update();
    }
  }

  void addParticle(int x_, int y_, int Resolution_) {
    float x = ( x_ + 0.5f ) * (float)Resolution_;
    float y = ( y_ + 0.5f ) * (float)Resolution_;
    particles.add(new Particle(new PVec(x, y,0)));
  }
}

class Particle {
  PVec mLoc, newLoc, mDirToCursor;
  float time, sinOffset, distance, mDistanceToCursor,mRadius;

  Particle(PVec loc_) {
    mLoc = loc_;
    mRadius = Resolution;
  }
  void update() {
    float dx = mLoc.x - mousey.x;
    float dy = mLoc.x - mousey.y;
    float dz = 0;
    mDistanceToCursor = (float)Math.sqrt(dx * dx + dy * dy + dz * dz);
    mDirToCursor = new PVec(mLoc.x - mousey.x, mLoc.y - mousey.y, mLoc.z - mousey.z);
    float m = (float)Math.sqrt(mDirToCursor.x * mDirToCursor.x + mDirToCursor.y * mDirToCursor.y + mDirToCursor.z * mDirToCursor.z);
    
    if ((m != 0.0) && (m != 1.0)) {
      mDirToCursor.x = mDirToCursor.x / m;
      mDirToCursor.y = mDirToCursor.y / m;
      mDirToCursor.z = mDirToCursor.z / m;
    }
    time += 10;
    distance = mDistanceToCursor * 0.025;
    sinOffset = (sin(distance-(time/100))+1); 
    mDirToCursor.x = mDirToCursor.x * (sinOffset * 10);
    mDirToCursor.y = mDirToCursor.y * (sinOffset * 10);
    mDirToCursor.z = mDirToCursor.z * (sinOffset * 10);
    
    newLoc = new PVec(mLoc.x + mDirToCursor.x, mLoc.y + mDirToCursor.y, mLoc.z + mDirToCursor.z);

    
    
    render();
  }

  void render () {
    fill(255);
    noStroke();
    ellipse(newLoc.x,newLoc.y,100/Resolution,100/Resolution);
  }
}



class PVec {
  float x;
  float y;
  float z;

  PVec(float x_, float y_, float z_) {
    x = x_;
    y = y_;
    z = z_;
  }
}






</script></particles></script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jasonmcdermott.net/2010/08/particle-patterns/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sin and Cos</title>
		<link>http://www.jasonmcdermott.net/2010/08/sin-and-cos/</link>
		<comments>http://www.jasonmcdermott.net/2010/08/sin-and-cos/#comments</comments>
		<pubDate>Mon, 16 Aug 2010 14:48:22 +0000</pubDate>
		<dc:creator>jasonmcdermott</dc:creator>
				<category><![CDATA[teaching]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[cos]]></category>
		<category><![CDATA[processing]]></category>
		<category><![CDATA[PVec]]></category>
		<category><![CDATA[sin]]></category>
		<category><![CDATA[sketch]]></category>

		<guid isPermaLink="false">http://www.jasonmcdermott.net/?p=1183</guid>
		<description><![CDATA[<img src="http://www.jasonmcdermott.net/blog/wp-content/uploads/media/screengrab-2010-08-17-23-58-55.tif" class="attachment-medium wp-post-image" alt="screengrab 2010-08-17 23-58-55" title="screengrab 2010-08-17 23-58-55" />Sin and waves can be used to create simple and visually interesting patterns. This example uses the sin function to create a two dimensional pattern, with the sin value adjusting the radius of each circle. Source Code ArrayList balls = new ArrayList(); int mode =  &#8230;]]></description>
			<content:encoded><![CDATA[<img src="http://www.jasonmcdermott.net/blog/wp-content/uploads/media/screengrab-2010-08-17-23-58-55.tif" class="attachment-medium wp-post-image" alt="screengrab 2010-08-17 23-58-55" title="screengrab 2010-08-17 23-58-55" /><p></p><br /><p>Sin and waves can be used to create simple and visually interesting patterns.  This example uses the sin function to create a two dimensional pattern, with the sin value adjusting the radius of each circle.</p>
<p><a href="http://dl.dropbox.com/u/3801794/sin_and_cos.pde" onclick="javascript: pageTracker._trackPageview('/downloads/source'); ">Source Code</a></p>
<p><script type="application/processing">

ArrayList balls = new ArrayList();
int mode = 2;
int W;
int H;
boolean online;

void setup() {
  if (online == false) {
    W = 800;
    H = 300;
  } 
  else {
    W = 600;
    H = 200;
  }
  size(W,H);
  smooth();
  frameRate(30);
  for (int i=0;i< W /10;i++) {
    for (int j=0;j<H/10;j++) {
      balls.add(new Ball(5+i*10,5+j*10, sin(i), sin(j)));
    }
  }
}

void draw() {
  background(0);
  for (int i=0;i<balls.size();i++) {
    Ball bb = (Ball) balls.get(i);
    bb.update();
  }
}

class Ball {
  PVec loc;
  float sinX;
  float sinY;
  float x;
  float radius;

  Ball(float x_, float y_, float sinX_, float sinY_) {
    loc = new PVec(x_,y_,0);
    sinX = sinX_;
    sinY = sinY_;
  }

  void update() {
    render();
  }

  void render() {
    x+= 0.1;
    noStroke();
    if (mode == 1) {
      radius = 8 * sin(x*sinY*sinX);
    } 
    else if (mode == 2) {
      radius = 8 * sin(x+sinY+sinX);
    }
    fill(255);
    ellipse(loc.x,loc.y,radius, radius);
  }
}

class PVec
{
  float x;
  float y;
  float z;

  PVec(float x_, float y_, float z_)
  {
    x = x_;
    y = y_;
    z = z_;
  }
}
</script></script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jasonmcdermott.net/2010/08/sin-and-cos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>exploring pvec</title>
		<link>http://www.jasonmcdermott.net/2010/08/exploring-pvec/</link>
		<comments>http://www.jasonmcdermott.net/2010/08/exploring-pvec/#comments</comments>
		<pubDate>Sun, 15 Aug 2010 16:14:08 +0000</pubDate>
		<dc:creator>jasonmcdermott</dc:creator>
				<category><![CDATA[teaching]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[processing]]></category>
		<category><![CDATA[PVec]]></category>
		<category><![CDATA[sketch]]></category>

		<guid isPermaLink="false">http://www.jasonmcdermott.net/?p=1174</guid>
		<description><![CDATA[<img src="http://www.jasonmcdermott.net/blog/wp-content/uploads/media/screengrab-2010-08-18-00-31-30.tif" class="attachment-medium wp-post-image" alt="screengrab 2010-08-18 00-31-30" title="screengrab 2010-08-18 00-31-30" />Might as well use our little PVec class to do something interesting, wouldn&#8217;t you say? Source Code PVec mouse; ArrayList balls = new ArrayList(); int ticker; int W; int w; int H; boolean online; float r; float theta; float theta_vel; float theta_acc; float dir; void  &#8230;]]></description>
			<content:encoded><![CDATA[<img src="http://www.jasonmcdermott.net/blog/wp-content/uploads/media/screengrab-2010-08-18-00-31-30.tif" class="attachment-medium wp-post-image" alt="screengrab 2010-08-18 00-31-30" title="screengrab 2010-08-18 00-31-30" /><p></p><br /><p>Might as well use our little PVec class to do something interesting, wouldn&#8217;t you say?</p>
<p><a href='http://dl.dropbox.com/u/3801794/exploring_pvec.pde' onclick="javascript: pageTracker._trackPageview('/downloads/source'); ">Source Code</a></p>
<p><script type="application/processing">


PVec mouse;
ArrayList balls = new ArrayList();
int ticker;

int W;
int w;
int H;
boolean online;

float r;
float theta;
float theta_vel;
float theta_acc;
float dir;

void setup() {
  if (online == false) {
    W = 800;
    w = 800;
    H = 300;
  } 
  else {
    W = 600;
    w = 600;
    H = 300;
  }
  size(W,H);
  smooth();
  frameRate(30);


  r = 50;
  theta = 0;
  theta_vel = 0;
  theta_acc = 0.0005;
  dir = 0.01;
  mouse = new PVec(random(0,420),random(0,300),0);
  for (int i=0;i< W /10;i++) {
    for (int j=0;j<H/10;j++) {
      balls.add(new Ball(5+i*10,5+j*10));
    }
  }
}

void draw() {
  background(0);
  pushMatrix();
  translate(210,150);
  float x = r * cos(theta);
  float y = r * sin(theta);
  mouse = new PVec(210+x,150+y,0);
  if (theta_vel < 0.3) {
    theta_vel += theta_acc;
    theta += theta_vel;
  }
  popMatrix();
  for (int i=0;i<balls.size();i++) {
    Ball bb = (Ball) balls.get(i);
    bb.update();
  }
}

class Ball {
  PVec loc;
  float temp;

  Ball(float x_, float y_) {
    loc = new PVec(x_,y_,0);
  }

  void update() {
    temp = loc.dist(mouse);
    render();
  }

  void render() {
    temp = map(temp,0,100,150,50);
    noStroke();
    fill(255,temp);
    ellipse(loc.x,loc.y,temp/25,temp/25);
  }
}

class PVec
{
  float x;
  float y;
  float z;

  PVec(float x_, float y_, float z_)
  {
    x = x_;
    y = y_;
    z = z_;
  }

  float dist(PVec v)
  {
    float dx = x - v.x;
    float dy = y - v.y;
    float dz = z - v.z;
    return (float)Math.sqrt(dx * dx + dy * dy + dz * dz);
  }
}


</script><br />
</script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.jasonmcdermott.net/2010/08/exploring-pvec/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
