All pastes #2092473 Raw Edit

Something

public text v1 · immutable
#2092473 ·published 2011-10-22 08:29 UTC
rendered paste body
/*File: ship2.cxx
  Written by: Emily Cai (emilyrune@hotmail.com)
  October 20th, 2011
  The purpose of this program is to graw a gravitational field of 3 stars.*/

//------------------------------------------------------------------------
//Directives:
#include <cassert>
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <graphics.h>
using namespace std;
//------------------------------------------------------------------------

//------------------------------------------------------------------------
//Named Constants:

const double G = 6.67e-11;
const int FRAMES_PER_SEC = 30;
const int S = 500;
const double SIMTIME = 50000;
const double WMAX = 2.5e11;

//------------------------------------------------------------------------

//------------------------------------------------------------------------
//Prototypes:

// The parameters x and y give the location of a spaceship in a
// two-dimensional star field. The parameters sx and sy give the
// location of a star of mass m in this field. The return value
// is the acceleration along the x-axis that the ship feels from
// the star. All distances are in meters and the mass
// is in kilograms. The answer is in m/sec^2.
double accx(double x, double y, double sx, double sy, double m);

//------------------------------------------------------------------------
// The parameters x and y give the location of a spaceship in a
// two-dimensional star field. The parameters sx and sy give the
// location of a star of mass m in this field. The return value
// is the acceleration along the y-axis that the ship feels from
// the star. All distances are in meters and the mass
// is in kilograms. The answer is in m/sec^2.

double accy(double x, double y, double sx, double sy, double m);

//------------------------------------------------------------------------
//This draws a vector field.
void draw_grid(double x1, double y1, double m1, double x2,
	       double y2, double m2, double x3, double y3, double m3);

//------------------------------------------------------------------------
//This draws a ship!
void draw_ship (double x, double y);
//------------------------------------------------------------------------
//This retrieves the clicking of the left mouse to move the ship to where
//it was and reset the velocity of it to 0.
void left_mouseclick (double &x, double &y, double &vx, double &vy);

//------------------------------------------------------------------------
//This converts world coordinates to pixel coordinates.
int pixel(double wx, double w0, double w1, int p0, int p1);

//------------------------------------------------------------------------
//This gets the mouse click of the right mouse button to move the 3 planets
//and their gravitational field around them.
void right_mouseclick (int &count, double &x1, double &y1,double &x2, double &y2,
		       double &x3, double &y3);
//------------------------------------------------------------------------
//Opposite of the pixel function, changes pixel coords into world coords.
double world(int p, double v0, double v1, int p0, int p1);

//------------------------------------------------------------------------

//------------------------------------------------------------------------
int main()
{
      
    double x1 = 3.0e10;
    double y1 = -7.5e10;
    double x2 = -4.5e10;
    double y2 = 3.0e10;
    double x3 = 4.5e10;
    double y3 = 9.0e10;
    double m1 = 2.5e30;
    double m2 = 9.5e30;
    double m3 = 1.5e31;
    double x = -6.0e10;
    double y = -1.3e11;
    double vx = 0.0;
    double vy = 0.0;
    int count = 0;
    
    initwindow (S, S, "Field of Dreams", 0, 0, true);
    while (true)
    {

	clearviewport ();
	draw_ship(x, y);
	draw_grid(x1, y1, m1, x2, y2, m2, x3, y3, m3);

	setfillstyle (SOLID_FILL, YELLOW);
	fillellipse (pixel (x1, -WMAX, WMAX, 0, S),
		     pixel (y1, WMAX, -WMAX, 0, S), 5, 5);

	setfillstyle (SOLID_FILL, BLUE);
	fillellipse (pixel (x2, -WMAX, WMAX, 0, S),
		     pixel (y2, WMAX, -WMAX, 0, S), 7, 7);
    
	setfillstyle (SOLID_FILL, RED);
	fillellipse (pixel (x3, -WMAX, WMAX, 0, S),
		     pixel (y3, WMAX, -WMAX, 0, S), 9, 9);

	swapbuffers ();
	vx += (accx(x, y, x1, y1, m1) + accx (x, y, x2, y2, m2) +
	       accx(x, y, x3, y3, m3))*SIMTIME;
	vy += (accy (x, y, x1, y1, m1) + accy (x, y, x2, y2, m2) +
	       accy (x, y, x3, y3, m3))*SIMTIME;
	x += vx*SIMTIME;
	y += vy*SIMTIME;

	delay (1000/FRAMES_PER_SEC);
	left_mouseclick(x, y, vx, vy);
	right_mouseclick (count, x1, y1 ,x2 ,y2 ,x3 , y3);
	
    }
    return EXIT_SUCCESS;

}

//------------------------------------------------------------------------

//------------------------------------------------------------------------

double accx(double x, double y, double sx, double sy, double m)
{
    double dx = (sx - x);
    double dy = (sy - y);
    double denominator = pow(dx*dx + dy*dy, 1.5);

    return G*m*dx/denominator;
}
//-----------------------------------------------------------------------

//-----------------------------------------------------------------------

double accy(double x, double y, double sx, double sy, double m)
{
    double dx = (sx - x);
    double dy = (sy - y);
    double denominator = pow(dx*dx + dy*dy, 1.5);
    
    return G*m*dy/denominator;
}
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//The void draw_grid draws the white dots on the grid screen as well
//as the lines which show the gravitational pull of the planets through
//the m's.  The x's and y's are for the location of the stars.

void draw_grid(double x1, double y1, double m1, double x2,
	       double y2, double m2, double x3, double y3, double m3)
{
    double xvector;
    double yvector;
    double y;
    double x;
    double distance;
    
    for (x =-WMAX; x<=WMAX; x +=WMAX/6)
    {   
	for  (y =-WMAX; y<=WMAX; y +=WMAX/6)
	{
	    /*This part of the for loop shows what is needed to draw
	      the vectors in every point.*/
	    xvector = (accx(x, y, x1, y1, m1)+ accx (x, y, x2, y2, m2)
		       + accx (x, y,  x3, y3, m3));
	    yvector = (accy(x, y, x1, y1, m1)+ accy (x, y, x2, y2, m2)
		       + accy(x, y, x3, y3, m3));

	    xvector *= 5.0e10;
	    yvector *= 5.0e10;

	    distance = sqrt(xvector*xvector+yvector*yvector);
	    if (distance <= WMAX/7.07107)
	    {
		/*This part draws the lines that are connected to
		  the grid.*/
		line (pixel (x, -WMAX, WMAX, 0, S),
		      pixel (y, WMAX, -WMAX, 0, S),
		      pixel (x+xvector, -WMAX, WMAX, 0, S),
		      pixel (y+yvector, WMAX, -WMAX, 0, S));
		setfillstyle (SOLID_FILL, WHITE);
		fillellipse ( pixel (x+xvector, -WMAX, WMAX, 0, S),
			      pixel (y+yvector, WMAX, -WMAX, 0, S),
			      2, 2);
	    }
		       
	}		     
    }
}

//----------------------------------------------------------------------

//----------------------------------------------------------------------

void draw_ship (double x, double y)
{
   
    setfillstyle(SOLID_FILL, GREEN);
    fillellipse(pixel (x, -WMAX, WMAX, 0, S),
		pixel (y, WMAX, -WMAX, 0, S), 4, 4);
    
}
//----------------------------------------------------------------------

//----------------------------------------------------------------------

int pixel( double wx, double w0, double w1, int p0, int p1)
{
    // Sizes of the parts of the two coordinate systems
    // that we are using:
    double world_width = w1 - w0; 
    double pixel_width = p1 - p0;

    // How far across the world coordinate system is wx?
    double fraction = (wx - w0)/world_width;

    // Convert that fraction to the corresponding spot in
    // the pixel coordinate system:
    return int(p0 + fraction*pixel_width);
    //From professeur Michael Main's android.cxx
}

//----------------------------------------------------------------------

//----------------------------------------------------------------------
void left_mouseclick (double &x, double &y, double &vx, double &vy)
{
    int pixel_x, pixel_y;

    if (ismouseclick (WM_LBUTTONDOWN))
    {
	getmouseclick (WM_LBUTTONDOWN, pixel_x, pixel_y);
	vx = 0.0;
	vy = 0.0;
	x = world(pixel_x, -WMAX, WMAX, 0, S);
	y = world(pixel_y, WMAX, -WMAX, 0, S);

    }

}
//----------------------------------------------------------------------
void right_mouseclick (int &count, double &x1, double &y1,double &x2, double &y2,
		       double &x3, double &y3)
{
    
    int x, y;
    if(ismouseclick(WM_RBUTTONDOWN))
    {
	count++;
	switch(count%3)
	{
	case 1:
	    getmouseclick(WM_RBUTTONDOWN, x, y);
	    x1 = world(x, -WMAX, WMAX, 0, S);
	    y1 = world(y, WMAX, -WMAX, 0, S);

	    break;

	case 2:
	    getmouseclick(WM_RBUTTONDOWN, x, y);
	    x2 = world(x, -WMAX, WMAX, 0, S);
	    y2 = world(y, WMAX, -WMAX, 0, S);
	    
	    break;
	    
	case 0:
	    getmouseclick(WM_RBUTTONDOWN, x, y);
	    x3 = world(x, -WMAX, WMAX, 0, S);
	    y3 = world(y, WMAX, -WMAX, 0, S);

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