At the end of class, on Thursday, Feb. 17, we started on the complex example below.
I have completed it. This is too complex to spend more time on right now, but it is a pleasantly rich example to view.
final float DELTA_T = 0.6;
final float AIR_RESISTANCE = 0.0005;
interface Location {
PVector location();
}
class Anchor implements Location {
PVector anchorPoint;
Anchor(PVector anchorPoint_) {
anchorPoint = anchorPoint_.copy();
}
PVector location() {
return anchorPoint;
}
}
class Bob implements Location {
PVector location;
PVector velocity;
PVector acceleration;
float mass;
Bob(float m, float x, float y, float vx, float vy) {
mass = m;
location = new PVector(x, y);
velocity = new PVector(vx, vy);
acceleration = new PVector(0, 0);
}
PVector location() {
return location;
}
void applyForce(PVector force) {
PVector f = PVector.div(force, mass);
acceleration.add(f);
}
void update() {
velocity.add(acceleration.mult(DELTA_T));
location.add(velocity.copy().mult(DELTA_T));
acceleration.mult(0);
}
void display() {
stroke(0);
fill(175);
ellipseMode(CENTER);
ellipse(location.x, location.y, mass*16, mass*16);
}
}
class Spring {
float len;
float k;
Location anchor;
Spring(float k_, float len_, Location l_) {
k = k_;
len = len_;
anchor = l_;
}
PVector forceAtLocation(Location l) {
PVector force = PVector.sub(l.location(), anchor.location());
float d = force.mag();
float stretch = d - len;
force.normalize();
return force.mult(-1 * k * stretch);
}
PVector forceAtAnchor(Location l) {
return forceAtLocation(l).mult(-1);
}
void displayAnchor() {
fill(100);
rectMode(CENTER);
PVector location = anchor.location();
rect(location.x, location.y, 10, 10);
}
void displayLine(Location l) {
stroke(255);
PVector end = anchor.location();
PVector otherEnd = l.location();
line(end.x, end.y, otherEnd.x, otherEnd.y);
}
}
Bob bob;
Bob bob2;
Spring spring;
Spring spring2;
void setup() {
size(800, 800);
Anchor anchor = new Anchor(new PVector(400, 50));
spring = new Spring(1, 400, anchor);
bob = new Bob(1, 100, 100, 0, 0);
spring2 = new Spring(1, 160, bob);
bob2 = new Bob(0.5, 150, 125, 0, 0);
}
void draw() {
push();
fill(188, 20);
noStroke();
rectMode(CORNERS);
rect(0, 0, width, height);
pop();
PVector gravity = new PVector(0, bob.mass);
bob.applyForce(gravity);
bob.applyForce(spring.forceAtLocation(bob));
bob.applyForce(spring2.forceAtAnchor(bob2));
PVector airResistance = bob.velocity.copy();
airResistance.mult(-AIR_RESISTANCE * airResistance.mag());
bob.applyForce(airResistance);
PVector gravity2 = new PVector(0, bob2.mass);
bob2.applyForce(gravity2);
bob2.applyForce(spring2.forceAtLocation(bob2));
PVector airResistance2 = bob2.velocity.copy();
airResistance2.mult(-AIR_RESISTANCE * airResistance2.mag());
bob2.applyForce(airResistance2);
bob.update();
bob2.update();
bob.display();
bob2.display();
spring.displayAnchor();
spring.displayLine(bob);
spring2.displayLine(bob2);
}