color black = color(0, 0, 0);
color brown = color(39, 23, 16);
ps = new ParticleSystem();
noiseSeed((int)random(10000));
if (key == 'p' || key == 'P') pause = !pause;
if (key == 's' || key =='S') saveFrame("smoke-###.png");
void bg(color c1, color c2)
for (int i = 0; i < height; i++)
float j = map(i, 0, height, 0, 1);
stroke(lerpColor(c1,c2,j));
rows = height/resolution;
field = new PVector[cols][rows];
for (int i = 0; i < cols; i++)
for (int j = 0; j < rows; j++)
float theta = noise(xoff, yoff, t);
theta = map(theta, 0, 1, 0, TWO_PI);
field[i][j] = new PVector(cos(theta), sin(theta));
PVector lookup(PVector lookup)
int column = int(lookup.x / resolution);
column = constrain(column, 0, cols - 1);
int row = int(lookup.y / resolution);
row = constrain(row, 0, rows - 1);
return field[column][row].get();
velocity = new PVector(0, 0);
acceleration = new PVector(0, 0);
if (location.x < 0) { location.x = width; }
else if (location.x > width) { location.x = 0; }
if (location.y < 0) { location.y = height; }
else if (location.y > height) { location.y = 0; }
void follow(FlowField flow)
PVector desired = flow.lookup(location);
PVector steer = PVector.sub(desired, velocity);
void applyForce(PVector force)
velocity.add(acceleration);
velocity.limit(maxSpeed);
stroke(chooseColor(), 10);
point(location.x, location.y);
color orange = color(255, 246, 237);
color white = color(255, 255, 255);
color blue = color(163, 229, 253);
int choice = frameCount % 400;
int amt = (frameCount % 100) / 100;
if (choice < 100) { c = lerpColor(orange, white, amt); }
else if (choice < 200) { c = lerpColor(white, blue, amt); }
else if (choice < 300) { c = lerpColor(blue, white, amt); }
else { c = lerpColor(white, orange, amt); }
ArrayList <Particle> particles;
particles = new ArrayList <Particle> ();
for (int i = 0; i < 100; i++)
PVector l = new PVector(random(width), random(height));
particles.add(new Particle(l));
for (int i = 99; i >= 0; i--) { particles.remove(i); }
for (Particle p : particles)