/* intersect.cpp Laura Toma What it does: Draws a set of horizontal and vertical line segments in the default 2D projection. Then it pretends to compute their intersections using the line sweep algorithm, and simulates the sweep line moving from left to right. */ #include "geom.h" #include "rtimer.h" #include #include #include #include #include //for usleep() #ifdef __APPLE__ #include #else #include #endif #include #include using namespace std; GLfloat red[3] = {1.0, 0.0, 0.0}; GLfloat green[3] = {0.0, 1.0, 0.0}; GLfloat blue[3] = {0.0, 0.0, 1.0}; GLfloat black[3] = {0.0, 0.0, 0.0}; GLfloat white[3] = {1.0, 1.0, 1.0}; GLfloat gray[3] = {0.5, 0.5, 0.5}; GLfloat yellow[3] = {1.0, 1.0, 0.0}; GLfloat magenta[3] = {1.0, 0.0, 1.0}; GLfloat cyan[3] = {0.0, 1.0, 1.0}; /* forward declarations of functions */ void display(void); void keypress(unsigned char key, int x, int y); void timerfunc(); void initialize_segments_random(); void initialize_segments_horizontal(); void print_segments(); //renders the sweep line void draw_sweep_line(); //renders the active structure void draw_active_structure(); //renders the intersection points void draw_intersection_points(); /* global variables */ const int WINDOWSIZE = 500; //we got two test cases so far: random and horizontal; add more! int init_case = 0; const int NB_TEST_CASES = 2; //NOTE: all the structures below need to be global so that they can be rendered //number of segments requested by user. This is entered on the command //line. int n; //the array of segments. Its size should match n vector segments; //the active structure that stores the segments intersecting the sweep line //this should be a BBST vector as; //the intersections points of the segments vector intpoints; //current position of sweep line; this is used to animate the sweep line moving int sweep_line_x = 0; //event types const int START = 1; const int END = 2; const int VERT = 3; struct event { point2D p; //the point corresponding to the event int type; //event type, START, END or VERT point2D op; // the other endpoint of the segment bool operator<(const event& a) const { return ((p.x < a.p.x) || //START before VERTICAL ((p.x == a.p.x) && (type == START) && (a.type == VERT)) || //VERTICAL before END ((p.x == a.p.x) && (type == VERT) && (a.type == END))); } }; vector events; int current_event = 0; /* ************************************************** */ //fills global variable "segments" with n segments void initialize_segments() { switch (init_case) { case 0: initialize_segments_random(); break; case 1: initialize_segments_horizontal(); break; default: initialize_segments_random(); } init_case = (init_case+1) % NB_TEST_CASES; return; } /* ************************************************** */ //fills global variable "segments" with a long horizontal segment and //n-1 vertical segments void initialize_segments_horizontal() { int i; point2D a,b; segment2D s; //clear the vector of segments segments.clear(); //a long horizontal segment a.x = 1; a.y = WINDOWSIZE/2; b.x = WINDOWSIZE - 10; b.y = a.y; s.start = a; s.end = b; segments.push_back(s); //n-1 vertical segments for (i=0; i= y1) && (as[i].start.y <= y2)) { point2D p; p.x = x; p.y = as[i].start.y; intpoints.push_back (p); printf("intersection point (%d,%d)\n", p.x, p.y); } } } /* ************************************************** */ void print_events(vector ev) { for (int i=0; i\n"); exit(1); } n = atoi(argv[1]); printf("you entered n=%d\n", n); assert(n >0); //the default is to initialize the segments randomly initialize_segments_random(); //print_segments(); initialize_events(); //print the timing // char buf [1024]; //rt_sprint(buf,rt1); //printf("run time: %s\n\n", buf); //fflush(stdout); /* initialize GLUT */ glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(WINDOWSIZE, WINDOWSIZE); glutInitWindowPosition(100,100); glutCreateWindow(argv[0]); /* register callback functions */ glutDisplayFunc(display); glutKeyboardFunc(keypress); glutIdleFunc(timerfunc); //<-------- we'll use it to animate /* init GL */ /* set background color black*/ glClearColor(0, 0, 0, 0); /* give control to event handler */ glutMainLoop(); return 0; } /* ****************************** */ /* draw the segments stored in global variable segments NOTE: We draw in the local coordinate system (0,0) to (WINSIZE,WINSIZE) */ void draw_segments(){ //set color glColor3fv(yellow); int i; for (i=0; i= events.size()) { current_event = 0; intpoints.clear(); as.clear(); } //advance sweep line to next event sweep_line_x = events[current_event].p.x; printf("sweepline at %d\n", sweep_line_x); //process next event switch (events[current_event].type) { case START: //insert segment in AS segment2D s; s.start = events[current_event].p; s.end = events[current_event].op; as.push_back(s); printf("\tinsert segment [(%d,%d),(%d,%d)]\n", events[current_event].p.x, events[current_event].p.y, events[current_event].op.x, events[current_event].op.y); break; case END: //delete segment from AS //to do printf("\tdelete segment [(%d,%d),(%d,%d)]\n", events[current_event].p.x, events[current_event].p.y, events[current_event].op.x, events[current_event].op.y); break; case VERT: //rangequery the AS and add intersections range_and_report(events[current_event].p.x, events[current_event].p.y, events[current_event].op.y); printf("\tvertical query segment [(%d,%d),(%d,%d)]\n", events[current_event].p.x, events[current_event].p.y, events[current_event].op.x, events[current_event].op.y); break; } current_event++; glutPostRedisplay(); } /* Handler for window re-size event. Called back when the window first appears and whenever the window is re-sized with its new width and height */ void reshape(GLsizei width, GLsizei height) { // GLsizei for non-negative integer // Set the viewport to cover the new window glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); // To operate on the Projection matrix glLoadIdentity(); // Reset gluOrtho2D(0.0, (GLdouble) width, 0.0, (GLdouble) height); }