All pastes #184701 Raw Edit

Anonymous

public c v1 · immutable
#184701 ·published 2006-09-28 04:42 UTC
rendered paste body
/* Assignment 1 - Duy Nguyen: September 12, 2006 *  This program draws a grid and allows the user to draw lines and polygons. * It handles techniques to draw lines at the pixel level, as well as filling * polygons as required. * *  Just to note, this program uses triangle.c as a template for many of the *  Glut functions. */#include <stdio.h>       #include <stdlib.h>      #include <string.h> #include <math.h>#include <unistd.h>/*// Sometimes glu.h includes glut.h--sometimes not.*/#ifdef MAC_OSX#    include <OpenGL/glu.h>#    include <GLUT/glut.h>#else #    include <GL/glu.h>       #    include <GL/glut.h>       #endif/* -------------------------------------------------------------------------- */// Function Declarationsint main(int argc, char *argv[]);static void display_CB(void);            /* Called whenever redisplay needed */static void key_CB(unsigned char key, int x, int y);     /* Called on key press */static void mouse_CB(int button, int state, int x, int y);  /* Called on mouse click */static void mouse_move_CB(int x, int y);static void parseFile();static void saveFile();static void drawLines();static void drawGun();static void splitAndRotate(int* lineA, int* lineB, int* point, int angle);static void rotate(int* lineA, int* lineB, int angle);static void fire();static int length(int x1, int y1, int x2, int y2);/* -------------------------------------------------------------------------- */// Instance Variable Declarationsstatic int lines[1000][2][3];static int size = 0;static double gunAngle = 90.0;static int mouseX = 0;static int mode = 0; // 1 is war modestatic int pointX;static int pointY;/* -------------------------------------------------------------------------- */int main(int argc, char *argv[]){    int win;    glutInit(&argc, argv);                /* initialize GLUT system */    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);    glutInitWindowSize(800, 600);     win = glutCreateWindow("Assignment 1");   /* create window */    /* set background to black */    glClearColor((GLclampf)0.0,(GLclampf)0.0,(GLclampf)0.0,(GLclampf)0.0);      gluOrtho2D(0.0, 800.0, 0.0, 600.0); /* how object is mapped to window */    glutDisplayFunc(display_CB);        /* set window's display callback */    glutKeyboardFunc(key_CB);           /* set window's key callback */    glutMouseFunc(mouse_CB);            /* set window's mouse callback */    glutMotionFunc(mouse_move_CB);      parseFile(); // Read in any predone code    glutMainLoop();                       /* start processing events... */    /* Execution never reaches this point, so return value is failure */    return EXIT_FAILURE;}/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////static void parseFile(){	if(!isatty(fileno(stdin)))	{		char temp[500];		while( fgets(temp, 500, stdin) != NULL)		{						const char delimiters[] = " ";			char* token;			char cp[500];			strcpy (cp, temp);        			token = strtok (cp, delimiters);			if( strcmp(token, "line") == 0)			{				int a = atoi(strtok (NULL, delimiters));				int b = atoi(strtok (NULL, delimiters));				int c = atoi(strtok (NULL, delimiters));				int d = atoi(strtok (NULL, delimiters));				lines[size][0][0] = a;				lines[size][0][1] = b;				lines[size][0][2] = 1;				lines[size][1][0] = c;				lines[size][1][1] = d;				lines[size][1][2]=  1;				size++;			}		}	}}static void saveFile(){	int i = 0;	for(i = 0; i < size; i++)	{		int a = lines[i][0][0];		int b = lines[i][0][1];		int c = lines[i][1][0];		int d = lines[i][1][1];		if( a != 0 || b != 0 || c != 0 || d != 0)		{			printf("lines %d %d %d %d\n", a,b,c,d);		}	}}static void drawLines(){	glColor3d(.8, .8, .8); 	int i = 0;	for( i = 0; i < size; i ++)	{  		glBegin(GL_LINES); //Start Draw		//printf("%d %d %d %d\n", lines[i][0][0],lines[i][0][1],lines[i][1][0],lines[i][1][1]);		glVertex3f( lines[i][0][0], lines[i][0][1], 0);		glVertex3f( lines[i][1][0], lines[i][1][1], 0);				glEnd(); //End Draw	}}static void drawGun(){	glColor3d(0, .8, 0);	double a = sin(gunAngle*(3.1415/180));	double b = cos(gunAngle*(3.1415/180));	glBegin(GL_LINES); //Start Draw	glVertex3f( 400, 0, 0);	glVertex3f( b*50 + 400, a*50, 0);			glEnd(); //End Draw}static void splitAndRotate(int* lineA, int* lineB, int* point, int angle){	//Split	int x = lineB[0];	int y = lineB[1];	lineB[0] = point[0];	lineB[1] = point[1];	lines[size][0][0] = x;	lines[size][0][1] = y;	lines[size][0][2] = 1;	lines[size][1][0] = point[0];	lines[size][1][1] = point[1];	lines[size][1][2]=  1;	//Rotate	if( lineA[0] == lines[size][0][0] ) //Vertical line	{		if(lineA[0] >=400) //on right side of screen		{			if(lineA[1] > lines[size][0][1])			{				rotate(lineA, lineB, angle);				rotate(lines[size][0], lines[size][1], -angle);			}			else			{				rotate(lineA, lineB, -angle);				rotate(lines[size][0], lines[size][1], angle);			}		}		else		{			if(lineA[1] > lines[size][0][1])			{				rotate(lineA, lineB, -angle);				rotate(lines[size][0], lines[size][1], angle);			}			else			{				rotate(lineA, lineB, angle);				rotate(lines[size][0], lines[size][1], -angle);			}		}	}	else if( lineA[0] <= lines[size][0][0]) //lineA is leftmost anchor	{		//Rotate lineA positive		rotate(lineA, lineB, angle);		rotate(lines[size][0], lines[size][1], -angle);	}	else 	//lineA is rightmost anchor	{		rotate(lineA, lineB, -angle);		rotate(lines[size][0], lines[size][1], angle);	}		//check line size	size++;}static void rotate(int* lineA, int* lineB, int angle){	//Move to origin	int a = lineA[0];	int b = lineA[1];	int mat[3][3] = {{1,0,-a},				 {0,1,-b},				 {0,0,1}};	int x = lineB[0]*mat[0][0] + lineB[1]*mat[0][1] + lineB[2]*mat[0][2];	int y = lineB[0]*mat[1][0] + lineB[1]*mat[1][1] + lineB[2]*mat[1][2];	int z = lineB[0]*mat[2][0] + lineB[1]*mat[2][1] + lineB[2]*mat[2][2];	lineB[0] = x;	lineB[1] = y;	lineB[2] = z;	double rad = angle*(3.14/180);	double mat2[3][3] = {{cos(rad),-sin(rad),0},			{ sin(rad),cos(rad),0},			{ 0,0,1}};	double x2 = lineB[0]*mat2[0][0] + lineB[1]*mat2[0][1] + lineB[2]*mat2[0][2];	double y2 = lineB[0]*mat2[1][0] + lineB[1]*mat2[1][1] + lineB[2]*mat2[1][2];	double z2 = lineB[0]*mat2[2][0] + lineB[1]*mat2[2][1] + lineB[2]*mat2[2][2];	lineB[0] = x2;	lineB[1] = y2;	lineB[2] = z2;	int mat3[3][3] = {{1,0,a},				 {0,1,b},				 {0,0,1}};	 x = lineB[0]*mat3[0][0] + lineB[1]*mat3[0][1] + lineB[2]*mat3[0][2];	 y = lineB[0]*mat3[1][0] + lineB[1]*mat3[1][1] + lineB[2]*mat3[1][2];	 z = lineB[0]*mat3[2][0] + lineB[1]*mat3[2][1] + lineB[2]*mat3[2][2];	lineB[0] = x;	lineB[1] = y;	lineB[2] = z;}static void fire(){	double a = sin(gunAngle*(3.1415/180));	double b = cos(gunAngle*(3.1415/180));	int gunX = (b*50 + 400);	int gunY = (a*50);	//Find intersecting line	int bestLine = -1;	pointX = 0; 	pointY = -20; //gun can't shoot down, so Y must be at least 0	int distance = 5000;	int i = 0;	for(i = 0; i < size; i++)	{		int x1 = lines[i][0][0];		int x2 = lines[i][1][0];		int y1 = lines[i][0][1];		int y2 = lines[i][1][1];		int yB = 0;		int xB = 400;				if (x2 != x1)		{			double m = (y2-y1)/(x2-x1);			double m2 = tan(gunAngle*(3.14/180));				if(m != m2)			{				int newX = (yB - m2*xB - y1 + m*x1)/(m-m2);				int newY = y1 + m*(newX-x1);					printf("news: %d %d\n", newX, newY);							if( x1 < x2)				{					if(newX >= x1 && newX <= x2)					{						if(length(400,0,newX,newY) < distance && length(400,0,newX,newY) > 50)						{							distance = length(400,0,newX,newY);							pointX = newX;							pointY = newY;							bestLine = i;						}					}				}				else				{					if(newX <= x1 && newX >= x2)					{						if(length(400,0,newX,newY) < distance && length(400,0,newX,newY) > 50)						{							distance = length(400,0,newX,newY);							pointX = newX;							pointY = newY;							bestLine = i;						}					}				}			}		}		else		{			double m2 = tan(gunAngle*(3.14/180));			int newX = x1;			int newY = yB + m2*(newX-xB);			if(length(400,0,newX,newY) < distance && length(400,0,newX,newY) > 50)			{				distance = length(400,0,newX,newY);				pointX = newX;				pointY = newY;				bestLine = i;			}		}		}	//printf("%d %d\n", pointX, pointY);	if(pointY < 0)	{		double m2 = tan(gunAngle*(3.14/180));		if(gunAngle < 90)		{			pointX = 400;			pointY = 0 + m2*(pointX-400);		}		else(gunAngle > 90)		{			pointX = -400;			pointY = 0 + m2*(pointX-400);		}		else		{			pointX = 400;			pointY = 600;		}	}	//shoot laser	//printf("fire! %d %d\n", pointX, pointY);	display_CB();	if(bestLine != -1)	{			splitAndRotate(lines[bestLine][0], lines[bestLine][1], point, 45);	}	sleep(3);	pointX = 0; 	pointY = -20;		printf("%d\n", size);	display_CB();	saveFile();}static int length(int x1, int y1, int x2, int y2){	//printf("%d %d %d %d\n", x1, y1, x2, y2);	int xd = x2-x1;	int yd = y2-y1;	return sqrt(xd*xd + yd*yd);}//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*  /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\   *//*// Function called whenever redisplay needed (try hiding the window and then// exposing it. The debug macro should print something.)*/static void display_CB(void){    glClear(GL_COLOR_BUFFER_BIT);         /* clear the display */	drawLines();	drawGun();	glColor3d(.8, 0, 0);	glBegin(GL_LINES); //Start Draw	glVertex3f( 400, 0, 0);	glVertex3f( pointX, pointY, 0);			glEnd(); //End Draw	    glFlush();         /* Complete any pending operations */    glutSwapBuffers(); /* Make the drawing buffer the frame buffer                           and vice versa */}/*  /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\   *//* Function called on key press */static void key_CB(unsigned char key, int x, int y) {    	if( key == 'q' ) 	{		saveFile();		exit(0);	}}/*  /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\   *//* Function called on mouse click */static void mouse_CB(int button, int state, int x, int y)  {	//printf("%d %d %d\n", button, state, mode);	if(button == 0 && state == 0)	{		mode = 2;		mouseX = x;	}		if(button == 0 && state == 1)	{		mode = 1;		mouseX = x;	}	if(button == 2 && state == 1)	{		fire();	}}/*  /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\   *//* Function called on mouse move while depressed. */static void mouse_move_CB(int x, int y)  {	if(mode == 2)	{		if( x > mouseX)		{			gunAngle = gunAngle - 2;			if( gunAngle < 0)				gunAngle = 0;					mouseX = x;		}		else if( x < mouseX)		{			gunAngle = gunAngle + 2;			if( gunAngle > 180)				gunAngle = 180;						mouseX = x;		}			display_CB();	}	//printf("%f\n", gunAngle);}