Here we’ll see some chaotic interaction happening between our particles – 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 Codeint 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 offlineif (online == false) {// if so, we know we’re in a processing window// so we set our height/width variables accordinglyW = 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 propertieselse {W = 600;H = 200;}size(W,H);smooth();frameRate(30);// how closely packed our particles might beResolution = 20;// our particle controller class objectpC = 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 particlesArrayList 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 gridint mXRes, mYRes;// this we’ll use to give each particle a unique identifierint 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 randomlyif (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 windowfor (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 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 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 itPVec 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 particlefor (int i = 0 ; i 0) && (p < desiredseparation)) {// draw a line between this object and that one// but only between our particles, not between the particles and the boundariesif (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 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 particlePVec getLocation() {PVec tempLoc = newLoc;return tempLoc;}// this function tells us the distance between the location and a pvecfloat 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 objectsPVec 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 classesclass 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;}}