Re-adding Topics to SVN

This commit is contained in:
Casey Reas
2011-09-05 23:58:47 +00:00
parent 4fc6dcca86
commit 391c79c2b6
219 changed files with 31093 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
/**
* Chain.
*
* One mass is attached to the mouse position and the other
* is attached the position of the other mass. The gravity
* in the environment pulls down on both.
*/
Spring2D s1, s2;
float gravity = 6.0;
float mass = 2.0;
void setup()
{
size(200, 200);
smooth();
fill(0);
// Inputs: x, y, mass, gravity
s1 = new Spring2D(0.0, width/2, mass, gravity);
s2 = new Spring2D(0.0, width/2, mass, gravity);
}
void draw()
{
background(204);
s1.update(mouseX, mouseY);
s1.display(mouseX, mouseY);
s2.update(s1.x, s1.y);
s2.display(s1.x, s1.y);
}
class Spring2D {
float vx, vy; // The x- and y-axis velocities
float x, y; // The x- and y-coordinates
float gravity;
float mass;
float radius = 20;
float stiffness = 0.2;
float damping = 0.7;
Spring2D(float xpos, float ypos, float m, float g) {
x = xpos;
y = ypos;
mass = m;
gravity = g;
}
void update(float targetX, float targetY) {
float forceX = (targetX - x) * stiffness;
float ax = forceX / mass;
vx = damping * (vx + ax);
x += vx;
float forceY = (targetY - y) * stiffness;
forceY += gravity;
float ay = forceY / mass;
vy = damping * (vy + ay);
y += vy;
}
void display(float nx, float ny) {
noStroke();
ellipse(x, y, radius*2, radius*2);
stroke(255);
line(x, y, nx, ny);
}
}

View File

@@ -0,0 +1,196 @@
// The Boid class
class Boid {
PVector loc;
PVector vel;
PVector acc;
float r;
float maxforce; // Maximum steering force
float maxspeed; // Maximum speed
Boid(PVector l, float ms, float mf) {
acc = new PVector(0,0);
vel = new PVector(random(-1,1),random(-1,1));
loc = l.get();
r = 2.0;
maxspeed = ms;
maxforce = mf;
}
void run(ArrayList boids) {
flock(boids);
update();
borders();
render();
}
// We accumulate a new acceleration each time based on three rules
void flock(ArrayList boids) {
PVector sep = separate(boids); // Separation
PVector ali = align(boids); // Alignment
PVector coh = cohesion(boids); // Cohesion
// Arbitrarily weight these forces
sep.mult(1.5);
ali.mult(1.0);
coh.mult(1.0);
// Add the force vectors to acceleration
acc.add(sep);
acc.add(ali);
acc.add(coh);
}
// Method to update location
void update() {
// Update velocity
vel.add(acc);
// Limit speed
vel.limit(maxspeed);
loc.add(vel);
// Reset accelertion to 0 each cycle
acc.mult(0);
}
void seek(PVector target) {
acc.add(steer(target,false));
}
void arrive(PVector target) {
acc.add(steer(target,true));
}
// A method that calculates a steering vector towards a target
// Takes a second argument, if true, it slows down as it approaches the target
PVector steer(PVector target, boolean slowdown) {
PVector steer; // The steering vector
PVector desired = target.sub(target,loc); // A vector pointing from the location to the target
float d = desired.mag(); // Distance from the target is the magnitude of the vector
// If the distance is greater than 0, calc steering (otherwise return zero vector)
if (d > 0) {
// Normalize desired
desired.normalize();
// Two options for desired vector magnitude (1 -- based on distance, 2 -- maxspeed)
if ((slowdown) && (d < 100.0)) desired.mult(maxspeed*(d/100.0)); // This damping is somewhat arbitrary
else desired.mult(maxspeed);
// Steering = Desired minus Velocity
steer = target.sub(desired,vel);
steer.limit(maxforce); // Limit to maximum steering force
}
else {
steer = new PVector(0,0);
}
return steer;
}
void render() {
// Draw a triangle rotated in the direction of velocity
float theta = vel.heading2D() + PI/2;
fill(200,100);
stroke(255);
pushMatrix();
translate(loc.x,loc.y);
rotate(theta);
beginShape(TRIANGLES);
vertex(0, -r*2);
vertex(-r, r*2);
vertex(r, r*2);
endShape();
popMatrix();
}
// Wraparound
void borders() {
if (loc.x < -r) loc.x = width+r;
if (loc.y < -r) loc.y = height+r;
if (loc.x > width+r) loc.x = -r;
if (loc.y > height+r) loc.y = -r;
}
// Separation
// Method checks for nearby boids and steers away
PVector separate (ArrayList boids) {
float desiredseparation = 20.0;
PVector steer = new PVector(0,0,0);
int count = 0;
// For every boid in the system, check if it's too close
for (int i = 0 ; i < boids.size(); i++) {
Boid other = (Boid) boids.get(i);
float d = PVector.dist(loc,other.loc);
// If the distance is greater than 0 and less than an arbitrary amount (0 when you are yourself)
if ((d > 0) && (d < desiredseparation)) {
// Calculate vector pointing away from neighbor
PVector diff = PVector.sub(loc,other.loc);
diff.normalize();
diff.div(d); // Weight by distance
steer.add(diff);
count++; // Keep track of how many
}
}
// Average -- divide by how many
if (count > 0) {
steer.div((float)count);
}
// As long as the vector is greater than 0
if (steer.mag() > 0) {
// Implement Reynolds: Steering = Desired - Velocity
steer.normalize();
steer.mult(maxspeed);
steer.sub(vel);
steer.limit(maxforce);
}
return steer;
}
// Alignment
// For every nearby boid in the system, calculate the average velocity
PVector align (ArrayList boids) {
float neighbordist = 25.0;
PVector steer = new PVector(0,0,0);
int count = 0;
for (int i = 0 ; i < boids.size(); i++) {
Boid other = (Boid) boids.get(i);
float d = PVector.dist(loc,other.loc);
if ((d > 0) && (d < neighbordist)) {
steer.add(other.vel);
count++;
}
}
if (count > 0) {
steer.div((float)count);
}
// As long as the vector is greater than 0
if (steer.mag() > 0) {
// Implement Reynolds: Steering = Desired - Velocity
steer.normalize();
steer.mult(maxspeed);
steer.sub(vel);
steer.limit(maxforce);
}
return steer;
}
// Cohesion
// For the average location (i.e. center) of all nearby boids, calculate steering vector towards that location
PVector cohesion (ArrayList boids) {
float neighbordist = 25.0;
PVector sum = new PVector(0,0); // Start with empty vector to accumulate all locations
int count = 0;
for (int i = 0 ; i < boids.size(); i++) {
Boid other = (Boid) boids.get(i);
float d = loc.dist(other.loc);
if ((d > 0) && (d < neighbordist)) {
sum.add(other.loc); // Add location
count++;
}
}
if (count > 0) {
sum.div((float)count);
return steer(sum,false); // Steer towards the location
}
return sum;
}
}

View File

@@ -0,0 +1,22 @@
// The Flock (a list of Boid objects)
class Flock {
ArrayList boids; // An arraylist for all the boids
Flock() {
boids = new ArrayList(); // Initialize the arraylist
}
void run() {
for (int i = 0; i < boids.size(); i++) {
Boid b = (Boid) boids.get(i);
b.run(boids); // Passing the entire list of boids to each boid individually
}
}
void addBoid(Boid b) {
boids.add(b);
}
}

View File

@@ -0,0 +1,32 @@
/**
* Flocking
* by Daniel Shiffman.
*
* An implementation of Craig Reynold's Boids program to simulate
* the flocking behavior of birds. Each boid steers itself based on
* rules of avoidance, alignment, and coherence.
*
* Click the mouse to add a new boid.
*/
Flock flock;
void setup() {
size(640, 360);
flock = new Flock();
// Add an initial set of boids into the system
for (int i = 0; i < 150; i++) {
flock.addBoid(new Boid(new PVector(width/2,height/2), 3.0, 0.05));
}
smooth();
}
void draw() {
background(50);
flock.run();
}
// Add a new boid into the System
void mousePressed() {
flock.addBoid(new Boid(new PVector(mouseX,mouseY),2.0f,0.05f));
}

View File

@@ -0,0 +1,208 @@
/**
* Fluid
* by Glen Murphy.
*
* Click and drag the mouse to move the simulated fluid.
* Adjust the "res" variable below to change resolution.
* Code has not been optimised, and will run fairly slowly.
*/
int res = 2;
int penSize = 30;
int lwidth;
int lheight;
int pnum = 30000;
vsquare[][] v;
vbuffer[][] vbuf;
particle[] p = new particle[pnum];
int pcount = 0;
int mouseXvel = 0;
int mouseYvel = 0;
void setup()
{
size(200, 200);
noStroke();
frameRate(30);
lwidth = width/res;
lheight = height/res;
v = new vsquare[lwidth+1][lheight+1];
vbuf = new vbuffer[lwidth+1][lheight+1];
for (int i = 0; i < pnum; i++) {
p[i] = new particle(random(res,width-res),random(res,height-res));
}
for (int i = 0; i <= lwidth; i++) {
for (int u = 0; u <= lheight; u++) {
v[i][u] = new vsquare(i*res,u*res);
vbuf[i][u] = new vbuffer(i*res,u*res);
}
}
}
void draw()
{
background(#666666);
int axvel = mouseX-pmouseX;
int ayvel = mouseY-pmouseY;
mouseXvel = (axvel != mouseXvel) ? axvel : 0;
mouseYvel = (ayvel != mouseYvel) ? ayvel : 0;
for (int i = 0; i < lwidth; i++) {
for (int u = 0; u < lheight; u++) {
vbuf[i][u].updatebuf(i,u);
v[i][u].col = 32;
}
}
for (int i = 0; i < pnum-1; i++) {
p[i].updatepos();
}
for (int i = 0; i < lwidth; i++) {
for (int u = 0; u < lheight; u++) {
v[i][u].addbuffer(i, u);
v[i][u].updatevels(mouseXvel, mouseYvel);
v[i][u].display(i, u);
}
}
}
class particle {
float x;
float y;
float xvel;
float yvel;
int pos;
particle(float xIn, float yIn) {
x = xIn;
y = yIn;
}
void updatepos() {
float col1;
if (x > 0 && x < width && y > 0 && y < height) {
int vi = (int)(x/res);
int vu = (int)(y/res);
vsquare o = v[vi][vu];
float ax = (x%res)/res;
float ay = (y%res)/res;
xvel += (1-ax)*v[vi][vu].xvel*0.05;
yvel += (1-ay)*v[vi][vu].yvel*0.05;
xvel += ax*v[vi+1][vu].xvel*0.05;
yvel += ax*v[vi+1][vu].yvel*0.05;
xvel += ay*v[vi][vu+1].xvel*0.05;
yvel += ay*v[vi][vu+1].yvel*0.05;
o.col += 4;
x += xvel;
y += yvel;
}
else {
x = random(0,width);
y = random(0,height);
xvel = 0;
yvel = 0;
}
xvel *= 0.5;
yvel *= 0.5;
}
}
class vbuffer {
int x;
int y;
float xvel;
float yvel;
float pressurex = 0;
float pressurey = 0;
float pressure = 0;
vbuffer(int xIn,int yIn) {
x = xIn;
y = yIn;
pressurex = 0;
pressurey = 0;
}
void updatebuf(int i, int u) {
if (i>0 && i<lwidth && u>0 && u<lheight) {
pressurex = (v[i-1][u-1].xvel*0.5 + v[i-1][u].xvel + v[i-1][u+1].xvel*0.5 - v[i+1][u-1].xvel*0.5 - v[i+1][u].xvel - v[i+1][u+1].xvel*0.5);
pressurey = (v[i-1][u-1].yvel*0.5 + v[i][u-1].yvel + v[i+1][u-1].yvel*0.5 - v[i-1][u+1].yvel*0.5 - v[i][u+1].yvel - v[i+1][u+1].yvel*0.5);
pressure = (pressurex + pressurey)*0.25;
}
}
}
class vsquare {
int x;
int y;
float xvel;
float yvel;
float col;
vsquare(int xIn,int yIn) {
x = xIn;
y = yIn;
}
void addbuffer(int i, int u) {
if (i>0 && i<lwidth && u>0 && u<lheight) {
xvel += (vbuf[i-1][u-1].pressure*0.5
+vbuf[i-1][u].pressure
+vbuf[i-1][u+1].pressure*0.5
-vbuf[i+1][u-1].pressure*0.5
-vbuf[i+1][u].pressure
-vbuf[i+1][u+1].pressure*0.5
)*0.25;
yvel += (vbuf[i-1][u-1].pressure*0.5
+vbuf[i][u-1].pressure
+vbuf[i+1][u-1].pressure*0.5
-vbuf[i-1][u+1].pressure*0.5
-vbuf[i][u+1].pressure
-vbuf[i+1][u+1].pressure*0.5
)*0.25;
}
}
void updatevels(int mvelX, int mvelY) {
if (mousePressed) {
float adj = x - mouseX;
float opp = y - mouseY;
float dist = sqrt(opp*opp + adj*adj);
if (dist < penSize) {
if (dist < 4) dist = penSize;
float mod = penSize/dist;
xvel += mvelX*mod;
yvel += mvelY*mod;
}
}
xvel *= 0.99;
yvel *= 0.99;
}
void display(int i, int u) {
float tcol = 0;
if (col > 255) col = 255;
if (i>0 && i<lwidth-1 && u>0 && u<lheight-1) {
tcol = (+ v[i][u+1].col
+ v[i+1][u].col
+ v[i+1][u+1].col*0.5
)*0.4;
tcol = (int)(tcol+col*0.5);
}
else {
tcol = (int)col;
}
fill(tcol, tcol, tcol);
rect(x,y,res,res);
}
}

View File

@@ -0,0 +1,47 @@
// A subclass of Particle
class CrazyParticle extends Particle {
// Just adding one new variable to a CrazyParticle
// It inherits all other fields from "Particle", and we don't have to retype them!
float theta;
// The CrazyParticle constructor can call the parent class (super class) constructor
CrazyParticle(PVector l) {
// "super" means do everything from the constructor in Particle
super(l);
// One more line of code to deal with the new variable, theta
theta = 0.0;
}
// Notice we don't have the method run() here; it is inherited from Particle
// This update() method overrides the parent class update() method
void update() {
super.update();
// Increment rotation based on horizontal velocity
float theta_vel = (vel.x * vel.mag()) / 10.0f;
theta += theta_vel;
}
// Override timer
void timer() {
timer -= 0.5;
}
// Method to display
void render() {
// Render the ellipse just like in a regular particle
super.render();
// Then add a rotating line
pushMatrix();
translate(loc.x,loc.y);
rotate(theta);
stroke(255,timer);
line(0,0,25,0);
popMatrix();
}
}

View File

@@ -0,0 +1,50 @@
/**
* Multiple Particle Systems
* by Daniel Shiffman.
*
* Click the mouse to generate a burst of particles
* at mouse location.
*
* Each burst is one instance of a particle system
* with Particles and CrazyParticles (a subclass of Particle)
* Note use of Inheritance and Polymorphism here.
*/
ArrayList psystems;
void setup() {
size(640, 360);
colorMode(RGB, 255, 255, 255, 100);
psystems = new ArrayList();
smooth();
}
void draw() {
background(0);
// Cycle through all particle systems, run them and delete old ones
for (int i = psystems.size()-1; i >= 0; i--) {
ParticleSystem psys = (ParticleSystem) psystems.get(i);
psys.run();
if (psys.dead()) {
psystems.remove(i);
}
}
}
// When the mouse is pressed, add a new particle system
void mousePressed() {
psystems.add(new ParticleSystem(int(random(5,25)),new PVector(mouseX,mouseY)));
}

View File

@@ -0,0 +1,57 @@
// A simple Particle class
class Particle {
PVector loc;
PVector vel;
PVector acc;
float r;
float timer;
// One constructor
Particle(PVector a, PVector v, PVector l, float r_) {
acc = a.get();
vel = v.get();
loc = l.get();
r = r_;
timer = 100.0;
}
// Another constructor (the one we are using here)
Particle(PVector l) {
acc = new PVector(0,0.05,0);
vel = new PVector(random(-1,1),random(-2,0),0);
loc = l.get();
r = 10.0;
timer = 100.0;
}
void run() {
update();
render();
}
// Method to update location
void update() {
vel.add(acc);
loc.add(vel);
timer -= 1.0;
}
// Method to display
void render() {
ellipseMode(CENTER);
stroke(255,timer);
fill(100,timer);
ellipse(loc.x,loc.y,r,r);
}
// Is the particle still useful?
boolean dead() {
if (timer <= 0.0) {
return true;
} else {
return false;
}
}
}

View File

@@ -0,0 +1,51 @@
// An ArrayList is used to manage the list of Particles
class ParticleSystem {
ArrayList particles; // An arraylist for all the particles
PVector origin; // An origin point for where particles are birthed
ParticleSystem(int num, PVector v) {
particles = new ArrayList(); // Initialize the arraylist
origin = v.get(); // Store the origin point
for (int i = 0; i < num; i++) {
// We have a 50% chance of adding each kind of particle
if (random(1) < 0.5) {
particles.add(new CrazyParticle(origin));
} else {
particles.add(new Particle(origin));
}
}
}
void run() {
// Cycle through the ArrayList backwards b/c we are deleting
for (int i = particles.size()-1; i >= 0; i--) {
Particle p = (Particle) particles.get(i);
p.run();
if (p.dead()) {
particles.remove(i);
}
}
}
void addParticle() {
particles.add(new Particle(origin));
}
void addParticle(Particle p) {
particles.add(p);
}
// A method to test if the particle system still has particles
boolean dead() {
if (particles.isEmpty()) {
return true;
}
else {
return false;
}
}
}

View File

@@ -0,0 +1,67 @@
// A simple Particle class
class Particle {
PVector loc;
PVector vel;
PVector acc;
float r;
float timer;
// Another constructor (the one we are using here)
Particle(PVector l) {
acc = new PVector(0,0.05,0);
vel = new PVector(random(-1,1),random(-2,0),0);
loc = l.get();
r = 10.0;
timer = 100.0;
}
void run() {
update();
render();
}
// Method to update location
void update() {
vel.add(acc);
loc.add(vel);
timer -= 1.0;
}
// Method to display
void render() {
ellipseMode(CENTER);
stroke(255,timer);
fill(100,timer);
ellipse(loc.x,loc.y,r,r);
displayVector(vel,loc.x,loc.y,10);
}
// Is the particle still useful?
boolean dead() {
if (timer <= 0.0) {
return true;
} else {
return false;
}
}
void displayVector(PVector v, float x, float y, float scayl) {
pushMatrix();
float arrowsize = 4;
// Translate to location to render vector
translate(x,y);
stroke(255);
// Call vector heading function to get direction (note that pointing up is a heading of 0) and rotate
rotate(v.heading2D());
// Calculate length of vector & scale it to be bigger or smaller if necessary
float len = v.mag()*scayl;
// Draw three lines to make an arrow (draw pointing up since we've rotate to the proper direction)
line(0,0,len,0);
line(len,0,len-arrowsize,+arrowsize/2);
line(len,0,len-arrowsize,-arrowsize/2);
popMatrix();
}
}

View File

@@ -0,0 +1,50 @@
// A class to describe a group of Particles
// An ArrayList is used to manage the list of Particles
class ParticleSystem {
ArrayList particles; // An arraylist for all the particles
PVector origin; // An origin point for where particles are born
ParticleSystem(int num, PVector v) {
particles = new ArrayList(); // Initialize the arraylist
origin = v.get(); // Store the origin point
for (int i = 0; i < num; i++) {
particles.add(new Particle(origin)); // Add "num" amount of particles to the arraylist
}
}
void run() {
// Cycle through the ArrayList backwards b/c we are deleting
for (int i = particles.size()-1; i >= 0; i--) {
Particle p = (Particle) particles.get(i);
p.run();
if (p.dead()) {
particles.remove(i);
}
}
}
void addParticle() {
particles.add(new Particle(origin));
}
void addParticle(float x, float y) {
particles.add(new Particle(new PVector(x,y)));
}
void addParticle(Particle p) {
particles.add(p);
}
// A method to test if the particle system still has particles
boolean dead() {
if (particles.isEmpty()) {
return true;
} else {
return false;
}
}
}

View File

@@ -0,0 +1,27 @@
/**
* Simple Particle System
* by Daniel Shiffman.
*
* Particles are generated each cycle through draw(),
* fall with gravity and fade out over time
* A ParticleSystem object manages a variable size (ArrayList)
* list of particles.
*/
ParticleSystem ps;
void setup() {
size(640, 360);
colorMode(RGB, 255, 255, 255, 100);
ps = new ParticleSystem(1, new PVector(width/2,height/2,0));
smooth();
}
void draw() {
background(0);
ps.run();
ps.addParticle(mouseX,mouseY);
}

View File

@@ -0,0 +1,264 @@
/**
* Smoke
* by Glen Murphy.
*
* Drag the mouse across the image to move the particles.
* Code has not been optimised and will run fairly slowly.
*/
int res = 2;
int penSize = 30;
int lwidth;
int lheight;
int pnum = 30000;
vsquare[][] v;
vbuffer[][] vbuf;
particle[] p;
int pcount = 0;
int mouseXvel = 0;
int mouseYvel = 0;
int randomGust = 0;
int randomGustMax;
float randomGustX;
float randomGustY;
float randomGustSize;
float randomGustXvel;
float randomGustYvel;
void setup()
{
size(200, 200);
lwidth = width/res;
lheight = height/res;
v = new vsquare[lwidth+1][lheight+1];
vbuf = new vbuffer[lwidth+1][lheight+1];
p = new particle[pnum];
noStroke();
for(int i = 0; i < pnum; i++) {
p[i] = new particle(random(width/2-20,width/2+20),random(height-20,height));
}
for(int i = 0; i <= lwidth; i++) {
for(int u = 0; u <= lheight; u++) {
v[i][u] = new vsquare(i*res,u*res);
vbuf[i][u] = new vbuffer(i*res,u*res);
}
}
}
void draw()
{
background(#cccccc);
int axvel = mouseX-pmouseX;
int ayvel = mouseY-pmouseY;
mouseXvel = (axvel != mouseXvel) ? axvel : 0;
mouseYvel = (ayvel != mouseYvel) ? ayvel : 0;
if(randomGust <= 0) {
if(random(0,10)<1) {
randomGustMax = (int)random(5,12);
randomGust = randomGustMax;
randomGustX = random(0,width);
randomGustY = random(0,height-10);
randomGustSize = random(0,50);
if(randomGustX > width/2) {
randomGustXvel = random(-8,0);
} else {
randomGustXvel = random(0,8);
}
randomGustYvel = random(-2,1);
}
randomGust--;
}
for(int i = 0; i < lwidth; i++) {
for(int u = 0; u < lheight; u++) {
vbuf[i][u].updatebuf(i,u);
v[i][u].col = 0;
}
}
for(int i = 0; i < pnum-1; i++) {
p[i].updatepos();
}
for(int i = 0; i < lwidth; i++) {
for(int u = 0; u < lheight; u++) {
v[i][u].addbuffer(i, u);
v[i][u].updatevels(mouseXvel, mouseYvel);
v[i][u].display(i, u);
}
}
randomGust = 0;
}
class particle
{
float x;
float y;
float xvel;
float yvel;
float temp;
int pos;
particle(float xIn, float yIn) {
x = xIn;
y = yIn;
}
void reposition() {
x = width/2+random(-20,20);
y = random(height-10,height);
xvel = random(-1,1);
yvel = random(-1,1);
}
void updatepos() {
int vi = (int)(x/res);
int vu = (int)(y/res);
if(vi > 0 && vi < lwidth && vu > 0 && vu < lheight) {
v[vi][vu].addcolour(2);
float ax = (x%res)/res;
float ay = (y%res)/res;
xvel += (1-ax)*v[vi][vu].xvel*0.05;
yvel += (1-ay)*v[vi][vu].yvel*0.05;
xvel += ax*v[vi+1][vu].xvel*0.05;
yvel += ax*v[vi+1][vu].yvel*0.05;
xvel += ay*v[vi][vu+1].xvel*0.05;
yvel += ay*v[vi][vu+1].yvel*0.05;
v[vi][vu].yvel -= (1-ay)*0.003;
v[vi+1][vu].yvel -= ax*0.003;
if(v[vi][vu].yvel < 0) v[vi][vu].yvel *= 1.00025;
x += xvel;
y += yvel;
}
else {
reposition();
}
if(random(0,400) < 1) {
reposition();
}
xvel *= 0.6;
yvel *= 0.6;
}
}
class vbuffer
{
int x;
int y;
float xvel;
float yvel;
float pressurex = 0;
float pressurey = 0;
float pressure = 0;
vbuffer(int xIn,int yIn) {
x = xIn;
y = yIn;
pressurex = 0;
pressurey = 0;
}
void updatebuf(int i, int u) {
if(i>0 && i<lwidth && u>0 && u<lheight) {
pressurex = (v[i-1][u-1].xvel*0.5 + v[i-1][u].xvel + v[i-1][u+1].xvel*0.5 - v[i+1][u-1].xvel*0.5 - v[i+1][u].xvel - v[i+1][u+1].xvel*0.5);
pressurey = (v[i-1][u-1].yvel*0.5 + v[i][u-1].yvel + v[i+1][u-1].yvel*0.5 - v[i-1][u+1].yvel*0.5 - v[i][u+1].yvel - v[i+1][u+1].yvel*0.5);
pressure = (pressurex + pressurey)*0.25;
}
}
}
class vsquare {
int x;
int y;
float xvel;
float yvel;
float col;
vsquare(int xIn,int yIn) {
x = xIn;
y = yIn;
}
void addbuffer(int i, int u) {
if(i>0 && i<lwidth && u>0 && u<lheight) {
xvel += (vbuf[i-1][u-1].pressure*0.5
+vbuf[i-1][u].pressure
+vbuf[i-1][u+1].pressure*0.5
-vbuf[i+1][u-1].pressure*0.5
-vbuf[i+1][u].pressure
-vbuf[i+1][u+1].pressure*0.5
)*0.49;
yvel += (vbuf[i-1][u-1].pressure*0.5
+vbuf[i][u-1].pressure
+vbuf[i+1][u-1].pressure*0.5
-vbuf[i-1][u+1].pressure*0.5
-vbuf[i][u+1].pressure
-vbuf[i+1][u+1].pressure*0.5
)*0.49;
}
}
void updatevels(int mvelX, int mvelY) {
float adj;
float opp;
float dist;
float mod;
if(mousePressed) {
adj = x - mouseX;
opp = y - mouseY;
dist = sqrt(opp*opp + adj*adj);
if(dist < penSize) {
if(dist < 4) dist = penSize;
mod = penSize/dist;
xvel += mvelX*mod;
yvel += mvelY*mod;
}
}
if(randomGust > 0) {
adj = x - randomGustX;
opp = y - randomGustY;
dist = sqrt(opp*opp + adj*adj);
if(dist < randomGustSize) {
if(dist < res*2) dist = randomGustSize;
mod = randomGustSize/dist;
xvel += (randomGustMax-randomGust)*randomGustXvel*mod;
yvel += (randomGustMax-randomGust)*randomGustYvel*mod;
}
}
xvel *= 0.99;
yvel *= 0.98;
}
void addcolour(int amt) {
col += amt;
if(col > 196) col = 196;
}
void display(int i, int u) {
float tcol = 0;
if(i>0 && i<lwidth-1 && u>0 && u<lheight-1) {
tcol = (+ v[i][u+1].col
+ v[i+1][u].col
+ v[i+1][u+1].col*0.5
)*0.3;
tcol = (int)(tcol+col*0.5);
}
fill(255-tcol, 255-tcol, 255-tcol);
rect(x,y,res,res);
col = 0;
}
}

View File

@@ -0,0 +1,69 @@
// A simple Particle class, renders the particle as an image
class Particle {
PVector loc;
PVector vel;
PVector acc;
float timer;
PImage img;
// One constructor
Particle(PVector a, PVector v, PVector l, PImage img_) {
acc = a.get();
vel = v.get();
loc = l.get();
timer = 100.0;
img = img_;
}
// Another constructor (the one we are using here)
Particle(PVector l,PImage img_) {
acc = new PVector(0.0,0.0,0.0);
float x = (float) generator.nextGaussian()*0.3f;
float y = (float) generator.nextGaussian()*0.3f - 1.0f;
vel = new PVector(x,y,0);
loc = l.get();
timer = 100.0;
img = img_;
}
void run() {
update();
render();
}
// Method to apply a force vector to the Particle object
// Note we are ignoring "mass" here
void add_force(PVector f) {
acc.add(f);
}
// Method to update location
void update() {
vel.add(acc);
loc.add(vel);
timer -= 2.5;
acc.mult(0);
}
// Method to display
void render() {
imageMode(CORNER);
tint(255,timer);
image(img,loc.x-img.width/2,loc.y-img.height/2);
}
// Is the particle still useful?
boolean dead() {
if (timer <= 0.0) {
return true;
} else {
return false;
}
}
}

View File

@@ -0,0 +1,57 @@
// A class to describe a group of Particles
// An ArrayList is used to manage the list of Particles
class ParticleSystem {
ArrayList particles; // An arraylist for all the particles
PVector origin; // An origin point for where particles are birthed
PImage img;
ParticleSystem(int num, PVector v, PImage img_) {
particles = new ArrayList(); // Initialize the arraylist
origin = v.get(); // Store the origin point
img = img_;
for (int i = 0; i < num; i++) {
particles.add(new Particle(origin, img)); // Add "num" amount of particles to the arraylist
}
}
void run() {
// Cycle through the ArrayList backwards b/c we are deleting
for (int i = particles.size()-1; i >= 0; i--) {
Particle p = (Particle) particles.get(i);
p.run();
if (p.dead()) {
particles.remove(i);
}
}
}
// Method to add a force vector to all particles currently in the system
void add_force(PVector dir) {
for (int i = particles.size()-1; i >= 0; i--) {
Particle p = (Particle) particles.get(i);
p.add_force(dir);
}
}
void addParticle() {
particles.add(new Particle(origin,img));
}
void addParticle(Particle p) {
particles.add(p);
}
// A method to test if the particle system still has particles
boolean dead() {
if (particles.isEmpty()) {
return true;
} else {
return false;
}
}
}

View File

@@ -0,0 +1,69 @@
/**
* Smoke Particle System
* by Daniel Shiffman.
*
* A basic smoke effect using a particle system.
* Each particle is rendered as an alpha masked image.
*/
ParticleSystem ps;
Random generator;
void setup() {
size(640, 200);
colorMode(RGB, 255, 255, 255, 100);
// Using a Java random number generator for Gaussian random numbers
generator = new Random();
// Create an alpha masked image to be applied as the particle's texture
PImage msk = loadImage("texture.gif");
PImage img = new PImage(msk.width,msk.height);
for (int i = 0; i < img.pixels.length; i++) img.pixels[i] = color(255);
img.mask(msk);
ps = new ParticleSystem(0, new PVector(width/2,height-20 ),img);
smooth();
}
void draw() {
background(75);
// Calculate a "wind" force based on mouse horizontal position
float dx = (mouseX - width/2) / 1000.0;
PVector wind = new PVector(dx,0,0);
displayVector(wind,width/2,50,500);
ps.add_force(wind);
ps.run();
for (int i = 0; i < 2; i++) {
ps.addParticle();
}
}
void displayVector(PVector v, float x, float y, float scayl) {
pushMatrix();
float arrowsize = 4;
// Translate to location to render vector
translate(x,y);
stroke(255);
// Call vector heading function to get direction (note that pointing up is a heading of 0) and rotate
rotate(v.heading2D());
// Calculate length of vector & scale it to be bigger or smaller if necessary
float len = v.mag()*scayl;
// Draw three lines to make an arrow (draw pointing up since we've rotate to the proper direction)
line(0,0,len,0);
line(len,0,len-arrowsize,+arrowsize/2);
line(len,0,len-arrowsize,-arrowsize/2);
popMatrix();
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

@@ -0,0 +1,99 @@
/**
* Soft Body
* by Ira Greenberg.
*
* Softbody dynamics simulation using curveVertex() and curveTightness().
*/
// center point
float centerX = 0, centerY = 0;
float radius = 45, rotAngle = -90;
float accelX, accelY;
float springing = .0009, damping = .98;
//corner nodes
int nodes = 5;
float nodeStartX[] = new float[nodes];
float nodeStartY[] = new float[nodes];
float[]nodeX = new float[nodes];
float[]nodeY = new float[nodes];
float[]angle = new float[nodes];
float[]frequency = new float[nodes];
// soft-body dynamics
float organicConstant = 1;
void setup() {
size(640, 360);
//center shape in window
centerX = width/2;
centerY = height/2;
// iniitalize frequencies for corner nodes
for (int i=0; i<nodes; i++){
frequency[i] = random(5, 12);
}
noStroke();
smooth();
frameRate(30);
}
void draw() {
//fade background
fill(0, 100);
rect(0,0,width, height);
drawShape();
moveShape();
}
void drawShape() {
// calculate node starting locations
for (int i=0; i<nodes; i++){
nodeStartX[i] = centerX+cos(radians(rotAngle))*radius;
nodeStartY[i] = centerY+sin(radians(rotAngle))*radius;
rotAngle += 360.0/nodes;
}
// draw polygon
curveTightness(organicConstant);
fill(255);
beginShape();
for (int i=0; i<nodes; i++){
curveVertex(nodeX[i], nodeY[i]);
}
for (int i=0; i<nodes-1; i++){
curveVertex(nodeX[i], nodeY[i]);
}
endShape(CLOSE);
}
void moveShape() {
//move center point
float deltaX = mouseX-centerX;
float deltaY = mouseY-centerY;
// create springing effect
deltaX *= springing;
deltaY *= springing;
accelX += deltaX;
accelY += deltaY;
// move predator's center
centerX += accelX;
centerY += accelY;
// slow down springing
accelX *= damping;
accelY *= damping;
// change curve tightness
organicConstant = 1-((abs(accelX)+abs(accelY))*.1);
//move nodes
for (int i=0; i<nodes; i++){
nodeX[i] = nodeStartX[i]+sin(radians(angle[i]))*(accelX*2);
nodeY[i] = nodeStartY[i]+sin(radians(angle[i]))*(accelY*2);
angle[i]+=frequency[i];
}
}

View File

@@ -0,0 +1,97 @@
/**
* Spring.
*
* Click, drag, and release the horizontal bar to start the spring.
*/
// Spring drawing constants for top bar
int s_height = 16; // Height
int left = 50; // Left position
int right = 150; // Right position
int max = 100; // Maximum Y value
int min = 20; // Minimum Y value
boolean over = false; // If mouse over
boolean move = false; // If mouse down and over
// Spring simulation constants
float M = 0.8; // Mass
float K = 0.2; // Spring constant
float D = 0.92; // Damping
float R = 60; // Rest position
// Spring simulation variables
float ps = 60.0; // Position
float vs = 0.0; // Velocity
float as = 0; // Acceleration
float f = 0; // Force
void setup()
{
size(200, 200);
rectMode(CORNERS);
noStroke();
}
void draw()
{
background(102);
updateSpring();
drawSpring();
}
void drawSpring()
{
// Draw base
fill(0.2);
float b_width = 0.5 * ps + -8;
rect(width/2 - b_width, ps + s_height, width/2 + b_width, 150);
// Set color and draw top bar
if(over || move) {
fill(255);
} else {
fill(204);
}
rect(left, ps, right, ps + s_height);
}
void updateSpring()
{
// Update the spring position
if(!move) {
f = -K * (ps - R); // f=-ky
as = f / M; // Set the acceleration, f=ma == a=f/m
vs = D * (vs + as); // Set the velocity
ps = ps + vs; // Updated position
}
if(abs(vs) < 0.1) {
vs = 0.0;
}
// Test if mouse is over the top bar
if(mouseX > left && mouseX < right && mouseY > ps && mouseY < ps + s_height) {
over = true;
} else {
over = false;
}
// Set and constrain the position of top bar
if(move) {
ps = mouseY - s_height/2;
if (ps < min) { ps = min; }
if (ps > max) { ps = max; }
}
}
void mousePressed() {
if(over) {
move = true;
}
}
void mouseReleased()
{
move = false;
}

View File

@@ -0,0 +1,162 @@
/**
* Springs.
*
* Move the mouse over one of the circles and click to re-position.
* When you release the mouse, it will snap back into position.
* Each circle has a slightly different behavior.
*/
int num = 3;
Spring[] springs = new Spring[num];
void setup()
{
size(200, 200);
noStroke();
smooth();
springs[0] = new Spring( 70, 160, 20, 0.98, 8.0, 0.1, springs, 0);
springs[1] = new Spring(150, 110, 60, 0.95, 9.0, 0.1, springs, 1);
springs[2] = new Spring( 40, 70, 120, 0.90, 9.9, 0.1, springs, 2);
}
void draw()
{
background(51);
for (int i = 0; i < num; i++) {
springs[i].update();
springs[i].display();
}
}
void mousePressed()
{
for (int i = 0; i < num; i++) {
springs[i].pressed();
}
}
void mouseReleased()
{
for (int i=0; i<num; i++) {
springs[i].released();
}
}
class Spring
{
// Screen values
float xpos, ypos;
float tempxpos, tempypos;
int size = 20;
boolean over = false;
boolean move = false;
// Spring simulation constants
float mass; // Mass
float k = 0.2; // Spring constant
float damp; // Damping
float rest_posx; // Rest position X
float rest_posy; // Rest position Y
// Spring simulation variables
//float pos = 20.0; // Position
float velx = 0.0; // X Velocity
float vely = 0.0; // Y Velocity
float accel = 0; // Acceleration
float force = 0; // Force
Spring[] friends;
int me;
// Constructor
Spring(float x, float y, int s, float d, float m,
float k_in, Spring[] others, int id)
{
xpos = tempxpos = x;
ypos = tempypos = y;
rest_posx = x;
rest_posy = y;
size = s;
damp = d;
mass = m;
k = k_in;
friends = others;
me = id;
}
void update()
{
if (move) {
rest_posy = mouseY;
rest_posx = mouseX;
}
force = -k * (tempypos - rest_posy); // f=-ky
accel = force / mass; // Set the acceleration, f=ma == a=f/m
vely = damp * (vely + accel); // Set the velocity
tempypos = tempypos + vely; // Updated position
force = -k * (tempxpos - rest_posx); // f=-ky
accel = force / mass; // Set the acceleration, f=ma == a=f/m
velx = damp * (velx + accel); // Set the velocity
tempxpos = tempxpos + velx; // Updated position
if ((over() || move) && !otherOver() ) {
over = true;
} else {
over = false;
}
}
// Test to see if mouse is over this spring
boolean over() {
float disX = tempxpos - mouseX;
float disY = tempypos - mouseY;
if (sqrt(sq(disX) + sq(disY)) < size/2 ) {
return true;
} else {
return false;
}
}
// Make sure no other springs are active
boolean otherOver() {
for (int i=0; i<num; i++) {
if (i != me) {
if (friends[i].over == true) {
return true;
}
}
}
return false;
}
void display()
{
if (over) {
fill(153);
} else {
fill(255);
}
ellipse(tempxpos, tempypos, size, size);
}
void pressed()
{
if (over) {
move = true;
} else {
move = false;
}
}
void released()
{
move = false;
rest_posx = xpos;
rest_posy = ypos;
}
}