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

#define gconst_1 gconst_

/* Table of constant values */

static integer c__1 = 1;
static doublereal c_b41 = 0.;
static integer c__0 = 0;
static integer c__2 = 2;


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

/* Subroutine */ int bedgmv_(nvc, npolg, nvert, maxvc, h, vcl, hvl, pvl, 
	vstart, vnum)
integer *nvc, *npolg, *nvert, *maxvc;
doublereal *h, *vcl;
integer *hvl, *pvl, *vstart, *vnum;
{
    /* System generated locals */
    integer i__1, i__2;
    doublereal d__1, d__2;

    /* Builtin functions */
    double sqrt();

    /* Local variables */
    static doublereal leng;
    static integer i, j, k, l, m, u, v;
    static doublereal x, y;
    static integer ia;
    static doublereal hh, dx, dy;


/*     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: Generate mesh vertices on boundary of convex polygons */
/*        of decomposition with spacing determined by H array. */

/*     Input parameters: */
/*        NVC - number of coordinates or positions used in VCL array */
/*        NPOLG - number of polygons or positions used in HVL array */
/*        NVERT - number of vertices or positions used in PVL array */
/*        MAXVC - maximum size available for VCL array */
/*        H(1:NPOLG) - spacing of mesh vertices for convex polygons */
/*        VCL(1:2,1:NVC) - vertex coordinate list */
/*        HVL(1:NPOLG) - head vertex list */
/*        PVL(1:4,1:NVERT) - polygon vertex list */

/*     Updated parameters: */
/*        NVC,VCL */

/*     Output parameters: */
/*        VSTART(1:NVERT) - start location in VCL for mesh vertices on */
/*              each edge in PVL if there are any, else 0 */
/*        VNUM(1:NVERT) - number of mesh vertices on interior of each */
/*              edge in PVL; entry is negated if mesh vertices are */
/*              listed in backward order in VCL */

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




    /* Parameter adjustments */
    --vnum;
    --vstart;
    pvl -= 5;
    --hvl;
    vcl -= 3;
    --h;

    /* Function Body */
    i__1 = *nvert;
    for (i = 1; i <= i__1; ++i) {
	vstart[i] = -1;
/* L10: */
    }
    i__1 = *npolg;
    for (k = 1; k <= i__1; ++k) {
	i = hvl[k];
L20:
	j = pvl[(i << 2) + 3];
	if (vstart[i] == -1) {
	    u = pvl[(i << 2) + 1];
	    v = pvl[(j << 2) + 1];
	    x = vcl[(u << 1) + 1];
	    y = vcl[(u << 1) + 2];
/* Computing 2nd power */
	    d__1 = vcl[(v << 1) + 1] - x;
/* Computing 2nd power */
	    d__2 = vcl[(v << 1) + 2] - y;
	    leng = sqrt(d__1 * d__1 + d__2 * d__2);
	    ia = pvl[(i << 2) + 4];
	    if (ia <= 0) {
		hh = h[k];
	    } else {
		hh = sqrt(h[k] * h[pvl[(ia << 2) + 2]]);
	    }
	    l = (integer) (leng / hh);
	    if (leng / hh - l > (doublereal) l / (doublereal) ((l << 1) + 1)) 
		    {
		++l;
	    }
	    if (l <= 1) {
		vstart[i] = 0;
		vnum[i] = 0;
	    } else {
		dx = (vcl[(v << 1) + 1] - x) / (doublereal) l;
		dy = (vcl[(v << 1) + 2] - y) / (doublereal) l;
		--l;
		if (*nvc + l > *maxvc) {
		    gerror_1.ierr = 3;
		    return 0;
		}
		vstart[i] = *nvc + 1;
		vnum[i] = l;
		i__2 = l;
		for (m = 1; m <= i__2; ++m) {
		    x += dx;
		    y += dy;
		    ++(*nvc);
		    vcl[(*nvc << 1) + 1] = x;
		    vcl[(*nvc << 1) + 2] = y;
/* L30: */
		}
	    }
	    if (ia > 0) {
		vstart[ia] = vstart[i];
		vnum[ia] = -vnum[i];
	    }
	}
	i = j;
	if (i != hvl[k]) {
	    goto L20;
	}
/* L40: */
    }
} /* bedgmv_ */


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

/* Subroutine */ int cvdtri_(inter, ldv, nt, vcl, til, tedg, sptr)
logical *inter;
integer *ldv, *nt;
doublereal *vcl;
integer *til, *tedg, *sptr;
{
    /* System generated locals */
    integer vcl_dim1, vcl_offset, i__1;

    /* Local variables */
    static integer mxtr, e, k;
    static logical sflag;
    extern /* Subroutine */ int fndtri_();
    static integer ind[2];
    extern /* Subroutine */ int lop_();
    static integer itr[2], top;


/*     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: Convert triangles in strip near boundary of polygon */
/*        or inside polygon to Delaunay triangles. */

/*     Input parameters: */
/* 	 INTER - .TRUE. iff at least one interior mesh vertex */
/*        LDV - leading dimension of VCL in calling routine */
/* 	 NT - number of triangles in strip or polygon */
/*        VCL(1:2,1:*) - vertex coordinate list */
/*        TIL(1:3,1:NT) - triangle incidence list */
/*        TEDG(1:3,1:NT) - TEDG(J,I) refers to edge with vertices */
/*              TIL(J:J+1,I) and contains index of merge edge or */
/*              > NT for edge of chains */

/*     Updated parameters: */
/*        TIL,TEDG - updated due to diagonal edge swaps */

/*     Working parameter: */
/*        SPTR(1:NT) - SPTR(I) = -1 if merge edge I is not in LOP stack, 
*/
/*              else >= 0 and pointer (index of SPTR) to next edge in */
/*              stack (0 indicates bottom of stack) */

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

/*     Routines called: */
/*        FNDTRI, LOP */



    /* Parameter adjustments */
    --sptr;
    tedg -= 4;
    til -= 4;
    vcl_dim1 = *ldv;
    vcl_offset = vcl_dim1 + 1;
    vcl -= vcl_offset;

    /* Function Body */
    sflag = TRUE_;
    i__1 = *nt;
    for (k = 1; k <= i__1; ++k) {
	sptr[k] = -1;
/* L10: */
    }
    i__1 = *nt;
    for (k = 1; k <= i__1; ++k) {
	mxtr = k + 1;
	if (k == *nt) {
	    if (! (*inter)) {
		return 0;
	    }
	    mxtr = *nt;
	    sflag = FALSE_;
	}
	top = k;
	sptr[k] = 0;
L20:
	e = top;
	top = sptr[e];
	fndtri_(&e, &mxtr, &sflag, &tedg[4], itr, ind);
	if (gerror_1.ierr != 0) {
	    return 0;
	}
	lop_(itr, ind, &k, &top, ldv, &vcl[vcl_offset], &til[4], &tedg[4], &
		sptr[1]);
	if (top > 0) {
	    goto L20;
	}
/* L30: */
    }
} /* cvdtri_ */


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

/* Subroutine */ int fndtri_(iedg, mxtr, sflag, tedg, itr, ind)
integer *iedg, *mxtr;
logical *sflag;
integer *tedg, *itr, *ind;
{
    static integer i, j, k;


/*     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 two triangles containing edge with index IEDG */
/*        in array TEDG. */

/*     Input parameters: */
/*        IEDG - index of edge to be searched in TEDG */
/*        MXTR - maximum index of triangle to be searched in TEDG */
/* 	 SFLAG - .TRUE. iff second triangle is to be searched from */
/*              end of array */
/*        TEDG(1:3,1:MXTR) - triangle edge indices; see routine CVDTRI */

/*     Output parameters: */
/*        ITR(1:2),IND(1:2) - indices such that IEDG = */
/*              TEDG(IND(1),ITR(1)) = TEDG(IND(2),ITR(2)) */

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



/*     Search from end of array TEDG. */

    /* Parameter adjustments */
    --ind;
    --itr;
    tedg -= 4;

    /* Function Body */
    k = 1;
    j = 1;
    i = *mxtr;
L10:
    if (tedg[j + i * 3] != *iedg) {
	++j;
	if (j > 3) {
	    j = 1;
	    --i;
	    if (i <= 0) {
		gerror_1.ierr = 231;
		return 0;
	    }
	}
	goto L10;
    }
    itr[k] = i;
    ind[k] = j;
    if (k == 2) {
	return 0;
    }
    k = 2;
    if (*sflag) {
	j = 1;
	--i;
	if (i <= 0) {
	    gerror_1.ierr = 231;
	    return 0;
	}
	goto L10;
    }

/*     Search from beginning of array TEDG for second triangle. */

    j = 1;
    i = 1;
L20:
    if (i >= itr[1]) {
	gerror_1.ierr = 231;
	return 0;
    }
L30:
    if (tedg[j + i * 3] != *iedg) {
	++j;
	if (j > 3) {
	    j = 1;
	    ++i;
	    goto L20;
	} else {
	    goto L30;
	}
    }
    itr[2] = i;
    ind[2] = j;
} /* fndtri_ */


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

/* Subroutine */ int inttri_(nvrt, xc, yc, h, ibot, costh, sinth, ldv, nvc, 
	ntri, maxvc, maxti, maxcw, vcl, til, ncw, cwalk)
integer *nvrt;
doublereal *xc, *yc, *h;
integer *ibot;
doublereal *costh, *sinth;
integer *ldv, *nvc, *ntri, *maxvc, *maxti, *maxcw;
doublereal *vcl;
integer *til, *ncw, *cwalk;
{
    /* System generated locals */
    integer vcl_dim1, vcl_offset, i__1, i__2;
    doublereal d__1;

    /* Local variables */
    static doublereal a, b;
    static integer i, j, k, l, m, n, p, r;
    static doublereal x, y;
    static integer l0, l1, r0, r1, il, ir;
    static doublereal cy, xj;
    static integer lw;
    static doublereal xk, xl;
    static integer rw;
    static doublereal xr, sy;
    static integer im1l, im1r;
    static doublereal xm1l, xm1r;


/*     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: Generate triangles inside convex polygon using quasi- */
/*        uniform grid of spacing H. It is assumed that diameter of */
/*        polygon is parallel to y-axis. */

/*     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)) */
/*        H - spacing of mesh vertices in polygon */
/*        IBOT - index of bottom vertex; diameter contains vertices */
/*              (XC(0),YC(0)) and (XC(IBOT),YC(IBOT)) */
/*        COSTH,SINTH - COS(THETA), SIN(THETA) where THETA in [-PI,PI] */
/*              is rotation angle to get diameter parallel to y-axis */
/*        LDV - leading dimension of VCL in calling routine */
/*        NVC - number of coordinates or positions used in VCL array */
/*        NTRI - number of triangles or positions used in TIL */
/*        MAXVC - maximum size available for VCL array */
/*        MAXTI - maximum size available for TIL array */
/*        MAXCW - maximum size available for CWALK array; assumed to be */

/*              >= 6*(1 + INT((YC(0) - YC(IBOT))/H)) */
/*        VCL(1:2,1:NVC) - vertex coordinate list */
/*        TIL(1:3,1:NTRI) - triangle incidence list */

/*     Updated parameters: */
/*        NVC,NTRI,VCL,TIL */

/*     Output parameters: */
/*        NCW - number of mesh vertices in closed walk, except NCW = 0 */
/*              for 1 vertex */
/*        CWALK(0:NCW) - indices in VCL of mesh vertices of closed */
/*              walk; CWALK(0) = CWALK(NCW) */

/*     Abnormal return: */
/*        IERR is set to 3, 9, or 10 */



    /* Parameter adjustments */
    til -= 4;
    vcl_dim1 = *ldv;
    vcl_offset = vcl_dim1 + 1;
    vcl -= vcl_offset;

    /* Function Body */
    n = (integer) ((yc[0] - yc[*ibot]) / *h);
    y = yc[0] - (yc[0] - yc[*ibot] - (doublereal) n * *h) * .5;
    l = 0;
    r = *nvrt;
    i__1 = n;
    for (i = 0; i <= i__1; ++i) {

/*        Determine left and right x-coordinates of polygon for */
/*        scan line with y-coordinate Y, and generate mesh vertices. 
*/

L10:
	if (yc[l + 1] > y) {
	    ++l;
	    goto L10;
	}
L20:
	if (yc[r - 1] > y) {
	    --r;
	    goto L20;
	}
	xl = xc[l] + (xc[l + 1] - xc[l]) * (y - yc[l]) / (yc[l + 1] - yc[l]);
	xr = xc[r] + (xc[r - 1] - xc[r]) * (y - yc[r]) / (yc[r - 1] - yc[r]);
	m = (integer) ((xr - xl) / *h);
	x = xl + (xr - xl - (doublereal) m * *h) * .5;
	if (*nvc + m + 1 > *maxvc) {
	    gerror_1.ierr = 3;
	    return 0;
	}
	cy = *costh * y;
	sy = *sinth * y;
	il = *nvc + 1;
	xl = x;
	i__2 = m;
	for (j = 0; j <= i__2; ++j) {
	    ++(*nvc);
	    vcl[*nvc * vcl_dim1 + 1] = *costh * x + sy;
	    vcl[*nvc * vcl_dim1 + 2] = cy - *sinth * x;
	    x += *h;
/* L30: */
	}
	ir = *nvc;
	xr = x - *h;
	if (n == 0) {
	    *ncw = 0;
	    cwalk[0] = *nvc;
	    return 0;
	} else if (i == 0) {
	    lw = 0;
	    cwalk[lw] = il;
	    rw = *maxcw + 1;
	    i__2 = ir;
	    for (j = il; j <= i__2; ++j) {
		--rw;
		cwalk[rw] = j;
/* L40: */
	    }
	    goto L100;
	}

/*        Generate triangles between scan lines Y+H and Y. */

	a = max(xl,xm1l);
	b = min(xr,xm1r);
	if (xm1l == a) {
	    l0 = im1l;
	    x = (xm1l - xl) / *h;
	    j = (integer) (x + gconst_1.tol);
	    if ((d__1 = x - (doublereal) j, abs(d__1)) <= gconst_1.tol) {
		--j;
	    }
	    if (j < 0) {
		j = 0;
	    }
	    l1 = il + j;
	} else {
	    l1 = il;
	    x = (xl - xm1l) / *h;
	    j = (integer) (x + gconst_1.tol);
	    if ((d__1 = x - (doublereal) j, abs(d__1)) <= gconst_1.tol) {
		--j;
	    }
	    if (j < 0) {
		j = 0;
	    }
	    l0 = im1l + j;
	}
	if (xm1r == b) {
	    r0 = im1r;
	    x = (xr - xm1r) / *h;
	    j = (integer) (x + gconst_1.tol);
	    if ((d__1 = x - (doublereal) j, abs(d__1)) <= gconst_1.tol) {
		--j;
	    }
	    if (j < 0) {
		j = 0;
	    }
	    r1 = ir - j;
	} else {
	    r1 = ir;
	    x = (xm1r - xr) / *h;
	    j = (integer) (x + gconst_1.tol);
	    if ((d__1 = x - (doublereal) j, abs(d__1)) <= gconst_1.tol) {
		--j;
	    }
	    if (j < 0) {
		j = 0;
	    }
	    r0 = im1r - j;
	}
	if (l0 < r0 || l1 < r1) {
	    j = l0;
	    k = l1;
	    xj = xm1l + (doublereal) (j - im1l) * *h;
	    xk = xl + (doublereal) (k - il) * *h;
L50:
	    if (k < r1 && (xk <= xj || j == r0)) {
		p = k;
		++k;
		xk += *h;
	    } else {
		p = j;
		++j;
		xj += *h;
	    }
	    ++(*ntri);
	    if (*ntri > *maxti) {
		gerror_1.ierr = 9;
		return 0;
	    }
	    til[*ntri * 3 + 1] = j;
	    til[*ntri * 3 + 2] = p;
	    til[*ntri * 3 + 3] = k;
	    if (j < r0 || k < r1) {
		goto L50;
	    }
	}

/*        Generate paths of closed walk between scan lines Y+H and Y. 
*/

	if (xm1l < xl) {
	    i__2 = l0;
	    for (j = im1l + 1; j <= i__2; ++j) {
		++lw;
		cwalk[lw] = j;
/* L60: */
	    }
	    ++lw;
	    cwalk[lw] = il;
	} else {
	    i__2 = il;
	    for (j = l1; j >= i__2; --j) {
		++lw;
		cwalk[lw] = j;
/* L70: */
	    }
	}
	if (xm1r > xr) {
	    i__2 = r0;
	    for (j = im1r - 1; j >= i__2; --j) {
		--rw;
		cwalk[rw] = j;
/* L80: */
	    }
	    --rw;
	    cwalk[rw] = ir;
	} else {
	    i__2 = ir;
	    for (j = r1; j <= i__2; ++j) {
		--rw;
		cwalk[rw] = j;
/* L90: */
	    }
	}
L100:
	y -= *h;
	im1l = il;
	im1r = ir;
	xm1l = xl;
	xm1r = xr;
/* L110: */
    }

/*     Add last path of left walk and shift indices of right walk. */

    if (m == 0) {
	++rw;
    } else {
	i__1 = ir - 1;
	for (j = il + 1; j <= i__1; ++j) {
	    ++lw;
	    cwalk[lw] = j;
/* L120: */
	}
    }
    if (rw <= lw) {
	gerror_1.ierr = 10;
	return 0;
    }
    i__1 = *maxcw;
    for (j = rw; j <= i__1; ++j) {
	++lw;
	cwalk[lw] = cwalk[j];
/* L130: */
    }
    *ncw = lw;
} /* inttri_ */


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

/* Subroutine */ int lop_(itr, ind, mxedg, top, ldv, vcl, til, tedg, sptr)
integer *itr, *ind, *mxedg, *top, *ldv;
doublereal *vcl;
integer *til, *tedg, *sptr;
{
    /* System generated locals */
    integer vcl_dim1, vcl_offset;

    /* Local variables */
    static integer iedg, a, b, c, d, i, j, ind1m1, ind2m1, ind1p1, ind2p1;
    extern integer diaedg_();
    static integer in;


/*     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: Apply local optimization procedure to two triangles */
/*        indicated by ITR(1) and ITR(2). This may result in swapping */
/*        diagonal edge of quadrilateral. */

/*     Input parameters: */
/*        ITR(1),ITR(2) - indices of triangles for LOP */
/*        IND(1),IND(2) - indices indicating common edge of triangles */
/*        MXEDG - maximum index of edge to be considered for LOP */
/*        TOP - index of SPTR indicating top of stack */
/*        LDV - leading dimension of VCL in calling routine */
/*        VCL(1:2,1:*) - vertex coordinate list */
/*        TIL(1:3,1:*) - triangle incidence list */
/*        TEDG(1:3,1:*) - triangle edge indices; see routine CVDTRI */
/*        SPTR(1:*) - stack pointers; see routine CVDTRI */

/*     Updated parameters: */
/*        TOP,TIL,TEDG,SPTR - updated due diagonal edge swaps */

/*     Routines called: */
/*        DIAEDG */


/*     Common edge is BC, other two vertices are A and D. */

    /* Parameter adjustments */
    --sptr;
    tedg -= 4;
    til -= 4;
    vcl_dim1 = *ldv;
    vcl_offset = vcl_dim1 + 1;
    vcl -= vcl_offset;
    --ind;
    --itr;

    /* Function Body */
    iedg = tedg[ind[1] + itr[1] * 3];
    sptr[iedg] = -1;
    ind1m1 = ind[1] - 1;
    if (ind1m1 <= 0) {
	ind1m1 = 3;
    }
    ind1p1 = ind[1] + 1;
    if (ind1p1 >= 4) {
	ind1p1 = 1;
    }
    ind2m1 = ind[2] - 1;
    if (ind2m1 <= 0) {
	ind2m1 = 3;
    }
    ind2p1 = ind[2] + 1;
    if (ind2p1 >= 4) {
	ind2p1 = 1;
    }
    b = til[ind[1] + itr[1] * 3];
    c = til[ind1p1 + itr[1] * 3];
    a = til[ind1m1 + itr[1] * 3];
    d = til[ind2m1 + itr[2] * 3];
    in = diaedg_(&vcl[d * vcl_dim1 + 1], &vcl[d * vcl_dim1 + 2], &vcl[c * 
	    vcl_dim1 + 1], &vcl[c * vcl_dim1 + 2], &vcl[a * vcl_dim1 + 1], &
	    vcl[a * vcl_dim1 + 2], &vcl[b * vcl_dim1 + 1], &vcl[b * vcl_dim1 
	    + 2]);
    if (in == 1) {

/*        Check if four edges of quadrilateral should be put on LOP */

/*        stack, and swap edge BC for AD. */

	i = tedg[ind1m1 + itr[1] * 3];
	for (j = 1; j <= 4; ++j) {
	    if (j == 2) {
		i = tedg[ind1p1 + itr[1] * 3];
	    } else if (j == 3) {
		i = tedg[ind2m1 + itr[2] * 3];
	    } else if (j == 4) {
		i = tedg[ind2p1 + itr[2] * 3];
	    }
	    if (i <= *mxedg) {
		if (sptr[i] == -1) {
		    sptr[i] = *top;
		    *top = i;
		}
	    }
/* L10: */
	}
	til[ind1p1 + itr[1] * 3] = d;
	til[ind2p1 + itr[2] * 3] = a;
	tedg[ind[1] + itr[1] * 3] = tedg[ind2p1 + itr[2] * 3];
	tedg[ind[2] + itr[2] * 3] = tedg[ind1p1 + itr[1] * 3];
	tedg[ind1p1 + itr[1] * 3] = iedg;
	tedg[ind2p1 + itr[2] * 3] = iedg;
    }
} /* lop_ */


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

/* Subroutine */ int mtredg_(utype, i1, i2, i3, ibndry, nt, til, tedg)
logical *utype;
integer *i1, *i2, *i3, *ibndry, *nt, *til, *tedg;
{

/*     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: Set fields for triangle as needed by routine TMERGE. */

/*     Input parameters: */
/* 	 UTYPE - .TRUE. iff triangle contains two 'U' vertices */
/* 	 I1, I2, I3 - indices of 3 triangle vertices in VCL; the first */
/*              2 indices also belong to the next merge edge */
/*        IBNDRY - index of boundary edge for TEDG */
/*        NT - number of entries in TIL, TEDG so far */
/*        TIL(1:NT) - triangle incidence list */
/*        TEDG(1:NT) - triangle edge indices; see routine TMERGE */

/*     Updated parameters: */
/*        NT,TIL,TEDG - one more triangle is added at end of arrays */

    /* Parameter adjustments */
    tedg -= 4;
    til -= 4;

    /* Function Body */
    ++(*nt);
    til[*nt * 3 + 1] = *i1;
    til[*nt * 3 + 2] = *i2;
    til[*nt * 3 + 3] = *i3;
    tedg[*nt * 3 + 1] = *nt;
    if (*utype) {
	tedg[*nt * 3 + 2] = *nt - 1;
	tedg[*nt * 3 + 3] = *ibndry;
    } else {
	tedg[*nt * 3 + 2] = *ibndry;
	tedg[*nt * 3 + 3] = *nt - 1;
    }
} /* mtredg_ */


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

/* Subroutine */ int rotpg_(nvrt, xc, yc, i1, i2, ibot, costh, sinth)
integer *nvrt;
doublereal *xc, *yc;
integer *i1, *i2, *ibot;
doublereal *costh, *sinth;
{
    /* System generated locals */
    integer i__1, i__2;

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

    /* Local variables */
    static integer itop, a, b, i, j, k, l, m, r;
    static doublereal theta, x0, y0;


/*     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: Rotate convex polygon so that a line segment joining two 
*/
/*        of its vertices is parallel to y-axis. */

/*     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)) */
/*        I1,I2 - index of vertices of line segment; I1, I2 > 0 */

/*     Output parameters: */
/*        XC(0:NVRT),YC(0:NVRT) - rotated vertex coordinates; indices are 
*/
/*              also rotated so that (XC(0),YC(0)) = (XC(NVRT),YC(NVRT)) 
*/
/*              is top vertex and (XC(IBOT),YC(IBOT)) is bottom vertex */
/*        IBOT - index of bottom vertex */
/*        COSTH,SINTH - COS(THETA) and SIN(THETA) where THETA in */
/*              [-PI,PI] is rotation angle */



    itop = *i1;
    *ibot = *i2;
    if (yc[*i1] == yc[*i2]) {
	if (xc[*i1] < xc[*i2]) {
	    theta = -gconst_1.pi / 2.;
	} else {
	    theta = gconst_1.pi / 2.;
	}
    } else {
	if (yc[*i1] < yc[*i2]) {
	    itop = *i2;
	    *ibot = *i1;
	}
	theta = gconst_1.pi / 2. - atan2(yc[itop] - yc[*ibot], xc[itop] - xc[*
		ibot]);
    }
    *costh = cos(theta);
    *sinth = sin(theta);
    i__1 = *nvrt;
    for (i = 1; i <= i__1; ++i) {
	x0 = xc[i];
	xc[i] = *costh * x0 - *sinth * yc[i];
	yc[i] = *sinth * x0 + *costh * yc[i];
/* L10: */
    }

/*     Rotate indices. */

    if (itop == *nvrt) {
	goto L50;
    }
    a = *nvrt;
    b = itop;
L20:
    r = a % b;
    a = b;
    b = r;
    if (r > 0) {
	goto L20;
    }
    m = *nvrt / a - 1;
    i__1 = a;
    for (i = 1; i <= i__1; ++i) {
	x0 = xc[i];
	y0 = yc[i];
	k = i;
	i__2 = m;
	for (j = 1; j <= i__2; ++j) {
	    l = k + itop;
	    if (l > *nvrt) {
		l -= *nvrt;
	    }
	    xc[k] = xc[l];
	    yc[k] = yc[l];
	    k = l;
/* L30: */
	}
	xc[k] = x0;
	yc[k] = y0;
/* L40: */
    }
    *ibot -= itop;
    if (*ibot < 0) {
	*ibot += *nvrt;
    }
L50:
    xc[0] = xc[*nvrt];
    yc[0] = yc[*nvrt];
} /* rotpg_ */


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

/* Subroutine */ int tmerge_(inter, nbl, ncr, chbl, chcr, ldv, vcl, til, tedg)

logical *inter;
integer *nbl, *ncr, *chbl, *chcr, *ldv;
doublereal *vcl;
integer *til, *tedg;
{
    /* System generated locals */
    integer vcl_dim1, vcl_offset;

    /* Local variables */
    static integer lrip1, i, j;
    extern integer diaedg_();
    static integer in, nl, nr;
    static doublereal xi;
    static integer nt;
    static doublereal xj, yi, yj;
    extern /* Subroutine */ int mtredg_();
    extern integer lrline_();
    static integer ibndry, lri;
    static doublereal xip1, xjp1, yip1, yjp1;


/*     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: Form triangles in strip near boundary of polygon or */
/*        inside polygon by merging two chains of vertices. */

/*     Input parameters: */
/* 	 INTER - .TRUE. iff at least one interior mesh vertex */
/* 	 NBL - number of vertices on boundary cycle if INTER, */
/*              otherwise on left boundary chain */
/* 	 NCR - number of vertices on closed walk if INTER, */
/*              otherwise on right boundary chain */
/* 	 CHBL(0:NBL) - indices in VCL of vertices on boundary cycle */
/*              or left boundary chain; if INTER, CHBL(NBL) = CHBL(0) */
/* 	 CHCR(0:NCR) - indices in VCL of vertices on closed walk */
/*              or right boundary chain; if INTER, CHCR(NCR) = CHCR(0), */

/*              otherwise CHCR(0) is not referenced */
/*        LDV - leading dimension of VCL in calling routine */
/*        VCL(1:2,1:*) - vertex coordinate list */

/*     Output parameters: */
/*        TIL(1:3,1:NT) - triangle incidence list, where NT = */
/*              NBL + NCR - K where K = 0 if INTER, else K = 2 */
/*        TEDG(1:3,1:NT) - TEDG(J,I) refers to edge with vertices */
/*              TIL(J:J+1,I) and contains index of merge edge or */
/*              NBL+NCR+1 for edge of chains */
/*        [Note: It is assumed there is enough space in 2 arrays.] */

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

/*     Routines called: */
/*        DIAEDG, LRLINE, MTREDG */



    /* Parameter adjustments */
    tedg -= 4;
    til -= 4;
    vcl_dim1 = *ldv;
    vcl_offset = vcl_dim1 + 1;
    vcl -= vcl_offset;

    /* Function Body */
    ibndry = *nbl + *ncr + 1;
    nt = 0;
    if (*inter) {
	nl = *nbl;
	nr = *ncr;
	i = 0;
	j = 0;
    } else {
	mtredg_(&c__1, &chbl[1], &chcr[1], chbl, &ibndry, &nt, &til[4], &tedg[
		4]);
	tedg[5] = ibndry;
	if (*nbl + *ncr <= 3) {
	    return 0;
	}
	nl = *nbl - 1;
	nr = *ncr - 1;
	i = 1;
	j = 1;
	lri = 1;
	lrip1 = 1;
    }

/*     Main while loop for determining next triangle and edge. */

L10:
    if (i >= nl || j >= nr) {
	goto L20;
    }
    xi = vcl[chbl[i] * vcl_dim1 + 1];
    yi = vcl[chbl[i] * vcl_dim1 + 2];
    xip1 = vcl[chbl[i + 1] * vcl_dim1 + 1];
    yip1 = vcl[chbl[i + 1] * vcl_dim1 + 2];
    xj = vcl[chcr[j] * vcl_dim1 + 1];
    yj = vcl[chcr[j] * vcl_dim1 + 2];
    xjp1 = vcl[chcr[j + 1] * vcl_dim1 + 1];
    yjp1 = vcl[chcr[j + 1] * vcl_dim1 + 2];
    in = diaedg_(&xjp1, &yjp1, &xj, &yj, &xi, &yi, &xip1, &yip1);
    if (*inter) {
	lri = lrline_(&xi, &yi, &xj, &yj, &xjp1, &yjp1, &c_b41);
	lrip1 = lrline_(&xip1, &yip1, &xj, &yj, &xjp1, &yjp1, &c_b41);
    }
    if (in <= 0 || lri <= 0 && lrip1 <= 0) {
	mtredg_(&c__1, &chbl[i + 1], &chcr[j], &chbl[i], &ibndry, &nt, &til[4]
		, &tedg[4]);
	++i;
    } else {
	mtredg_(&c__0, &chbl[i], &chcr[j + 1], &chcr[j], &ibndry, &nt, &til[4]
		, &tedg[4]);
	++j;
    }
    goto L10;

/*     Add remaining triangles at end of strip or bottom of polygon. */

L20:
    if (i < nl) {
	if (! (*inter) && j == nr) {
	    ++nl;
	}
L30:
	mtredg_(&c__1, &chbl[i + 1], &chcr[j], &chbl[i], &ibndry, &nt, &til[4]
		, &tedg[4]);
	++i;
	if (i < nl) {
	    goto L30;
	}
    } else {
/*        J < NR .OR. I = NL = J = NR = 1 */
	if (! (*inter) && i == nl) {
	    ++nr;
	}
L40:
	mtredg_(&c__0, &chbl[i], &chcr[j + 1], &chcr[j], &ibndry, &nt, &til[4]
		, &tedg[4]);
	if (*inter) {
	    lri = lrline_(&vcl[chbl[i] * vcl_dim1 + 1], &vcl[chbl[i] * 
		    vcl_dim1 + 2], &vcl[chcr[j + 1] * vcl_dim1 + 1], &vcl[
		    chcr[j + 1] * vcl_dim1 + 2], &vcl[chcr[j] * vcl_dim1 + 1],
		     &vcl[chcr[j] * vcl_dim1 + 2], &c_b41);
	    if (lri >= 0) {
		gerror_1.ierr = 230;
		return 0;
	    }
	}
	++j;
	if (j < nr) {
	    goto L40;
	}
    }

    if (*inter) {
	if (tedg[5] == 0) {
	    tedg[5] = *nbl + *ncr;
	} else {
	    tedg[6] = *nbl + *ncr;
	}
    }
} /* tmerge_ */


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

/* Subroutine */ int tripr2_(nvc, npolg, nvert, maxvc, maxti, maxiw, maxwk, h,
	 vcl, hvl, pvl, iang, ntri, til, vstart, vnum, tstart, iwk, wk)
integer *nvc, *npolg, *nvert, *maxvc, *maxti, *maxiw, *maxwk;
doublereal *h, *vcl;
integer *hvl, *pvl;
doublereal *iang;
integer *ntri, *til, *vstart, *vnum, *tstart, *iwk;
doublereal *wk;
{
    /* System generated locals */
    integer i__1, i__2, i__3;

    /* Local variables */
    static integer nvrt, i, j, k, xc, yc, bndcyc;
    extern /* Subroutine */ int bedgmv_();
    static doublereal pimtol;
    extern /* Subroutine */ int trpolg_();
    static integer nbc;


/*     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: Generate mesh vertices and triangles inside each convex */

/*        polygon of decomposition according to mesh spacings in H array 
*/
/*        to get a triangulation of a polygonal region. */

/*     Input parameters: */
/*        NVC - number of vertex coordinates or positions used in VCL */
/*              array */
/*        NPOLG - number of polygonal subregions or positions used in */
/*              HVL array */
/*        NVERT - number of polygon vertices or positions used in PVL */
/*              array */
/*        MAXVC - maximum size available for VCL array, should be >= */
/*              number of mesh vertices in triangulation of region */
/*        MAXTI - maximum size available for TIL array, should be >= */
/*              number of triangles in triangulation of region */
/*        MAXIW - maximum size available for IWK array, should be >= */
/*              5*(NBC+NCW)+2 where NBC is maximum number of mesh edges */

/*              on boundary of a polygon, NCW is maximum number of edges 
*/
/*              on boundary of interior triangulation */
/*        MAXWK - maximum size available for WK array, should be >= */
/*              5*NVRT+4 where NVRT is max no. of vertices in a polygon */

/* 	 H(1:NPOLG) - mesh spacings for polygons of decomposition */
/*        HVL(1:NPOLG) - head vertex list */
/*        PVL(1:4,1:NVERT),IANG(1:NVERT) - polygon vertex list and */
/*              interior angles; see routine DSPGDC for more details */

/*     Updated parameters: */
/*        NVC,VCL - updated due to generation of mesh vertices */

/*     Output parameters: */
/*        NTRI - number of triangles in triangulation of region */
/*        TIL(1:3,1:NTRI) - triangle incidence list; TIL(1:3,I) contains 
*/
/*              indices in VCL of 3 vertices of Ith triangle in CCW order 
*/
/*        VSTART(1:NVERT) - start location in VCL for mesh vertices on */
/*              each edge in PVL if there are any, else 0 */
/*        VNUM(1:NVERT) - number of mesh vertices on interior of each */
/*              edge in PVL; entry is negated if mesh vertices are */
/*              listed in backward order in VCL */
/*        TSTART(1:NPOLG) - start location in TIL of triangles in */
/*              each polygon; TIL(1:3,I) for I=TSTRT(K),...,TSTRT(K+1)-1 
*/
/*              are the triangles in Kth polygon */

/*     Working parameters: */
/*        IWK(1:MAXIW) - integer work array */
/*        WK(1:MAXWK) - double precision work array */

/*     Abnormal return: */
/*        IERR is set to 3, 6, 7, 9, 10, 200, 202, 230, or 231 */

/*     Routines called: */
/*        BEDGMV, TRPOLG */




    /* Parameter adjustments */
    --wk;
    --iwk;
    --tstart;
    --vnum;
    --vstart;
    til -= 4;
    --iang;
    pvl -= 5;
    --hvl;
    vcl -= 3;
    --h;

    /* Function Body */
    *ntri = 0;
    pimtol = gconst_1.pi - gconst_1.tol;
    bedgmv_(nvc, npolg, nvert, maxvc, &h[1], &vcl[3], &hvl[1], &pvl[5], &
	    vstart[1], &vnum[1]);
    if (gerror_1.ierr != 0) {
	return 0;
    }
    i__1 = *npolg;
    for (k = 1; k <= i__1; ++k) {
	nvrt = 0;
	nbc = 0;
	i = hvl[k];
L10:
	if (iang[i] < pimtol) {
	    ++nvrt;
	}
	nbc = nbc + 1 + (i__2 = vnum[i], abs(i__2));
	i = pvl[(i << 2) + 3];
	if (i != hvl[k]) {
	    goto L10;
	}
	if (nbc + 1 > *maxiw) {
	    gerror_1.ierr = 6;
	    return 0;
	} else if ((nvrt << 1) + 2 > *maxwk) {
	    gerror_1.ierr = 7;
	    return 0;
	}
	xc = 1;
	yc = xc + nvrt + 1;
	bndcyc = 1;
L20:
	j = pvl[(i << 2) + 1];
	if (iang[i] < pimtol) {
	    wk[xc] = vcl[(j << 1) + 1];
	    wk[yc] = vcl[(j << 1) + 2];
	    ++xc;
	    ++yc;
	}
	iwk[bndcyc] = j;
	++bndcyc;
	if (vnum[i] >= 0) {
	    i__2 = vstart[i] + vnum[i] - 1;
	    for (j = vstart[i]; j <= i__2; ++j) {
		iwk[bndcyc] = j;
		++bndcyc;
/* L30: */
	    }
	} else {
	    i__2 = vstart[i];
	    for (j = vstart[i] - vnum[i] - 1; j >= i__2; --j) {
		iwk[bndcyc] = j;
		++bndcyc;
/* L40: */
	    }
	}
	i = pvl[(i << 2) + 3];
	if (i != hvl[k]) {
	    goto L20;
	}
	wk[xc] = wk[1];
	wk[yc] = wk[nvrt + 2];
	iwk[bndcyc] = iwk[1];
	xc = 1;
	yc = xc + nvrt + 1;
	bndcyc = 1;
	tstart[k] = *ntri + 1;
	i__2 = *maxiw - nbc - 1;
	i__3 = *maxwk - (nvrt << 1) - 2;
	trpolg_(&nvrt, &wk[xc], &wk[yc], &h[k], &nbc, &iwk[bndcyc], &c__2, 
		nvc, ntri, maxvc, maxti, &i__2, &i__3, &vcl[3], &til[4], &iwk[
		nbc + 2], &wk[(nvrt << 1) + 3]);
	if (gerror_1.ierr != 0) {
	    return 0;
	}
/* L50: */
    }
} /* tripr2_ */


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

/* Subroutine */ int trpolg_(nvrt, xc, yc, h, nbc, bndcyc, ldv, nvc, ntri, 
	maxvc, maxti, maxiw, maxwk, vcl, til, iwk, wk)
integer *nvrt;
doublereal *xc, *yc, *h;
integer *nbc, *bndcyc, *ldv, *nvc, *ntri, *maxvc, *maxti, *maxiw, *maxwk;
doublereal *vcl;
integer *til, *iwk;
doublereal *wk;
{
    /* System generated locals */
    integer vcl_dim1, vcl_offset, i__1;
    doublereal d__1, d__2;

    /* Builtin functions */
    double sqrt();

    /* Local variables */
    static integer tedg, ibot;
    static doublereal dist;
    static integer nshr, sptr;
    extern /* Subroutine */ int diam2_();
    static integer i, iedge, cwalk, maxcw;
    static doublereal costh;
    static logical inter;
    static integer sdist;
    static doublereal sinth;
    static integer i1, i2;
    extern /* Subroutine */ int rotpg_();
    static doublereal x0, y0;
    extern /* Subroutine */ int shrnk2_();
    static doublereal hs, xi;
    static integer nt;
    static doublereal yi;
    static integer xs, ys;
    static doublereal yr;
    extern /* Subroutine */ int tmerge_(), cvdtri_(), rotiar_();
    static doublereal smdist;
    extern /* Subroutine */ int inttri_();
    static integer mbc, ind, ncw;


/*     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: Generate Delaunay triangular mesh inside convex polygon */

/*        using quasi-uniform grid of spacing H. */

/*     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)); it is assumed */
/*              that all interior angles are < PI */
/*        H - spacing of mesh vertices in polygon */
/*        NBC - size of BNDCYC */
/*        BNDCYC(0:NBC) - indices in VCL of mesh vertices of boundary */
/*              cycle; BNDCYC(0) = BNDCYC(NBC); contains (XC(I),YC(I)) */
/*        LDV - leading dimension of VCL in calling routine */
/*        NVC - number of coordinates or positions used in VCL array */
/*        NTRI - number of triangles or positions used in TIL */
/*        MAXVC - maximum size available for VCL array */
/*        MAXTI - maximum size available for TIL array */
/*        MAXIW - maximum size available for IWK array, should be >= */
/*              6*(1 + INT(DIAM/H)) + 4*(NBC + NCW) where DIAM is */
/*              diameter of polygon, NCW is number of edges on boundary */

/*              of interior triangulation */
/*        MAXWK - maximum size available for WK array, should be >= */
/*              3*NVRT+2 */
/*        VCL(1:2,1:NVC) - vertex coordinate list */
/*        TIL(1:3,1:NTRI) - triangle incidence list */

/*     Updated parameters: */
/*        BNDCYC(0:NBC) - elements of array may be rotated */
/*        NVC,NTRI,VCL,TIL */

/*     Working parameters: */
/*        IWK(1:MAXIW) - integer work array */
/*        WK(1:MAXWK) - double precision work array */

/*     Abnormal return: */
/*        IERR is set to 3, 6, 7, 9, 10, 200, 202, 230, or 231 */

/*     Routines called: */
/*        CVDTRI, DIAM2, INTTRI, ROTIAR, ROTPG, SHRNK2, TMERGE */



    /* Parameter adjustments */
    --wk;
    --iwk;
    til -= 4;
    vcl_dim1 = *ldv;
    vcl_offset = vcl_dim1 + 1;
    vcl -= vcl_offset;

    /* Function Body */
    if (*nvrt + 1 > *maxiw) {
	gerror_1.ierr = 6;
	return 0;
    } else if (*nvrt * 3 + 2 > *maxwk) {
	gerror_1.ierr = 7;
	return 0;
    }
    xs = 1;
    ys = xs + *nvrt + 1;
    sdist = ys + *nvrt + 1;
    iedge = 1;
    hs = *h / sqrt(2.);
    i__1 = *nvrt - 1;
    for (i = 0; i <= i__1; ++i) {
	wk[sdist + i] = hs;
/* L10: */
    }
    shrnk2_(nvrt, xc, yc, &wk[sdist], &nshr, &wk[xs], &wk[ys], &iwk[iedge]);
    if (gerror_1.ierr != 0) {
	return 0;
    }
    inter = nshr > 0;

    if (inter) {
	diam2_(&nshr, &wk[xs + 1], &wk[ys + 1], &i1, &i2, &dist);
	if (gerror_1.ierr != 0) {
	    return 0;
	}
	rotpg_(&nshr, &wk[xs], &wk[ys], &i1, &i2, &ibot, &costh, &sinth);
	maxcw = ((integer) ((wk[ys] - wk[ys + ibot]) / *h) + 1) * 6;
	if (maxcw + 1 > *maxiw) {
	    gerror_1.ierr = 6;
	    return 0;
	}
	cwalk = 1;
	inttri_(&nshr, &wk[xs], &wk[ys], h, &ibot, &costh, &sinth, ldv, nvc, 
		ntri, maxvc, maxti, &maxcw, &vcl[vcl_offset], &til[4], &ncw, &
		iwk[cwalk]);
	if (gerror_1.ierr != 0) {
	    return 0;
	}

/*        Determine the mesh vertex which should be moved to front of 
*/
/*        BNDCYC - closest to CWALK(0) and also with y-coordinate > */

/*        that of CWALK(0) when rotated if NCW > 0. */

	x0 = vcl[iwk[cwalk] * vcl_dim1 + 1];
	y0 = vcl[iwk[cwalk] * vcl_dim1 + 2];
	if (ncw > 0) {
	    yr = sinth * x0 + costh * y0;
	}
/* Computing 2nd power */
	d__1 = *h;
	smdist = d__1 * d__1 * 1e5;
	i__1 = *nbc - 1;
	for (i = 0; i <= i__1; ++i) {
	    xi = vcl[bndcyc[i] * vcl_dim1 + 1];
	    yi = vcl[bndcyc[i] * vcl_dim1 + 2];
	    if (ncw > 0) {
		if (sinth * xi + costh * yi <= yr) {
		    goto L20;
		}
	    }
/* Computing 2nd power */
	    d__1 = xi - x0;
/* Computing 2nd power */
	    d__2 = yi - y0;
	    dist = d__1 * d__1 + d__2 * d__2;
	    if (dist < smdist) {
		smdist = dist;
		ind = i;
	    }
L20:
	    ;
	}
	rotiar_(nbc, bndcyc, &ind);
	bndcyc[*nbc] = bndcyc[0];
	nt = *nbc + ncw;
	tedg = cwalk + ncw + 1;
    } else {
	diam2_(nvrt, &xc[1], &yc[1], &i1, &i2, &dist);
	if (gerror_1.ierr != 0) {
	    return 0;
	}
	ind = 0;
L30:
	if (ind >= *nbc) {
	    goto L40;
	}
	if (xc[i1] == vcl[bndcyc[ind] * vcl_dim1 + 1] && yc[i1] == vcl[bndcyc[
		ind] * vcl_dim1 + 2]) {
	    goto L40;
	}
	++ind;
	goto L30;
L40:
	rotiar_(nbc, bndcyc, &ind);
	bndcyc[*nbc] = bndcyc[0];
	mbc = 1;
L50:
	if (mbc >= *nbc) {
	    goto L60;
	}
	if (xc[i2] == vcl[bndcyc[mbc] * vcl_dim1 + 1] && yc[i2] == vcl[bndcyc[
		mbc] * vcl_dim1 + 2]) {
	    goto L60;
	}
	++mbc;
	goto L50;
L60:
	ind = *nbc;
	i__1 = mbc + (*nbc - mbc - 1) / 2;
	for (i = mbc + 1; i <= i__1; ++i) {
	    --ind;
	    i1 = bndcyc[i];
	    bndcyc[i] = bndcyc[ind];
	    bndcyc[ind] = i1;
/* L70: */
	}
	bndcyc[*nbc] = bndcyc[mbc];
	nt = *nbc - 2;
	tedg = 1;
/*        Left boundary chain contains mesh vertices BNDCYC(0:MBC) */
/*        and right chain contains BNDCYC(0,MBC+1:NBC); MBC < NBC. */
    }

    if (*ntri + nt > *maxti) {
	gerror_1.ierr = 9;
	return 0;
    } else if (tedg + (nt << 2) - 1 > *maxiw) {
	gerror_1.ierr = 6;
	return 0;
    }
    if (inter) {
	tmerge_(&inter, nbc, &ncw, bndcyc, &iwk[cwalk], ldv, &vcl[vcl_offset],
		 &til[(*ntri + 1) * 3 + 1], &iwk[tedg]);
    } else {
	i__1 = *nbc - mbc;
	tmerge_(&inter, &mbc, &i__1, bndcyc, &bndcyc[mbc], ldv, &vcl[
		vcl_offset], &til[(*ntri + 1) * 3 + 1], &iwk[tedg]);
    }
    if (gerror_1.ierr != 0) {
	return 0;
    }
    sptr = tedg + nt * 3;
    cvdtri_(&inter, ldv, &nt, &vcl[vcl_offset], &til[(*ntri + 1) * 3 + 1], &
	    iwk[tedg], &iwk[sptr]);
    *ntri += nt;
} /* trpolg_ */

