noc-examples-processing
noc-examples-processing copied to clipboard
exercise 2.7 solution
"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!