nature-of-code / noc-examples-processing

Repository for example code from The Nature of Code book
MIT License
2.56k stars 951 forks source link

exercise 2.7 solution #47

Open shiffman opened 10 years ago

shiffman commented 10 years ago

"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."

GilesCartmel commented 8 years ago

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; } } }

shiffman commented 8 years ago

Thanks for this!