Exemple #1
0
IGL_INLINE void igl::circulation(
  const int e,
  const bool ccw,
  const Eigen::MatrixXi & F,
  const Eigen::MatrixXi & E,
  const Eigen::VectorXi & EMAP,
  const Eigen::MatrixXi & EF,
  const Eigen::MatrixXi & EI,
  Eigen::VectorXi & vN)
{
  std::vector<int> N = circulation(e,ccw,F,E,EMAP,EF,EI);
  igl::list_to_matrix(N,vN);
}
Exemple #2
0
void
plP_plfclp(PLINT *x, PLINT *y, PLINT npts,
	   PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax,
	   void (*draw) (short *, short *, PLINT))
{
    PLINT i, xx1, xx2, yy1, yy2;
    int iclp = 0, iout = 2;
    short _xclp[2*PL_MAXPOLY+2], _yclp[2*PL_MAXPOLY+2];
    short *xclp, *yclp;
    int drawable;
    int crossed_xmin1 = 0, crossed_xmax1 = 0;
    int crossed_ymin1 = 0, crossed_ymax1 = 0;
    int crossed_xmin2 = 0, crossed_xmax2 = 0;
    int crossed_ymin2 = 0, crossed_ymax2 = 0;
    int crossed_up    = 0, crossed_down  = 0;
    int crossed_left  = 0, crossed_right = 0;
    int inside_lb ;
    int inside_lu ;
    int inside_rb ;
    int inside_ru ;

/* Must have at least 3 points and draw() specified */
    if (npts < 3 || !draw) return;

    if ( npts < PL_MAXPOLY ) {
        xclp = _xclp;
        yclp = _yclp;
    } else {
        xclp = (short *) malloc( (2*npts+2)*sizeof(short) ) ;
        yclp = (short *) malloc( (2*npts+2)*sizeof(short) ) ;
    }


    inside_lb = pointinpolygon(npts,x,y,xmin,ymin) ;
    inside_lu = pointinpolygon(npts,x,y,xmin,ymax) ;
    inside_rb = pointinpolygon(npts,x,y,xmax,ymin) ;
    inside_ru = pointinpolygon(npts,x,y,xmax,ymax) ;

    for (i = 0; i < npts - 1; i++) {
	xx1 = x[i]; xx2 = x[i+1];
	yy1 = y[i]; yy2 = y[i+1];

	drawable = (INSIDE(xx1, yy1) && INSIDE(xx2, yy2));
	if ( ! drawable)
	    drawable = ! clipline(&xx1, &yy1, &xx2, &yy2,
				  xmin, xmax, ymin, ymax);

	if (drawable) {
	/* Boundary crossing condition -- coming in. */
	    crossed_xmin2 = (xx1 == xmin); crossed_xmax2 = (xx1 == xmax);
	    crossed_ymin2 = (yy1 == ymin); crossed_ymax2 = (yy1 == ymax);

	    crossed_left  = (crossed_left  || crossed_xmin2);
	    crossed_right = (crossed_right || crossed_xmax2);
	    crossed_down  = (crossed_down  || crossed_ymin2);
	    crossed_up    = (crossed_up    || crossed_ymax2);
	    iout = iclp+2;
	/* If the first segment, just add it. */

	    if (iclp == 0) {
		xclp[iclp] = xx1; yclp[iclp] = yy1; iclp++;
		xclp[iclp] = xx2; yclp[iclp] = yy2; iclp++;
	    }

	/* Not first point.  If first point of this segment matches up to the
	   previous point, just add it.  */

	    else if (xx1 == xclp[iclp-1] && yy1 == yclp[iclp-1]) {
		xclp[iclp] = xx2; yclp[iclp] = yy2; iclp++;
	    }

	/* Otherwise, we need to add both points, to connect the points in the
	 * polygon along the clip boundary.  If we encircled a corner, we have
	 * to add that first.
	 */

	    else {
	    /* Treat the case where we encircled two corners:
	       Construct a polygon out of the subset of vertices
	       Note that the direction is important too when adding
	       the extra points */
		xclp[iclp+1] = xx2; yclp[iclp+1] = yy2;
		xclp[iclp+2] = xx1; yclp[iclp+2] = yy1;
		iout = iout - iclp + 1;
	    /* Upper two */
		if ( ((crossed_xmin1 && crossed_xmax2) ||
			     (crossed_xmin2 && crossed_xmax1)) &&
			inside_lu )
		{
		    if ( crossed_xmin1 )
		    {
		        xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
		        xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
		    } else {
		        xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
		        xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
		    }
		}
	    /* Lower two */
		else if ( ((crossed_xmin1 && crossed_xmax2) ||
			          (crossed_xmin2 && crossed_xmax1)) &&
			inside_lb )
		{
		    if ( crossed_xmin1 )
		    {
		        xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
		        xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
		    } else {
		        xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
		        xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
		    }
		}
	    /* Left two */
		else if ( ((crossed_ymin1 && crossed_ymax2) ||
			          (crossed_ymin2 && crossed_ymax1)) &&
			inside_lb )
		{
		    if ( crossed_ymin1 )
		    {
		        xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
		        xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
		    } else {
		        xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
		        xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
		    }
		}
	    /* Right two */
		else if ( ((crossed_ymin1 && crossed_ymax2) ||
			          (crossed_ymin2 && crossed_ymax1)) &&
			inside_rb )
		{
		    if ( crossed_ymin1 )
		    {
		        xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
		        xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
		    } else {
		        xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
		        xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
		    }
		}
	    /* Now the case where we encircled one corner */
	    /* Lower left */
		else if ( (crossed_xmin1 && crossed_ymin2) ||
			  (crossed_ymin1 && crossed_xmin2) )
		{
		    xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
		}
	    /* Lower right */
		else if ( (crossed_xmax1 && crossed_ymin2) ||
			  (crossed_ymin1 && crossed_xmax2) )
		{
		    xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
		}
	    /* Upper left */
		else if ( (crossed_xmin1 && crossed_ymax2) ||
			  (crossed_ymax1 && crossed_xmin2) )
		{
		    xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
		}
	    /* Upper right */
		else if ( (crossed_xmax1 && crossed_ymax2) ||
			  (crossed_ymax1 && crossed_xmax2) )
		{
		    xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
		}

	    /* Now add current segment. */
		xclp[iclp] = xx1; yclp[iclp] = yy1; iclp++;
		xclp[iclp] = xx2; yclp[iclp] = yy2; iclp++;
	    }

	/* Boundary crossing condition -- going out. */
	    crossed_xmin1 = (xx2 == xmin); crossed_xmax1 = (xx2 == xmax);
	    crossed_ymin1 = (yy2 == ymin); crossed_ymax1 = (yy2 == ymax);
	}
    }

/* Limit case - all vertices are outside of bounding box.  So just fill entire
   box, *if* the bounding box is completely encircled.
*/

    if (iclp == 0) {
	PLINT xmin1, xmax1, ymin1, ymax1;
	xmin1 = xmax1 = x[0];
	ymin1 = ymax1 = y[0];
	for (i = 1; i < npts; i++) {
	    if (x[i] < xmin1) xmin1 = x[i];
	    if (x[i] > xmax1) xmax1 = x[i];
	    if (y[i] < ymin1) ymin1 = y[i];
	    if (y[i] > ymax1) ymax1 = y[i];
	}
	if (xmin1 <= xmin && xmax1 >= xmax && ymin1 <= ymin && ymax1 >= ymax ) {
	    xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
	    xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
	    xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
	    xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
	    (*draw)(xclp, yclp, iclp);

	    if ( xclp != _xclp ) {
	        free( xclp );
	        free( yclp );
	    }


	    return;
	}
    }

/* Now handle cases where fill polygon intersects two sides of the box */

    if (iclp >= 2) {
	int debug=0;
	int dir = circulation(x, y, npts);
	if (debug) {
	    if ( (xclp[0] == xmin && xclp[iclp-1] == xmax) ||
		 (xclp[0] == xmax && xclp[iclp-1] == xmin) ||
		 (yclp[0] == ymin && yclp[iclp-1] == ymax) ||
		 (yclp[0] == ymax && yclp[iclp-1] == ymin) ||
		 (xclp[0] == xmin && yclp[iclp-1] == ymin) ||
		 (yclp[0] == ymin && xclp[iclp-1] == xmin) ||
		 (xclp[0] == xmax && yclp[iclp-1] == ymin) ||
		 (yclp[0] == ymin && xclp[iclp-1] == xmax) ||
		 (xclp[0] == xmax && yclp[iclp-1] == ymax) ||
		 (yclp[0] == ymax && xclp[iclp-1] == xmax) ||
		 (xclp[0] == xmin && yclp[iclp-1] == ymax) ||
		 (yclp[0] == ymax && xclp[iclp-1] == xmin) ) {
		printf("dir=%d, clipped points:\n", dir);
		for (i=0; i < iclp; i++)
		    printf(" x[%d]=%d y[%d]=%d", i, xclp[i], i, yclp[i]);
		printf("\n");
		printf("pre-clipped points:\n");
		for (i=0; i < npts; i++)
		    printf(" x[%d]=%d y[%d]=%d", i, x[i], i, y[i]);
		printf("\n");
	    }
	}

    /* The cases where the fill region is divided 2/2 */
    /* Divided horizontally */
	if (xclp[0] == xmin && xclp[iclp-1] == xmax)
	{
	    if (dir > 0) {
		xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
		xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
	    }
	    else {
		xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
		xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
	    }
	}
	else if (xclp[0] == xmax && xclp[iclp-1] == xmin)
	{
	    if (dir > 0) {
		xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
		xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
	    }
	    else {
		xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
		xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
	    }
	}

    /* Divided vertically */
	else if (yclp[0] == ymin && yclp[iclp-1] == ymax)
	{
	    if (dir > 0) {
		xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
		xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
	    }
	    else {
		xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
		xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
	    }
	}
	else if (yclp[0] == ymax && yclp[iclp-1] == ymin)
	{
	    if (dir > 0) {
		xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
		xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
	    }
	    else {
		xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
		xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
	    }
	}

    /* The cases where the fill region is divided 3/1 --
          LL           LR           UR           UL
       +-----+      +-----+      +-----+      +-----+
       |     |      |     |      |    \|      |/    |
       |     |      |     |      |     |      |     |
       |\    |      |    /|      |     |      |     |
       +-----+      +-----+      +-----+      +-----+

       Note when we go the long way around, if the direction is reversed the
       three vertices must be visited in the opposite order.
    */
    /* LL, short way around */
	else if ((xclp[0] == xmin && yclp[iclp-1] == ymin && dir < 0) ||
		 (yclp[0] == ymin && xclp[iclp-1] == xmin && dir > 0) )
	{
	    xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
	}
    /* LL, long way around, counterclockwise */
	else if ((xclp[0] == xmin && yclp[iclp-1] == ymin && dir > 0))
	{
	    xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
	    xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
	    xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
	}
    /* LL, long way around, clockwise */
	else if ((yclp[0] == ymin && xclp[iclp-1] == xmin && dir < 0))
	{
	    xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
	    xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
	    xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
	}
    /* LR, short way around */
	else if ((xclp[0] == xmax && yclp[iclp-1] == ymin && dir > 0) ||
		 (yclp[0] == ymin && xclp[iclp-1] == xmax && dir < 0) )
	{
	    xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
	}
    /* LR, long way around, counterclockwise */
	else if (yclp[0] == ymin && xclp[iclp-1] == xmax && dir > 0)
	{
	    xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
	    xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
	    xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
	}
    /* LR, long way around, clockwise */
	else if (xclp[0] == xmax && yclp[iclp-1] == ymin && dir < 0)
	{
	    xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
	    xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
	    xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
	}
    /* UR, short way around */
	else if ((xclp[0] == xmax && yclp[iclp-1] == ymax && dir < 0) ||
		 (yclp[0] == ymax && xclp[iclp-1] == xmax && dir > 0) )
	{
	    xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
	}
    /* UR, long way around, counterclockwise */
	else if (xclp[0] == xmax && yclp[iclp-1] == ymax && dir > 0)
	{
	    xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
	    xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
	    xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
	}
    /* UR, long way around, clockwise */
	else if (yclp[0] == ymax && xclp[iclp-1] == xmax && dir < 0)
	{
	    xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
	    xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
	    xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
	}
    /* UL, short way around */
	else if ((xclp[0] == xmin && yclp[iclp-1] == ymax && dir > 0) ||
		 (yclp[0] == ymax && xclp[iclp-1] == xmin && dir < 0) )
	{
	    xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
	}
    /* UL, long way around, counterclockwise */
	else if (yclp[0] == ymax && xclp[iclp-1] == xmin && dir > 0)
	{
	    xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
	    xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
	    xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
	}
    /* UL, long way around, clockwise */
	else if (xclp[0] == xmin && yclp[iclp-1] == ymax && dir < 0)
	{
	    xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
	    xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
	    xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
	}
    }

/* Check for the case that only one side has been crossed
   (AM) Just checking a single point turns out not to be
   enough, apparently the crossed_*1 and crossed_*2 variables
   are not quite what I expected.
*/
    if ( crossed_left+crossed_right+crossed_down+crossed_up == 1 &&
		inside_lb+inside_rb+inside_lu+inside_ru == 4 ) {
	int dir = circulation(x, y, npts);
	PLINT xlim[4], ylim[4];
	int insert;
	int incr;

	xlim[0] = xmin ; ylim[0] = ymin ;
	xlim[1] = xmax ; ylim[1] = ymin ;
	xlim[2] = xmax ; ylim[2] = ymax ;
	xlim[3] = xmin ; ylim[3] = ymax ;
	if ( dir > 0 ) {
	    incr   = 1;
	    insert = 0*crossed_left + 1*crossed_down + 2*crossed_right +
	             3*crossed_up ;
	} else {
	    incr   = -1;
	    insert = 3*crossed_left + 2*crossed_up + 1*crossed_right +
	             0*crossed_down ;
	}
	for ( i=0; i < 4; i ++ ) {
	    xclp[iclp] = xlim[insert] ;
	    yclp[iclp] = ylim[insert] ;
	    iclp   ++ ;
	    insert += incr ;
	    if ( insert > 3 ) insert = 0 ;
	    if ( insert < 0 ) insert = 3 ;
	}
    }

/* Draw the sucker */
    if (iclp >= 3)
	(*draw)(xclp, yclp, iclp);

    if ( xclp != _xclp ) {
        free( xclp );
        free( yclp );
    }
}
Exemple #3
0
void
plP_plfclp(PLINT *x, PLINT *y, PLINT npts,
	   PLINT xmin, PLINT xmax, PLINT ymin, PLINT ymax,
	   void (*draw) (short *, short *, PLINT))
{
    PLINT i, x1, x2, y1, y2;
    int iclp = 0, iout = 2;
    short xclp[2*PL_MAXPOLY+2], yclp[2*PL_MAXPOLY+2];
    int drawable;
    int crossed_xmin1 = 0, crossed_xmax1 = 0;
    int crossed_ymin1 = 0, crossed_ymax1 = 0;
    int crossed_xmin2 = 0, crossed_xmax2 = 0;
    int crossed_ymin2 = 0, crossed_ymax2 = 0;

/* Must have at least 3 points and draw() specified */
    if (npts < 3 || !draw) return;

    for (i = 0; i < npts - 1; i++) {
	x1 = x[i]; x2 = x[i+1];
	y1 = y[i]; y2 = y[i+1];

	drawable = (INSIDE(x1, y1) && INSIDE(x2, y2));
	if ( ! drawable)
	    drawable = ! clipline(&x1, &y1, &x2, &y2, xmin, xmax, ymin, ymax);

	if (!drawable) {
	/* Store the edges outside the viewport */
	    xclp[iout] = x2;
	    yclp[iout] = y2;
	    iout ++;
	} else {
	/* Boundary crossing condition -- coming in. */
	    crossed_xmin2 = (x1 == xmin); crossed_xmax2 = (x1 == xmax);
	    crossed_ymin2 = (y1 == ymin); crossed_ymax2 = (y1 == ymax);
	    iout = iclp+2;

	/* If the first segment, just add it. */

	    if (iclp == 0) {
		xclp[iclp] = x1; yclp[iclp] = y1; iclp++;
		xclp[iclp] = x2; yclp[iclp] = y2; iclp++;
	    }

	/* Not first point.  If first point of this segment matches up to the
	   previous point, just add it.  */

	    else if (x1 == xclp[iclp-1] && y1 == yclp[iclp-1]) {
		xclp[iclp] = x2; yclp[iclp] = y2; iclp++;
	    }

	/* Otherwise, we need to add both points, to connect the points in the
	 * polygon along the clip boundary.  If we encircled a corner, we have
	 * to add that first.
	 */

	    else {
	    /* Treat the case where we encircled two corners:
	       Construct a polygon out of the subset of vertices
	       Note that the direction is important too when adding
	       the extra points */
		xclp[iclp+1] = x2; yclp[iclp+1] = y2;
		xclp[iclp+2] = x1; yclp[iclp+2] = y1;
		iout = iout - iclp;
	    /* Upper two */
		if ( ((crossed_xmin1 && crossed_xmax2) ||
			     (crossed_xmin2 && crossed_xmax1)) &&
			pointinpolygon(iout,&xclp[iclp+1],&yclp[iclp+1],xmin,ymax) )
		{
		    if ( crossed_xmin1 )
		    {
		        xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
		        xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
		    } else {
		        xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
		        xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
		    }
		}
	    /* Lower two */
		else if ( ((crossed_xmin1 && crossed_xmax2) ||
			          (crossed_xmin2 && crossed_xmax1)) &&
			pointinpolygon(iout,&xclp[iclp+1],&yclp[iclp+1],xmin,ymin) )
		{
		    if ( crossed_xmin1 )
		    {
		        xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
		        xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
		    } else {
		        xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
		        xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
		    }
		}
	    /* Left two */
		else if ( ((crossed_ymin1 && crossed_ymax2) ||
			          (crossed_ymin2 && crossed_ymax1)) &&
			pointinpolygon(iout,&xclp[iclp+1],&yclp[iclp+1],xmin,ymin) )
		{
		    if ( crossed_ymin1 )
		    {
		        xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
		        xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
		    } else {
		        xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
		        xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
		    }
		}
	    /* Right two */
		else if ( ((crossed_ymin1 && crossed_ymax2) ||
			          (crossed_ymin2 && crossed_ymax1)) &&
			pointinpolygon(iout,&xclp[iclp+1],&yclp[iclp+1],xmax,ymin) )
		{
		    if ( crossed_ymin1 )
		    {
		        xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
		        xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
		    } else {
		        xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
		        xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
		    }
		}
	    /* Now the case where we encircled one corner */
	    /* Lower left */
		else if ( (crossed_xmin1 && crossed_ymin2) ||
			  (crossed_ymin1 && crossed_xmin2) )
		{
		    xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
		}
	    /* Lower right */
		else if ( (crossed_xmax1 && crossed_ymin2) ||
			  (crossed_ymin1 && crossed_xmax2) )
		{
		    xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
		}
	    /* Upper left */
		else if ( (crossed_xmin1 && crossed_ymax2) ||
			  (crossed_ymax1 && crossed_xmin2) )
		{
		    xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
		}
	    /* Upper right */
		else if ( (crossed_xmax1 && crossed_ymax2) ||
			  (crossed_ymax1 && crossed_xmax2) )
		{
		    xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
		}

	    /* Now add current segment. */
		xclp[iclp] = x1; yclp[iclp] = y1; iclp++;
		xclp[iclp] = x2; yclp[iclp] = y2; iclp++;
	    }

	/* Boundary crossing condition -- going out. */
	    crossed_xmin1 = (x2 == xmin); crossed_xmax1 = (x2 == xmax);
	    crossed_ymin1 = (y2 == ymin); crossed_ymax1 = (y2 == ymax);
	}
    }

/* Limit case - all vertices are outside of bounding box.  So just fill entire
   box, *if* the bounding box is completely encircled.
*/

    if (iclp == 0) {
	PLINT xmin1, xmax1, ymin1, ymax1;
	xmin1 = xmax1 = x[0];
	ymin1 = ymax1 = y[0];
	for (i = 1; i < npts; i++) {
	    if (x[i] < xmin1) xmin1 = x[i];
	    if (x[i] > xmax1) xmax1 = x[i];
	    if (y[i] < ymin1) ymin1 = y[i];
	    if (y[i] > ymax1) ymax1 = y[i];
	}
	if (xmin1 <= xmin && xmax1 >= xmax && ymin1 <= ymin && ymax1 >= ymax ) {
	    xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
	    xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
	    xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
	    xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
	    (*draw)(xclp, yclp, iclp);
	    return;
	}
    }

/* Now handle cases where fill polygon intersects two sides of the box */

    if (iclp >= 2) {
	int debug=0;
	int dir = circulation(x, y, npts);
	if (debug) {
	    if ( (xclp[0] == xmin && xclp[iclp-1] == xmax) ||
		 (xclp[0] == xmax && xclp[iclp-1] == xmin) ||
		 (yclp[0] == ymin && yclp[iclp-1] == ymax) ||
		 (yclp[0] == ymax && yclp[iclp-1] == ymin) ||
		 (xclp[0] == xmin && yclp[iclp-1] == ymin) ||
		 (yclp[0] == ymin && xclp[iclp-1] == xmin) ||
		 (xclp[0] == xmax && yclp[iclp-1] == ymin) ||
		 (yclp[0] == ymin && xclp[iclp-1] == xmax) ||
		 (xclp[0] == xmax && yclp[iclp-1] == ymax) ||
		 (yclp[0] == ymax && xclp[iclp-1] == xmax) ||
		 (xclp[0] == xmin && yclp[iclp-1] == ymax) ||
		 (yclp[0] == ymax && xclp[iclp-1] == xmin) ) {
		printf("dir=%d, clipped points:\n", dir);
		for (i=0; i < iclp; i++)
		    printf(" x[%d]=%d y[%d]=%d", i, xclp[i], i, yclp[i]);
		printf("\n");
		printf("pre-clipped points:\n");
		for (i=0; i < npts; i++)
		    printf(" x[%d]=%d y[%d]=%d", i, x[i], i, y[i]);
		printf("\n");
	    }
	}

    /* The cases where the fill region is divided 2/2 */
    /* Divided horizontally */
	if (xclp[0] == xmin && xclp[iclp-1] == xmax)
	{
	    if (dir > 0) {
		xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
		xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
	    }
	    else {
		xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
		xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
	    }
	}
	else if (xclp[0] == xmax && xclp[iclp-1] == xmin)
	{
	    if (dir > 0) {
		xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
		xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
	    }
	    else {
		xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
		xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
	    }
	}

    /* Divided vertically */
	else if (yclp[0] == ymin && yclp[iclp-1] == ymax)
	{
	    if (dir > 0) {
		xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
		xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
	    }
	    else {
		xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
		xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
	    }
	}
	else if (yclp[0] == ymax && yclp[iclp-1] == ymin)
	{
	    if (dir > 0) {
		xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
		xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
	    }
	    else {
		xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
		xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
	    }
	}

    /* The cases where the fill region is divided 3/1 --
          LL           LR           UR           UL
       +-----+      +-----+      +-----+      +-----+
       |     |      |     |      |    \|      |/    |
       |     |      |     |      |     |      |     |
       |\    |      |    /|      |     |      |     |
       +-----+      +-----+      +-----+      +-----+

       Note when we go the long way around, if the direction is reversed the
       three vertices must be visited in the opposite order.
    */
    /* LL, short way around */
	else if ((xclp[0] == xmin && yclp[iclp-1] == ymin && dir < 0) ||
		 (yclp[0] == ymin && xclp[iclp-1] == xmin && dir > 0) )
	{
	    xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
	}
    /* LL, long way around, counterclockwise */
	else if ((xclp[0] == xmin && yclp[iclp-1] == ymin && dir > 0))
	{
	    xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
	    xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
	    xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
	}
    /* LL, long way around, clockwise */
	else if ((yclp[0] == ymin && xclp[iclp-1] == xmin && dir < 0))
	{
	    xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
	    xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
	    xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
	}
    /* LR, short way around */
	else if ((xclp[0] == xmax && yclp[iclp-1] == ymin && dir > 0) ||
		 (yclp[0] == ymin && xclp[iclp-1] == xmax && dir < 0) )
	{
	    xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
	}
    /* LR, long way around, counterclockwise */
	else if (yclp[0] == ymin && xclp[iclp-1] == xmax && dir > 0)
	{
	    xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
	    xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
	    xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
	}
    /* LR, long way around, clockwise */
	else if (xclp[0] == xmax && yclp[iclp-1] == ymin && dir < 0)
	{
	    xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
	    xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
	    xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
	}
    /* UR, short way around */
	else if ((xclp[0] == xmax && yclp[iclp-1] == ymax && dir < 0) ||
		 (yclp[0] == ymax && xclp[iclp-1] == xmax && dir > 0) )
	{
	    xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
	}
    /* UR, long way around, counterclockwise */
	else if (xclp[0] == xmax && yclp[iclp-1] == ymax && dir > 0)
	{
	    xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
	    xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
	    xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
	}
    /* UR, long way around, clockwise */
	else if (yclp[0] == ymax && xclp[iclp-1] == xmax && dir < 0)
	{
	    xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
	    xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
	    xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
	}
    /* UL, short way around */
	else if ((xclp[0] == xmin && yclp[iclp-1] == ymax && dir > 0) ||
		 (yclp[0] == ymax && xclp[iclp-1] == xmin && dir < 0) )
	{
	    xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
	}
    /* UL, long way around, counterclockwise */
	else if (yclp[0] == ymax && xclp[iclp-1] == xmin && dir > 0)
	{
	    xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
	    xclp[iclp] = xmax; yclp[iclp] = ymin; iclp++;
	    xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
	}
    /* UL, long way around, clockwise */
	else if (xclp[0] == xmin && yclp[iclp-1] == ymax && dir < 0)
	{
	    xclp[iclp] = xmax; yclp[iclp] = ymax; iclp++;
	    xclp[iclp] = xmin; yclp[iclp] = ymax; iclp++;
	    xclp[iclp] = xmin; yclp[iclp] = ymin; iclp++;
	}
    }

/* Draw the sucker */
    if (iclp >= 3)
	(*draw)(xclp, yclp, iclp);
}