/* basic2d.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 {
    doublereal pi, tol;
} gconst_;

#define gconst_1 gconst_

struct {
    integer ierr;
} gerror_;

#define gerror_1 gerror_


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

doublereal angle_(xa, ya, xb, yb, xc, yc)
doublereal *xa, *ya, *xb, *yb, *xc, *yc;
{
    /* System generated locals */
    doublereal ret_val, d__1, d__2, d__3, d__4;

    /* Builtin functions */
    double sqrt(), acos();

    /* Local variables */
    static doublereal t, x1, x2, y1, y2, signus;


/*     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 interior angle (in radians) at vertex */
/*        (XB,YB) of the chain formed by the directed edges from */
/*        (XA,YA) to (XB,YB) to (XC,YC) - the interior is to the */
/*        left of the two directed edges. */

/*     Input parameters: */
/*        XA,YA, XB,YB, XC,YC - vertex coordinates */

/*     Returned function value: */
/*        ANGLE - angle between 0 and 2*PI (PI/2 in degenerate case) */



    x1 = *xa - *xb;
    y1 = *ya - *yb;
    x2 = *xc - *xb;
    y2 = *yc - *yb;
/* Computing 2nd power */
    d__1 = x1;
/* Computing 2nd power */
    d__2 = y1;
/* Computing 2nd power */
    d__3 = x2;
/* Computing 2nd power */
    d__4 = y2;
    t = sqrt((d__1 * d__1 + d__2 * d__2) * (d__3 * d__3 + d__4 * d__4));
    if (t == 0.) {
	t = 1.;
    }
    t = (x1 * x2 + y1 * y2) / t;

/*     Eliminate the call to sign to avoid using the fortran math library 
*/
/*     IF (ABS(T) .GT. 1.0D0 - TOL) T = SIGN(1.0D0,T) */

    signus = -1.;
    if (t > 0.) {
	signus = 1.;
    }

    if (abs(t) > 1. - gconst_1.tol) {
	t = signus;
    }
    ret_val = acos(t);
    if (x2 * y1 - y2 * x1 < 0.) {
	ret_val = gconst_1.pi * 2. - ret_val;
    }
    return ret_val;
} /* angle_ */


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

doublereal areapg_(nvrt, xc, yc)
integer *nvrt;
doublereal *xc, *yc;
{
    /* System generated locals */
    integer i__1;
    doublereal ret_val;

    /* Local variables */
    static integer i;
    static doublereal sum;


/*     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 twice the signed area of a simple polygon with */
/*        vertices given in circular (CCW or CW) order. */

/*     Input parameters: */
/* 	 NVRT - number of vertices on the boundary of polygon (>= 3) */
/* 	 XC(1:NVRT),YC(1:NVRT) - vertex coordinates in CCW or CW order */

/*     Returned function value: */
/*        AREAPG - twice the signed area of polygon, positive if CCW */


    /* Parameter adjustments */
    --yc;
    --xc;

    /* Function Body */
    sum = xc[1] * (yc[2] - yc[*nvrt]) + xc[*nvrt] * (yc[1] - yc[*nvrt - 1]);
    i__1 = *nvrt - 1;
    for (i = 2; i <= i__1; ++i) {
	sum += xc[i] * (yc[i + 1] - yc[i - 1]);
/* L10: */
    }
    ret_val = sum;
    return ret_val;
} /* areapg_ */


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

doublereal areatr_(xa, ya, xb, yb, xc, yc)
doublereal *xa, *ya, *xb, *yb, *xc, *yc;
{
    /* System generated locals */
    doublereal ret_val;


/*     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 twice the signed area of the triangle with */
/*         vertices (XA,YA), (XB,YB), and (XC,YC) in CCW or CW order. */

/*     Input parameters: */
/*        XA,YA, XB,YB, XC,YC - vertex coordinates */

/*     Returned function value: */
/*        AREATR - twice the signed area of triangle, positive if CCW */

    ret_val = (*xb - *xa) * (*yc - *ya) - (*xc - *xa) * (*yb - *ya);
    return ret_val;
} /* areatr_ */


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

integer diaedg_(x0, y0, x1, y1, x2, y2, x3, y3)
doublereal *x0, *y0, *x1, *y1, *x2, *y2, *x3, *y3;
{
    /* System generated locals */
    integer ret_val;
    doublereal d__1, d__2;

    /* Local variables */
    static doublereal tola, tolb, s, ca, cb, dx10, dy10, dx12, dx30, dx32, 
	    dy12, dy30, dy32;


/*     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 whether 02 or 13 is the diagonal edge chosen */
/*        based on the circumcircle criterion, where (X0,Y0), (X1,Y1), */
/*        (X2,Y2), (X3,Y3) are the vertices of a simple quadrilateral */
/*        in counterclockwise order. */

/*     Input parameters: */
/*        X0,Y0, X1,Y1, X2,Y2, X3,Y3 - vertex coordinates */

/*     Returned function value: */
/*        DIAEDG -  1 if diagonal edge 02 is chosen, i.e. 02 is inside */
/*                  quadrilateral + vertex 3 is outside circumcircle 012 
*/
/*                 -1 if diagonal edge 13 is chosen, i.e. 13 is inside */
/*                  quadrilateral + vertex 0 is outside circumcircle 123 
*/
/*                  0 if four vertices are cocircular */



    dx10 = *x1 - *x0;
    dy10 = *y1 - *y0;
    dx12 = *x1 - *x2;
    dy12 = *y1 - *y2;
    dx30 = *x3 - *x0;
    dy30 = *y3 - *y0;
    dx32 = *x3 - *x2;
    dy32 = *y3 - *y2;
/* Computing MAX */
    d__1 = abs(dx10), d__2 = abs(dy10), d__1 = max(d__1,d__2), d__2 = abs(
	    dx30), d__1 = max(d__1,d__2), d__2 = abs(dy30);
    tola = gconst_1.tol * max(d__1,d__2);
/* Computing MAX */
    d__1 = abs(dx12), d__2 = abs(dy12), d__1 = max(d__1,d__2), d__2 = abs(
	    dx32), d__1 = max(d__1,d__2), d__2 = abs(dy32);
    tolb = gconst_1.tol * max(d__1,d__2);
    ca = dx10 * dx30 + dy10 * dy30;
    cb = dx12 * dx32 + dy12 * dy32;
    if (ca > tola && cb > tolb) {
	ret_val = -1;
    } else if (ca < -tola && cb < -tolb) {
	ret_val = 1;
    } else {
	tola = max(tola,tolb);
	s = (dx10 * dy30 - dx30 * dy10) * cb + (dx32 * dy12 - dx12 * dy32) * 
		ca;
	if (s > tola) {
	    ret_val = -1;
	} else if (s < -tola) {
	    ret_val = 1;
	} else {
	    ret_val = 0;
	}
    }
    return ret_val;
} /* diaedg_ */


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

/* Subroutine */ int diam2_(nvrt, xc, yc, i1, i2, diamsq)
integer *nvrt;
doublereal *xc, *yc;
integer *i1, *i2;
doublereal *diamsq;
{
    /* System generated locals */
    doublereal d__1, d__2;

    /* Local variables */
    static doublereal dist, area1, area2;
    static integer j, k, m;
    static doublereal c1mtol, c1ptol;
    extern doublereal areatr_();
    static integer jp1, kp1;


/*     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: Find the diameter of a convex polygon with vertices */
/*        given in CCW order and with all interior angles < PI. */

/*     Input parameters: */
/* 	 NVRT - number of vertices on the boundary of convex polygon */
/* 	 XC(1:NVRT),YC(1:NVRT) - vertex coordinates in CCW order */

/*     Output parameters: */
/*        I1,I2 - indices in XC,YC of diameter edge; diameter is from */
/*              (XC(I1),YC(I1)) to (XC(I2),YC(I2)) */
/*        DIAMSQ - square of diameter */

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

/*     Routines called: */
/*        AREATR */



/*     Find first vertex which is farthest from edge connecting */
/*     vertices with indices NVRT, 1. */

    /* Parameter adjustments */
    --yc;
    --xc;

    /* Function Body */
    c1mtol = 1. - gconst_1.tol;
    c1ptol = gconst_1.tol + 1.;
    j = *nvrt;
    jp1 = 1;
    k = 2;
    area1 = areatr_(&xc[j], &yc[j], &xc[jp1], &yc[jp1], &xc[k], &yc[k]);
L10:
    area2 = areatr_(&xc[j], &yc[j], &xc[jp1], &yc[jp1], &xc[k + 1], &yc[k + 1]
	    );
    if (area2 > area1 * c1ptol) {
	area1 = area2;
	++k;
	goto L10;
    }
    m = k;
    *diamsq = 0.;

/*     Find diameter = maximum distance of antipodal pairs. */

    area1 = areatr_(&xc[j], &yc[j], &xc[jp1], &yc[jp1], &xc[k], &yc[k]);
L20:
    kp1 = k + 1;
    if (kp1 > *nvrt) {
	kp1 = 1;
    }
    area2 = areatr_(&xc[j], &yc[j], &xc[jp1], &yc[jp1], &xc[kp1], &yc[kp1]);
    if (area2 > area1 * c1ptol) {
	++k;
	area1 = area2;
    } else if (area2 < area1 * c1mtol) {
	j = jp1;
	jp1 = j + 1;
	area1 = areatr_(&xc[j], &yc[j], &xc[jp1], &yc[jp1], &xc[k], &yc[k]);
    } else {
	++k;
	j = jp1;
	jp1 = j + 1;
	area1 = areatr_(&xc[j], &yc[j], &xc[jp1], &yc[jp1], &xc[k], &yc[k]);
    }
    if (j > m || k > *nvrt) {
	gerror_1.ierr = 200;
	return 0;
    }
/* Computing 2nd power */
    d__1 = xc[j] - xc[k];
/* Computing 2nd power */
    d__2 = yc[j] - yc[k];
    dist = d__1 * d__1 + d__2 * d__2;
    if (dist > *diamsq) {
	*diamsq = dist;
	*i1 = j;
	*i2 = k;
    }
    if (j != m || k != *nvrt) {
	goto L20;
    }
} /* diam2_ */


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

integer lrline_(xu, yu, xv1, yv1, xv2, yv2, dv)
doublereal *xu, *yu, *xv1, *yv1, *xv2, *yv2, *dv;
{
    /* System generated locals */
    integer ret_val;
    doublereal d__1, d__2;

    /* Builtin functions */
    double sqrt();

    /* Local variables */
    static doublereal t, dx, dy, tolabs, signus, dxu, dyu;


/*     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 whether a point is to the left of, right of, */
/*        or on a directed line parallel to a line through given points. 
*/

/*     Input parameters: */
/*        XU,YU, XV1,YV1, XV2,YV2 - vertex coordinates; the directed */
/*              line is parallel to and at signed distance DV to the */
/*              left of the directed line from (XV1,YV1) to (XV2,YV2); */
/*              (XU,YU) is the vertex for which the position */
/*              relative to the directed line is to be determined */
/*        DV - signed distance (positive for left) */

/*     Returned function value: */
/*        LRLINE - +1, 0, or -1 depending on whether (XU,YU) is */
/*              to the right of, on, or left of the directed line */
/*              (0 if line degenerates to a point) */



    dx = *xv2 - *xv1;
    dy = *yv2 - *yv1;
    dxu = *xu - *xv1;
    dyu = *yu - *yv1;
/* Computing MAX */
    d__1 = abs(dx), d__2 = abs(dy), d__1 = max(d__1,d__2), d__2 = abs(dxu), 
	    d__1 = max(d__1,d__2), d__2 = abs(dyu), d__1 = max(d__1,d__2), 
	    d__2 = abs(*dv);
    tolabs = gconst_1.tol * max(d__1,d__2);
    t = dy * dxu - dx * dyu;
    if (*dv != 0.) {
/* Computing 2nd power */
	d__1 = dx;
/* Computing 2nd power */
	d__2 = dy;
	t += *dv * sqrt(d__1 * d__1 + d__2 * d__2);
    }

/*     Eliminate the call to sign to avoid using the fortran math library 
*/
/*     LRLINE = INT(SIGN(1.0D0,T)) */

    signus = -1.;
    if (t > 0.) {
	signus = 1.;
    }

    ret_val = (integer) signus;
    if (abs(t) <= tolabs) {
	ret_val = 0;
    }
    return ret_val;
} /* lrline_ */


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

/* Subroutine */ int shrnk2_(nvrt, xc, yc, sdist, nshr, xs, ys, iedge)
integer *nvrt;
doublereal *xc, *yc, *sdist;
integer *nshr;
doublereal *xs, *ys;
integer *iedge;
{
    /* System generated locals */
    integer i__1;
    doublereal d__1;

    /* Builtin functions */
    double atan2();

    /* Local variables */
    static integer i, j, k;
    static doublereal alpha, theta;
    extern /* Subroutine */ int xline_();
    static logical first;
    static integer lr;
    static logical parall;
    extern integer lrline_();
    static doublereal pi2;


/*     Purpose: Shrink a convex polygon, with vertices given in CCW */
/*        order and with all interior angles < PI, by distance SDIST(I) */

/*        for Ith edge, I = 0,...,NVRT-1. */

/*     Input parameters: */
/* 	 NVRT - number of vertices on the boundary of convex polygon */
/* 	 XC(0:NVRT),YC(0:NVRT) - vertex coordinates in CCW order; */
/*              (XC(0),YC(0)) = (XC(NVRT),YC(NVRT)) */
/*        SDIST(0:NVRT-1) - nonnegative shrink distances for edges */

/*     Output parameters: */
/*        NSHR - number of vertices on boundary of shrunken polygon; */
/*              0 if shrunken polygon is empty else 3 <= NSHR <= NVRT */
/*        XS(0:NSHR),YS(0:NSHR) - coordinates of shrunken polygon in CCW 
*/
/*              order if NSHR > 0; (XS(0),YS(0)) = (XS(NSHR),YS(NSHR)) */
/*        IEDGE(0:NVRT) - indices of edges of shrunken polygon in */
/*              range from 0 to NVRT-1 */

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

/*     Routines called: */
/*        LRLINE, XLINE */



    pi2 = gconst_1.pi * 2.;
    alpha = atan2(yc[1] - yc[0], xc[1] - xc[0]);
    xline_(xc, yc, &xc[1], &yc[1], &xc[1], &yc[1], &xc[2], &yc[2], sdist, &
	    sdist[1], &xs[1], &ys[1], &parall);
    if (parall) {
	gerror_1.ierr = 202;
	goto L90;
    }
    iedge[0] = 0;
    iedge[1] = 1;
    i = 2;
    j = 0;
    *nshr = 1;
    first = TRUE_;

/*     First while loop processes edges subtending angle <= PI */
/*     with respect to first edge. */

L10:
    theta = atan2(yc[i + 1] - yc[i], xc[i + 1] - xc[i]) - alpha;
    if (theta < 0.) {
	theta += pi2;
    }
    if (theta > gconst_1.pi + gconst_1.tol) {
	goto L40;
    }
L20:
    lr = lrline_(&xs[*nshr], &ys[*nshr], &xc[i], &yc[i], &xc[i + 1], &yc[i + 
	    1], &sdist[i]);
    if (lr < 0) {
	goto L30;
    }
    --(*nshr);
    if (*nshr >= 1) {
	goto L20;
    }
L30:
    if (*nshr < 1 && (d__1 = theta - gconst_1.pi, abs(d__1)) <= gconst_1.tol) 
	    {
	goto L90;
    }
    k = iedge[*nshr];
    ++(*nshr);
    xline_(&xc[k], &yc[k], &xc[k + 1], &yc[k + 1], &xc[i], &yc[i], &xc[i + 1],
	     &yc[i + 1], &sdist[k], &sdist[i], &xs[*nshr], &ys[*nshr], &
	    parall);
    if (parall) {
	gerror_1.ierr = 202;
	goto L90;
    }
    iedge[*nshr] = i;
    ++i;
    goto L10;

/*     Second while loop processes remaining edges. */

L40:
    if (first) {
	first = FALSE_;
	goto L50;
    }
    lr = lrline_(&xs[j], &ys[j], &xc[i], &yc[i], &xc[i + 1], &yc[i + 1], &
	    sdist[i]);
    if (lr <= 0) {
	goto L70;
    }
L50:
    if (*nshr <= j) {
	goto L90;
    }
    lr = lrline_(&xs[*nshr], &ys[*nshr], &xc[i], &yc[i], &xc[i + 1], &yc[i + 
	    1], &sdist[i]);
    if (lr >= 0) {
	--(*nshr);
	goto L50;
    }
    k = iedge[*nshr];
    ++(*nshr);
    xline_(&xc[k], &yc[k], &xc[k + 1], &yc[k + 1], &xc[i], &yc[i], &xc[i + 1],
	     &yc[i + 1], &sdist[k], &sdist[i], &xs[*nshr], &ys[*nshr], &
	    parall);
    if (parall) {
	gerror_1.ierr = 202;
	goto L90;
    }
    iedge[*nshr] = i;
L60:
    lr = lrline_(&xs[j + 1], &ys[j + 1], &xc[i], &yc[i], &xc[i + 1], &yc[i + 
	    1], &sdist[i]);
    if (lr >= 0) {
	++j;
	goto L60;
    }
    k = iedge[j];
    xline_(&xc[k], &yc[k], &xc[k + 1], &yc[k + 1], &xc[i], &yc[i], &xc[i + 1],
	     &yc[i + 1], &sdist[k], &sdist[i], &xs[j], &ys[j], &parall);
    if (parall) {
	gerror_1.ierr = 202;
	goto L90;
    }
    xs[*nshr + 1] = xs[j];
    ys[*nshr + 1] = ys[j];
    iedge[*nshr + 1] = iedge[j];
L70:
    ++i;
    if (i < *nvrt) {
	goto L40;
    }

    if (j > 0) {
	i__1 = *nshr + 1 - j;
	for (i = 0; i <= i__1; ++i) {
	    xs[i] = xs[i + j];
	    ys[i] = ys[i + j];
	    iedge[i] = iedge[i + j];
/* L80: */
	}
    }
    *nshr = *nshr + 1 - j;
    return 0;

L90:
    *nshr = 0;
    return 0;
} /* shrnk2_ */


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

/* Subroutine */ int width2_(nvrt, xc, yc, i1, i2, widsq)
integer *nvrt;
doublereal *xc, *yc;
integer *i1, *i2;
doublereal *widsq;
{
    /* System generated locals */
    doublereal d__1, d__2, d__3;

    /* Local variables */
    static doublereal dist, area1, area2;
    static integer a, b, c, j, k, m;
    static doublereal c1mtol, c1ptol, dx, dy;
    extern doublereal areatr_();
    static integer jp1, kp1;


/*     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: Find the width (minimum breadth) of a convex polygon with 
*/
/*        vertices given in CCW order and with all interior angles < PI. 
*/

/*     Input parameters: */
/* 	 NVRT - number of vertices on the boundary of convex polygon */
/* 	 XC(1:NVRT),YC(1:NVRT) - vertex coordinates in CCW order */

/*     Output parameters: */
/*        I1,I2 - indices in XC,YC such that width is from vertex */
/*              (XC(I1),YC(I1)) to line joining (XC(I2),YC(I2)) and */
/*              (XC(I2+1),YC(I2+1)), where index NVRT+1 is same as 1 */
/*        WIDSQ - square of width */

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

/*     Routines called: */
/*        AREATR */



/*     Find first vertex which is farthest from edge connecting */
/*     vertices with indices NVRT, 1. */

    /* Parameter adjustments */
    --yc;
    --xc;

    /* Function Body */
    c1mtol = 1. - gconst_1.tol;
    c1ptol = gconst_1.tol + 1.;
    j = *nvrt;
    jp1 = 1;
    k = 2;
    area1 = areatr_(&xc[j], &yc[j], &xc[jp1], &yc[jp1], &xc[k], &yc[k]);
L10:
    area2 = areatr_(&xc[j], &yc[j], &xc[jp1], &yc[jp1], &xc[k + 1], &yc[k + 1]
	    );
    if (area2 > area1 * c1ptol) {
	area1 = area2;
	++k;
	goto L10;
    }
    m = k;
    *widsq = 0.;

/*     Find width = min distance of antipodal edge-vertex pairs. */

    area1 = areatr_(&xc[j], &yc[j], &xc[jp1], &yc[jp1], &xc[k], &yc[k]);
L20:
    kp1 = k + 1;
    if (kp1 > *nvrt) {
	kp1 = 1;
    }
    area2 = areatr_(&xc[j], &yc[j], &xc[jp1], &yc[jp1], &xc[kp1], &yc[kp1]);
    if (area2 > area1 * c1ptol) {
	a = j;
	b = k;
	++k;
	c = k;
	if (c > *nvrt) {
	    c = 1;
	}
	area1 = area2;
    } else if (area2 < area1 * c1mtol) {
	a = k;
	b = j;
	c = jp1;
	j = jp1;
	jp1 = j + 1;
	area1 = areatr_(&xc[j], &yc[j], &xc[jp1], &yc[jp1], &xc[k], &yc[k]);
    } else {
	a = k;
	b = j;
	c = jp1;
	++k;
	j = jp1;
	jp1 = j + 1;
	area1 = areatr_(&xc[j], &yc[j], &xc[jp1], &yc[jp1], &xc[k], &yc[k]);
    }
    if (j > m || k > *nvrt) {
	gerror_1.ierr = 201;
	return 0;
    }
    dx = xc[c] - xc[b];
    dy = yc[c] - yc[b];
/* Computing 2nd power */
    d__1 = (yc[a] - yc[b]) * dx - (xc[a] - xc[b]) * dy;
/* Computing 2nd power */
    d__2 = dx;
/* Computing 2nd power */
    d__3 = dy;
    dist = d__1 * d__1 / (d__2 * d__2 + d__3 * d__3);
    if (dist < *widsq || *widsq <= 0.) {
	*widsq = dist;
	*i1 = a;
	*i2 = b;
    }
    if (j != m || k != *nvrt) {
	goto L20;
    }
} /* width2_ */


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

/* Subroutine */ int xedge_(mode, xv1, yv1, xv2, yv2, xw1, yw1, xw2, yw2, xu, 
	yu, intsct)
integer *mode;
doublereal *xv1, *yv1, *xv2, *yv2, *xw1, *yw1, *xw2, *yw2, *xu, *yu;
logical *intsct;
{
    /* System generated locals */
    doublereal d__1, d__2;

    /* Local variables */
    static doublereal t, denom, tolabs, dxv, dxw, dyv, dyw;


/*     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 whether two edges or a ray and an edge */
/*        intersect and return the intersection point if they do. */

/*     Input parameters: */
/*        MODE - 0 for two edges, 1 (or nonzero) for a ray and an edge */
/*        XV1,YV1, XV2,YV2, XW1,YW1, XW2,YW2 - vertex coordinates; */
/*              an edge (ray) is from (XV1,YV1) to (thru) (XV2,YV2); */
/*              an edge joins vertices (XW1,YW1) and (XW2,YW2) */

/*     Output parameters: */
/*        XU,YU - coordinates of the point of intersection iff INTSCT */
/*              is .TRUE. */
/*        INTSCT - .TRUE. if the edges/ray are nondegenerate, not */
/*              parallel, and intersect, .FALSE. otherwise */



    *intsct = FALSE_;
    dxv = *xv2 - *xv1;
    dyv = *yv2 - *yv1;
    dxw = *xw2 - *xw1;
    dyw = *yw2 - *yw1;
/* Computing MAX */
    d__1 = abs(dxv), d__2 = abs(dyv), d__1 = max(d__1,d__2), d__2 = abs(dxw), 
	    d__1 = max(d__1,d__2), d__2 = abs(dyw);
    tolabs = gconst_1.tol * max(d__1,d__2);
    denom = dyv * dxw - dxv * dyw;
    if (abs(denom) <= tolabs) {
	return 0;
    }
    t = (dyv * (*xv1 - *xw1) - dxv * (*yv1 - *yw1)) / denom;
    if (t < -gconst_1.tol || t > gconst_1.tol + 1.) {
	return 0;
    }
    *xu = *xw1 + t * dxw;
    *yu = *yw1 + t * dyw;
    if (abs(dxv) >= abs(dyv)) {
	t = (*xu - *xv1) / dxv;
    } else {
	t = (*yu - *yv1) / dyv;
    }
    if (*mode == 0) {
	if (t >= -gconst_1.tol && t <= gconst_1.tol + 1.) {
	    *intsct = TRUE_;
	}
    } else {
	if (t >= -gconst_1.tol) {
	    *intsct = TRUE_;
	}
    }
} /* xedge_ */


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

/* Subroutine */ int xline_(xv1, yv1, xv2, yv2, xw1, yw1, xw2, yw2, dv, dw, 
	xu, yu, parall)
doublereal *xv1, *yv1, *xv2, *yv2, *xw1, *yw1, *xw2, *yw2, *dv, *dw, *xu, *yu;

logical *parall;
{
    /* System generated locals */
    doublereal d__1, d__2;

    /* Builtin functions */
    double sqrt();

    /* Local variables */
    static doublereal b1, b2, a11, a12, a21, a22, tolabs, 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 intersection point of two lines parallel */
/*        to lines through given points. */

/*     Input parameters: */
/*        XV1,YV1, XV2,YV2, XW1,YW1, XW2,YW2 - vertex coordinates; */
/*              first line is parallel to and at signed distance DV to */
/*              left of directed line from (XV1,YV1) to (XV2,YV2); */
/*              second line is parallel to and at signed distance DW to */

/*              left of directed line from (XW1,YW1) to (XW2,YW2) */
/*        DV,DW - signed distances (positive for left) */

/*     Output parameters: */
/*        XU,YU - coordinates of the point of intersection iff PARALL */
/*              is .FALSE. */
/*        PARALL - .TRUE. if the lines are parallel or two points for a */

/*              line are identical, .FALSE. otherwise */



    *parall = TRUE_;
    a11 = *yv2 - *yv1;
    a12 = *xv1 - *xv2;
    a21 = *yw2 - *yw1;
    a22 = *xw1 - *xw2;
/* 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) {
	return 0;
    }
    b1 = *xv1 * a11 + *yv1 * a12;
    if (*dv != 0.) {
/* Computing 2nd power */
	d__1 = a11;
/* Computing 2nd power */
	d__2 = a12;
	b1 -= *dv * sqrt(d__1 * d__1 + d__2 * d__2);
    }
    b2 = *xw1 * a21 + *yw1 * a22;
    if (*dw != 0.) {
/* Computing 2nd power */
	d__1 = a21;
/* Computing 2nd power */
	d__2 = a22;
	b2 -= *dw * sqrt(d__1 * d__1 + d__2 * d__2);
    }
    *xu = (b1 * a22 - b2 * a12) / det;
    *yu = (b2 * a11 - b1 * a21) / det;
    *parall = FALSE_;
} /* xline_ */

