Instantly share code, notes, and snippets.

# dharmatech/pse problem 4.11 - projectile motion.cpp Created Dec 8, 2012

What would you like to do?
 #include "stdafx.h" #include "..\..\include\symbolicc++.h" Symbolic Pi = "Pi"; Symbolic g = "g"; Symbolic Radians(Symbolic n) { return n * Pi / 180; } Symbolic Degrees(Symbolic n) { return 180 * n / Pi; } class Point { public: Symbolic x; Symbolic y; Point() { x = "NOTSET" ; y = "NOTSET"; } Point(Symbolic x_val, Symbolic y_val) { x = x_val; y = y_val; } void Print() { cout << "Point(" << x << ", " << y << ")"; } static Point FromAngle(Symbolic angle, Symbolic mag) { return Point(cos(angle) * mag, sin(angle) * mag); } Point operator+(Point p) { return Point(x + p.x, y + p.y); } Point operator*(Symbolic sym) { return Point(x * sym, y * sym); } Point operator/(Symbolic sym) { return Point(x / sym, y / sym); } Symbolic Norm() { return sqrt(x*x + y*y); } double ToAngle() { return atan2(y, x); } }; void Unset(Symbolic &sym) { sym = "NOTSET"; } bool IsSet(Symbolic sym) { if (sym == "NOTSET") return false; else return true; } bool HasVal(Symbolic sym) { if (sym == "NOTSET") return false; else return true; } class Obj { public: Point position, velocity, acceleration; Symbolic speed; Symbolic time; void Print() { // cout << "Obj:" << endl; cout << "time: " << time << endl; cout << "position.x: " << position.x << endl; cout << "position.y: " << position.y << endl; cout << "velocity.x: " << velocity.x << endl; cout << "velocity.y: " << velocity.y << endl; cout << "acceleration.x: " << acceleration.x << endl; cout << "acceleration.y: " << acceleration.y << endl; } Obj AtTime(Symbolic t) { Obj obj; obj.time = t; auto dt = t - time; obj.acceleration = acceleration; obj.velocity = velocity + acceleration * dt; obj.position = position + velocity * dt + acceleration * dt * dt / 2; return obj; } }; Symbolic CalcTime(Obj& a, Obj& b, int flag=0) { if (HasVal(b.velocity.x) && HasVal(a.velocity.x) && HasVal(a.acceleration.x) && a.acceleration.x != 0.0 && a.acceleration.x != 0) return (b.velocity.x - a.velocity.x) / a.acceleration.x; if (HasVal(b.velocity.y) && HasVal(a.velocity.y) && HasVal(a.acceleration.y) && a.acceleration.y != 0.0 && a.acceleration.y != 0) return (b.velocity.y - a.velocity.y) / a.acceleration.y; if (HasVal(a.position.x) && HasVal(b.position.x) && HasVal(a.velocity.x) && a.velocity.x != 0 && a.velocity.x != 0.0) return (b.position.x - a.position.x) / a.velocity.x; if (HasVal(b.position.x) && HasVal(a.position.x) && HasVal(a.velocity.x) && HasVal(a.acceleration.x) && a.acceleration.x != 0 && a.acceleration.x != 0.0) { if (flag == 0) return (-a.velocity.x + sqrt(pow(a.velocity.x, Symbolic(2)) - 2 * a.acceleration.x * (a.position.x - b.position.x))) / a.acceleration.x; else return (-a.velocity.x - sqrt(pow(a.velocity.x, Symbolic(2)) - 2 * a.acceleration.x * (a.position.x - b.position.x))) / a.acceleration.x; } if (HasVal(a.position.y) && HasVal(b.position.y) && HasVal(a.velocity.y) && HasVal(a.acceleration.y) && a.acceleration.y != 0 && a.acceleration.y != 0.0) { if (flag == 0) return (-a.velocity.y + sqrt(pow(a.velocity.y, Symbolic(2)) - 2 * a.acceleration.y * (a.position.y - b.position.y))) / a.acceleration.y; else return (-a.velocity.y - sqrt(pow(a.velocity.y, Symbolic(2)) - 2 * a.acceleration.y * (a.position.y - b.position.y))) / a.acceleration.y; } throw "exception"; } Symbolic CalcInitialVelocityX(Obj& a, Obj& b) { if (HasVal(a.position.x) && HasVal(a.position.y) && HasVal(a.time) && HasVal(b.time) && HasVal(a.acceleration.x)) { auto dt = b.time - a.time; return (b.position.x - a.position.x - a.acceleration.x * dt^2 / 2) / dt; } throw "exception"; } auto _g = Point(0, -g); double SymmetricalAbout(double a, double b) { return a + a - b; } // sin(a th) = b Symbolic SineCalcTheta(Symbolic a, Symbolic b, int solution = 0, int n = 0) { if (solution == 0) return (- asin(b) + 2 * Pi * n + Pi) / a; if (solution == 1) return (asin(b) + 2 * Pi * n) / a; } Symbolic CalcInitialAngle(Obj a, Obj b, int sol = 0, int n = 0) { if (HasVal(a.position.x) && HasVal(b.position.x) && HasVal(a.acceleration.y) && HasVal(a.speed)) if (sol == 0) return (- asin(- a.acceleration.y * (b.position.x - a.position.x) / (a.speed^2)) + 2 * Pi * n + Pi) / 2; if (sol == 1) return (asin(- a.acceleration.y * (b.position.x - a.position.x) / (a.speed^2)) + 2 * Pi * n) / 2; throw "exception"; } int _tmain(int argc, _TCHAR* argv[]) { // One strategy in a snowball fight is to throw a first // snowball at a high angle over level ground. While your // opponent is watching the first one, you throw a second one // at a low angle and timed to arrive at your opponent // before or at the same time as the first one. Assume both // snowballs are thrown with a speed of 25.0 m/s. The first // one is thrown at an angle of 70.0° with respect to the // horizontal. (a) At what angle should the second // (low-angle) snowball be thrown if it is to land at the same // point as the first? (b) How many seconds later should // the second snowball be thrown if it is to land at the // same time as the first? { Obj obj1A; Obj obj1B; obj1A.time = 0; obj1A.position.x = 0; obj1A.position.y = 0; auto pi = 3.14159; obj1A.velocity = Point::FromAngle(Radians(70)[Pi == pi], 25); _g = Point(0, -9.8); obj1A.acceleration = _g; obj1B.position.y = 0; obj1B.velocity.x = obj1A.velocity.x; obj1B.acceleration = _g; auto time1B = CalcTime(obj1A, obj1B, 1); // cout << "showball 1 at initial position: " << endl; // obj1A.Print(); obj1B = obj1A.AtTime(time1B); // cout << "showball 1 at final position: " << endl; // obj1B.Print(); Obj obj2A; Obj obj2B; obj2A.position = obj1A.position; obj2A.speed = 25; obj2A.acceleration = _g; obj2B.position = obj1B.position; obj2B.acceleration = _g; auto angle2 = CalcInitialAngle(obj2A, obj2B, 1); cout << "showball 2 should be thrown at angle: " << Degrees(angle2)[Pi == pi] << endl; obj2A.velocity = Point::FromAngle(angle2, 25); // time it takes for snowball 2 to go from A to B: auto time2AB = CalcTime(obj2A, obj2B, 0); // They land at the same time: obj2B.time = obj1B.time; // Calculate start time: obj2A.time = obj2B.time - time2AB; cout << "snowball 2 should be thrown at time: " << obj2A.time << endl; } system("pause"); return 0; }