Created
November 28, 2012 10:22
-
-
Save dharmatech/4160330 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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); } | |
}; | |
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 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) | |
{ | |
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; | |
throw "exception"; | |
} | |
int _tmain(int argc, _TCHAR* argv[]) | |
{ | |
// A long-jumper leaves the ground at an angle of 20.0° above | |
// the horizontal and at a speed of 11.0 m/s. (a) How far does | |
// he jump in the horizontal direction? (Assume his motion is | |
// equivalent to that of a particle.) | |
// For the purposes of solving the problem, let's take | |
// point A as the initial position | |
// point B as the peak position | |
// point C as the final position. | |
// First we'll get the answer in a symbolic form. | |
Obj objA; // An Obj representing the object at A | |
objA.position = Point(0, 0); | |
auto thA = Symbolic("thA"); // angle at point A | |
auto vA = Symbolic("vA"); // velocity at point A | |
objA.velocity = Point::FromAngle(thA, vA); | |
objA.acceleration = Point(0, -g); | |
objA.time = 0; | |
Obj objB; | |
// The horizontal velocity at B is the same as it is at A. | |
// The vertical velocity at B is 0; | |
objB.velocity = Point(objA.velocity.x, 0); | |
objB.acceleration = Point(0, -g); | |
auto timeB = CalcTime(objA, objB); | |
auto timeC = timeB * 2; | |
// Let's display the object at the three states, A, B, C: | |
cout << "object at point A:" << endl; | |
objA.Print(); | |
cout << endl ; | |
cout << "object at point B:" << endl; | |
objA.AtTime(timeB).Print(); | |
cout << endl; | |
cout << "object at point C:" << endl; | |
objA.AtTime(timeC).Print(); | |
cout << endl; | |
// Now let's get the numerical answer. | |
// Subsitute the numerical values to get a numerical timeB value: | |
auto timeBNum = timeB[g==9.8, thA==Radians(20), vA==11][Pi==3.14159]; | |
cout << "numerical time at B is "; | |
cout << timeBNum << endl << endl; | |
// Let's reassign some symbols to their numerical values: | |
Pi = 3.14159; | |
thA = Radians(20); | |
vA = 11; | |
g = 9.8; | |
// Re-run the calculation to get the numerical values. | |
objA.velocity = Point::FromAngle(thA, vA); | |
objA.acceleration = Point(0, -g); | |
cout << "object at point A (numerical): " << endl; | |
objA.AtTime(0).Print(); | |
cout << endl; | |
cout << "object at point B (numerical): " << endl; | |
objA.AtTime(timeBNum).Print(); | |
cout << endl; | |
cout << "object at point C (numerical): " << endl; | |
objA.AtTime(timeBNum*2).Print(); | |
cout << endl; | |
cout << "How far does he dump in the horizontal direction?" << endl; | |
cout << objA.AtTime(timeBNum*2).position.x << endl << endl; | |
cout << "What is the maximum height reached?" << endl; | |
cout << objA.AtTime(timeBNum).position.y << endl; | |
system("pause"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment