exercise 2.7 solution
shiffman opened this issue · comments
"Fluid resistance does not only work opposite to the velocity vector, but also perpendicular to it. This is known as “lift-induced drag” and will cause an airplane with an angled wing to rise in altitude. Try creating a simulation of lift."
Here's my attempt (certainly it's a simulation - but I wouldn't trust my code to flying a real plane hehe!)...
// Use "q" and "a" to increase/decrease the power of the jet acceleration
Wing wing;
float jetPower;
void setup() {
size(800,600);
ellipseMode(CENTER);
wing = new Wing();
jetPower = 0.5;
}
void draw() {
background(255);
PVector wind = new PVector(-0.01,0);
PVector jet = new PVector(jetPower,0);
PVector gravity;
wing.applyForce(wind);
wing.applyForce(jet);
gravity = new PVector(0,0.1*wing.mass);
wing.applyForce(gravity);
wing.applyDrag(0.1);
wing.applyLift(0.02);
wing.update();
wing.display();
wing.checkEdges();
}
void keyPressed() {
if (key == 'q') {
jetPower += 0.05;
println("Jet Power: "+jetPower);
} else if (key =='a') {
jetPower -= 0.05;
println("Jet Power: "+jetPower);
}
}
class Wing {
PVector location;
PVector velocity;
PVector acceleration, hacceleration;
PVector drag, lift;
float mass, sz, angle;
Wing() {
mass = 1;
sz = width/5;
location = new PVector((width/2), (height/2));
angle = 0;
velocity = new PVector(0,0);
acceleration = new PVector(0,0);
}
void applyForce(PVector force) {
PVector f = PVector.div(force,mass);
acceleration.add(f);
}
void applyFriction(float coeff) {
PVector friction = velocity.copy();
friction.mult(-1);
friction.normalize();
friction.mult(coeff);
applyForce(friction);
}
void applyDrag(float coeff) {
float dragMagnitude = coeff * pow(velocity.mag(),2);
drag = velocity.copy();
drag.mult(-1);
drag.normalize();
drag.mult(dragMagnitude);
applyForce(drag);
}
void applyLift(float coeff) {
float liftMagnitude = coeff * pow(velocity.mag(),2);
lift = velocity.copy();
lift.rotate(HALF_PI); // lift is perpendicular to drag
lift.mult(-1);
lift.normalize();
lift.mult(liftMagnitude);
applyForce(lift);
}
void update() {
velocity.add(acceleration);
location.add(velocity);
hacceleration = acceleration.copy();
acceleration.mult(0);
}
void display() {
stroke(0);
fill(175);
pushMatrix();
translate(location.x, location.y);
rotate(-radians(angle)); // for future use
ellipse(0,0,sz,sz/20);
popMatrix();
stroke(0);
line(location.x, location.y, location.x+velocity.x_10, location.y+velocity.y_10);
stroke(0,0,255);
line(location.x, location.y, location.x+hacceleration.x_1000, location.y+hacceleration.y_1000);
stroke(255,0,0);
line(location.x, location.y, location.x+drag.x_1000, location.y);
stroke(0,200,0);
line(location.x, location.y, location.x, location.y-drag.y_1000);
}
void checkEdges() {
if (location.x > width) {
location.x = 0;
} else if (location.x < 0) {
location.x = width;
}
if (location.y > height) {
location.y = height;
} else if (location.y < 0) {
location.y = 0;
}
}
}
Thanks for this!