/*
Jeffrey Grafton <jgrafton at tjhsst dot edu>
10/1/2002

This program is released under the GNU General Public License.
A copy of this license is available online at
http://www.gnu.org/copyleft/gpl.html.
*/

#include <GL/glut.h>
#include <math.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

#define MINX 0.1
#define MINY 0.1
#define MAXX 180.0
#define MAXY 200.0
#define WINDOW_WIDTH 600
#define WINDOW_HEIGHT 600

#define GRAVITY 9.80

void display_init(void);
void display(void);
void draw_graph(void);
void keyboard(unsigned char, int, int);

GLdouble angle = 30.0, velocity = 20.0, t = 0.0, wind = 10.0;
int status = 0;
char message[32]="";

int
main (int argc, char **argv)
{
	time_t time_var;
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
	glutCreateWindow("trajectory2");
	display_init();
	glutDisplayFunc(display);
	glutKeyboardFunc(keyboard);
	
	time(&time_var);
	srand(time_var); /* seed the random number generator */
	
	wind = (rand() % 201 - 100) / 10.0; /* set the wind velocity */
	
	glutMainLoop();
	return 0;
}

/* initialization routines */
void
display_init (void)
{
	glClearColor(0.0, 0.0, 0.2, 0.0);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(MINX, MAXX, MINY, MAXY, -1.0, 1.0);
	glClear(GL_COLOR_BUFFER_BIT);
}

/* main display function */
void
display (void)
{
	glClear(GL_COLOR_BUFFER_BIT);
	draw_graph();
}


/* draws the projectile in motion */
void
draw_graph (void)
{
	printf("wind: %f m/s\n", wind);
	glBegin(GL_POINTS);
	for (angle = 0.1; angle <= 180.0; angle += 0.1)
	{
		for (velocity = 0.1; velocity <= 200.0; velocity += 0.1)
		{
		GLdouble x = 1.0, y = 1.0, lastx = 0.0, lasty = 0.0, xv, yv, x0, y0, hitx = 0.0, distance = 0.00001;
		xv = velocity * cos(M_PI * angle / 180);
		yv = velocity * sin(M_PI * angle / 180);
		x0 = 10.0 * cos(M_PI * angle / 180);
		y0 = 10.0 * sin(M_PI * angle / 180);
	
			for(t = 0.0; y > 0.0; t += 0.1)
			{
				x = x0 + xv * t  + 0.5 * wind * t * t;
				y = y0 + yv * t - 0.5 * GRAVITY * t * t;

			
				/* check to see if we've hit the ground yet */
				if (y < 0.0 && (y - lasty) != 0.0)
				{
					GLdouble slope = (y - lasty) / (x - lastx);
					GLdouble yintercept = (y) - (slope * (x));
					hitx = -yintercept / (slope + 0.0001);
					/*printf ("y = %fx + %f -> %f\n", slope, yintercept, hitx);*/
				}
				lastx = x;
				lasty = y;
			}

			if (hitx < 100.0 && hitx != 0.0)
				distance = fabs(100.0 - hitx);
			else if (hitx > 110.0)
				distance = fabs(hitx - 110.0);
			else
				distance = 0.00001;
			
			/* closer to target = redder, higher angle = greener, higher velocity = bluer */
			glColor3d(1.0 - fabs(distance) / 100.0, fabs(angle) / 180.0, fabs(velocity) / 200.0);
			glVertex2d(angle, velocity);
		}
	}
	glEnd();
	glFlush();
}

/* keyboard callback function */
void
keyboard (unsigned char key, int x, int y)
{
	if (key == 13 || key == 32)
		wind = (rand() % 201 - 100) / 10.0; /* set the wind velocity */
	
 	glutPostRedisplay();
}

