// File: projectile.cxx // Written by: Michael Main (main@colorado.edu) on Sep 27, 2011 // The purpose of this program is to show // how to draw the path of a free-falling projectile. //------------------------------------------------------------- // Directives: #include #include #include #include #include using namespace std; //------------------------------------------------------------- //------------------------------------------------------------- const int S = 500; // Screen size in pixels const double W = 200.0; // World coordinates go from -W to +W //------------------------------------------------------------- //------------------------------------------------------------- // Function Prototypes. // This function assumes that a square graphics window of size // pmax is open. It waits for a mouse click and then converts // the coordinates of that click into a point in a coordinate // system where x can range from vx0 to vx1 and y can range // from vy0 to vy1). These new coordinates are returned in the // reference parameters wx and wy. void get_mouse( int pmax, double vx0, double vy0, double vx1, double vy1, double& x, double& y ); // pixel(v, v0, v1, p0, p1) converts v from an interval that // ranges from v0 to v1 into an integer interval that ranges // from p0 to p1. int pixel(double v, double v0, double v1, int p0, int p1); // Draws the path of a projectile in a square graphics window // of size pmax. The world coordinate system goes from // -wmax to +wmax, with the origin in the center of the screen. // The projectile is launched from the origin at an angle of // theta radians and with a speed of v meters per second. The // strength of gravity is 9.8 m/sec^2. void projectile (int pmax, double wmax, double theta, double v, int color); // world(p, v0, v1, p0, p1) is a coordinate transformation, // similar to the pixel function, but it goes in the other // direction (converting a pixel coordinate p (ranging // from p0 to p1) into a world coordinate (ranging // from v0 to v1). double world(int p, double v0, double v1, int p0, int p1); //------------------------------------------------------------- //------------------------------------------------------------- int main() { double speed; // Initial speed of the projectile double angle; // Angle (in radians) for launch double mx, my; // Position of a mouse click in world coord. int color; // Color of a projectile path // Open the window and draw the cliff initwindow(S, S, "Projectile"); setfillstyle(SOLID_FILL, GREEN); bar (0, S/2, S/2, S); // Try different initial speeds and angles. while (true) { get_mouse(S, -W, +W, +W, -W, mx, my); cout << "That click was at " << "(" << mx << ", " << my << ")" << endl; color = YELLOW; speed = mx; angle = my; projectile(S, W, angle, speed, color); } // Pause and exit delay(20000); return EXIT_SUCCESS; } //------------------------------------------------------------- //------------------------------------------------------------- void get_mouse( int pmax, double vx0, double vy0, double vx1, double vy1, double& x, double& y ) { int px, py; // Pixel coordinates of a mouse click while (!ismouseclick(WM_LBUTTONDOWN)) { delay(100); } getmouseclick(WM_LBUTTONDOWN, px, py); x = world(px, vx0, vx1, 0, pmax); y = world(py, vy0, vy1, 0, pmax); } //------------------------------------------------------------- //------------------------------------------------------------- int pixel(double v, double v0, double v1, int p0, int p1) { return int(p0 + (v - v0)/(v1 - v0) * (p1 - p0)); } //------------------------------------------------------------- //------------------------------------------------------------- void projectile (int pmax, double wmax, double theta, double v, int color) { const double G = -9.8; // Strength of gravity in m/sec^2 double t; // Time in seconds double wx, wy; // Position of the projectile in meters int px, py; // Pixel coordinates of the projectile double vx = v * cos(theta); // Initial x velocity in m/sec double vy = v * sin(theta); // Initial y velocity in m/sec // Move the drawing pen to the center of the screen: setcolor(color); moveto(pmax/2, pmax/2); // For t values starting at t=0, draw a line to the point // of the curve that is determined by t. The curve is drawn // until the y coordinate falls off the bottom. t = 0; do { wx = vx*t; wy = vy*t + 0.5*G*t*t; px = pixel(wx, -wmax, +wmax, 0, pmax); py = pixel(wy, +wmax, -wmax, 0, pmax); lineto(px, py); t += 0.01; } while (wy > -wmax); } //------------------------------------------------------------- //------------------------------------------------------------- double world(int p, double v0, double v1, int p0, int p1) { double fraction = double(p - p0)/double(p1 - p0); double distance_from_v0 = fraction*(v1 - v0); return v0 + distance_from_v0; } //-------------------------------------------------------------