示例#1
0
/***************************************************************************
 *
 *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;
}
示例#2
0
/**************************************************************************
 *
 *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;
}
示例#3
0
/*************************************************************************
 *
 *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;
}