Skip to content

Instantly share code, notes, and snippets.

@wonderburg7
Created January 21, 2019 22:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wonderburg7/a300ff61649b193ed6c22f1a27de7cd7 to your computer and use it in GitHub Desktop.
Save wonderburg7/a300ff61649b193ed6c22f1a27de7cd7 to your computer and use it in GitHub Desktop.
FlowField flowfield;
ArrayList<Particle> particles;
int lineSize = 2;
int noOfParticles = 1000;
float rateOfGridChangeOverTime = 0.0004;
int minSpeed = 1;
int maxSpeed = 3;
int lineAlpha = 10;
float gridVectorDiff = 0.1;
boolean gridChangesOverTime = false;
boolean showVertices = false;
boolean startAtCentre = false;
boolean giveParticlesALifespan = true;
boolean debug = false;
void setup() {
size(1200, 800);
flowfield = new FlowField(10);
flowfield.update();
particles = new ArrayList<Particle>();
for (int i = 0; i < noOfParticles; i++) {
// PVector start = new PVector(random(width), random(height)); // gives particles a random location
if (startAtCentre == true){
PVector start = new PVector(width/2, height/2);
particles.add(new Particle(start, random(minSpeed, maxSpeed)));
} else {
PVector start = new PVector(random(width), random(height));
particles.add(new Particle(start, random(minSpeed, maxSpeed)));
}
}
background(255);
}
void draw() {
flowfield.update();
if (debug) flowfield.display();
for (Particle p : particles) {
p.follow(flowfield);
p.run();
}
}
// array which stores the grid vectors
public class FlowField {
PVector[] vectors;
int cols, rows;
float inc = gridVectorDiff;
float zoff = 0;
int scl;
FlowField(int res) {
scl = res;
cols = floor(width / res) + 1;
rows = floor(height / res) + 1;
vectors = new PVector[cols * rows];
}
void update() {
float xoff = 0;
for (int y = 0; y < rows; y++) {
float yoff = 0;
for (int x = 0; x < cols; x++) {
float angle = noise(xoff, yoff, zoff) * TWO_PI * 2;
PVector v = PVector.fromAngle(angle);
v.setMag(0.5);
int index = x + y * cols;
vectors[index] = v;
if (showVertices == true){
pushMatrix();
translate(x * scl, y*scl);
rotate(v.heading());
line(0,0,scl,0);
popMatrix();
}
xoff += inc;
}
yoff += inc;
}
if (gridChangesOverTime == true) {
zoff += rateOfGridChangeOverTime;
}
}
void display() {
for (int y = 0; y < rows; y++) {
for (int x = 0; x < cols; x++) {
int index = x + y * cols;
PVector v = vectors[index];
stroke(0, 0, 0, 40);
strokeWeight(0.1);
pushMatrix();
translate(x * scl, y * scl);
rotate(v.heading());
line(0, 0, scl, 0);
popMatrix();
}
}
}
}
public class Particle {
PVector pos;
PVector vel;
PVector acc;
PVector previousPos;
float maxSpeed;
float lifeSpan = 500;
Particle(PVector start, float maxspeed) {
maxSpeed = maxspeed;
pos = start;
//vel = new PVector(random(10), random(10));//gives particles random velocity to start
vel = new PVector(0, 0);
acc = new PVector(0, 0);
previousPos = pos.copy();
}
void run() {
update();
edges();
show();
if(isDead()){ //if the particles dead it does something
// background(0);
}
}
void update() {
pos.add(vel);
vel.limit(maxSpeed);
vel.add(acc);
acc.mult(0);
lifeSpan -=2;
}
boolean isDead(){
if (lifeSpan <= 0){
return true;
} else {
return false;
}
}
// applies the grid vector to the particles as a 'force'
void applyForce(PVector force) {
acc.add(force);
}
//what we see on the screen
void show() {
stroke(0, 0, 0, lifeSpan);
/* int coin = int(random(1, 3));
if (coin == 1) {
stroke(0, 0, 0, lineAlpha);
} else if (coin == 2) {
stroke(40, 40, 40, lineAlpha);
} else if (coin == 3) {
stroke(100, 100, 100, lineAlpha);
}*/
strokeWeight(lineSize);
line(pos.x, pos.y, previousPos.x, previousPos.y);
//point(pos.x, pos.y);
updatePreviousPos();
}
//makes particles move to other side when it meets an edge
void edges() {
if (pos.x > width) {
pos.x = 0;
updatePreviousPos();
}
if (pos.x < 0) {
pos.x = width;
updatePreviousPos();
}
if (pos.y > height) {
pos.y = 0;
updatePreviousPos();
}
if (pos.y < 0) {
pos.y = height;
updatePreviousPos();
}
}
void updatePreviousPos() {
this.previousPos.x = pos.x;
this.previousPos.y = pos.y;
}
void follow(FlowField flowfield) {
int x = floor(pos.x / flowfield.scl);
int y = floor(pos.y / flowfield.scl);
int index = x + y * flowfield.cols;
PVector force = flowfield.vectors[index];
applyForce(force);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment