/* vispoly.f -- translated by f2c (version of 22 July 1992  22:54:52).
   You must link the resulting object file with the libraries:
	-lF77 -lI77 -lm -lc   (in that order)
*/

#include "f2c.h"

/* Common Block Declarations */

struct {
    integer ierr;
} gerror_;

#define gerror_1 gerror_

struct {
    integer nv, oper, cur, top;
    doublereal xe, ye, xw, yw;
    logical beye;
} gvpvar_;

#define gvpvar_1 gvpvar_

struct {
    doublereal pi, tol;
} gconst_;

#define gconst_1 gconst_

/* Table of constant values */

static doublereal c_b4 = 0.;
static integer c__1 = 1;
static integer c__0 = 0;


/*     The following code was excerpted from: vispol.f */

/* Subroutine */ int vispol_(xeye, yeye, nvrt, xc, yc, nvis, ivis)
doublereal *xeye, *yeye;
integer *nvrt;
doublereal *xc, *yc;
integer *nvis, *ivis;
{
    /* System generated locals */
    integer i__1;

    /* Local variables */
    static integer i, lr;
    extern integer lrline_();
    extern /* Subroutine */ int vpscna_(), vpscnb_(), vpscnc_(), vpscnd_(), 
	    vpleft_(), vprght_();


/*     Written and copyright by: */
/*        Barry Joe, Dept. of Computing Science, Univ. of Alberta */
/*        Edmonton, Alberta, Canada  T6G 2H1 */
/*        Phone: (403) 492-5757      Email: barry@cs.ualberta.ca */

/*     Purpose: Compute the visibility polygon VP from an eyepoint in */
/*        the interior or blocked exterior of a simple polygon P or */
/*        on the boundary of a simply connected polygonal region P. */
/* 	 In the latter case, the interior angles at all vertices must */
/*        be strictly between 0 and 2*PI. */

/*     Input parameters: */
/*        XEYE,YEYE - coordinates of eyepoint; must be a simple vertex */
/*              if it lies on the boundary (i.e. occurs only once) */
/* 	 NVRT - upper subscript of XC, YC (approx number of vertices) */
/* 	 XC(0:NVRT),YC(0:NVRT) - If eyepoint is interior or blocked */
/*              exterior then arrays contain coordinates in CCW or CW */
/*              order, respectively, with (XC(0),YC(0)) = (XC(NVRT), */
/*              YC(NVRT)); (XC(0),YC(0)) is a vertex visible from */
/*              (XEYE,YEYE), e.g. as computed by routine ROTIPG. */
/*              If eyepoint is a vertex of P then arrays contain */
/* 	       coordinates in CCW order; (XC(0),YC(0)) is successor */
/*              vertex of (XEYE,YEYE); (XC(NVRT),YC(NVRT)) is */
/*              predecessor vertex of (XEYE,YEYE). */

/*     Updated parameters: */
/*        XC(0:NVIS),YC(0:NVIS) - vertices of VP in CCW order; */
/*              if eyepoint is interior or blocked exterior then */
/*              (XC(0),YC(0)) = (XC(NVIS),YC(NVIS)), else (XC(0),YC(0)) */

/*              and (XC(NVIS),YC(NVIS)) are the successor and */
/*              predecessor vertices of (XEYE,YEYE) in VP */

/*     Output parameters: */
/* 	 NVIS - upper subscript of XC, YC on output (approx number */
/*              of vertices of VP); NVIS <= NVRT */
/*        IVIS(0:NVIS) - contains information about the vertices of VP */
/*              w.r.t. the vertices of P; IVIS(I) = K if (XC(I),YC(I)) */
/*              is the vertex of index K in the input polygon; IVIS(I) */
/*              = -K if (XC(I),YC(I)) is on the interior of the edge */
/*              joining vertices of index K-1 and K in input polygon */

/*     Note about algorithm: */
/*        On input, XC and YC contain vertex coordinates of P. During */
/*        the algorithm, part of XC, YC is used as a stack, which, on */
/*        output, contains the vertex coordinates of VP. The stack */
/*        vertices overwrite the input vertices as the input vertices */
/*        are scanned. Elements of IVIS are set when vertices are added */

/*        to the stack; these values may have +NV or -NV added to them */
/*        to indicate that stack point has same angle as previous one. */

/*     Reference: */
/*        B. Joe and R. B. Simpson, BIT 27 (1987), pp. 458-473. */

/*     Abnormal return: */
/*        IERR is set to 206, 207, 208, 209, or 210 */

/*     Routines called: */
/*        LRLINE, VPLEFT, VPRGHT, VPSCNA, VPSCNB, VPSCNC, VPSCND */


/*     Variables in common block GVPVAR: */
/*        NV - NVRT */
/*        OPER - operation code 1 to 7 for LEFT, RIGHT, SCANA, SCANB, */
/*              SCANC, SCAND, FINISH */
/*        CUR - index of current vertex of P in XC, YC arrays */
/*        TOP - index of top vertex of stack in XC, YC arrays */
/*              (TOP <= CUR is always satisfied) */
/*        XE,YE - XEYE,YEYE */
/*        XW,YW - coordinates of point on last or second-last edge */
/*              processed (needed for routines VPSCNB, VPSCNC, VPSCND) */
/*        BEYE - .TRUE. iff eyepoint is on boundary */


    gvpvar_1.beye = xc[0] != xc[*nvrt] || yc[0] != yc[*nvrt];
    gvpvar_1.nv = *nvrt;
    gvpvar_1.xe = *xeye;
    gvpvar_1.ye = *yeye;
    ivis[0] = 0;
    gvpvar_1.cur = 1;
    if (! gvpvar_1.beye) {
	goto L20;
    }
L10:
    lr = lrline_(&xc[gvpvar_1.nv - 1], &yc[gvpvar_1.nv - 1], &gvpvar_1.xe, &
	    gvpvar_1.ye, &xc[gvpvar_1.nv], &yc[gvpvar_1.nv], &c_b4);
    if (lr == 0) {
	--gvpvar_1.nv;
	goto L10;
    }

L20:
    lr = lrline_(&xc[gvpvar_1.cur], &yc[gvpvar_1.cur], &gvpvar_1.xe, &
	    gvpvar_1.ye, xc, yc, &c_b4);
    if (lr == 0) {
	++gvpvar_1.cur;
	goto L20;
    }
    if (lr == -1) {
	gvpvar_1.oper = 1;
	if (gvpvar_1.cur == 1) {
	    gvpvar_1.top = 1;
	    ivis[1] = gvpvar_1.cur;
	} else if (gvpvar_1.beye) {
	    gvpvar_1.top = 1;
	    xc[0] = xc[gvpvar_1.cur - 1];
	    yc[0] = yc[gvpvar_1.cur - 1];
	    ivis[0] = gvpvar_1.cur - 1;
	    xc[1] = xc[gvpvar_1.cur];
	    yc[1] = yc[gvpvar_1.cur];
	    ivis[1] = gvpvar_1.cur;
	} else {
	    gvpvar_1.top = 2;
	    xc[1] = xc[gvpvar_1.cur - 1];
	    yc[1] = yc[gvpvar_1.cur - 1];
	    ivis[1] = gvpvar_1.cur - 1 + gvpvar_1.nv;
	    xc[2] = xc[gvpvar_1.cur];
	    yc[2] = yc[gvpvar_1.cur];
	    ivis[2] = gvpvar_1.cur;
	}
    } else {
	gvpvar_1.oper = 3;
	gvpvar_1.top = 0;
	if (gvpvar_1.beye && gvpvar_1.cur > 1) {
	    xc[0] = xc[gvpvar_1.cur - 1];
	    yc[0] = yc[gvpvar_1.cur - 1];
	    ivis[0] = gvpvar_1.cur - 1;
	}
    }

/*     Angular displacement of stack points are in nondecreasing order, */

/*     with at most two consecutive points having the same displacement. 
*/

L30:
    if (gvpvar_1.oper == 1) {
	vpleft_(xc, yc, ivis);
    } else if (gvpvar_1.oper == 2) {
	vprght_(xc, yc, ivis);
    } else if (gvpvar_1.oper == 3) {
	vpscna_(xc, yc, ivis);
    } else if (gvpvar_1.oper == 4) {
	vpscnb_(xc, yc, ivis);
    } else if (gvpvar_1.oper == 5) {
	vpscnc_(xc, yc, ivis);
    } else {
	vpscnd_(xc, yc, ivis);
    }
    if (gerror_1.ierr != 0) {
	*nvis = gvpvar_1.top;
	return 0;
    }
    if (gvpvar_1.oper <= 6) {
	goto L30;
    }

/*     Add or subtract NV from those IVIS values which are used to */
/*     indicate that stack point has same angle as previous one. */

    i__1 = gvpvar_1.top;
    for (i = 1; i <= i__1; ++i) {
	if (ivis[i] > gvpvar_1.nv) {
	    ivis[i] -= gvpvar_1.nv;
	} else if (ivis[i] < -gvpvar_1.nv) {
	    ivis[i] += gvpvar_1.nv;
	}
/* L40: */
    }
    *nvis = gvpvar_1.top;
} /* vispol_ */


/*     The following code was excerpted from: visvrt.f */

/* Subroutine */ int visvrt_(angspc, xeye, yeye, nvis, xc, yc, ivis, maxn, 
	nvsvrt, theta)
doublereal *angspc, *xeye, *yeye;
integer *nvis;
doublereal *xc, *yc;
integer *ivis, *maxn, *nvsvrt;
doublereal *theta;
{
    /* System generated locals */
    integer i__1;
    doublereal d__1, d__2, d__3, d__4;

    /* Builtin functions */
    double atan2(), cos(), sin();

    /* Local variables */
    static doublereal diff;
    static integer i, k, n;
    static doublereal r, alpha;
    extern doublereal angle_();
    static doublereal numer, angsp2, angdif, dx;
    static integer lr;
    static doublereal dy, cosang, sinang;
    extern integer lrline_();
    static doublereal ang;
    static integer ind, cur, top;
    static doublereal ang1, ang2;


/*     Written and copyright by: */
/*        Barry Joe, Dept. of Computing Science, Univ. of Alberta */
/*        Edmonton, Alberta, Canada  T6G 2H1 */
/*        Phone: (403) 492-5757      Email: barry@cs.ualberta.ca */

/*     Purpose: Determine a list of visible vertices, ordered by */
/*        increasing "polar angle", on the boundary of the visibilty */
/*        polygon from boundary eyepoint (XEYE,YEYE). This list */
/*        includes the vertices of visibility polygon such that a */
/*        line segment from (XEYE,YEYE) to vertex lies in interior */
/*        of polygon, as well as extra points on edges which subtend */
/*        an angle >= 2*ANGSPC at (XEYE,YEYE). These extra points are */
/*        at an equal angular spacing of >= ANGSPC and < 2*ANGSPC. The */
/*        successor and predecessor of eyepoint are included in list. */

/*     Input parameters: */
/*        ANGSPC - angle spacing parameter in radians which controls */
/*              how many extra points become visible vertices */
/*        XEYE,YEYE - coordinates of boundary eyepoint */
/*        NVIS - (number of vertices of visibility polygon) - 2 */
/*        XC(0:NVIS),YC(0:NVIS) - the coordinates of the vertices of */
/*              visibility polygon in CCW order; (XC(0),YC(0)) and */
/*              (XC(NVIS),YC(NVIS)) are the successor and predecessor */
/*              vertices of eyepoint in visibility polygon; at most 2 */
/*              consecutive vertices have same polar angle wrt eyepoint */

/*        IVIS(0:NVIS) - contains information about the vertices of */
/*              XC, YC arrays with respect to the original polygon from */

/*              which visibility polygon is computed; if IVIS(I) >= 0 */
/*              then (XC(I),YC(I)) has index I in original polygon; */
/*              if IVIS(I) < 0 then (XC(I),YC(I)) is on the edge */
/*              ending at vertex of index -IVIS(I) in original polygon; */

/*              indexing starts at 0 from successor of eyepoint */
/*        MAXN - upper bound on NVSVRT; should be at least */
/*              NVIS + INT(PHI/ANGSPC) where PHI is the interior */
/*              angle at (XEYE,YEYE) */

/*     Updated parameters: */
/*        XC(0:NVSVRT),YC(0:NVSVRT) - coordinates of visible vertices */
/*              which overwrite the input coordinates */
/*        IVIS(0:NVSVRT) - contains information about the output */
/*              vertices of XC, YC arrays as described above for input */

/*     Output parameters: */
/*        NVSVRT - (number of visible vertices) - 1 */
/*        THETA(0:NVSVRT) - polar angles of visible vertices wrt (XEYE, */

/*              YEYE) at origin and (XC(0),YC(0)) on positive x-axis */

/*     Routines called: */
/*        ANGLE, LRLINE */



/*     Shift input vertices right, and possibly remove first and last */
/*     vertices due to collinearity with eyepoint. */

    angsp2 = *angspc * 2.;
    cur = *maxn + 1;
    n = *maxn;
    for (i = *nvis; i >= 0; --i) {
	--cur;
	xc[cur] = xc[i];
	yc[cur] = yc[i];
	ivis[cur] = ivis[i];
/* L10: */
    }
    lr = lrline_(&xc[cur + 1], &yc[cur + 1], xeye, yeye, &xc[cur], &yc[cur], &
	    c_b4);
    if (lr >= 0) {
	++cur;
	xc[0] = xc[cur];
	yc[0] = yc[cur];
	ivis[0] = ivis[cur];
    }
    lr = lrline_(&xc[n - 1], &yc[n - 1], xeye, yeye, &xc[n], &yc[n], &c_b4);
    if (lr <= 0) {
	--n;
    }
    alpha = atan2(yc[0] - *yeye, xc[0] - *xeye);
    ang2 = 0.;
    theta[0] = 0.;
    top = 0;
    ++cur;

/*     Process edge from vertices of indices CUR-1, CUR. */

L20:
    ang1 = ang2;
    ang2 = angle_(&xc[cur], &yc[cur], xeye, yeye, xc, yc);
    angdif = ang2 - ang1;
    if (angdif <= gconst_1.tol) {
/* Computing 2nd power */
	d__1 = xc[cur] - *xeye;
/* Computing 2nd power */
	d__2 = yc[cur] - *yeye;
/* Computing 2nd power */
	d__3 = xc[cur - 1] - *xeye;
/* Computing 2nd power */
	d__4 = yc[cur - 1] - *yeye;
	diff = d__1 * d__1 + d__2 * d__2 - (d__3 * d__3 + d__4 * d__4);
	if (diff < 0.) {
	    xc[top] = xc[cur];
	    yc[top] = yc[cur];
	    ivis[top] = ivis[cur];
	    theta[top] = ang2;
	}
    } else {
	if (angdif >= angsp2) {
	    k = (integer) (angdif / *angspc);
	    ind = -(i__1 = ivis[cur], abs(i__1));
	    angdif /= (doublereal) k;
	    dx = xc[cur] - xc[cur - 1];
	    dy = yc[cur] - yc[cur - 1];
	    numer = (xc[cur] - *xeye) * dy - (yc[cur] - *yeye) * dx;
	    i__1 = k - 1;
	    for (i = 1; i <= i__1; ++i) {
		++top;
		theta[top] = ang1 + (doublereal) i * angdif;
		ang = theta[top] + alpha;
		cosang = cos(ang);
		sinang = sin(ang);
		r = numer / (dy * cosang - dx * sinang);
		xc[top] = r * cosang + *xeye;
		yc[top] = r * sinang + *yeye;
		ivis[top] = ind;
/* L30: */
	    }
	}
	++top;
	xc[top] = xc[cur];
	yc[top] = yc[cur];
	ivis[top] = ivis[cur];
	theta[top] = ang2;
    }
    ++cur;
    if (cur <= n) {
	goto L20;
    }
    *nvsvrt = top;
} /* visvrt_ */


/*     The following code was excerpted from: vornbr.f */

/* Subroutine */ int vornbr_(xeye, yeye, nvrt, xc, yc, nvor, ivor, xvor, yvor)

doublereal *xeye, *yeye;
integer *nvrt;
doublereal *xc, *yc;
integer *nvor, *ivor;
doublereal *xvor, *yvor;
{
    /* System generated locals */
    doublereal d__1, d__2;

    /* Local variables */
    static integer k, m;
    static doublereal b1, b2, a11, a12, a21, a22;
    static integer im, lr;
    static doublereal xi, yi, tolabs;
    extern integer lrline_();
    static doublereal det;


/*     Written and copyright by: */
/*        Barry Joe, Dept. of Computing Science, Univ. of Alberta */
/*        Edmonton, Alberta, Canada  T6G 2H1 */
/*        Phone: (403) 492-5757      Email: barry@cs.ualberta.ca */

/*     Purpose: Determine the Voronoi neighbours of (XEYE,YEYE) from a */
/*        list of vertices which are in increasing "polar angle" order. */

/*        The Voronoi neighbours are a sublist of this list. The */
/*        Voronoi polygon is restricted to the sector formed from the */
/*        the edges joining (XEYE,YEYE) to the first and last vertices */
/*        of this list. Each Voronoi neighbour corresponds to an edge */
/*        of the Voronoi polygon. */

/*     Input parameters: */
/*        XEYE,YEYE - coordinates of eyepoint */
/*        NVRT - (number of vertices in list) - 1 */
/*        XC(0:NVRT),YC(0:NVRT) - vertex coordinates from which */
/*              Voronoi neighbours are determined; (XC(0),YC(0)),..., */
/*              (XC(NVRT),YC(NVRT)) are in increasing angular */
/*              displacement order w.r.t. (XEYE,YEYE) */

/*     Output parameters: */
/*        NVOR - (number of Voronoi neighbours) - 1 [<= NVRT] */
/*        IVOR(0:NVOR) - indices of Voronoi neighbours in XC, YC */
/*               arrays; 0 <= IVOR(0) < ... < IVOR(NVOR) <= NVRT */

/*     Working parameters: */
/*        XVOR(0:NVRT),YVOR(0:NVRT) - arrays for storing the vertex */
/*              coordinates of the Voronoi polygon */

/*     Abnormal return: */
/*        IERR is set to 212 */

/*     Routines called: */
/*        LRLINE */



    k = 1;
    m = 0;
    ivor[0] = 0;
    xvor[0] = (*xeye + xc[0]) * .5;
    yvor[0] = (*yeye + yc[0]) * .5;

/*     Beginning of main loop */

L10:
    if (k > *nvrt) {
	goto L20;
    }

/*        Determine the intersection of the perpendicular bisectors */
/*        of edges from (XEYE,YEYE) to (XC(K),YC(K)) and from */
/*        (XEYE,YEYE) to (XC(IM),YC(IM)). */

    im = ivor[m];
    a11 = xc[k] - *xeye;
    a12 = yc[k] - *yeye;
    a21 = xc[im] - *xeye;
    a22 = yc[im] - *yeye;
/* Computing MAX */
    d__1 = abs(a11), d__2 = abs(a12), d__1 = max(d__1,d__2), d__2 = abs(a21), 
	    d__1 = max(d__1,d__2), d__2 = abs(a22);
    tolabs = gconst_1.tol * max(d__1,d__2);
    det = a11 * a22 - a21 * a12;
    if (abs(det) <= tolabs) {
	gerror_1.ierr = 212;
	return 0;
    }
/* Computing 2nd power */
    d__1 = a11;
/* Computing 2nd power */
    d__2 = a12;
    b1 = (d__1 * d__1 + d__2 * d__2) * .5;
/* Computing 2nd power */
    d__1 = a21;
/* Computing 2nd power */
    d__2 = a22;
    b2 = (d__1 * d__1 + d__2 * d__2) * .5;
    xi = (b1 * a22 - b2 * a12) / det;
    yi = (b2 * a11 - b1 * a21) / det;

/*        Determine whether (XVOR(M+1),YVOR(M+1)) is to the left of or */
/*        on the directed line from (XEYE,YEYE) to (XVOR(M),YVOR(M)). */

    xvor[m + 1] = xi + *xeye;
    yvor[m + 1] = yi + *yeye;
    lr = lrline_(&xvor[m + 1], &yvor[m + 1], xeye, yeye, &xvor[m], &yvor[m], &
	    c_b4);
    if (lr <= 0) {
	++m;
	ivor[m] = k;
	++k;
    } else if (m > 0) {
	--m;
    } else {

/*           Determine the intersection of edge from (XEYE,YEYE) to */

/*           (XC(0),YC(0)) and the perpendicular bisector of the edge 
*/
/*           from (XEYE,YEYE) to (XC(K),YC(K)). */

	a11 = xc[k] - *xeye;
	a12 = yc[k] - *yeye;
	a21 = yc[0] - *yeye;
	a22 = *xeye - xc[0];
/* Computing MAX */
	d__1 = abs(a11), d__2 = abs(a12), d__1 = max(d__1,d__2), d__2 = abs(
		a21), d__1 = max(d__1,d__2), d__2 = abs(a22);
	tolabs = gconst_1.tol * max(d__1,d__2);
	det = a11 * a22 - a21 * a12;
	if (abs(det) <= tolabs) {
	    gerror_1.ierr = 212;
	    return 0;
	}
/* Computing 2nd power */
	d__1 = a11;
/* Computing 2nd power */
	d__2 = a12;
	b1 = (d__1 * d__1 + d__2 * d__2) * .5;
	b2 = 0.;
	xi = (b1 * a22 - b2 * a12) / det;
	yi = (b2 * a11 - b1 * a21) / det;
	xvor[m] = xi + *xeye;
	yvor[m] = yi + *yeye;
	ivor[m] = k;
	++k;
    }
    goto L10;

/*     The following short loop determines which vertices at the end */
/*     of list are not Voronoi neighbours. */

L20:
    lr = lrline_(&xvor[m], &yvor[m], xeye, yeye, &xc[*nvrt], &yc[*nvrt], &
	    c_b4);
    if (lr >= 0) {
	goto L30;
    }
    --m;
    if (m >= 0) {
	goto L20;
    }
L30:
    *nvor = m;
} /* vornbr_ */


/*     The following code was excerpted from: vpleft.f */

/* Subroutine */ int vpleft_(xc, yc, ivis)
doublereal *xc, *yc;
integer *ivis;
{
    static integer j;
    extern /* Subroutine */ int xedge_();
    static integer lr;
    static doublereal xu, yu;
    extern integer lrline_();
    static logical intsct;
    static integer lr1, lr2;


/*     Written and copyright by: */
/*        Barry Joe, Dept. of Computing Science, Univ. of Alberta */
/*        Edmonton, Alberta, Canada  T6G 2H1 */
/*        Phone: (403) 492-5757      Email: barry@cs.ualberta.ca */

/*     Purpose: This routine is called by routine VISPOL for the LEFT */
/*        operation (OPER = 1). */

/*     Input and updated parameters: */
/*        XC,YC,IVIS - see comments in routine VISPOL */

/*     Routines called: */
/*        LRLINE, XEDGE */



/*     EYE-V(CUR-1)-V(CUR) is a left turn, S(TOP) = V(CUR), TOP <= CUR, */

/*     S(TOP-1) = V(CUR-1) or on interior of edge V(CUR-1)-V(CUR). */

L10:
    if (gvpvar_1.cur == gvpvar_1.nv) {
	gvpvar_1.oper = 7;
	return 0;
    }
    if (! gvpvar_1.beye && gvpvar_1.top <= 2) {
	goto L20;
    }

/*     Check if angular displacement of stack chain >= 2*PI or */
/*     interior angle at boundary viewpoint. */

    xedge_(&c__1, &gvpvar_1.xe, &gvpvar_1.ye, &xc[gvpvar_1.nv], &yc[
	    gvpvar_1.nv], &xc[gvpvar_1.top - 1], &yc[gvpvar_1.top - 1], &xc[
	    gvpvar_1.top], &yc[gvpvar_1.top], &xu, &yu, &intsct);
    if (intsct) {
	gvpvar_1.oper = 4;
	gvpvar_1.xw = xc[gvpvar_1.cur];
	gvpvar_1.yw = yc[gvpvar_1.cur];
	lr = lrline_(&xc[gvpvar_1.top], &yc[gvpvar_1.top], &gvpvar_1.xe, &
		gvpvar_1.ye, &xc[gvpvar_1.nv], &yc[gvpvar_1.nv], &c_b4);
	if (lr == -1) {
	    xc[gvpvar_1.top] = xu;
	    yc[gvpvar_1.top] = yu;
	    ivis[gvpvar_1.top] = -gvpvar_1.cur;
	}
	return 0;
    }

/*     Process next edge. */

L20:
    lr = lrline_(&xc[gvpvar_1.cur + 1], &yc[gvpvar_1.cur + 1], &gvpvar_1.xe, &
	    gvpvar_1.ye, &xc[gvpvar_1.cur], &yc[gvpvar_1.cur], &c_b4);
    if (lr == -1) {
	++gvpvar_1.cur;
	++gvpvar_1.top;
	xc[gvpvar_1.top] = xc[gvpvar_1.cur];
	yc[gvpvar_1.top] = yc[gvpvar_1.cur];
	ivis[gvpvar_1.top] = gvpvar_1.cur;
    } else {
	j = gvpvar_1.cur + 1;
	lr1 = lrline_(&xc[j], &yc[j], &xc[gvpvar_1.top - 1], &yc[gvpvar_1.top 
		- 1], &xc[gvpvar_1.cur], &yc[gvpvar_1.cur], &c_b4);
	if (lr1 == 1) {
	    gvpvar_1.oper = 3;
	    gvpvar_1.cur = j;
	} else {
	    if (lr == 1) {
		lr2 = 1;
		goto L40;
	    }
L30:
	    ++j;
	    lr2 = lrline_(&xc[j], &yc[j], &gvpvar_1.xe, &gvpvar_1.ye, &xc[
		    gvpvar_1.cur], &yc[gvpvar_1.cur], &c_b4);
	    if (lr2 == 0) {
		goto L30;
	    }
L40:
	    if (lr2 == -1) {
		++gvpvar_1.top;
		xc[gvpvar_1.top] = xc[j - 1];
		yc[gvpvar_1.top] = yc[j - 1];
		ivis[gvpvar_1.top] = j - 1 + gvpvar_1.nv;
		++gvpvar_1.top;
		xc[gvpvar_1.top] = xc[j];
		yc[gvpvar_1.top] = yc[j];
		ivis[gvpvar_1.top] = j;
	    } else {
		gvpvar_1.oper = 2;
	    }
	    gvpvar_1.cur = j;
	}
    }

/*     This test avoids extra subroutine calls. */

    if (gvpvar_1.oper == 1) {
	goto L10;
    }
} /* vpleft_ */


/*     The following code was excerpted from: vprght.f */

/* Subroutine */ int vprght_(xc, yc, ivis)
doublereal *xc, *yc;
integer *ivis;
{
    /* System generated locals */
    integer i__1;
    doublereal d__1, d__2, d__3, d__4;

    /* Local variables */
    static integer case__, j;
    extern /* Subroutine */ int xedge_();
    static integer lr;
    static doublereal xu, yu;
    extern integer lrline_();
    static logical intsct;
    static integer lr1, lr2;


/*     Written and copyright by: */
/*        Barry Joe, Dept. of Computing Science, Univ. of Alberta */
/*        Edmonton, Alberta, Canada  T6G 2H1 */
/*        Phone: (403) 492-5757      Email: barry@cs.ualberta.ca */

/*     Purpose: This routine is called by routine VISPOL for the RIGHT */
/*        operation (OPER = 2). */

/*     Input and updated parameters: */
/*        XC,YC,IVIS - see comments in routine VISPOL */

/*     Abnormal return: */
/*        IERR is set to 206 */

/*     Routines called: */
/*        LRLINE, XEDGE */



/*     EYE-V(CUR-1)-V(CUR) is a right turn, EYE-S(TOP)-V(CUR) is a right 
*/
/*     turn, EYE-S(TOP-1)-S(TOP) is a left turn, TOP < CUR, S(TOP) = */
/*     V(CUR-1) and S(TOP-1)-S(TOP)-V(CUR) is a left turn or S(TOP) is */
/*     not on edge V(CUR-1)-V(CUR) and V(CUR-1)-V(CUR) intersects */
/*     EYE-S(TOP). */
/*     Pop points from stack. If BEYE, it is not possible for */
/*     (XC(CUR),YC(CUR)) to be identical to any stack points. */

L10:
    case__ = 0;
    j = gvpvar_1.top;
L20:
    if ((i__1 = ivis[j], abs(i__1)) <= gvpvar_1.nv) {
	lr = lrline_(&xc[gvpvar_1.cur], &yc[gvpvar_1.cur], &gvpvar_1.xe, &
		gvpvar_1.ye, &xc[j - 1], &yc[j - 1], &c_b4);
	if (lr == -1) {
	    case__ = 1;
	} else if (lr == 0) {
	    if ((i__1 = ivis[j - 1], abs(i__1)) <= gvpvar_1.nv) {
		--j;
		case__ = 2;
	    } else /* if(complicated condition) */ {
/* Computing 2nd power */
		d__1 = xc[j - 2] - gvpvar_1.xe;
/* Computing 2nd power */
		d__2 = yc[j - 2] - gvpvar_1.ye;
/* Computing 2nd power */
		d__3 = xc[j - 1] - gvpvar_1.xe;
/* Computing 2nd power */
		d__4 = yc[j - 1] - gvpvar_1.ye;
		if (d__1 * d__1 + d__2 * d__2 >= d__3 * d__3 + d__4 * d__4) {
		    j += -2;
		    case__ = 2;
		} else {
		    case__ = -1;
		}
	    }
	}
    } else if (case__ == -1) {
/* Computing 2nd power */
	d__1 = xc[j - 1] - gvpvar_1.xe;
/* Computing 2nd power */
	d__2 = yc[j - 1] - gvpvar_1.ye;
/* Computing 2nd power */
	d__3 = xc[gvpvar_1.cur] - gvpvar_1.xe;
/* Computing 2nd power */
	d__4 = yc[gvpvar_1.cur] - gvpvar_1.ye;
	if (d__1 * d__1 + d__2 * d__2 >= d__3 * d__3 + d__4 * d__4) {
	    --j;
	    case__ = 2;
	} else {
	    gvpvar_1.xw = xc[gvpvar_1.cur];
	    gvpvar_1.yw = yc[gvpvar_1.cur];
	    case__ = 3;
	}
    } else {
	xedge_(&c__0, &xc[gvpvar_1.cur - 1], &yc[gvpvar_1.cur - 1], &xc[
		gvpvar_1.cur], &yc[gvpvar_1.cur], &xc[j - 1], &yc[j - 1], &xc[
		j], &yc[j], &gvpvar_1.xw, &gvpvar_1.yw, &intsct);
	if (intsct) {
	    case__ = 3;
	}
    }
    if (case__ > 0) {
	goto L30;
    }
    --j;
    if (j >= 1) {
	goto L20;
    }

/*     Error from no more edges in stack. */

    gerror_1.ierr = 206;
    return 0;

/*     Process next edge. */

L30:
    if (case__ == 3) {
	gvpvar_1.oper = 6;
	gvpvar_1.top = j - 1;
    } else {
	gvpvar_1.top = j;
	gvpvar_1.xw = xc[gvpvar_1.cur - 1];
	gvpvar_1.yw = yc[gvpvar_1.cur - 1];
	if (case__ == 1) {
	    xedge_(&c__1, &gvpvar_1.xe, &gvpvar_1.ye, &xc[gvpvar_1.cur], &yc[
		    gvpvar_1.cur], &xc[gvpvar_1.top - 1], &yc[gvpvar_1.top - 
		    1], &xc[gvpvar_1.top], &yc[gvpvar_1.top], &xu, &yu, &
		    intsct);
	    xc[gvpvar_1.top] = xu;
	    yc[gvpvar_1.top] = yu;
	    ivis[gvpvar_1.top] = -(i__1 = ivis[gvpvar_1.top], abs(i__1));
	}
	lr = lrline_(&xc[gvpvar_1.cur + 1], &yc[gvpvar_1.cur + 1], &
		gvpvar_1.xe, &gvpvar_1.ye, &xc[gvpvar_1.cur], &yc[
		gvpvar_1.cur], &c_b4);
	if (lr == 1) {
	    ++gvpvar_1.cur;
	} else {
	    j = gvpvar_1.cur + 1;
	    lr1 = lrline_(&xc[j], &yc[j], &gvpvar_1.xw, &gvpvar_1.yw, &xc[
		    gvpvar_1.cur], &yc[gvpvar_1.cur], &c_b4);
	    if (lr1 == -1) {
		gvpvar_1.oper = 5;
		gvpvar_1.cur = j;
	    } else {
		if (lr == -1) {
		    lr2 = -1;
		    goto L50;
		}
L40:
		++j;
		lr2 = lrline_(&xc[j], &yc[j], &gvpvar_1.xe, &gvpvar_1.ye, &xc[
			gvpvar_1.cur], &yc[gvpvar_1.cur], &c_b4);
		if (lr2 == 0) {
		    goto L40;
		}
L50:
		if (lr2 == -1) {
		    gvpvar_1.oper = 1;
		    ++gvpvar_1.top;
		    xc[gvpvar_1.top] = xc[j - 1];
		    yc[gvpvar_1.top] = yc[j - 1];
		    ivis[gvpvar_1.top] = j - 1 + gvpvar_1.nv;
		    ++gvpvar_1.top;
		    xc[gvpvar_1.top] = xc[j];
		    yc[gvpvar_1.top] = yc[j];
		    ivis[gvpvar_1.top] = j;
		}
		gvpvar_1.cur = j;
	    }
	}
    }

/*     This test avoids extra subroutine calls. */

    if (gvpvar_1.oper == 2) {
	goto L10;
    }
} /* vprght_ */


/*     The following code was excerpted from: vpscna.f */

/* Subroutine */ int vpscna_(xc, yc, ivis)
doublereal *xc, *yc;
integer *ivis;
{
    /* System generated locals */
    doublereal d__1, d__2, d__3, d__4;

    /* Local variables */
    static integer case__, j, k;
    extern /* Subroutine */ int xedge_();
    static integer lr;
    extern integer lrline_();
    static logical intsct;
    static integer lr1, lr2, lr3;


/*     Written and copyright by: */
/*        Barry Joe, Dept. of Computing Science, Univ. of Alberta */
/*        Edmonton, Alberta, Canada  T6G 2H1 */
/*        Phone: (403) 492-5757      Email: barry@cs.ualberta.ca */

/*     Purpose: This routine is called by routine VISPOL for the SCANA */
/*        operation (OPER = 3). */

/*     Input and updated parameters: */
/*        XC,YC,IVIS - see comments in routine VISPOL */

/*     Abnormal return: */
/*        IERR is set to 207 */

/*     Routines called: */
/*        LRLINE, XEDGE */



/*     EYE-V(CUR-1)-V(CUR) is a right turn or forward move, S(TOP) = */
/*     V(CUR-1) or EYE-S(TOP)-V(CUR-1) is a forward move and TOP = 0, */
/*     TOP < CUR; S(TOP-1)-S(TOP)-V(CUR) is a right turn if TOP >= 1 */
/*     or EYE-S(TOP)-V(CUR) is a right turn if TOP = 0. */
/*     If BEYE, it is possible that (XC(TOP),YC(TOP)) is a non-simple */
/*     vertex but any edge incident on this vertex encountered during */
/*     scan must be invisible from (XE,YE). */

    k = gvpvar_1.cur;
L10:
    if (xc[k + 1] == xc[gvpvar_1.top] && yc[k + 1] == yc[gvpvar_1.top]) {
	k += 2;
    } else {
	xedge_(&c__1, &gvpvar_1.xe, &gvpvar_1.ye, &xc[gvpvar_1.top], &yc[
		gvpvar_1.top], &xc[k], &yc[k], &xc[k + 1], &yc[k + 1], &
		gvpvar_1.xw, &gvpvar_1.yw, &intsct);
	if (intsct) {
	    lr = lrline_(&xc[k + 1], &yc[k + 1], &gvpvar_1.xe, &gvpvar_1.ye, &
		    xc[k], &yc[k], &c_b4);
	    if (lr == 1) {
/* Computing 2nd power */
		d__1 = xc[gvpvar_1.top] - gvpvar_1.xe;
/* Computing 2nd power */
		d__2 = yc[gvpvar_1.top] - gvpvar_1.ye;
/* Computing 2nd power */
		d__3 = gvpvar_1.xw - gvpvar_1.xe;
/* Computing 2nd power */
		d__4 = gvpvar_1.yw - gvpvar_1.ye;
		if (d__1 * d__1 + d__2 * d__2 >= d__3 * d__3 + d__4 * d__4) {
		    if (gvpvar_1.top > 0) {
			case__ = 1;
			goto L20;
		    }
		} else {
		    lr1 = lrline_(&xc[k], &yc[k], &gvpvar_1.xe, &gvpvar_1.ye, 
			    &xc[gvpvar_1.top], &yc[gvpvar_1.top], &c_b4);
		    if (lr1 == -1) {
			case__ = 2;
			goto L20;
		    }
		}
	    } else {
		lr1 = lrline_(&xc[k + 1], &yc[k + 1], &gvpvar_1.xe, &
			gvpvar_1.ye, &xc[gvpvar_1.top], &yc[gvpvar_1.top], &
			c_b4);
		if (lr1 == -1) {
		    case__ = 3;
		    goto L20;
		}
	    }
	}
	++k;
    }
    if (k < gvpvar_1.nv) {
	goto L10;
    }

/*     Error from unsuccessful scan. */

    gerror_1.ierr = 207;
    return 0;

/*     Process current edge. */

L20:
    if (case__ == 3) {
	gvpvar_1.oper = 1;
	gvpvar_1.cur = k + 1;
	lr = lrline_(&xc[k], &yc[k], &gvpvar_1.xe, &gvpvar_1.ye, &xc[
		gvpvar_1.top], &yc[gvpvar_1.top], &c_b4);
	++gvpvar_1.top;
	if (lr == 0) {
	    xc[gvpvar_1.top] = xc[k];
	    yc[gvpvar_1.top] = yc[k];
	    ivis[gvpvar_1.top] = k + gvpvar_1.nv;
	} else {
	    xc[gvpvar_1.top] = gvpvar_1.xw;
	    yc[gvpvar_1.top] = gvpvar_1.yw;
	    ivis[gvpvar_1.top] = -(k + 1 + gvpvar_1.nv);
	}
	++gvpvar_1.top;
	xc[gvpvar_1.top] = xc[gvpvar_1.cur];
	yc[gvpvar_1.top] = yc[gvpvar_1.cur];
	ivis[gvpvar_1.top] = gvpvar_1.cur;
    } else if (case__ == 1) {
	gvpvar_1.cur = k + 1;
	lr = lrline_(&xc[gvpvar_1.cur], &yc[gvpvar_1.cur], &gvpvar_1.xe, &
		gvpvar_1.ye, &xc[gvpvar_1.top], &yc[gvpvar_1.top], &c_b4);
	if (lr == 1) {
	    gvpvar_1.oper = 2;
	} else {
	    j = gvpvar_1.cur + 1;
	    lr1 = lrline_(&xc[j], &yc[j], &gvpvar_1.xe, &gvpvar_1.ye, &xc[
		    gvpvar_1.cur], &yc[gvpvar_1.cur], &c_b4);
	    lr2 = lrline_(&xc[j], &yc[j], &xc[k], &yc[k], &xc[gvpvar_1.cur], &
		    yc[gvpvar_1.cur], &c_b4);
	    if (lr1 <= 0 && lr2 == -1) {
		gvpvar_1.oper = 5;
		gvpvar_1.xw = xc[k];
		gvpvar_1.yw = yc[k];
		gvpvar_1.cur = j;
	    } else {
		if (lr1 != 0) {
		    lr3 = lr1;
		    goto L40;
		}
L30:
		++j;
		lr3 = lrline_(&xc[j], &yc[j], &gvpvar_1.xe, &gvpvar_1.ye, &xc[
			gvpvar_1.cur], &yc[gvpvar_1.cur], &c_b4);
		if (lr3 == 0) {
		    goto L30;
		}
L40:
		if (lr3 == 1) {
		    gvpvar_1.oper = 2;
		} else {
		    gvpvar_1.oper = 1;
		    ++gvpvar_1.top;
		    xc[gvpvar_1.top] = xc[j - 1];
		    yc[gvpvar_1.top] = yc[j - 1];
		    ivis[gvpvar_1.top] = j - 1 + gvpvar_1.nv;
		    ++gvpvar_1.top;
		    xc[gvpvar_1.top] = xc[j];
		    yc[gvpvar_1.top] = yc[j];
		    ivis[gvpvar_1.top] = j;
		}
		gvpvar_1.cur = j;
	    }
	}
    } else {
	gvpvar_1.oper = 6;
	gvpvar_1.cur = k + 1;
	lr = lrline_(&xc[gvpvar_1.cur], &yc[gvpvar_1.cur], &gvpvar_1.xe, &
		gvpvar_1.ye, &xc[gvpvar_1.top], &yc[gvpvar_1.top], &c_b4);
	if (lr == 0) {
	    gvpvar_1.xw = xc[gvpvar_1.cur];
	    gvpvar_1.yw = yc[gvpvar_1.cur];
	}
    }
} /* vpscna_ */


/*     The following code was excerpted from: vpscnb.f */

/* Subroutine */ int vpscnb_(xc, yc, ivis)
doublereal *xc, *yc;
integer *ivis;
{
    /* System generated locals */
    doublereal d__1, d__2;

    /* Local variables */
    static integer k;
    extern /* Subroutine */ int xedge_();
    static integer lr;
    static doublereal xu, yu, tolabs;
    extern integer lrline_();
    static logical intsct;
    static integer lr1;


/*     Written and copyright by: */
/*        Barry Joe, Dept. of Computing Science, Univ. of Alberta */
/*        Edmonton, Alberta, Canada  T6G 2H1 */
/*        Phone: (403) 492-5757      Email: barry@cs.ualberta.ca */

/*     Purpose: This routine is called by routine VISPOL for the SCANB */
/*        operation (OPER = 4). */

/*     Input and updated parameters: */
/*        XC,YC,IVIS - see comments in routine VISPOL */

/*     Abnormal return: */
/*        IERR is set to 208 */

/*     Routines called: */
/*        LRLINE, XEDGE */



/*     EYE-V(CUR-1)-V(CUR) is a left turn, S(TOP) = V(CUR) or S(TOP) is */

/*     on interior of edge V(CUR-1)-V(CUR), TOP <= CUR, S(TOP) has */
/*     angular displacement of 2*PI or interior angle at boundary eye. */
/*     (XW,YW) is the input version of (XC(CUR),YC(CUR)). */
/*     If BEYE, it is possible that (XC(TOP),YC(TOP)) is a non-simple */
/*     point but any edge containing this point encountered during scan */

/*     must be invisible from (XE,YE), except for 1 case where K = CUR. */


/* Computing 2nd power */
    d__1 = xc[gvpvar_1.nv] - xc[gvpvar_1.top];
/* Computing 2nd power */
    d__2 = yc[gvpvar_1.nv] - yc[gvpvar_1.top];
    tolabs = gconst_1.tol * (d__1 * d__1 + d__2 * d__2);
    k = gvpvar_1.cur;
    if (ivis[gvpvar_1.top] < 0 || k + 1 == gvpvar_1.nv) {
	goto L10;
    }
    lr = lrline_(&xc[k + 1], &yc[k + 1], &gvpvar_1.xe, &gvpvar_1.ye, &xc[
	    gvpvar_1.top], &yc[gvpvar_1.top], &c_b4);
    lr1 = lrline_(&xc[k + 1], &yc[k + 1], &xc[gvpvar_1.top - 1], &yc[
	    gvpvar_1.top - 1], &xc[gvpvar_1.top], &yc[gvpvar_1.top], &c_b4);
    if (lr == 1 && lr1 == -1) {
	gvpvar_1.oper = 2;
	gvpvar_1.cur = k + 1;
	return 0;
    } else {
	++k;
    }

L10:
    if (k + 1 == gvpvar_1.nv) {
	gvpvar_1.oper = 7;
	gvpvar_1.cur = gvpvar_1.nv;
	++gvpvar_1.top;
	xc[gvpvar_1.top] = xc[gvpvar_1.nv];
	yc[gvpvar_1.top] = yc[gvpvar_1.nv];
	ivis[gvpvar_1.top] = gvpvar_1.nv;
	return 0;
    } else {
	if (k == gvpvar_1.cur) {
	    xedge_(&c__0, &xc[gvpvar_1.nv], &yc[gvpvar_1.nv], &xc[
		    gvpvar_1.top], &yc[gvpvar_1.top], &gvpvar_1.xw, &
		    gvpvar_1.yw, &xc[k + 1], &yc[k + 1], &xu, &yu, &intsct);
	} else {
	    xedge_(&c__0, &xc[gvpvar_1.nv], &yc[gvpvar_1.nv], &xc[
		    gvpvar_1.top], &yc[gvpvar_1.top], &xc[k], &yc[k], &xc[k + 
		    1], &yc[k + 1], &xu, &yu, &intsct);
	}
	if (intsct) {
/* Computing 2nd power */
	    d__1 = xc[gvpvar_1.top] - xu;
/* Computing 2nd power */
	    d__2 = yc[gvpvar_1.top] - yu;
	    if (d__1 * d__1 + d__2 * d__2 <= tolabs) {
		goto L20;
	    }
	    lr = lrline_(&xc[k + 1], &yc[k + 1], &gvpvar_1.xe, &gvpvar_1.ye, &
		    xc[gvpvar_1.nv], &yc[gvpvar_1.nv], &c_b4);
	    if (lr == 1) {
		gvpvar_1.oper = 2;
		gvpvar_1.cur = k + 1;
		return 0;
	    }
	}
L20:
	++k;
    }
    if (k < gvpvar_1.nv) {
	goto L10;
    }

/*     Error from unsuccessful scan. */

    gerror_1.ierr = 208;
} /* vpscnb_ */


/*     The following code was excerpted from: vpscnc.f */

/* Subroutine */ int vpscnc_(xc, yc, ivis)
doublereal *xc, *yc;
integer *ivis;
{
    static integer j, k;
    extern /* Subroutine */ int xedge_();
    static integer lr;
    static doublereal xp, yp, xu, yu;
    extern integer lrline_();
    static logical intsct;
    static integer lr1, lr2;


/*     Written and copyright by: */
/*        Barry Joe, Dept. of Computing Science, Univ. of Alberta */
/*        Edmonton, Alberta, Canada  T6G 2H1 */
/*        Phone: (403) 492-5757      Email: barry@cs.ualberta.ca */

/*     Purpose: This routine is called by routine VISPOL for the SCANC */
/*        operation (OPER = 5). */

/*     Input and updated parameters: */
/*        XC,YC,IVIS - see comments in routine VISPOL */

/*     Abnormal return: */
/*        IERR is set to 209 */

/*     Routines called: */
/*        LRLINE, XEDGE */



/*     EYE-V(CUR-1)-V(CUR) is a left turn or forward move, EYE-V(CUR-2)- 
*/
/*     V(CUR-1) is a right turn, V(CUR-2)-V(CUR-1)-V(CUR) is a left turn, 
*/
/*     TOP < CUR-1, W = V(CUR-2), S(TOP) is not on V(CUR-1)-V(CUR), EYE- 
*/
/*     S(TOP)-V(CUR-1) is a backward move, EYE-S(TOP-1)-S(TOP) is a left 
*/
/*     turn. If BEYE, it is possible that V(CUR-1) is a non-simple point, 
*/
/*     but intersection at (XC(TOP),YC(TOP)) cannot occur. */

    xp = xc[gvpvar_1.cur - 1];
    yp = yc[gvpvar_1.cur - 1];
    k = gvpvar_1.cur;
L10:
    if (xc[k + 1] == xp && yc[k + 1] == yp) {
	goto L40;
    } else if (xc[k] == xp && yc[k] == yp) {
	j = k + 1;
	lr = lrline_(&xc[j], &yc[j], &gvpvar_1.xe, &gvpvar_1.ye, &xp, &yp, &
		c_b4);
	lr1 = lrline_(&xc[j], &yc[j], &gvpvar_1.xw, &gvpvar_1.yw, &xp, &yp, &
		c_b4);
	if (lr <= 0 && lr1 == -1) {
	    goto L40;
	}
	if (lr != 0) {
	    lr2 = lr;
	    goto L30;
	}
L20:
	++j;
	lr2 = lrline_(&xc[j], &yc[j], &gvpvar_1.xe, &gvpvar_1.ye, &xp, &yp, &
		c_b4);
	if (lr2 == 0) {
	    goto L20;
	}
L30:
	if (lr2 == 1) {
	    gvpvar_1.oper = 2;
	} else {
	    gvpvar_1.oper = 1;
	    ++gvpvar_1.top;
	    xc[gvpvar_1.top] = xc[j - 1];
	    yc[gvpvar_1.top] = yc[j - 1];
	    ivis[gvpvar_1.top] = j - 1 + gvpvar_1.nv;
	    ++gvpvar_1.top;
	    xc[gvpvar_1.top] = xc[j];
	    yc[gvpvar_1.top] = yc[j];
	    ivis[gvpvar_1.top] = j;
	}
	gvpvar_1.cur = j;
	return 0;
    } else {
	xedge_(&c__0, &xp, &yp, &xc[gvpvar_1.top], &yc[gvpvar_1.top], &xc[k], 
		&yc[k], &xc[k + 1], &yc[k + 1], &xu, &yu, &intsct);
	if (intsct) {
	    lr = lrline_(&xc[k + 1], &yc[k + 1], &gvpvar_1.xe, &gvpvar_1.ye, &
		    xp, &yp, &c_b4);
	    if (lr == 1) {
		gvpvar_1.oper = 2;
		gvpvar_1.cur = k + 1;
		return 0;
	    }
	}
    }
L40:
    ++k;
    if (k < gvpvar_1.nv) {
	goto L10;
    }

/*     Error from unsuccessful scan. */

    gerror_1.ierr = 209;
} /* vpscnc_ */


/*     The following code was excerpted from: vpscnd.f */

/* Subroutine */ int vpscnd_(xc, yc, ivis)
doublereal *xc, *yc;
integer *ivis;
{
    static integer k;
    extern /* Subroutine */ int xedge_();
    static integer lr;
    static doublereal xp, yp, xu, yu;
    extern integer lrline_();
    static logical intsct;
    static integer lr1, lr2;


/*     Written and copyright by: */
/*        Barry Joe, Dept. of Computing Science, Univ. of Alberta */
/*        Edmonton, Alberta, Canada  T6G 2H1 */
/*        Phone: (403) 492-5757      Email: barry@cs.ualberta.ca */

/*     Purpose: This routine is called by routine VISPOL for the SCAND */
/*        operation (OPER = 6). */

/*     Input and updated parameters: */
/*        XC,YC,IVIS - see comments in routine VISPOL */

/*     Abnormal return: */
/*        IERR is set to 210 */

/*     Routines called: */
/*        LRLINE, XEDGE */



/*     EYE-V(CUR-1)-V(CUR) is a right turn, S(TOP) is a V vertex not on */

/*     V(CUR-1)-V(CUR), TOP < CUR, W is intersection of V(CUR-1)-V(CUR) */

/*     and ray EYE-S(TOP), EYE-S(TOP)-W is a forward move, and */
/*     EYE-S(TOP-1)-S(TOP) is a left turn if TOP >= 1. */
/*     If BEYE, it is possible that (XW,YW) is a non-simple point, */
/*     but intersection at (XC(TOP),YC(TOP)) cannot occur. */

    xp = xc[gvpvar_1.cur - 1];
    yp = yc[gvpvar_1.cur - 1];
    k = gvpvar_1.cur;
L10:
    xedge_(&c__0, &gvpvar_1.xw, &gvpvar_1.yw, &xc[gvpvar_1.top], &yc[
	    gvpvar_1.top], &xc[k], &yc[k], &xc[k + 1], &yc[k + 1], &xu, &yu, &
	    intsct);
    if (intsct) {
	lr = lrline_(&xc[k + 1], &yc[k + 1], &gvpvar_1.xe, &gvpvar_1.ye, &xc[
		k], &yc[k], &c_b4);
	lr1 = lrline_(&xc[k + 1], &yc[k + 1], &gvpvar_1.xe, &gvpvar_1.ye, &xc[
		gvpvar_1.top], &yc[gvpvar_1.top], &c_b4);
	if (lr == -1 && lr1 == -1) {
	    if (xc[k] != gvpvar_1.xw || yc[k] != gvpvar_1.yw) {
		goto L20;
	    }
	    lr2 = lrline_(&xc[k + 1], &yc[k + 1], &xp, &yp, &gvpvar_1.xw, &
		    gvpvar_1.yw, &c_b4);
	    if (lr2 == -1) {
		goto L30;
	    }
L20:
	    gvpvar_1.oper = 1;
	    gvpvar_1.cur = k + 1;
	    lr2 = lrline_(&xc[k], &yc[k], &gvpvar_1.xe, &gvpvar_1.ye, &xc[
		    gvpvar_1.top], &yc[gvpvar_1.top], &c_b4);
	    ++gvpvar_1.top;
	    if (lr2 == 0) {
		xc[gvpvar_1.top] = xc[k];
		yc[gvpvar_1.top] = yc[k];
		ivis[gvpvar_1.top] = k + gvpvar_1.nv;
	    } else {
		xc[gvpvar_1.top] = xu;
		yc[gvpvar_1.top] = yu;
		ivis[gvpvar_1.top] = -(k + 1 + gvpvar_1.nv);
	    }
	    ++gvpvar_1.top;
	    xc[gvpvar_1.top] = xc[gvpvar_1.cur];
	    yc[gvpvar_1.top] = yc[gvpvar_1.cur];
	    ivis[gvpvar_1.top] = gvpvar_1.cur;
	    return 0;
	}
    }
L30:
    ++k;
    if (k < gvpvar_1.nv) {
	goto L10;
    }

/*     Error from unsuccessful scan. */

    gerror_1.ierr = 210;
} /* vpscnd_ */

