Skip to content

Instantly share code, notes, and snippets.

@Craigson
Created February 6, 2015 23:39
Show Gist options
  • Select an option

  • Save Craigson/044fa2ac88ab65286213 to your computer and use it in GitHub Desktop.

Select an option

Save Craigson/044fa2ac88ab65286213 to your computer and use it in GitHub Desktop.
Multiple particles that experience a drag force when passing through "patches" with a higher density than the surrounding environment
Mover [] movers;
Patch [] patches;
float count = 0;
void setup() {
size(1200, 675);
movers = new Mover[150]; //create an array of movers
patches = new Patch[10]; //create an array of friction patches
for (int i = 0; i < movers.length; i++) {
movers[i] = new Mover();
}
for (int j = 0; j < patches.length; j++) {
patches[j] = new Patch();
}
}
void draw() {
background(255);
for (int i = 0; i < patches.length; i++) {
patches[i].display();
}
//loop through both arrays to check distance between
//each mover and each patch
for (int j = 0; j < movers.length; j++) {
for (int k = 0; k < patches.length; k++) {
if (patches[k].isInside(movers[j]) == true) {
movers[j].applyForce(patches[k].calcDrag(movers[j]));
movers[j].k = color(100, 200, 100);
//println(frameCount + " " + j + " " + "i'm inside");
//println();
} else {
// movers[j].k = color(0);
movers[j].applyForce(movers[j].initForce);
//println(frameCount + " " + j + " " + "Im outside");
}
}
movers[j].update();
movers[j].checkEdges();
movers[j].display();
}
println(frameRate);
}
class Mover {
PVector loc, vel, acc, initForce;
float mass;
float rad;
color k;
Mover() {
loc = new PVector(width/2,height/2);
vel = new PVector(0, 0);
mass = random (0.1,0.5); //randomly assign mass to the mover
acc = new PVector(0,0);
rad = mass*20; //make the radius size a function of the mass
k = color (0);
initForce = new PVector(random(-0.002,0.002),random(-0.002,0.002)); //assign an initial
//force that get's applied as the acceleration. This will be applied whenever
//the mover is outside of the patch
}
void update() {
vel.add(acc);
loc.add(vel);
acc.mult(0);
vel.limit(2); //limit the velocity of the mover
}
void applyForce(PVector force) {
//creace a copy of the original force and divide it by the mover's mass,
//this means any acceleration applied will be influenced by the mass of the object
PVector f = PVector.div(force, mass);
acc.add(f);
}
void display() {
fill(k);
ellipse(loc.x,loc.y,rad*2,rad*2);
k = 0;
}
//if the mover reaches the edge of the screen it reappears on the opposite side
void checkEdges(){
if (loc.x < 0){
loc.x += width;
} else if (loc.x > width){
loc.x -= width;
}
if (loc.y < 0){
loc.y += height;
} else if (loc.y > height){
loc.y -= height;
}
}
}
class Patch{
float rad;
PVector loc; //PVector to store the objects location
float c; //co-efficient of drag
Patch(){
rad = random(10,75); //assign a random radius
loc = new PVector(random(width),random(height)); //draw the patch in a random location
c = random(0.01,0.05); //initialise it to a random value
}
//pass patch p into the function
PVector calcDrag(Mover m){
float speed = m.vel.mag(); //speed is the scalar value of the mover's velocity
float dragMag = c*speed*speed; //the magnitude of the drag force is equivalent to the patch's
//coefficient of friction multiplied by the square of the movers speed
PVector drag = m.vel.get(); //get a copy of the movers direction
drag.normalize(); //normalize to get the unit vector
drag.mult(-1); //reverse the direction
drag.mult(dragMag); //multiply the unit vector by the magnitude of the force
return drag; //apply the new drag force to 'this' mover
}
boolean isInside(Mover m){
//basic distance check to see if the mover is inside the patch
PVector l = m.loc;
float d = dist(loc.x,loc.y,l.x,l.y);
if (d < rad + m.rad){
return true;
} else {
return false;
}
}
void display(){
fill(0,20);
noStroke();
ellipse(loc.x,loc.y,rad*2,rad*2);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment