/*************************************************************************** * *N intersect_polygon_edge * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * Count the number of intersections between a plum line from the * test point and infinity and the vertices of the given edge. *E *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * x <input> == (float) test point x coordinate. * y <input> == (float) test point y coordinate. * edge_rec <input> == (edge_rec_type) given edge. * intersect_polygon_edge <output> == (int) number of intersection points. *E **************************************************************************/ int intersect_polygon_edge( float x, float y, edge_rec_type edge_rec ) { register rspf_int32 i; line_segment_type lseg, pseg; int n; float xint,yint; coordinate_type coord1,coord2; lseg.x1 = x; lseg.y1 = y; lseg.x2 = MAXFLOAT/2.0; lseg.y2 = y; n = 0; coord1 = first_edge_coordinate(&edge_rec); for (i=1;i<edge_rec.npts;i++) { coord2 = next_edge_coordinate(&edge_rec); pseg.x1 = coord1.x; pseg.y1 = coord1.y; pseg.x2 = coord2.x; pseg.y2 = coord2.y; if (intersect(lseg,pseg,&xint,&yint)) { n++; } coord1 = coord2; } return n; }
/************************************************************************** * *N distance_to_edge_rec * *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function computes the minimum distance from the given point * to the given edge record by looking at each segment in the line. *E *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * x <input> == (float) given point x coordinate. * y <input> == (float) given point y coordinate * edge_rec <input> == (edge_rec_type) given edge record. * dec_degrees <inout> == (int) flag to indicate if coordinates are * in decimal degrees. * distance_to_edge_rec <output> == (float) minimum distance to the * edge record. *E *::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels, DOS Turbo C 1991 *E *************************************************************************/ float distance_to_edge_rec( float x, float y, edge_rec_type edge_rec, int dec_degrees ) { register long int i; line_segment_type lseg; float xint,yint, d, dseg, d1, d2; coordinate_type coord1, coord2; d = MAXFLOAT; coord1 = first_edge_coordinate(&edge_rec); for (i=1;i<edge_rec.npts;i++) { coord2 = next_edge_coordinate(&edge_rec); lseg.x1 = coord1.x; lseg.y1 = coord1.y; lseg.x2 = coord2.x; lseg.y2 = coord2.y; if (perpendicular_intersection(lseg,x,y,&xint,&yint)) { if (dec_degrees) dseg = distance( y, x, yint, xint, 0 ); else dseg = (float)(sqrt( (xint-x)*(xint-x) + (yint-y)*(yint-y) )); } else { if (dec_degrees) { dseg = (float)min( distance( y, x, lseg.y1, lseg.x1, 0 ), distance( y, x, lseg.y2, lseg.x2, 0 ) ); } else { d1 = (float)(sqrt( (lseg.x1-x)*(lseg.x1-x) + (lseg.y1-y)*(lseg.y1-y) )); d2 = (float)(sqrt( (lseg.x2-x)*(lseg.x2-x) + (lseg.y2-y)*(lseg.y2-y) )); dseg = (float)min(d1,d2); } } d = (float)min(d,dseg); coord1 = coord2; } return d; }
/************************************************************************* * *N draw_edge_coordinates * *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Purpose: *P * This function draws the coordinates of an edge record. * It tries its darndest to detect and get rid of projection * "zingers" - lines that dart across the screen because of * lines projected onto the map that wrap around behind the * globe or change hemispheres. The ability to handle these * projection artifacts is what turns what should be a very * simple function into a very ugly piece of code. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * Parameters: *A * edge_rec <input>==(edge_rec_type *) pointer to an edge record. * return <output>==(int) 0 if the user escapes, 1 upon successful * completion. *E *:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: * * History: *H * Barry Michaels Feb 1992 DOS Turbo C *E *************************************************************************/ int draw_edge_coordinates( edge_rec_type *edge_rec ) { int xscr,yscr, xprev,yprev, x1,y1,x2,y2, mbrx2, wrap; register ossim_int32 i; extent_type mbr; coordinate_type coord; /* First compute the MBR from the coordinates. */ coord = first_edge_coordinate(edge_rec); mbr.x1 = coord.x; mbr.y1 = coord.y; mbr.x2 = coord.x; mbr.y2 = coord.y; for (i=1;i<edge_rec->npts;i++) { coord = next_edge_coordinate(edge_rec); if (coord.x < mbr.x1) mbr.x1 = coord.x; if (coord.y < mbr.y1) mbr.y1 = coord.y; if (coord.x > mbr.x2) mbr.x2 = coord.x; if (coord.y > mbr.y2) mbr.y2 = coord.y; } screen_bounds(mbr.x1,mbr.y1,mbr.x2,mbr.y2,&x1,&y1,&x2,&y2); if ( (x1 < 0 && x2 < 0) || (x1 > gpgetmaxx() && x2 > gpgetmaxx()) || (y1 < 0 && y2 < 0) || (y1 > gpgetmaxy() && y2 > gpgetmaxy()) ) return 1; if (x1 > gpgetmaxx() && x2 < 0) return 1; wrap = 0; mbrx2 = x2; if (x2 < x1) { /* The box wraps around the screen */ /* (or at least wraps off the edge of the screen) */ wrap = gpgetmaxx(); if (x2 < 0) wrap -= x2; /* Adjust the maximum screen value */ x2 += wrap; } coord = first_edge_coordinate(edge_rec); screenxy(coord.x,coord.y,&xscr,&yscr); if (wrap && xscr < x1) xscr += wrap; gpmoveto(xscr,yscr); xprev = xscr; yprev = yscr; for (i=1;i<edge_rec->npts;i++) { coord = next_edge_coordinate(edge_rec); screenxy(coord.x,coord.y,&xscr,&yscr); if (xscr == MAXINT || yscr == MAXINT) { xprev = xscr; yprev = yscr; continue; } if (wrap && xscr < x1) xscr += wrap; if (xscr==xprev && yscr==yprev) continue; if (xprev == MAXINT || yprev == MAXINT) gpmoveto(xscr,yscr); hidemousecursor(); gplineto( xscr, yscr ); showmousecursor(); xprev = xscr; yprev = yscr; while (kbhit()) { if (getch()==27) { return 0; } } } if (wrap && mbrx2 > 0) { /* The edge wraps around and is displayed on the other */ /* edge of the screen. */ x2 -= wrap; coord = first_edge_coordinate(edge_rec); screenxy(coord.x,coord.y,&xscr,&yscr); if (xscr > x2) xscr -= wrap; gpmoveto(xscr,yscr); xprev = xscr; yprev = yscr; for (i=1;i<edge_rec->npts;i++) { coord = next_edge_coordinate(edge_rec); screenxy(coord.x,coord.y,&xscr,&yscr); if (xscr == MAXINT || yscr == MAXINT) { xprev = xscr; yprev = yscr; continue; } if (xscr > x2) xscr -= wrap; if (xscr==xprev && yscr==yprev) continue; if (xprev == MAXINT || yprev == MAXINT) gpmoveto(xscr,yscr); hidemousecursor(); gplineto( xscr, yscr ); showmousecursor(); xprev = xscr; yprev = yscr; while (kbhit()) { if (getch()==27) { return 0; } } } } return 1; }