triangle.c
上传用户:yflamps
上传日期:2010-04-01
资源大小:155k
文件大小:636k
源码类别:

3D图形编程

开发平台:

C/C++

  1. REAL bheight;
  2. REAL cheight;
  3. REAL dheight;
  4. #endif /* not ANSI_DECLARATORS */
  5. {
  6.   REAL adx, bdx, cdx, ady, bdy, cdy, adheight, bdheight, cdheight;
  7.   REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
  8.   REAL det;
  9.   REAL permanent, errbound;
  10.   m->orient3dcount++;
  11.   adx = pa[0] - pd[0];
  12.   bdx = pb[0] - pd[0];
  13.   cdx = pc[0] - pd[0];
  14.   ady = pa[1] - pd[1];
  15.   bdy = pb[1] - pd[1];
  16.   cdy = pc[1] - pd[1];
  17.   adheight = aheight - dheight;
  18.   bdheight = bheight - dheight;
  19.   cdheight = cheight - dheight;
  20.   bdxcdy = bdx * cdy;
  21.   cdxbdy = cdx * bdy;
  22.   cdxady = cdx * ady;
  23.   adxcdy = adx * cdy;
  24.   adxbdy = adx * bdy;
  25.   bdxady = bdx * ady;
  26.   det = adheight * (bdxcdy - cdxbdy) 
  27.       + bdheight * (cdxady - adxcdy)
  28.       + cdheight * (adxbdy - bdxady);
  29.   if (b->noexact) {
  30.     return det;
  31.   }
  32.   permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * Absolute(adheight)
  33.             + (Absolute(cdxady) + Absolute(adxcdy)) * Absolute(bdheight)
  34.             + (Absolute(adxbdy) + Absolute(bdxady)) * Absolute(cdheight);
  35.   errbound = o3derrboundA * permanent;
  36.   if ((det > errbound) || (-det > errbound)) {
  37.     return det;
  38.   }
  39.   return orient3dadapt(pa, pb, pc, pd, aheight, bheight, cheight, dheight,
  40.                        permanent);
  41. }
  42. /*****************************************************************************/
  43. /*                                                                           */
  44. /*  nonregular()   Return a positive value if the point pd is incompatible   */
  45. /*                 with the circle or plane passing through pa, pb, and pc   */
  46. /*                 (meaning that pd is inside the circle or below the        */
  47. /*                 plane); a negative value if it is compatible; and zero if */
  48. /*                 the four points are cocircular/coplanar.  The points pa,  */
  49. /*                 pb, and pc must be in counterclockwise order, or the sign */
  50. /*                 of the result will be reversed.                           */
  51. /*                                                                           */
  52. /*  If the -w switch is used, the points are lifted onto the parabolic       */
  53. /*  lifting map, then they are dropped according to their weights, then the  */
  54. /*  3D orientation test is applied.  If the -W switch is used, the points'   */
  55. /*  heights are already provided, so the 3D orientation test is applied      */
  56. /*  directly.  If neither switch is used, the incircle test is applied.      */
  57. /*                                                                           */
  58. /*****************************************************************************/
  59. #ifdef ANSI_DECLARATORS
  60. REAL nonregular(struct mesh *m, struct behavior *b,
  61.                 vertex pa, vertex pb, vertex pc, vertex pd)
  62. #else /* not ANSI_DECLARATORS */
  63. REAL nonregular(m, b, pa, pb, pc, pd)
  64. struct mesh *m;
  65. struct behavior *b;
  66. vertex pa;
  67. vertex pb;
  68. vertex pc;
  69. vertex pd;
  70. #endif /* not ANSI_DECLARATORS */
  71. {
  72.   if (b->weighted == 0) {
  73.     return incircle(m, b, pa, pb, pc, pd);
  74.   } else if (b->weighted == 1) {
  75.     return orient3d(m, b, pa, pb, pc, pd,
  76.                     pa[0] * pa[0] + pa[1] * pa[1] - pa[2],
  77.                     pb[0] * pb[0] + pb[1] * pb[1] - pb[2],
  78.                     pc[0] * pc[0] + pc[1] * pc[1] - pc[2],
  79.                     pd[0] * pd[0] + pd[1] * pd[1] - pd[2]);
  80.   } else {
  81.     return orient3d(m, b, pa, pb, pc, pd, pa[2], pb[2], pc[2], pd[2]);
  82.   }
  83. }
  84. /*****************************************************************************/
  85. /*                                                                           */
  86. /*  findcircumcenter()   Find the circumcenter of a triangle.                */
  87. /*                                                                           */
  88. /*  The result is returned both in terms of x-y coordinates and xi-eta       */
  89. /*  (barycentric) coordinates.  The xi-eta coordinate system is defined in   */
  90. /*  terms of the triangle:  the origin of the triangle is the origin of the  */
  91. /*  coordinate system; the destination of the triangle is one unit along the */
  92. /*  xi axis; and the apex of the triangle is one unit along the eta axis.    */
  93. /*  This procedure also returns the square of the length of the triangle's   */
  94. /*  shortest edge.                                                           */
  95. /*                                                                           */
  96. /*****************************************************************************/
  97. #ifdef ANSI_DECLARATORS
  98. void findcircumcenter(struct mesh *m, struct behavior *b,
  99.                       vertex torg, vertex tdest, vertex tapex,
  100.                       vertex circumcenter, REAL *xi, REAL *eta, int offcenter)
  101. #else /* not ANSI_DECLARATORS */
  102. void findcircumcenter(m, b, torg, tdest, tapex, circumcenter, xi, eta,
  103.                       offcenter)
  104. struct mesh *m;
  105. struct behavior *b;
  106. vertex torg;
  107. vertex tdest;
  108. vertex tapex;
  109. vertex circumcenter;
  110. REAL *xi;
  111. REAL *eta;
  112. int offcenter;
  113. #endif /* not ANSI_DECLARATORS */
  114. {
  115.   REAL xdo, ydo, xao, yao;
  116.   REAL dodist, aodist, dadist;
  117.   REAL denominator;
  118.   REAL dx, dy, dxoff, dyoff;
  119.   m->circumcentercount++;
  120.   /* Compute the circumcenter of the triangle. */
  121.   xdo = tdest[0] - torg[0];
  122.   ydo = tdest[1] - torg[1];
  123.   xao = tapex[0] - torg[0];
  124.   yao = tapex[1] - torg[1];
  125.   dodist = xdo * xdo + ydo * ydo;
  126.   aodist = xao * xao + yao * yao;
  127.   dadist = (tdest[0] - tapex[0]) * (tdest[0] - tapex[0]) +
  128.            (tdest[1] - tapex[1]) * (tdest[1] - tapex[1]);
  129.   if (b->noexact) {
  130.     denominator = 0.5 / (xdo * yao - xao * ydo);
  131.   } else {
  132.     /* Use the counterclockwise() routine to ensure a positive (and */
  133.     /*   reasonably accurate) result, avoiding any possibility of   */
  134.     /*   division by zero.                                          */
  135.     denominator = 0.5 / counterclockwise(m, b, tdest, tapex, torg);
  136.     /* Don't count the above as an orientation test. */
  137.     m->counterclockcount--;
  138.   }
  139.   dx = (yao * dodist - ydo * aodist) * denominator;
  140.   dy = (xdo * aodist - xao * dodist) * denominator;
  141.   /* Find the (squared) length of the triangle's shortest edge.  This   */
  142.   /*   serves as a conservative estimate of the insertion radius of the */
  143.   /*   circumcenter's parent.  The estimate is used to ensure that      */
  144.   /*   the algorithm terminates even if very small angles appear in     */
  145.   /*   the input PSLG.                                                  */
  146.   if ((dodist < aodist) && (dodist < dadist)) {
  147.     if (offcenter && (b->offconstant > 0.0)) {
  148.       /* Find the position of the off-center, as described by Alper Ungor. */
  149.       dxoff = 0.5 * xdo - b->offconstant * ydo;
  150.       dyoff = 0.5 * ydo + b->offconstant * xdo;
  151.       /* If the off-center is closer to the origin than the */
  152.       /*   circumcenter, use the off-center instead.        */
  153.       if (dxoff * dxoff + dyoff * dyoff < dx * dx + dy * dy) {
  154.         dx = dxoff;
  155.         dy = dyoff;
  156.       }
  157.     }
  158.   } else if (aodist < dadist) {
  159.     if (offcenter && (b->offconstant > 0.0)) {
  160.       dxoff = 0.5 * xao + b->offconstant * yao;
  161.       dyoff = 0.5 * yao - b->offconstant * xao;
  162.       /* If the off-center is closer to the origin than the */
  163.       /*   circumcenter, use the off-center instead.        */
  164.       if (dxoff * dxoff + dyoff * dyoff < dx * dx + dy * dy) {
  165.         dx = dxoff;
  166.         dy = dyoff;
  167.       }
  168.     }
  169.   } else {
  170.     if (offcenter && (b->offconstant > 0.0)) {
  171.       dxoff = 0.5 * (tapex[0] - tdest[0]) -
  172.               b->offconstant * (tapex[1] - tdest[1]);
  173.       dyoff = 0.5 * (tapex[1] - tdest[1]) +
  174.               b->offconstant * (tapex[0] - tdest[0]);
  175.       /* If the off-center is closer to the destination than the */
  176.       /*   circumcenter, use the off-center instead.             */
  177.       if (dxoff * dxoff + dyoff * dyoff <
  178.           (dx - xdo) * (dx - xdo) + (dy - ydo) * (dy - ydo)) {
  179.         dx = xdo + dxoff;
  180.         dy = ydo + dyoff;
  181.       }
  182.     }
  183.   }
  184.   circumcenter[0] = torg[0] + dx;
  185.   circumcenter[1] = torg[1] + dy;
  186.   /* To interpolate vertex attributes for the new vertex inserted at */
  187.   /*   the circumcenter, define a coordinate system with a xi-axis,  */
  188.   /*   directed from the triangle's origin to its destination, and   */
  189.   /*   an eta-axis, directed from its origin to its apex.            */
  190.   /*   Calculate the xi and eta coordinates of the circumcenter.     */
  191.   *xi = (yao * dx - xao * dy) * (2.0 * denominator);
  192.   *eta = (xdo * dy - ydo * dx) * (2.0 * denominator);
  193. }
  194. /**                                                                         **/
  195. /**                                                                         **/
  196. /********* Geometric primitives end here                             *********/
  197. /*****************************************************************************/
  198. /*                                                                           */
  199. /*  triangleinit()   Initialize some variables.                              */
  200. /*                                                                           */
  201. /*****************************************************************************/
  202. #ifdef ANSI_DECLARATORS
  203. void triangleinit(struct mesh *m)
  204. #else /* not ANSI_DECLARATORS */
  205. void triangleinit(m)
  206. struct mesh *m;
  207. #endif /* not ANSI_DECLARATORS */
  208. {
  209.   poolzero(&m->vertices);
  210.   poolzero(&m->triangles);
  211.   poolzero(&m->subsegs);
  212.   poolzero(&m->viri);
  213.   poolzero(&m->badsubsegs);
  214.   poolzero(&m->badtriangles);
  215.   poolzero(&m->flipstackers);
  216.   poolzero(&m->splaynodes);
  217.   m->recenttri.tri = (triangle *) NULL; /* No triangle has been visited yet. */
  218.   m->undeads = 0;                       /* No eliminated input vertices yet. */
  219.   m->samples = 1;         /* Point location should take at least one sample. */
  220.   m->checksegments = 0;   /* There are no segments in the triangulation yet. */
  221.   m->checkquality = 0;     /* The quality triangulation stage has not begun. */
  222.   m->incirclecount = m->counterclockcount = m->orient3dcount = 0;
  223.   m->hyperbolacount = m->circletopcount = m->circumcentercount = 0;
  224.   randomseed = 1;
  225.   exactinit();                     /* Initialize exact arithmetic constants. */
  226. }
  227. /*****************************************************************************/
  228. /*                                                                           */
  229. /*  randomnation()   Generate a random number between 0 and `choices' - 1.   */
  230. /*                                                                           */
  231. /*  This is a simple linear congruential random number generator.  Hence, it */
  232. /*  is a bad random number generator, but good enough for most randomized    */
  233. /*  geometric algorithms.                                                    */
  234. /*                                                                           */
  235. /*****************************************************************************/
  236. #ifdef ANSI_DECLARATORS
  237. unsigned long randomnation(unsigned int choices)
  238. #else /* not ANSI_DECLARATORS */
  239. unsigned long randomnation(choices)
  240. unsigned int choices;
  241. #endif /* not ANSI_DECLARATORS */
  242. {
  243.   randomseed = (randomseed * 1366l + 150889l) % 714025l;
  244.   return randomseed / (714025l / choices + 1);
  245. }
  246. /********* Mesh quality testing routines begin here                  *********/
  247. /**                                                                         **/
  248. /**                                                                         **/
  249. /*****************************************************************************/
  250. /*                                                                           */
  251. /*  checkmesh()   Test the mesh for topological consistency.                 */
  252. /*                                                                           */
  253. /*****************************************************************************/
  254. #ifndef REDUCED
  255. #ifdef ANSI_DECLARATORS
  256. void checkmesh(struct mesh *m, struct behavior *b)
  257. #else /* not ANSI_DECLARATORS */
  258. void checkmesh(m, b)
  259. struct mesh *m;
  260. struct behavior *b;
  261. #endif /* not ANSI_DECLARATORS */
  262. {
  263.   struct otri triangleloop;
  264.   struct otri oppotri, oppooppotri;
  265.   vertex triorg, tridest, triapex;
  266.   vertex oppoorg, oppodest;
  267.   int horrors;
  268.   int saveexact;
  269.   triangle ptr;                         /* Temporary variable used by sym(). */
  270.   /* Temporarily turn on exact arithmetic if it's off. */
  271.   saveexact = b->noexact;
  272.   b->noexact = 0;
  273.   if (!b->quiet) {
  274.     printf("  Checking consistency of mesh...n");
  275.   }
  276.   horrors = 0;
  277.   /* Run through the list of triangles, checking each one. */
  278.   traversalinit(&m->triangles);
  279.   triangleloop.tri = triangletraverse(m);
  280.   while (triangleloop.tri != (triangle *) NULL) {
  281.     /* Check all three edges of the triangle. */
  282.     for (triangleloop.orient = 0; triangleloop.orient < 3;
  283.          triangleloop.orient++) {
  284.       org(triangleloop, triorg);
  285.       dest(triangleloop, tridest);
  286.       if (triangleloop.orient == 0) {       /* Only test for inversion once. */
  287.         /* Test if the triangle is flat or inverted. */
  288.         apex(triangleloop, triapex);
  289.         if (counterclockwise(m, b, triorg, tridest, triapex) <= 0.0) {
  290.           printf("  !! !! Inverted ");
  291.           printtriangle(m, b, &triangleloop);
  292.           horrors++;
  293.         }
  294.       }
  295.       /* Find the neighboring triangle on this edge. */
  296.       sym(triangleloop, oppotri);
  297.       if (oppotri.tri != m->dummytri) {
  298.         /* Check that the triangle's neighbor knows it's a neighbor. */
  299.         sym(oppotri, oppooppotri);
  300.         if ((triangleloop.tri != oppooppotri.tri)
  301.             || (triangleloop.orient != oppooppotri.orient)) {
  302.           printf("  !! !! Asymmetric triangle-triangle bond:n");
  303.           if (triangleloop.tri == oppooppotri.tri) {
  304.             printf("   (Right triangle, wrong orientation)n");
  305.           }
  306.           printf("    First ");
  307.           printtriangle(m, b, &triangleloop);
  308.           printf("    Second (nonreciprocating) ");
  309.           printtriangle(m, b, &oppotri);
  310.           horrors++;
  311.         }
  312.         /* Check that both triangles agree on the identities */
  313.         /*   of their shared vertices.                       */
  314.         org(oppotri, oppoorg);
  315.         dest(oppotri, oppodest);
  316.         if ((triorg != oppodest) || (tridest != oppoorg)) {
  317.           printf("  !! !! Mismatched edge coordinates between two triangles:n"
  318.                  );
  319.           printf("    First mismatched ");
  320.           printtriangle(m, b, &triangleloop);
  321.           printf("    Second mismatched ");
  322.           printtriangle(m, b, &oppotri);
  323.           horrors++;
  324.         }
  325.       }
  326.     }
  327.     triangleloop.tri = triangletraverse(m);
  328.   }
  329.   if (horrors == 0) {
  330.     if (!b->quiet) {
  331.       printf("  In my studied opinion, the mesh appears to be consistent.n");
  332.     }
  333.   } else if (horrors == 1) {
  334.     printf("  !! !! !! !! Precisely one festering wound discovered.n");
  335.   } else {
  336.     printf("  !! !! !! !! %d abominations witnessed.n", horrors);
  337.   }
  338.   /* Restore the status of exact arithmetic. */
  339.   b->noexact = saveexact;
  340. }
  341. #endif /* not REDUCED */
  342. /*****************************************************************************/
  343. /*                                                                           */
  344. /*  checkdelaunay()   Ensure that the mesh is (constrained) Delaunay.        */
  345. /*                                                                           */
  346. /*****************************************************************************/
  347. #ifndef REDUCED
  348. #ifdef ANSI_DECLARATORS
  349. void checkdelaunay(struct mesh *m, struct behavior *b)
  350. #else /* not ANSI_DECLARATORS */
  351. void checkdelaunay(m, b)
  352. struct mesh *m;
  353. struct behavior *b;
  354. #endif /* not ANSI_DECLARATORS */
  355. {
  356.   struct otri triangleloop;
  357.   struct otri oppotri;
  358.   struct osub opposubseg;
  359.   vertex triorg, tridest, triapex;
  360.   vertex oppoapex;
  361.   int shouldbedelaunay;
  362.   int horrors;
  363.   int saveexact;
  364.   triangle ptr;                         /* Temporary variable used by sym(). */
  365.   subseg sptr;                      /* Temporary variable used by tspivot(). */
  366.   /* Temporarily turn on exact arithmetic if it's off. */
  367.   saveexact = b->noexact;
  368.   b->noexact = 0;
  369.   if (!b->quiet) {
  370.     printf("  Checking Delaunay property of mesh...n");
  371.   }
  372.   horrors = 0;
  373.   /* Run through the list of triangles, checking each one. */
  374.   traversalinit(&m->triangles);
  375.   triangleloop.tri = triangletraverse(m);
  376.   while (triangleloop.tri != (triangle *) NULL) {
  377.     /* Check all three edges of the triangle. */
  378.     for (triangleloop.orient = 0; triangleloop.orient < 3;
  379.          triangleloop.orient++) {
  380.       org(triangleloop, triorg);
  381.       dest(triangleloop, tridest);
  382.       apex(triangleloop, triapex);
  383.       sym(triangleloop, oppotri);
  384.       apex(oppotri, oppoapex);
  385.       /* Only test that the edge is locally Delaunay if there is an   */
  386.       /*   adjoining triangle whose pointer is larger (to ensure that */
  387.       /*   each pair isn't tested twice).                             */
  388.       shouldbedelaunay = (oppotri.tri != m->dummytri) &&
  389.             !deadtri(oppotri.tri) && (triangleloop.tri < oppotri.tri) &&
  390.             (triorg != m->infvertex1) && (triorg != m->infvertex2) &&
  391.             (triorg != m->infvertex3) &&
  392.             (tridest != m->infvertex1) && (tridest != m->infvertex2) &&
  393.             (tridest != m->infvertex3) &&
  394.             (triapex != m->infvertex1) && (triapex != m->infvertex2) &&
  395.             (triapex != m->infvertex3) &&
  396.             (oppoapex != m->infvertex1) && (oppoapex != m->infvertex2) &&
  397.             (oppoapex != m->infvertex3);
  398.       if (m->checksegments && shouldbedelaunay) {
  399.         /* If a subsegment separates the triangles, then the edge is */
  400.         /*   constrained, so no local Delaunay test should be done.  */
  401.         tspivot(triangleloop, opposubseg);
  402.         if (opposubseg.ss != m->dummysub){
  403.           shouldbedelaunay = 0;
  404.         }
  405.       }
  406.       if (shouldbedelaunay) {
  407.         if (nonregular(m, b, triorg, tridest, triapex, oppoapex) > 0.0) {
  408.           if (!b->weighted) {
  409.             printf("  !! !! Non-Delaunay pair of triangles:n");
  410.             printf("    First non-Delaunay ");
  411.             printtriangle(m, b, &triangleloop);
  412.             printf("    Second non-Delaunay ");
  413.           } else {
  414.             printf("  !! !! Non-regular pair of triangles:n");
  415.             printf("    First non-regular ");
  416.             printtriangle(m, b, &triangleloop);
  417.             printf("    Second non-regular ");
  418.           }
  419.           printtriangle(m, b, &oppotri);
  420.           horrors++;
  421.         }
  422.       }
  423.     }
  424.     triangleloop.tri = triangletraverse(m);
  425.   }
  426.   if (horrors == 0) {
  427.     if (!b->quiet) {
  428.       printf(
  429.   "  By virtue of my perceptive intelligence, I declare the mesh Delaunay.n");
  430.     }
  431.   } else if (horrors == 1) {
  432.     printf(
  433.          "  !! !! !! !! Precisely one terrifying transgression identified.n");
  434.   } else {
  435.     printf("  !! !! !! !! %d obscenities viewed with horror.n", horrors);
  436.   }
  437.   /* Restore the status of exact arithmetic. */
  438.   b->noexact = saveexact;
  439. }
  440. #endif /* not REDUCED */
  441. /*****************************************************************************/
  442. /*                                                                           */
  443. /*  enqueuebadtriang()   Add a bad triangle data structure to the end of a   */
  444. /*                       queue.                                              */
  445. /*                                                                           */
  446. /*  The queue is actually a set of 4096 queues.  I use multiple queues to    */
  447. /*  give priority to smaller angles.  I originally implemented a heap, but   */
  448. /*  the queues are faster by a larger margin than I'd suspected.             */
  449. /*                                                                           */
  450. /*****************************************************************************/
  451. #ifndef CDT_ONLY
  452. #ifdef ANSI_DECLARATORS
  453. void enqueuebadtriang(struct mesh *m, struct behavior *b,
  454.                       struct badtriang *badtri)
  455. #else /* not ANSI_DECLARATORS */
  456. void enqueuebadtriang(m, b, badtri)
  457. struct mesh *m;
  458. struct behavior *b;
  459. struct badtriang *badtri;
  460. #endif /* not ANSI_DECLARATORS */
  461. {
  462.   REAL length, multiplier;
  463.   int exponent, expincrement;
  464.   int queuenumber;
  465.   int posexponent;
  466.   int i;
  467.   if (b->verbose > 2) {
  468.     printf("  Queueing bad triangle:n");
  469.     printf("    (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)n",
  470.            badtri->triangorg[0], badtri->triangorg[1],
  471.            badtri->triangdest[0], badtri->triangdest[1],
  472.            badtri->triangapex[0], badtri->triangapex[1]);
  473.   }
  474.   /* Determine the appropriate queue to put the bad triangle into.    */
  475.   /*   Recall that the key is the square of its shortest edge length. */
  476.   if (badtri->key >= 1.0) {
  477.     length = badtri->key;
  478.     posexponent = 1;
  479.   } else {
  480.     /* `badtri->key' is 2.0 to a negative exponent, so we'll record that */
  481.     /*   fact and use the reciprocal of `badtri->key', which is > 1.0.   */
  482.     length = 1.0 / badtri->key;
  483.     posexponent = 0;
  484.   }
  485.   /* `length' is approximately 2.0 to what exponent?  The following code */
  486.   /*   determines the answer in time logarithmic in the exponent.        */
  487.   exponent = 0;
  488.   while (length > 2.0) {
  489.     /* Find an approximation by repeated squaring of two. */
  490.     expincrement = 1;
  491.     multiplier = 0.5;
  492.     while (length * multiplier * multiplier > 1.0) {
  493.       expincrement *= 2;
  494.       multiplier *= multiplier;
  495.     }
  496.     /* Reduce the value of `length', then iterate if necessary. */
  497.     exponent += expincrement;
  498.     length *= multiplier;
  499.   }
  500.   /* `length' is approximately squareroot(2.0) to what exponent? */
  501.   exponent = 2.0 * exponent + (length > SQUAREROOTTWO);
  502.   /* `exponent' is now in the range 0...2047 for IEEE double precision.   */
  503.   /*   Choose a queue in the range 0...4095.  The shortest edges have the */
  504.   /*   highest priority (queue 4095).                                     */
  505.   if (posexponent) {
  506.     queuenumber = 2047 - exponent;
  507.   } else {
  508.     queuenumber = 2048 + exponent;
  509.   }
  510.   /* Are we inserting into an empty queue? */
  511.   if (m->queuefront[queuenumber] == (struct badtriang *) NULL) {
  512.     /* Yes, we are inserting into an empty queue.     */
  513.     /*   Will this become the highest-priority queue? */
  514.     if (queuenumber > m->firstnonemptyq) {
  515.       /* Yes, this is the highest-priority queue. */
  516.       m->nextnonemptyq[queuenumber] = m->firstnonemptyq;
  517.       m->firstnonemptyq = queuenumber;
  518.     } else {
  519.       /* No, this is not the highest-priority queue. */
  520.       /*   Find the queue with next higher priority. */
  521.       i = queuenumber + 1;
  522.       while (m->queuefront[i] == (struct badtriang *) NULL) {
  523.         i++;
  524.       }
  525.       /* Mark the newly nonempty queue as following a higher-priority queue. */
  526.       m->nextnonemptyq[queuenumber] = m->nextnonemptyq[i];
  527.       m->nextnonemptyq[i] = queuenumber;
  528.     }
  529.     /* Put the bad triangle at the beginning of the (empty) queue. */
  530.     m->queuefront[queuenumber] = badtri;
  531.   } else {
  532.     /* Add the bad triangle to the end of an already nonempty queue. */
  533.     m->queuetail[queuenumber]->nexttriang = badtri;
  534.   }
  535.   /* Maintain a pointer to the last triangle of the queue. */
  536.   m->queuetail[queuenumber] = badtri;
  537.   /* Newly enqueued bad triangle has no successor in the queue. */
  538.   badtri->nexttriang = (struct badtriang *) NULL;
  539. }
  540. #endif /* not CDT_ONLY */
  541. /*****************************************************************************/
  542. /*                                                                           */
  543. /*  enqueuebadtri()   Add a bad triangle to the end of a queue.              */
  544. /*                                                                           */
  545. /*  Allocates a badtriang data structure for the triangle, then passes it to */
  546. /*  enqueuebadtriang().                                                      */
  547. /*                                                                           */
  548. /*****************************************************************************/
  549. #ifndef CDT_ONLY
  550. #ifdef ANSI_DECLARATORS
  551. void enqueuebadtri(struct mesh *m, struct behavior *b, struct otri *enqtri,
  552.                    REAL minedge, vertex enqapex, vertex enqorg, vertex enqdest)
  553. #else /* not ANSI_DECLARATORS */
  554. void enqueuebadtri(m, b, enqtri, minedge, enqapex, enqorg, enqdest)
  555. struct mesh *m;
  556. struct behavior *b;
  557. struct otri *enqtri;
  558. REAL minedge;
  559. vertex enqapex;
  560. vertex enqorg;
  561. vertex enqdest;
  562. #endif /* not ANSI_DECLARATORS */
  563. {
  564.   struct badtriang *newbad;
  565.   /* Allocate space for the bad triangle. */
  566.   newbad = (struct badtriang *) poolalloc(&m->badtriangles);
  567.   newbad->poortri = encode(*enqtri);
  568.   newbad->key = minedge;
  569.   newbad->triangapex = enqapex;
  570.   newbad->triangorg = enqorg;
  571.   newbad->triangdest = enqdest;
  572.   enqueuebadtriang(m, b, newbad);
  573. }
  574. #endif /* not CDT_ONLY */
  575. /*****************************************************************************/
  576. /*                                                                           */
  577. /*  dequeuebadtriang()   Remove a triangle from the front of the queue.      */
  578. /*                                                                           */
  579. /*****************************************************************************/
  580. #ifndef CDT_ONLY
  581. #ifdef ANSI_DECLARATORS
  582. struct badtriang *dequeuebadtriang(struct mesh *m)
  583. #else /* not ANSI_DECLARATORS */
  584. struct badtriang *dequeuebadtriang(m)
  585. struct mesh *m;
  586. #endif /* not ANSI_DECLARATORS */
  587. {
  588.   struct badtriang *result;
  589.   /* If no queues are nonempty, return NULL. */
  590.   if (m->firstnonemptyq < 0) {
  591.     return (struct badtriang *) NULL;
  592.   }
  593.   /* Find the first triangle of the highest-priority queue. */
  594.   result = m->queuefront[m->firstnonemptyq];
  595.   /* Remove the triangle from the queue. */
  596.   m->queuefront[m->firstnonemptyq] = result->nexttriang;
  597.   /* If this queue is now empty, note the new highest-priority */
  598.   /*   nonempty queue.                                         */
  599.   if (result == m->queuetail[m->firstnonemptyq]) {
  600.     m->firstnonemptyq = m->nextnonemptyq[m->firstnonemptyq];
  601.   }
  602.   return result;
  603. }
  604. #endif /* not CDT_ONLY */
  605. /*****************************************************************************/
  606. /*                                                                           */
  607. /*  checkseg4encroach()   Check a subsegment to see if it is encroached; add */
  608. /*                        it to the list if it is.                           */
  609. /*                                                                           */
  610. /*  A subsegment is encroached if there is a vertex in its diametral lens.   */
  611. /*  For Ruppert's algorithm (-D switch), the "diametral lens" is the         */
  612. /*  diametral circle.  For Chew's algorithm (default), the diametral lens is */
  613. /*  just big enough to enclose two isosceles triangles whose bases are the   */
  614. /*  subsegment.  Each of the two isosceles triangles has two angles equal    */
  615. /*  to `b->minangle'.                                                        */
  616. /*                                                                           */
  617. /*  Chew's algorithm does not require diametral lenses at all--but they save */
  618. /*  time.  Any vertex inside a subsegment's diametral lens implies that the  */
  619. /*  triangle adjoining the subsegment will be too skinny, so it's only a     */
  620. /*  matter of time before the encroaching vertex is deleted by Chew's        */
  621. /*  algorithm.  It's faster to simply not insert the doomed vertex in the    */
  622. /*  first place, which is why I use diametral lenses with Chew's algorithm.  */
  623. /*                                                                           */
  624. /*  Returns a nonzero value if the subsegment is encroached.                 */
  625. /*                                                                           */
  626. /*****************************************************************************/
  627. #ifndef CDT_ONLY
  628. #ifdef ANSI_DECLARATORS
  629. int checkseg4encroach(struct mesh *m, struct behavior *b,
  630.                       struct osub *testsubseg)
  631. #else /* not ANSI_DECLARATORS */
  632. int checkseg4encroach(m, b, testsubseg)
  633. struct mesh *m;
  634. struct behavior *b;
  635. struct osub *testsubseg;
  636. #endif /* not ANSI_DECLARATORS */
  637. {
  638.   struct otri neighbortri;
  639.   struct osub testsym;
  640.   struct badsubseg *encroachedseg;
  641.   REAL dotproduct;
  642.   int encroached;
  643.   int sides;
  644.   vertex eorg, edest, eapex;
  645.   triangle ptr;                     /* Temporary variable used by stpivot(). */
  646.   encroached = 0;
  647.   sides = 0;
  648.   sorg(*testsubseg, eorg);
  649.   sdest(*testsubseg, edest);
  650.   /* Check one neighbor of the subsegment. */
  651.   stpivot(*testsubseg, neighbortri);
  652.   /* Does the neighbor exist, or is this a boundary edge? */
  653.   if (neighbortri.tri != m->dummytri) {
  654.     sides++;
  655.     /* Find a vertex opposite this subsegment. */
  656.     apex(neighbortri, eapex);
  657.     /* Check whether the apex is in the diametral lens of the subsegment */
  658.     /*   (the diametral circle if `conformdel' is set).  A dot product   */
  659.     /*   of two sides of the triangle is used to check whether the angle */
  660.     /*   at the apex is greater than (180 - 2 `minangle') degrees (for   */
  661.     /*   lenses; 90 degrees for diametral circles).                      */
  662.     dotproduct = (eorg[0] - eapex[0]) * (edest[0] - eapex[0]) +
  663.                  (eorg[1] - eapex[1]) * (edest[1] - eapex[1]);
  664.     if (dotproduct < 0.0) {
  665.       if (b->conformdel ||
  666.           (dotproduct * dotproduct >=
  667.            (2.0 * b->goodangle - 1.0) * (2.0 * b->goodangle - 1.0) *
  668.            ((eorg[0] - eapex[0]) * (eorg[0] - eapex[0]) +
  669.             (eorg[1] - eapex[1]) * (eorg[1] - eapex[1])) *
  670.            ((edest[0] - eapex[0]) * (edest[0] - eapex[0]) +
  671.             (edest[1] - eapex[1]) * (edest[1] - eapex[1])))) {
  672.         encroached = 1;
  673.       }
  674.     }
  675.   }
  676.   /* Check the other neighbor of the subsegment. */
  677.   ssym(*testsubseg, testsym);
  678.   stpivot(testsym, neighbortri);
  679.   /* Does the neighbor exist, or is this a boundary edge? */
  680.   if (neighbortri.tri != m->dummytri) {
  681.     sides++;
  682.     /* Find the other vertex opposite this subsegment. */
  683.     apex(neighbortri, eapex);
  684.     /* Check whether the apex is in the diametral lens of the subsegment */
  685.     /*   (or the diametral circle, if `conformdel' is set).              */
  686.     dotproduct = (eorg[0] - eapex[0]) * (edest[0] - eapex[0]) +
  687.                  (eorg[1] - eapex[1]) * (edest[1] - eapex[1]);
  688.     if (dotproduct < 0.0) {
  689.       if (b->conformdel ||
  690.           (dotproduct * dotproduct >=
  691.            (2.0 * b->goodangle - 1.0) * (2.0 * b->goodangle - 1.0) *
  692.            ((eorg[0] - eapex[0]) * (eorg[0] - eapex[0]) +
  693.             (eorg[1] - eapex[1]) * (eorg[1] - eapex[1])) *
  694.            ((edest[0] - eapex[0]) * (edest[0] - eapex[0]) +
  695.             (edest[1] - eapex[1]) * (edest[1] - eapex[1])))) {
  696.         encroached += 2;
  697.       }
  698.     }
  699.   }
  700.   if (encroached && (!b->nobisect || ((b->nobisect == 1) && (sides == 2)))) {
  701.     if (b->verbose > 2) {
  702.       printf(
  703.         "  Queueing encroached subsegment (%.12g, %.12g) (%.12g, %.12g).n",
  704.         eorg[0], eorg[1], edest[0], edest[1]);
  705.     }
  706.     /* Add the subsegment to the list of encroached subsegments. */
  707.     /*   Be sure to get the orientation right.                   */
  708.     encroachedseg = (struct badsubseg *) poolalloc(&m->badsubsegs);
  709.     if (encroached == 1) {
  710.       encroachedseg->encsubseg = sencode(*testsubseg);
  711.       encroachedseg->subsegorg = eorg;
  712.       encroachedseg->subsegdest = edest;
  713.     } else {
  714.       encroachedseg->encsubseg = sencode(testsym);
  715.       encroachedseg->subsegorg = edest;
  716.       encroachedseg->subsegdest = eorg;
  717.     }
  718.   }
  719.   return encroached;
  720. }
  721. #endif /* not CDT_ONLY */
  722. /*****************************************************************************/
  723. /*                                                                           */
  724. /*  testtriangle()   Test a triangle for quality and size.                   */
  725. /*                                                                           */
  726. /*  Tests a triangle to see if it satisfies the minimum angle condition and  */
  727. /*  the maximum area condition.  Triangles that aren't up to spec are added  */
  728. /*  to the bad triangle queue.                                               */
  729. /*                                                                           */
  730. /*****************************************************************************/
  731. #ifndef CDT_ONLY
  732. #ifdef ANSI_DECLARATORS
  733. void testtriangle(struct mesh *m, struct behavior *b, struct otri *testtri)
  734. #else /* not ANSI_DECLARATORS */
  735. void testtriangle(m, b, testtri)
  736. struct mesh *m;
  737. struct behavior *b;
  738. struct otri *testtri;
  739. #endif /* not ANSI_DECLARATORS */
  740. {
  741.   struct otri tri1, tri2;
  742.   struct osub testsub;
  743.   vertex torg, tdest, tapex;
  744.   vertex base1, base2;
  745.   vertex org1, dest1, org2, dest2;
  746.   vertex joinvertex;
  747.   REAL dxod, dyod, dxda, dyda, dxao, dyao;
  748.   REAL dxod2, dyod2, dxda2, dyda2, dxao2, dyao2;
  749.   REAL apexlen, orglen, destlen, minedge;
  750.   REAL angle;
  751.   REAL area;
  752.   REAL dist1, dist2;
  753.   subseg sptr;                      /* Temporary variable used by tspivot(). */
  754.   triangle ptr;           /* Temporary variable used by oprev() and dnext(). */
  755.   org(*testtri, torg);
  756.   dest(*testtri, tdest);
  757.   apex(*testtri, tapex);
  758.   dxod = torg[0] - tdest[0];
  759.   dyod = torg[1] - tdest[1];
  760.   dxda = tdest[0] - tapex[0];
  761.   dyda = tdest[1] - tapex[1];
  762.   dxao = tapex[0] - torg[0];
  763.   dyao = tapex[1] - torg[1];
  764.   dxod2 = dxod * dxod;
  765.   dyod2 = dyod * dyod;
  766.   dxda2 = dxda * dxda;
  767.   dyda2 = dyda * dyda;
  768.   dxao2 = dxao * dxao;
  769.   dyao2 = dyao * dyao;
  770.   /* Find the lengths of the triangle's three edges. */
  771.   apexlen = dxod2 + dyod2;
  772.   orglen = dxda2 + dyda2;
  773.   destlen = dxao2 + dyao2;
  774.   if ((apexlen < orglen) && (apexlen < destlen)) {
  775.     /* The edge opposite the apex is shortest. */
  776.     minedge = apexlen;
  777.     /* Find the square of the cosine of the angle at the apex. */
  778.     angle = dxda * dxao + dyda * dyao;
  779.     angle = angle * angle / (orglen * destlen);
  780.     base1 = torg;
  781.     base2 = tdest;
  782.     otricopy(*testtri, tri1);
  783.   } else if (orglen < destlen) {
  784.     /* The edge opposite the origin is shortest. */
  785.     minedge = orglen;
  786.     /* Find the square of the cosine of the angle at the origin. */
  787.     angle = dxod * dxao + dyod * dyao;
  788.     angle = angle * angle / (apexlen * destlen);
  789.     base1 = tdest;
  790.     base2 = tapex;
  791.     lnext(*testtri, tri1);
  792.   } else {
  793.     /* The edge opposite the destination is shortest. */
  794.     minedge = destlen;
  795.     /* Find the square of the cosine of the angle at the destination. */
  796.     angle = dxod * dxda + dyod * dyda;
  797.     angle = angle * angle / (apexlen * orglen);
  798.     base1 = tapex;
  799.     base2 = torg;
  800.     lprev(*testtri, tri1);
  801.   }
  802.   if (b->vararea || b->fixedarea || b->usertest) {
  803.     /* Check whether the area is larger than permitted. */
  804.     area = 0.5 * (dxod * dyda - dyod * dxda);
  805.     if (b->fixedarea && (area > b->maxarea)) {
  806.       /* Add this triangle to the list of bad triangles. */
  807.       enqueuebadtri(m, b, testtri, minedge, tapex, torg, tdest);
  808.       return;
  809.     }
  810.     /* Nonpositive area constraints are treated as unconstrained. */
  811.     if ((b->vararea) && (area > areabound(*testtri)) &&
  812.         (areabound(*testtri) > 0.0)) {
  813.       /* Add this triangle to the list of bad triangles. */
  814.       enqueuebadtri(m, b, testtri, minedge, tapex, torg, tdest);
  815.       return;
  816.     }
  817.     if (b->usertest) {
  818.       /* Check whether the user thinks this triangle is too large. */
  819.       if (triunsuitable(torg, tdest, tapex, area)) {
  820.         enqueuebadtri(m, b, testtri, minedge, tapex, torg, tdest);
  821.         return;
  822.       }
  823.     }
  824.   }
  825.   /* Check whether the angle is smaller than permitted. */
  826.   if (angle > b->goodangle) {
  827.     /* Use the rules of Miller, Pav, and Walkington to decide that certain */
  828.     /*   triangles should not be split, even if they have bad angles.      */
  829.     /*   A skinny triangle is not split if its shortest edge subtends a    */
  830.     /*   small input angle, and both endpoints of the edge lie on a        */
  831.     /*   concentric circular shell.  For convenience, I make a small       */
  832.     /*   adjustment to that rule:  I check if the endpoints of the edge    */
  833.     /*   both lie in segment interiors, equidistant from the apex where    */
  834.     /*   the two segments meet.                                            */
  835.     /* First, check if both points lie in segment interiors.               */
  836.     if ((vertextype(base1) == SEGMENTVERTEX) &&
  837.         (vertextype(base2) == SEGMENTVERTEX)) {
  838.       /* Check if both points lie in a common segment.  If they do, the */
  839.       /*   skinny triangle is enqueued to be split as usual.            */
  840.       tspivot(tri1, testsub);
  841.       if (testsub.ss == m->dummysub) {
  842.         /* No common segment.  Find a subsegment that contains `torg'. */
  843.         otricopy(tri1, tri2);
  844.         do {
  845.           oprevself(tri1);
  846.           tspivot(tri1, testsub);
  847.         } while (testsub.ss == m->dummysub);
  848.         /* Find the endpoints of the containing segment. */
  849.         segorg(testsub, org1);
  850.         segdest(testsub, dest1);
  851.         /* Find a subsegment that contains `tdest'. */
  852.         do {
  853.           dnextself(tri2);
  854.           tspivot(tri2, testsub);
  855.         } while (testsub.ss == m->dummysub);
  856.         /* Find the endpoints of the containing segment. */
  857.         segorg(testsub, org2);
  858.         segdest(testsub, dest2);
  859.         /* Check if the two containing segments have an endpoint in common. */
  860.         joinvertex = (vertex) NULL;
  861.         if ((dest1[0] == org2[0]) && (dest1[1] == org2[1])) {
  862.           joinvertex = dest1;
  863.         } else if ((org1[0] == dest2[0]) && (org1[1] == dest2[1])) {
  864.           joinvertex = org1;
  865.         }
  866.         if (joinvertex != (vertex) NULL) {
  867.           /* Compute the distance from the common endpoint (of the two  */
  868.           /*   segments) to each of the endpoints of the shortest edge. */
  869.           dist1 = ((base1[0] - joinvertex[0]) * (base1[0] - joinvertex[0]) +
  870.                    (base1[1] - joinvertex[1]) * (base1[1] - joinvertex[1]));
  871.           dist2 = ((base2[0] - joinvertex[0]) * (base2[0] - joinvertex[0]) +
  872.                    (base2[1] - joinvertex[1]) * (base2[1] - joinvertex[1]));
  873.           /* If the two distances are equal, don't split the triangle. */
  874.           if ((dist1 < 1.001 * dist2) && (dist1 > 0.999 * dist2)) {
  875.             /* Return now to avoid enqueueing the bad triangle. */
  876.             return;
  877.           }
  878.         }
  879.       }
  880.     }
  881.     /* Add this triangle to the list of bad triangles. */
  882.     enqueuebadtri(m, b, testtri, minedge, tapex, torg, tdest);
  883.   }
  884. }
  885. #endif /* not CDT_ONLY */
  886. /**                                                                         **/
  887. /**                                                                         **/
  888. /********* Mesh quality testing routines end here                    *********/
  889. /********* Point location routines begin here                        *********/
  890. /**                                                                         **/
  891. /**                                                                         **/
  892. /*****************************************************************************/
  893. /*                                                                           */
  894. /*  makevertexmap()   Construct a mapping from vertices to triangles to      */
  895. /*                    improve the speed of point location for segment        */
  896. /*                    insertion.                                             */
  897. /*                                                                           */
  898. /*  Traverses all the triangles, and provides each corner of each triangle   */
  899. /*  with a pointer to that triangle.  Of course, pointers will be            */
  900. /*  overwritten by other pointers because (almost) each vertex is a corner   */
  901. /*  of several triangles, but in the end every vertex will point to some     */
  902. /*  triangle that contains it.                                               */
  903. /*                                                                           */
  904. /*****************************************************************************/
  905. #ifdef ANSI_DECLARATORS
  906. void makevertexmap(struct mesh *m, struct behavior *b)
  907. #else /* not ANSI_DECLARATORS */
  908. void makevertexmap(m, b)
  909. struct mesh *m;
  910. struct behavior *b;
  911. #endif /* not ANSI_DECLARATORS */
  912. {
  913.   struct otri triangleloop;
  914.   vertex triorg;
  915.   if (b->verbose) {
  916.     printf("    Constructing mapping from vertices to triangles.n");
  917.   }
  918.   traversalinit(&m->triangles);
  919.   triangleloop.tri = triangletraverse(m);
  920.   while (triangleloop.tri != (triangle *) NULL) {
  921.     /* Check all three vertices of the triangle. */
  922.     for (triangleloop.orient = 0; triangleloop.orient < 3;
  923.          triangleloop.orient++) {
  924.       org(triangleloop, triorg);
  925.       setvertex2tri(triorg, encode(triangleloop));
  926.     }
  927.     triangleloop.tri = triangletraverse(m);
  928.   }
  929. }
  930. /*****************************************************************************/
  931. /*                                                                           */
  932. /*  preciselocate()   Find a triangle or edge containing a given point.      */
  933. /*                                                                           */
  934. /*  Begins its search from `searchtri'.  It is important that `searchtri'    */
  935. /*  be a handle with the property that `searchpoint' is strictly to the left */
  936. /*  of the edge denoted by `searchtri', or is collinear with that edge and   */
  937. /*  does not intersect that edge.  (In particular, `searchpoint' should not  */
  938. /*  be the origin or destination of that edge.)                              */
  939. /*                                                                           */
  940. /*  These conditions are imposed because preciselocate() is normally used in */
  941. /*  one of two situations:                                                   */
  942. /*                                                                           */
  943. /*  (1)  To try to find the location to insert a new point.  Normally, we    */
  944. /*       know an edge that the point is strictly to the left of.  In the     */
  945. /*       incremental Delaunay algorithm, that edge is a bounding box edge.   */
  946. /*       In Ruppert's Delaunay refinement algorithm for quality meshing,     */
  947. /*       that edge is the shortest edge of the triangle whose circumcenter   */
  948. /*       is being inserted.                                                  */
  949. /*                                                                           */
  950. /*  (2)  To try to find an existing point.  In this case, any edge on the    */
  951. /*       convex hull is a good starting edge.  You must screen out the       */
  952. /*       possibility that the vertex sought is an endpoint of the starting   */
  953. /*       edge before you call preciselocate().                               */
  954. /*                                                                           */
  955. /*  On completion, `searchtri' is a triangle that contains `searchpoint'.    */
  956. /*                                                                           */
  957. /*  This implementation differs from that given by Guibas and Stolfi.  It    */
  958. /*  walks from triangle to triangle, crossing an edge only if `searchpoint'  */
  959. /*  is on the other side of the line containing that edge.  After entering   */
  960. /*  a triangle, there are two edges by which one can leave that triangle.    */
  961. /*  If both edges are valid (`searchpoint' is on the other side of both      */
  962. /*  edges), one of the two is chosen by drawing a line perpendicular to      */
  963. /*  the entry edge (whose endpoints are `forg' and `fdest') passing through  */
  964. /*  `fapex'.  Depending on which side of this perpendicular `searchpoint'    */
  965. /*  falls on, an exit edge is chosen.                                        */
  966. /*                                                                           */
  967. /*  This implementation is empirically faster than the Guibas and Stolfi     */
  968. /*  point location routine (which I originally used), which tends to spiral  */
  969. /*  in toward its target.                                                    */
  970. /*                                                                           */
  971. /*  Returns ONVERTEX if the point lies on an existing vertex.  `searchtri'   */
  972. /*  is a handle whose origin is the existing vertex.                         */
  973. /*                                                                           */
  974. /*  Returns ONEDGE if the point lies on a mesh edge.  `searchtri' is a       */
  975. /*  handle whose primary edge is the edge on which the point lies.           */
  976. /*                                                                           */
  977. /*  Returns INTRIANGLE if the point lies strictly within a triangle.         */
  978. /*  `searchtri' is a handle on the triangle that contains the point.         */
  979. /*                                                                           */
  980. /*  Returns OUTSIDE if the point lies outside the mesh.  `searchtri' is a    */
  981. /*  handle whose primary edge the point is to the right of.  This might      */
  982. /*  occur when the circumcenter of a triangle falls just slightly outside    */
  983. /*  the mesh due to floating-point roundoff error.  It also occurs when      */
  984. /*  seeking a hole or region point that a foolish user has placed outside    */
  985. /*  the mesh.                                                                */
  986. /*                                                                           */
  987. /*  If `stopatsubsegment' is nonzero, the search will stop if it tries to    */
  988. /*  walk through a subsegment, and will return OUTSIDE.                      */
  989. /*                                                                           */
  990. /*  WARNING:  This routine is designed for convex triangulations, and will   */
  991. /*  not generally work after the holes and concavities have been carved.     */
  992. /*  However, it can still be used to find the circumcenter of a triangle, as */
  993. /*  long as the search is begun from the triangle in question.               */
  994. /*                                                                           */
  995. /*****************************************************************************/
  996. #ifdef ANSI_DECLARATORS
  997. enum locateresult preciselocate(struct mesh *m, struct behavior *b,
  998.                                 vertex searchpoint, struct otri *searchtri,
  999.                                 int stopatsubsegment)
  1000. #else /* not ANSI_DECLARATORS */
  1001. enum locateresult preciselocate(m, b, searchpoint, searchtri, stopatsubsegment)
  1002. struct mesh *m;
  1003. struct behavior *b;
  1004. vertex searchpoint;
  1005. struct otri *searchtri;
  1006. int stopatsubsegment;
  1007. #endif /* not ANSI_DECLARATORS */
  1008. {
  1009.   struct otri backtracktri;
  1010.   struct osub checkedge;
  1011.   vertex forg, fdest, fapex;
  1012.   REAL orgorient, destorient;
  1013.   int moveleft;
  1014.   triangle ptr;                         /* Temporary variable used by sym(). */
  1015.   subseg sptr;                      /* Temporary variable used by tspivot(). */
  1016.   if (b->verbose > 2) {
  1017.     printf("  Searching for point (%.12g, %.12g).n",
  1018.            searchpoint[0], searchpoint[1]);
  1019.   }
  1020.   /* Where are we? */
  1021.   org(*searchtri, forg);
  1022.   dest(*searchtri, fdest);
  1023.   apex(*searchtri, fapex);
  1024.   while (1) {
  1025.     if (b->verbose > 2) {
  1026.       printf("    At (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)n",
  1027.              forg[0], forg[1], fdest[0], fdest[1], fapex[0], fapex[1]);
  1028.     }
  1029.     /* Check whether the apex is the point we seek. */
  1030.     if ((fapex[0] == searchpoint[0]) && (fapex[1] == searchpoint[1])) {
  1031.       lprevself(*searchtri);
  1032.       return ONVERTEX;
  1033.     }
  1034.     /* Does the point lie on the other side of the line defined by the */
  1035.     /*   triangle edge opposite the triangle's destination?            */
  1036.     destorient = counterclockwise(m, b, forg, fapex, searchpoint);
  1037.     /* Does the point lie on the other side of the line defined by the */
  1038.     /*   triangle edge opposite the triangle's origin?                 */
  1039.     orgorient = counterclockwise(m, b, fapex, fdest, searchpoint);
  1040.     if (destorient > 0.0) {
  1041.       if (orgorient > 0.0) {
  1042.         /* Move left if the inner product of (fapex - searchpoint) and  */
  1043.         /*   (fdest - forg) is positive.  This is equivalent to drawing */
  1044.         /*   a line perpendicular to the line (forg, fdest) and passing */
  1045.         /*   through `fapex', and determining which side of this line   */
  1046.         /*   `searchpoint' falls on.                                    */
  1047.         moveleft = (fapex[0] - searchpoint[0]) * (fdest[0] - forg[0]) +
  1048.                    (fapex[1] - searchpoint[1]) * (fdest[1] - forg[1]) > 0.0;
  1049.       } else {
  1050.         moveleft = 1;
  1051.       }
  1052.     } else {
  1053.       if (orgorient > 0.0) {
  1054.         moveleft = 0;
  1055.       } else {
  1056.         /* The point we seek must be on the boundary of or inside this */
  1057.         /*   triangle.                                                 */
  1058.         if (destorient == 0.0) {
  1059.           lprevself(*searchtri);
  1060.           return ONEDGE;
  1061.         }
  1062.         if (orgorient == 0.0) {
  1063.           lnextself(*searchtri);
  1064.           return ONEDGE;
  1065.         }
  1066.         return INTRIANGLE;
  1067.       }
  1068.     }
  1069.     /* Move to another triangle.  Leave a trace `backtracktri' in case */
  1070.     /*   floating-point roundoff or some such bogey causes us to walk  */
  1071.     /*   off a boundary of the triangulation.                          */
  1072.     if (moveleft) {
  1073.       lprev(*searchtri, backtracktri);
  1074.       fdest = fapex;
  1075.     } else {
  1076.       lnext(*searchtri, backtracktri);
  1077.       forg = fapex;
  1078.     }
  1079.     sym(backtracktri, *searchtri);
  1080.     if (m->checksegments && stopatsubsegment) {
  1081.       /* Check for walking through a subsegment. */
  1082.       tspivot(backtracktri, checkedge);
  1083.       if (checkedge.ss != m->dummysub) {
  1084.         /* Go back to the last triangle. */
  1085.         otricopy(backtracktri, *searchtri);
  1086.         return OUTSIDE;
  1087.       }
  1088.     }
  1089.     /* Check for walking right out of the triangulation. */
  1090.     if (searchtri->tri == m->dummytri) {
  1091.       /* Go back to the last triangle. */
  1092.       otricopy(backtracktri, *searchtri);
  1093.       return OUTSIDE;
  1094.     }
  1095.     apex(*searchtri, fapex);
  1096.   }
  1097. }
  1098. /*****************************************************************************/
  1099. /*                                                                           */
  1100. /*  locate()   Find a triangle or edge containing a given point.             */
  1101. /*                                                                           */
  1102. /*  Searching begins from one of:  the input `searchtri', a recently         */
  1103. /*  encountered triangle `recenttri', or from a triangle chosen from a       */
  1104. /*  random sample.  The choice is made by determining which triangle's       */
  1105. /*  origin is closest to the point we are searching for.  Normally,          */
  1106. /*  `searchtri' should be a handle on the convex hull of the triangulation.  */
  1107. /*                                                                           */
  1108. /*  Details on the random sampling method can be found in the Mucke, Saias,  */
  1109. /*  and Zhu paper cited in the header of this code.                          */
  1110. /*                                                                           */
  1111. /*  On completion, `searchtri' is a triangle that contains `searchpoint'.    */
  1112. /*                                                                           */
  1113. /*  Returns ONVERTEX if the point lies on an existing vertex.  `searchtri'   */
  1114. /*  is a handle whose origin is the existing vertex.                         */
  1115. /*                                                                           */
  1116. /*  Returns ONEDGE if the point lies on a mesh edge.  `searchtri' is a       */
  1117. /*  handle whose primary edge is the edge on which the point lies.           */
  1118. /*                                                                           */
  1119. /*  Returns INTRIANGLE if the point lies strictly within a triangle.         */
  1120. /*  `searchtri' is a handle on the triangle that contains the point.         */
  1121. /*                                                                           */
  1122. /*  Returns OUTSIDE if the point lies outside the mesh.  `searchtri' is a    */
  1123. /*  handle whose primary edge the point is to the right of.  This might      */
  1124. /*  occur when the circumcenter of a triangle falls just slightly outside    */
  1125. /*  the mesh due to floating-point roundoff error.  It also occurs when      */
  1126. /*  seeking a hole or region point that a foolish user has placed outside    */
  1127. /*  the mesh.                                                                */
  1128. /*                                                                           */
  1129. /*  WARNING:  This routine is designed for convex triangulations, and will   */
  1130. /*  not generally work after the holes and concavities have been carved.     */
  1131. /*                                                                           */
  1132. /*****************************************************************************/
  1133. #ifdef ANSI_DECLARATORS
  1134. enum locateresult locate(struct mesh *m, struct behavior *b,
  1135.                          vertex searchpoint, struct otri *searchtri)
  1136. #else /* not ANSI_DECLARATORS */
  1137. enum locateresult locate(m, b, searchpoint, searchtri)
  1138. struct mesh *m;
  1139. struct behavior *b;
  1140. vertex searchpoint;
  1141. struct otri *searchtri;
  1142. #endif /* not ANSI_DECLARATORS */
  1143. {
  1144.   VOID **sampleblock;
  1145.   char *firsttri;
  1146.   struct otri sampletri;
  1147.   vertex torg, tdest;
  1148.   unsigned long alignptr;
  1149.   REAL searchdist, dist;
  1150.   REAL ahead;
  1151.   long samplesperblock, totalsamplesleft, samplesleft;
  1152.   long population, totalpopulation;
  1153.   triangle ptr;                         /* Temporary variable used by sym(). */
  1154.   if (b->verbose > 2) {
  1155.     printf("  Randomly sampling for a triangle near point (%.12g, %.12g).n",
  1156.            searchpoint[0], searchpoint[1]);
  1157.   }
  1158.   /* Record the distance from the suggested starting triangle to the */
  1159.   /*   point we seek.                                                */
  1160.   org(*searchtri, torg);
  1161.   searchdist = (searchpoint[0] - torg[0]) * (searchpoint[0] - torg[0]) +
  1162.                (searchpoint[1] - torg[1]) * (searchpoint[1] - torg[1]);
  1163.   if (b->verbose > 2) {
  1164.     printf("    Boundary triangle has origin (%.12g, %.12g).n",
  1165.            torg[0], torg[1]);
  1166.   }
  1167.   /* If a recently encountered triangle has been recorded and has not been */
  1168.   /*   deallocated, test it as a good starting point.                      */
  1169.   if (m->recenttri.tri != (triangle *) NULL) {
  1170.     if (!deadtri(m->recenttri.tri)) {
  1171.       org(m->recenttri, torg);
  1172.       if ((torg[0] == searchpoint[0]) && (torg[1] == searchpoint[1])) {
  1173.         otricopy(m->recenttri, *searchtri);
  1174.         return ONVERTEX;
  1175.       }
  1176.       dist = (searchpoint[0] - torg[0]) * (searchpoint[0] - torg[0]) +
  1177.              (searchpoint[1] - torg[1]) * (searchpoint[1] - torg[1]);
  1178.       if (dist < searchdist) {
  1179.         otricopy(m->recenttri, *searchtri);
  1180.         searchdist = dist;
  1181.         if (b->verbose > 2) {
  1182.           printf("    Choosing recent triangle with origin (%.12g, %.12g).n",
  1183.                  torg[0], torg[1]);
  1184.         }
  1185.       }
  1186.     }
  1187.   }
  1188.   /* The number of random samples taken is proportional to the cube root of */
  1189.   /*   the number of triangles in the mesh.  The next bit of code assumes   */
  1190.   /*   that the number of triangles increases monotonically (or at least    */
  1191.   /*   doesn't decrease enough to matter).                                  */
  1192.   while (SAMPLEFACTOR * m->samples * m->samples * m->samples <
  1193.          m->triangles.items) {
  1194.     m->samples++;
  1195.   }
  1196.   /* We'll draw ceiling(samples * TRIPERBLOCK / maxitems) random samples  */
  1197.   /*   from each block of triangles (except the first)--until we meet the */
  1198.   /*   sample quota.  The ceiling means that blocks at the end might be   */
  1199.   /*   neglected, but I don't care.                                       */
  1200.   samplesperblock = (m->samples * TRIPERBLOCK - 1) / m->triangles.maxitems + 1;
  1201.   /* We'll draw ceiling(samples * itemsfirstblock / maxitems) random samples */
  1202.   /*   from the first block of triangles.                                    */
  1203.   samplesleft = (m->samples * m->triangles.itemsfirstblock - 1) /
  1204.                 m->triangles.maxitems + 1;
  1205.   totalsamplesleft = m->samples;
  1206.   population = m->triangles.itemsfirstblock;
  1207.   totalpopulation = m->triangles.maxitems;
  1208.   sampleblock = m->triangles.firstblock;
  1209.   sampletri.orient = 0;
  1210.   while (totalsamplesleft > 0) {
  1211.     /* If we're in the last block, `population' needs to be corrected. */
  1212.     if (population > totalpopulation) {
  1213.       population = totalpopulation;
  1214.     }
  1215.     /* Find a pointer to the first triangle in the block. */
  1216.     alignptr = (unsigned long) (sampleblock + 1);
  1217.     firsttri = (char *) (alignptr +
  1218.                          (unsigned long) m->triangles.alignbytes -
  1219.                          (alignptr %
  1220.                           (unsigned long) m->triangles.alignbytes));
  1221.     /* Choose `samplesleft' randomly sampled triangles in this block. */
  1222.     do {
  1223.       sampletri.tri = (triangle *) (firsttri +
  1224.                                     (randomnation((unsigned int) population) *
  1225.                                      m->triangles.itembytes));
  1226.       if (!deadtri(sampletri.tri)) {
  1227.         org(sampletri, torg);
  1228.         dist = (searchpoint[0] - torg[0]) * (searchpoint[0] - torg[0]) +
  1229.                (searchpoint[1] - torg[1]) * (searchpoint[1] - torg[1]);
  1230.         if (dist < searchdist) {
  1231.           otricopy(sampletri, *searchtri);
  1232.           searchdist = dist;
  1233.           if (b->verbose > 2) {
  1234.             printf("    Choosing triangle with origin (%.12g, %.12g).n",
  1235.                    torg[0], torg[1]);
  1236.           }
  1237.         }
  1238.       }
  1239.       samplesleft--;
  1240.       totalsamplesleft--;
  1241.     } while ((samplesleft > 0) && (totalsamplesleft > 0));
  1242.     if (totalsamplesleft > 0) {
  1243.       sampleblock = (VOID **) *sampleblock;
  1244.       samplesleft = samplesperblock;
  1245.       totalpopulation -= population;
  1246.       population = TRIPERBLOCK;
  1247.     }
  1248.   }
  1249.   /* Where are we? */
  1250.   org(*searchtri, torg);
  1251.   dest(*searchtri, tdest);
  1252.   /* Check the starting triangle's vertices. */
  1253.   if ((torg[0] == searchpoint[0]) && (torg[1] == searchpoint[1])) {
  1254.     return ONVERTEX;
  1255.   }
  1256.   if ((tdest[0] == searchpoint[0]) && (tdest[1] == searchpoint[1])) {
  1257.     lnextself(*searchtri);
  1258.     return ONVERTEX;
  1259.   }
  1260.   /* Orient `searchtri' to fit the preconditions of calling preciselocate(). */
  1261.   ahead = counterclockwise(m, b, torg, tdest, searchpoint);
  1262.   if (ahead < 0.0) {
  1263.     /* Turn around so that `searchpoint' is to the left of the */
  1264.     /*   edge specified by `searchtri'.                        */
  1265.     symself(*searchtri);
  1266.   } else if (ahead == 0.0) {
  1267.     /* Check if `searchpoint' is between `torg' and `tdest'. */
  1268.     if (((torg[0] < searchpoint[0]) == (searchpoint[0] < tdest[0])) &&
  1269.         ((torg[1] < searchpoint[1]) == (searchpoint[1] < tdest[1]))) {
  1270.       return ONEDGE;
  1271.     }
  1272.   }
  1273.   return preciselocate(m, b, searchpoint, searchtri, 0);
  1274. }
  1275. /**                                                                         **/
  1276. /**                                                                         **/
  1277. /********* Point location routines end here                          *********/
  1278. /********* Mesh transformation routines begin here                   *********/
  1279. /**                                                                         **/
  1280. /**                                                                         **/
  1281. /*****************************************************************************/
  1282. /*                                                                           */
  1283. /*  insertsubseg()   Create a new subsegment and insert it between two       */
  1284. /*                   triangles.                                              */
  1285. /*                                                                           */
  1286. /*  The new subsegment is inserted at the edge described by the handle       */
  1287. /*  `tri'.  Its vertices are properly initialized.  The marker `subsegmark'  */
  1288. /*  is applied to the subsegment and, if appropriate, its vertices.          */
  1289. /*                                                                           */
  1290. /*****************************************************************************/
  1291. #ifdef ANSI_DECLARATORS
  1292. void insertsubseg(struct mesh *m, struct behavior *b, struct otri *tri,
  1293.                   int subsegmark)
  1294. #else /* not ANSI_DECLARATORS */
  1295. void insertsubseg(m, b, tri, subsegmark)
  1296. struct mesh *m;
  1297. struct behavior *b;
  1298. struct otri *tri;             /* Edge at which to insert the new subsegment. */
  1299. int subsegmark;                            /* Marker for the new subsegment. */
  1300. #endif /* not ANSI_DECLARATORS */
  1301. {
  1302.   struct otri oppotri;
  1303.   struct osub newsubseg;
  1304.   vertex triorg, tridest;
  1305.   triangle ptr;                         /* Temporary variable used by sym(). */
  1306.   subseg sptr;                      /* Temporary variable used by tspivot(). */
  1307.   org(*tri, triorg);
  1308.   dest(*tri, tridest);
  1309.   /* Mark vertices if possible. */
  1310.   if (vertexmark(triorg) == 0) {
  1311.     setvertexmark(triorg, subsegmark);
  1312.   }
  1313.   if (vertexmark(tridest) == 0) {
  1314.     setvertexmark(tridest, subsegmark);
  1315.   }
  1316.   /* Check if there's already a subsegment here. */
  1317.   tspivot(*tri, newsubseg);
  1318.   if (newsubseg.ss == m->dummysub) {
  1319.     /* Make new subsegment and initialize its vertices. */
  1320.     makesubseg(m, &newsubseg);
  1321.     setsorg(newsubseg, tridest);
  1322.     setsdest(newsubseg, triorg);
  1323.     setsegorg(newsubseg, tridest);
  1324.     setsegdest(newsubseg, triorg);
  1325.     /* Bond new subsegment to the two triangles it is sandwiched between. */
  1326.     /*   Note that the facing triangle `oppotri' might be equal to        */
  1327.     /*   `dummytri' (outer space), but the new subsegment is bonded to it */
  1328.     /*   all the same.                                                    */
  1329.     tsbond(*tri, newsubseg);
  1330.     sym(*tri, oppotri);
  1331.     ssymself(newsubseg);
  1332.     tsbond(oppotri, newsubseg);
  1333.     setmark(newsubseg, subsegmark);
  1334.     if (b->verbose > 2) {
  1335.       printf("  Inserting new ");
  1336.       printsubseg(m, b, &newsubseg);
  1337.     }
  1338.   } else {
  1339.     if (mark(newsubseg) == 0) {
  1340.       setmark(newsubseg, subsegmark);
  1341.     }
  1342.   }
  1343. }
  1344. /*****************************************************************************/
  1345. /*                                                                           */
  1346. /*  Terminology                                                              */
  1347. /*                                                                           */
  1348. /*  A "local transformation" replaces a small set of triangles with another  */
  1349. /*  set of triangles.  This may or may not involve inserting or deleting a   */
  1350. /*  vertex.                                                                  */
  1351. /*                                                                           */
  1352. /*  The term "casing" is used to describe the set of triangles that are      */
  1353. /*  attached to the triangles being transformed, but are not transformed     */
  1354. /*  themselves.  Think of the casing as a fixed hollow structure inside      */
  1355. /*  which all the action happens.  A "casing" is only defined relative to    */
  1356. /*  a single transformation; each occurrence of a transformation will        */
  1357. /*  involve a different casing.                                              */
  1358. /*                                                                           */
  1359. /*****************************************************************************/
  1360. /*****************************************************************************/
  1361. /*                                                                           */
  1362. /*  flip()   Transform two triangles to two different triangles by flipping  */
  1363. /*           an edge counterclockwise within a quadrilateral.                */
  1364. /*                                                                           */
  1365. /*  Imagine the original triangles, abc and bad, oriented so that the        */
  1366. /*  shared edge ab lies in a horizontal plane, with the vertex b on the left */
  1367. /*  and the vertex a on the right.  The vertex c lies below the edge, and    */
  1368. /*  the vertex d lies above the edge.  The `flipedge' handle holds the edge  */
  1369. /*  ab of triangle abc, and is directed left, from vertex a to vertex b.     */
  1370. /*                                                                           */
  1371. /*  The triangles abc and bad are deleted and replaced by the triangles cdb  */
  1372. /*  and dca.  The triangles that represent abc and bad are NOT deallocated;  */
  1373. /*  they are reused for dca and cdb, respectively.  Hence, any handles that  */
  1374. /*  may have held the original triangles are still valid, although not       */
  1375. /*  directed as they were before.                                            */
  1376. /*                                                                           */
  1377. /*  Upon completion of this routine, the `flipedge' handle holds the edge    */
  1378. /*  dc of triangle dca, and is directed down, from vertex d to vertex c.     */
  1379. /*  (Hence, the two triangles have rotated counterclockwise.)                */
  1380. /*                                                                           */
  1381. /*  WARNING:  This transformation is geometrically valid only if the         */
  1382. /*  quadrilateral adbc is convex.  Furthermore, this transformation is       */
  1383. /*  valid only if there is not a subsegment between the triangles abc and    */
  1384. /*  bad.  This routine does not check either of these preconditions, and     */
  1385. /*  it is the responsibility of the calling routine to ensure that they are  */
  1386. /*  met.  If they are not, the streets shall be filled with wailing and      */
  1387. /*  gnashing of teeth.                                                       */
  1388. /*                                                                           */
  1389. /*****************************************************************************/
  1390. #ifdef ANSI_DECLARATORS
  1391. void flip(struct mesh *m, struct behavior *b, struct otri *flipedge)
  1392. #else /* not ANSI_DECLARATORS */
  1393. void flip(m, b, flipedge)
  1394. struct mesh *m;
  1395. struct behavior *b;
  1396. struct otri *flipedge;                    /* Handle for the triangle abc. */
  1397. #endif /* not ANSI_DECLARATORS */
  1398. {
  1399.   struct otri botleft, botright;
  1400.   struct otri topleft, topright;
  1401.   struct otri top;
  1402.   struct otri botlcasing, botrcasing;
  1403.   struct otri toplcasing, toprcasing;
  1404.   struct osub botlsubseg, botrsubseg;
  1405.   struct osub toplsubseg, toprsubseg;
  1406.   vertex leftvertex, rightvertex, botvertex;
  1407.   vertex farvertex;
  1408.   triangle ptr;                         /* Temporary variable used by sym(). */
  1409.   subseg sptr;                      /* Temporary variable used by tspivot(). */
  1410.   /* Identify the vertices of the quadrilateral. */
  1411.   org(*flipedge, rightvertex);
  1412.   dest(*flipedge, leftvertex);
  1413.   apex(*flipedge, botvertex);
  1414.   sym(*flipedge, top);
  1415. #ifdef SELF_CHECK
  1416.   if (top.tri == m->dummytri) {
  1417.     printf("Internal error in flip():  Attempt to flip on boundary.n");
  1418.     lnextself(*flipedge);
  1419.     return;
  1420.   }
  1421.   if (m->checksegments) {
  1422.     tspivot(*flipedge, toplsubseg);
  1423.     if (toplsubseg.ss != m->dummysub) {
  1424.       printf("Internal error in flip():  Attempt to flip a segment.n");
  1425.       lnextself(*flipedge);
  1426.       return;
  1427.     }
  1428.   }
  1429. #endif /* SELF_CHECK */
  1430.   apex(top, farvertex);
  1431.   /* Identify the casing of the quadrilateral. */
  1432.   lprev(top, topleft);
  1433.   sym(topleft, toplcasing);
  1434.   lnext(top, topright);
  1435.   sym(topright, toprcasing);
  1436.   lnext(*flipedge, botleft);
  1437.   sym(botleft, botlcasing);
  1438.   lprev(*flipedge, botright);
  1439.   sym(botright, botrcasing);
  1440.   /* Rotate the quadrilateral one-quarter turn counterclockwise. */
  1441.   bond(topleft, botlcasing);
  1442.   bond(botleft, botrcasing);
  1443.   bond(botright, toprcasing);
  1444.   bond(topright, toplcasing);
  1445.   if (m->checksegments) {
  1446.     /* Check for subsegments and rebond them to the quadrilateral. */
  1447.     tspivot(topleft, toplsubseg);
  1448.     tspivot(botleft, botlsubseg);
  1449.     tspivot(botright, botrsubseg);
  1450.     tspivot(topright, toprsubseg);
  1451.     if (toplsubseg.ss == m->dummysub) {
  1452.       tsdissolve(topright);
  1453.     } else {
  1454.       tsbond(topright, toplsubseg);
  1455.     }
  1456.     if (botlsubseg.ss == m->dummysub) {
  1457.       tsdissolve(topleft);
  1458.     } else {
  1459.       tsbond(topleft, botlsubseg);
  1460.     }
  1461.     if (botrsubseg.ss == m->dummysub) {
  1462.       tsdissolve(botleft);
  1463.     } else {
  1464.       tsbond(botleft, botrsubseg);
  1465.     }
  1466.     if (toprsubseg.ss == m->dummysub) {
  1467.       tsdissolve(botright);
  1468.     } else {
  1469.       tsbond(botright, toprsubseg);
  1470.     }
  1471.   }
  1472.   /* New vertex assignments for the rotated quadrilateral. */
  1473.   setorg(*flipedge, farvertex);
  1474.   setdest(*flipedge, botvertex);
  1475.   setapex(*flipedge, rightvertex);
  1476.   setorg(top, botvertex);
  1477.   setdest(top, farvertex);
  1478.   setapex(top, leftvertex);
  1479.   if (b->verbose > 2) {
  1480.     printf("  Edge flip results in left ");
  1481.     printtriangle(m, b, &top);
  1482.     printf("  and right ");
  1483.     printtriangle(m, b, flipedge);
  1484.   }
  1485. }
  1486. /*****************************************************************************/
  1487. /*                                                                           */
  1488. /*  unflip()   Transform two triangles to two different triangles by         */
  1489. /*             flipping an edge clockwise within a quadrilateral.  Reverses  */
  1490. /*             the flip() operation so that the data structures representing */
  1491. /*             the triangles are back where they were before the flip().     */
  1492. /*                                                                           */
  1493. /*  Imagine the original triangles, abc and bad, oriented so that the        */
  1494. /*  shared edge ab lies in a horizontal plane, with the vertex b on the left */
  1495. /*  and the vertex a on the right.  The vertex c lies below the edge, and    */
  1496. /*  the vertex d lies above the edge.  The `flipedge' handle holds the edge  */
  1497. /*  ab of triangle abc, and is directed left, from vertex a to vertex b.     */
  1498. /*                                                                           */
  1499. /*  The triangles abc and bad are deleted and replaced by the triangles cdb  */
  1500. /*  and dca.  The triangles that represent abc and bad are NOT deallocated;  */
  1501. /*  they are reused for cdb and dca, respectively.  Hence, any handles that  */
  1502. /*  may have held the original triangles are still valid, although not       */
  1503. /*  directed as they were before.                                            */
  1504. /*                                                                           */
  1505. /*  Upon completion of this routine, the `flipedge' handle holds the edge    */
  1506. /*  cd of triangle cdb, and is directed up, from vertex c to vertex d.       */
  1507. /*  (Hence, the two triangles have rotated clockwise.)                       */
  1508. /*                                                                           */
  1509. /*  WARNING:  This transformation is geometrically valid only if the         */
  1510. /*  quadrilateral adbc is convex.  Furthermore, this transformation is       */
  1511. /*  valid only if there is not a subsegment between the triangles abc and    */
  1512. /*  bad.  This routine does not check either of these preconditions, and     */
  1513. /*  it is the responsibility of the calling routine to ensure that they are  */
  1514. /*  met.  If they are not, the streets shall be filled with wailing and      */
  1515. /*  gnashing of teeth.                                                       */
  1516. /*                                                                           */
  1517. /*****************************************************************************/
  1518. #ifdef ANSI_DECLARATORS
  1519. void unflip(struct mesh *m, struct behavior *b, struct otri *flipedge)
  1520. #else /* not ANSI_DECLARATORS */
  1521. void unflip(m, b, flipedge)
  1522. struct mesh *m;
  1523. struct behavior *b;
  1524. struct otri *flipedge;                    /* Handle for the triangle abc. */
  1525. #endif /* not ANSI_DECLARATORS */
  1526. {
  1527.   struct otri botleft, botright;
  1528.   struct otri topleft, topright;
  1529.   struct otri top;
  1530.   struct otri botlcasing, botrcasing;
  1531.   struct otri toplcasing, toprcasing;
  1532.   struct osub botlsubseg, botrsubseg;
  1533.   struct osub toplsubseg, toprsubseg;
  1534.   vertex leftvertex, rightvertex, botvertex;
  1535.   vertex farvertex;
  1536.   triangle ptr;                         /* Temporary variable used by sym(). */
  1537.   subseg sptr;                      /* Temporary variable used by tspivot(). */
  1538.   /* Identify the vertices of the quadrilateral. */
  1539.   org(*flipedge, rightvertex);
  1540.   dest(*flipedge, leftvertex);
  1541.   apex(*flipedge, botvertex);
  1542.   sym(*flipedge, top);
  1543. #ifdef SELF_CHECK
  1544.   if (top.tri == m->dummytri) {
  1545.     printf("Internal error in unflip():  Attempt to flip on boundary.n");
  1546.     lnextself(*flipedge);
  1547.     return;
  1548.   }
  1549.   if (m->checksegments) {
  1550.     tspivot(*flipedge, toplsubseg);
  1551.     if (toplsubseg.ss != m->dummysub) {
  1552.       printf("Internal error in unflip():  Attempt to flip a subsegment.n");
  1553.       lnextself(*flipedge);
  1554.       return;
  1555.     }
  1556.   }
  1557. #endif /* SELF_CHECK */
  1558.   apex(top, farvertex);
  1559.   /* Identify the casing of the quadrilateral. */
  1560.   lprev(top, topleft);
  1561.   sym(topleft, toplcasing);
  1562.   lnext(top, topright);
  1563.   sym(topright, toprcasing);
  1564.   lnext(*flipedge, botleft);
  1565.   sym(botleft, botlcasing);
  1566.   lprev(*flipedge, botright);
  1567.   sym(botright, botrcasing);
  1568.   /* Rotate the quadrilateral one-quarter turn clockwise. */
  1569.   bond(topleft, toprcasing);
  1570.   bond(botleft, toplcasing);
  1571.   bond(botright, botlcasing);
  1572.   bond(topright, botrcasing);
  1573.   if (m->checksegments) {
  1574.     /* Check for subsegments and rebond them to the quadrilateral. */
  1575.     tspivot(topleft, toplsubseg);
  1576.     tspivot(botleft, botlsubseg);
  1577.     tspivot(botright, botrsubseg);
  1578.     tspivot(topright, toprsubseg);
  1579.     if (toplsubseg.ss == m->dummysub) {
  1580.       tsdissolve(botleft);
  1581.     } else {
  1582.       tsbond(botleft, toplsubseg);
  1583.     }
  1584.     if (botlsubseg.ss == m->dummysub) {
  1585.       tsdissolve(botright);
  1586.     } else {
  1587.       tsbond(botright, botlsubseg);
  1588.     }
  1589.     if (botrsubseg.ss == m->dummysub) {
  1590.       tsdissolve(topright);
  1591.     } else {
  1592.       tsbond(topright, botrsubseg);
  1593.     }
  1594.     if (toprsubseg.ss == m->dummysub) {
  1595.       tsdissolve(topleft);
  1596.     } else {
  1597.       tsbond(topleft, toprsubseg);
  1598.     }
  1599.   }
  1600.   /* New vertex assignments for the rotated quadrilateral. */
  1601.   setorg(*flipedge, botvertex);
  1602.   setdest(*flipedge, farvertex);
  1603.   setapex(*flipedge, leftvertex);
  1604.   setorg(top, farvertex);
  1605.   setdest(top, botvertex);
  1606.   setapex(top, rightvertex);
  1607.   if (b->verbose > 2) {
  1608.     printf("  Edge unflip results in left ");
  1609.     printtriangle(m, b, flipedge);
  1610.     printf("  and right ");
  1611.     printtriangle(m, b, &top);
  1612.   }
  1613. }
  1614. /*****************************************************************************/
  1615. /*                                                                           */
  1616. /*  insertvertex()   Insert a vertex into a Delaunay triangulation,          */
  1617. /*                   performing flips as necessary to maintain the Delaunay  */
  1618. /*                   property.                                               */
  1619. /*                                                                           */
  1620. /*  The point `insertvertex' is located.  If `searchtri.tri' is not NULL,    */
  1621. /*  the search for the containing triangle begins from `searchtri'.  If      */
  1622. /*  `searchtri.tri' is NULL, a full point location procedure is called.      */
  1623. /*  If `insertvertex' is found inside a triangle, the triangle is split into */
  1624. /*  three; if `insertvertex' lies on an edge, the edge is split in two,      */
  1625. /*  thereby splitting the two adjacent triangles into four.  Edge flips are  */
  1626. /*  used to restore the Delaunay property.  If `insertvertex' lies on an     */
  1627. /*  existing vertex, no action is taken, and the value DUPLICATEVERTEX is    */
  1628. /*  returned.  On return, `searchtri' is set to a handle whose origin is the */
  1629. /*  existing vertex.                                                         */
  1630. /*                                                                           */
  1631. /*  Normally, the parameter `splitseg' is set to NULL, implying that no      */
  1632. /*  subsegment should be split.  In this case, if `insertvertex' is found to */
  1633. /*  lie on a segment, no action is taken, and the value VIOLATINGVERTEX is   */
  1634. /*  returned.  On return, `searchtri' is set to a handle whose primary edge  */
  1635. /*  is the violated subsegment.                                              */
  1636. /*                                                                           */
  1637. /*  If the calling routine wishes to split a subsegment by inserting a       */
  1638. /*  vertex in it, the parameter `splitseg' should be that subsegment.  In    */
  1639. /*  this case, `searchtri' MUST be the triangle handle reached by pivoting   */
  1640. /*  from that subsegment; no point location is done.                         */
  1641. /*                                                                           */
  1642. /*  `segmentflaws' and `triflaws' are flags that indicate whether or not     */
  1643. /*  there should be checks for the creation of encroached subsegments or bad */
  1644. /*  quality triangles.  If a newly inserted vertex encroaches upon           */
  1645. /*  subsegments, these subsegments are added to the list of subsegments to   */
  1646. /*  be split if `segmentflaws' is set.  If bad triangles are created, these  */
  1647. /*  are added to the queue if `triflaws' is set.                             */
  1648. /*                                                                           */
  1649. /*  If a duplicate vertex or violated segment does not prevent the vertex    */
  1650. /*  from being inserted, the return value will be ENCROACHINGVERTEX if the   */
  1651. /*  vertex encroaches upon a subsegment (and checking is enabled), or        */
  1652. /*  SUCCESSFULVERTEX otherwise.  In either case, `searchtri' is set to a     */
  1653. /*  handle whose origin is the newly inserted vertex.                        */
  1654. /*                                                                           */
  1655. /*  insertvertex() does not use flip() for reasons of speed; some            */
  1656. /*  information can be reused from edge flip to edge flip, like the          */
  1657. /*  locations of subsegments.                                                */
  1658. /*                                                                           */
  1659. /*****************************************************************************/
  1660. #ifdef ANSI_DECLARATORS
  1661. enum insertvertexresult insertvertex(struct mesh *m, struct behavior *b,
  1662.                                      vertex newvertex, struct otri *searchtri,
  1663.                                      struct osub *splitseg,
  1664.                                      int segmentflaws, int triflaws)
  1665. #else /* not ANSI_DECLARATORS */
  1666. enum insertvertexresult insertvertex(m, b, newvertex, searchtri, splitseg,
  1667.                                      segmentflaws, triflaws)
  1668. struct mesh *m;
  1669. struct behavior *b;
  1670. vertex newvertex;
  1671. struct otri *searchtri;
  1672. struct osub *splitseg;
  1673. int segmentflaws;
  1674. int triflaws;
  1675. #endif /* not ANSI_DECLARATORS */
  1676. {
  1677.   struct otri horiz;
  1678.   struct otri top;
  1679.   struct otri botleft, botright;
  1680.   struct otri topleft, topright;
  1681.   struct otri newbotleft, newbotright;
  1682.   struct otri newtopright;
  1683.   struct otri botlcasing, botrcasing;
  1684.   struct otri toplcasing, toprcasing;
  1685.   struct otri testtri;
  1686.   struct osub botlsubseg, botrsubseg;
  1687.   struct osub toplsubseg, toprsubseg;
  1688.   struct osub brokensubseg;
  1689.   struct osub checksubseg;
  1690.   struct osub rightsubseg;
  1691.   struct osub newsubseg;
  1692.   struct badsubseg *encroached;
  1693.   struct flipstacker *newflip;
  1694.   vertex first;
  1695.   vertex leftvertex, rightvertex, botvertex, topvertex, farvertex;
  1696.   vertex segmentorg, segmentdest;
  1697.   REAL attrib;
  1698.   REAL area;
  1699.   enum insertvertexresult success;
  1700.   enum locateresult intersect;
  1701.   int doflip;
  1702.   int mirrorflag;
  1703.   int enq;
  1704.   int i;
  1705.   triangle ptr;                         /* Temporary variable used by sym(). */
  1706.   subseg sptr;         /* Temporary variable used by spivot() and tspivot(). */
  1707.   if (b->verbose > 1) {
  1708.     printf("  Inserting (%.12g, %.12g).n", newvertex[0], newvertex[1]);
  1709.   }
  1710.   if (splitseg == (struct osub *) NULL) {
  1711.     /* Find the location of the vertex to be inserted.  Check if a good */
  1712.     /*   starting triangle has already been provided by the caller.     */
  1713.     if (searchtri->tri == m->dummytri) {
  1714.       /* Find a boundary triangle. */
  1715.       horiz.tri = m->dummytri;
  1716.       horiz.orient = 0;
  1717.       symself(horiz);
  1718.       /* Search for a triangle containing `newvertex'. */
  1719.       intersect = locate(m, b, newvertex, &horiz);
  1720.     } else {
  1721.       /* Start searching from the triangle provided by the caller. */
  1722.       otricopy(*searchtri, horiz);
  1723.       intersect = preciselocate(m, b, newvertex, &horiz, 1);
  1724.     }
  1725.   } else {
  1726.     /* The calling routine provides the subsegment in which */
  1727.     /*   the vertex is inserted.                             */
  1728.     otricopy(*searchtri, horiz);
  1729.     intersect = ONEDGE;
  1730.   }
  1731.   if (intersect == ONVERTEX) {
  1732.     /* There's already a vertex there.  Return in `searchtri' a triangle */
  1733.     /*   whose origin is the existing vertex.                            */
  1734.     otricopy(horiz, *searchtri);
  1735.     otricopy(horiz, m->recenttri);
  1736.     return DUPLICATEVERTEX;
  1737.   }
  1738.   if ((intersect == ONEDGE) || (intersect == OUTSIDE)) {
  1739.     /* The vertex falls on an edge or boundary. */
  1740.     if (m->checksegments && (splitseg == (struct osub *) NULL)) {
  1741.       /* Check whether the vertex falls on a subsegment. */
  1742.       tspivot(horiz, brokensubseg);
  1743.       if (brokensubseg.ss != m->dummysub) {
  1744.         /* The vertex falls on a subsegment, and hence will not be inserted. */
  1745.         if (segmentflaws) {
  1746.           enq = b->nobisect != 2;
  1747.           if (enq && (b->nobisect == 1)) {
  1748.             /* This subsegment may be split only if it is an */
  1749.             /*   internal boundary.                          */
  1750.             sym(horiz, testtri);
  1751.             enq = testtri.tri != m->dummytri;
  1752.           }
  1753.           if (enq) {
  1754.             /* Add the subsegment to the list of encroached subsegments. */
  1755.             encroached = (struct badsubseg *) poolalloc(&m->badsubsegs);
  1756.             encroached->encsubseg = sencode(brokensubseg);
  1757.             sorg(brokensubseg, encroached->subsegorg);
  1758.             sdest(brokensubseg, encroached->subsegdest);
  1759.             if (b->verbose > 2) {
  1760.               printf(
  1761.           "  Queueing encroached subsegment (%.12g, %.12g) (%.12g, %.12g).n",
  1762.                      encroached->subsegorg[0], encroached->subsegorg[1],
  1763.                      encroached->subsegdest[0], encroached->subsegdest[1]);
  1764.             }
  1765.           }
  1766.         }
  1767.         /* Return a handle whose primary edge contains the vertex, */
  1768.         /*   which has not been inserted.                          */
  1769.         otricopy(horiz, *searchtri);
  1770.         otricopy(horiz, m->recenttri);
  1771.         return VIOLATINGVERTEX;
  1772.       }
  1773.     }
  1774.     /* Insert the vertex on an edge, dividing one triangle into two (if */
  1775.     /*   the edge lies on a boundary) or two triangles into four.       */
  1776.     lprev(horiz, botright);
  1777.     sym(botright, botrcasing);
  1778.     sym(horiz, topright);
  1779.     /* Is there a second triangle?  (Or does this edge lie on a boundary?) */
  1780.     mirrorflag = topright.tri != m->dummytri;
  1781.     if (mirrorflag) {
  1782.       lnextself(topright);
  1783.       sym(topright, toprcasing);
  1784.       maketriangle(m, b, &newtopright);
  1785.     } else {
  1786.       /* Splitting a boundary edge increases the number of boundary edges. */
  1787.       m->hullsize++;
  1788.     }
  1789.     maketriangle(m, b, &newbotright);
  1790.     /* Set the vertices of changed and new triangles. */
  1791.     org(horiz, rightvertex);
  1792.     dest(horiz, leftvertex);
  1793.     apex(horiz, botvertex);
  1794.     setorg(newbotright, botvertex);
  1795.     setdest(newbotright, rightvertex);
  1796.     setapex(newbotright, newvertex);
  1797.     setorg(horiz, newvertex);
  1798.     for (i = 0; i < m->eextras; i++) {
  1799.       /* Set the element attributes of a new triangle. */
  1800.       setelemattribute(newbotright, i, elemattribute(botright, i));
  1801.     }
  1802.     if (b->vararea) {
  1803.       /* Set the area constraint of a new triangle. */
  1804.       setareabound(newbotright, areabound(botright));
  1805.     }
  1806.     if (mirrorflag) {
  1807.       dest(topright, topvertex);
  1808.       setorg(newtopright, rightvertex);
  1809.       setdest(newtopright, topvertex);
  1810.       setapex(newtopright, newvertex);
  1811.       setorg(topright, newvertex);
  1812.       for (i = 0; i < m->eextras; i++) {
  1813.         /* Set the element attributes of another new triangle. */
  1814.         setelemattribute(newtopright, i, elemattribute(topright, i));
  1815.       }
  1816.       if (b->vararea) {
  1817.         /* Set the area constraint of another new triangle. */
  1818.         setareabound(newtopright, areabound(topright));
  1819.       }
  1820.     }
  1821.     /* There may be subsegments that need to be bonded */
  1822.     /*   to the new triangle(s).                       */
  1823.     if (m->checksegments) {
  1824.       tspivot(botright, botrsubseg);
  1825.       if (botrsubseg.ss != m->dummysub) {
  1826.         tsdissolve(botright);
  1827.         tsbond(newbotright, botrsubseg);
  1828.       }
  1829.       if (mirrorflag) {
  1830.         tspivot(topright, toprsubseg);
  1831.         if (toprsubseg.ss != m->dummysub) {
  1832.           tsdissolve(topright);
  1833.           tsbond(newtopright, toprsubseg);
  1834.         }
  1835.       }
  1836.     }
  1837.     /* Bond the new triangle(s) to the surrounding triangles. */
  1838.     bond(newbotright, botrcasing);
  1839.     lprevself(newbotright);
  1840.     bond(newbotright, botright);
  1841.     lprevself(newbotright);
  1842.     if (mirrorflag) {
  1843.       bond(newtopright, toprcasing);
  1844.       lnextself(newtopright);
  1845.       bond(newtopright, topright);
  1846.       lnextself(newtopright);
  1847.       bond(newtopright, newbotright);
  1848.     }
  1849.     if (splitseg != (struct osub *) NULL) {
  1850.       /* Split the subsegment into two. */
  1851.       setsdest(*splitseg, newvertex);
  1852.       segorg(*splitseg, segmentorg);
  1853.       segdest(*splitseg, segmentdest);
  1854.       ssymself(*splitseg);
  1855.       spivot(*splitseg, rightsubseg);
  1856.       insertsubseg(m, b, &newbotright, mark(*splitseg));
  1857.       tspivot(newbotright, newsubseg);
  1858.       setsegorg(newsubseg, segmentorg);
  1859.       setsegdest(newsubseg, segmentdest);
  1860.       sbond(*splitseg, newsubseg);
  1861.       ssymself(newsubseg);
  1862.       sbond(newsubseg, rightsubseg);
  1863.       ssymself(*splitseg);
  1864.       /* Transfer the subsegment's boundary marker to the vertex */
  1865.       /*   if required.                                          */
  1866.       if (vertexmark(newvertex) == 0) {
  1867.         setvertexmark(newvertex, mark(*splitseg));
  1868.       }
  1869.     }
  1870.     if (m->checkquality) {
  1871.       poolrestart(&m->flipstackers);
  1872.       m->lastflip = (struct flipstacker *) poolalloc(&m->flipstackers);
  1873.       m->lastflip->flippedtri = encode(horiz);
  1874.       m->lastflip->prevflip = (struct flipstacker *) &insertvertex;
  1875.     }
  1876. #ifdef SELF_CHECK
  1877.     if (counterclockwise(m, b, rightvertex, leftvertex, botvertex) < 0.0) {
  1878.       printf("Internal error in insertvertex():n");
  1879.       printf(
  1880.             "  Clockwise triangle prior to edge vertex insertion (bottom).n");
  1881.     }
  1882.     if (mirrorflag) {
  1883.       if (counterclockwise(m, b, leftvertex, rightvertex, topvertex) < 0.0) {
  1884.         printf("Internal error in insertvertex():n");
  1885.         printf("  Clockwise triangle prior to edge vertex insertion (top).n");
  1886.       }
  1887.       if (counterclockwise(m, b, rightvertex, topvertex, newvertex) < 0.0) {
  1888.         printf("Internal error in insertvertex():n");
  1889.         printf(
  1890.             "  Clockwise triangle after edge vertex insertion (top right).n");
  1891.       }
  1892.       if (counterclockwise(m, b, topvertex, leftvertex, newvertex) < 0.0) {
  1893.         printf("Internal error in insertvertex():n");
  1894.         printf(
  1895.             "  Clockwise triangle after edge vertex insertion (top left).n");
  1896.       }
  1897.     }
  1898.     if (counterclockwise(m, b, leftvertex, botvertex, newvertex) < 0.0) {
  1899.       printf("Internal error in insertvertex():n");
  1900.       printf(
  1901.           "  Clockwise triangle after edge vertex insertion (bottom left).n");
  1902.     }
  1903.     if (counterclockwise(m, b, botvertex, rightvertex, newvertex) < 0.0) {
  1904.       printf("Internal error in insertvertex():n");
  1905.       printf(
  1906.         "  Clockwise triangle after edge vertex insertion (bottom right).n");
  1907.     }
  1908. #endif /* SELF_CHECK */
  1909.     if (b->verbose > 2) {
  1910.       printf("  Updating bottom left ");
  1911.       printtriangle(m, b, &botright);
  1912.       if (mirrorflag) {
  1913.         printf("  Updating top left ");
  1914.         printtriangle(m, b, &topright);
  1915.         printf("  Creating top right ");
  1916.         printtriangle(m, b, &newtopright);
  1917.       }
  1918.       printf("  Creating bottom right ");
  1919.       printtriangle(m, b, &newbotright);
  1920.     }
  1921.     /* Position `horiz' on the first edge to check for */
  1922.     /*   the Delaunay property.                        */
  1923.     lnextself(horiz);
  1924.   } else {
  1925.     /* Insert the vertex in a triangle, splitting it into three. */
  1926.     lnext(horiz, botleft);
  1927.     lprev(horiz, botright);
  1928.     sym(botleft, botlcasing);
  1929.     sym(botright, botrcasing);
  1930.     maketriangle(m, b, &newbotleft);
  1931.     maketriangle(m, b, &newbotright);
  1932.     /* Set the vertices of changed and new triangles. */
  1933.     org(horiz, rightvertex);
  1934.     dest(horiz, leftvertex);
  1935.     apex(horiz, botvertex);
  1936.     setorg(newbotleft, leftvertex);
  1937.     setdest(newbotleft, botvertex);
  1938.     setapex(newbotleft, newvertex);
  1939.     setorg(newbotright, botvertex);
  1940.     setdest(newbotright, rightvertex);
  1941.     setapex(newbotright, newvertex);
  1942.     setapex(horiz, newvertex);
  1943.     for (i = 0; i < m->eextras; i++) {
  1944.       /* Set the element attributes of the new triangles. */
  1945.       attrib = elemattribute(horiz, i);
  1946.       setelemattribute(newbotleft, i, attrib);
  1947.       setelemattribute(newbotright, i, attrib);
  1948.     }
  1949.     if (b->vararea) {
  1950.       /* Set the area constraint of the new triangles. */
  1951.       area = areabound(horiz);
  1952.       setareabound(newbotleft, area);
  1953.       setareabound(newbotright, area);
  1954.     }
  1955.     /* There may be subsegments that need to be bonded */
  1956.     /*   to the new triangles.                         */
  1957.     if (m->checksegments) {
  1958.       tspivot(botleft, botlsubseg);
  1959.       if (botlsubseg.ss != m->dummysub) {
  1960.         tsdissolve(botleft);
  1961.         tsbond(newbotleft, botlsubseg);
  1962.       }
  1963.       tspivot(botright, botrsubseg);
  1964.       if (botrsubseg.ss != m->dummysub) {
  1965.         tsdissolve(botright);
  1966.         tsbond(newbotright, botrsubseg);
  1967.       }
  1968.     }
  1969.     /* Bond the new triangles to the surrounding triangles. */
  1970.     bond(newbotleft, botlcasing);
  1971.     bond(newbotright, botrcasing);
  1972.     lnextself(newbotleft);
  1973.     lprevself(newbotright);
  1974.     bond(newbotleft, newbotright);
  1975.     lnextself(newbotleft);
  1976.     bond(botleft, newbotleft);
  1977.     lprevself(newbotright);
  1978.     bond(botright, newbotright);
  1979.     if (m->checkquality) {
  1980.       poolrestart(&m->flipstackers);
  1981.       m->lastflip = (struct flipstacker *) poolalloc(&m->flipstackers);
  1982.       m->lastflip->flippedtri = encode(horiz);
  1983.       m->lastflip->prevflip = (struct flipstacker *) NULL;
  1984.     }
  1985. #ifdef SELF_CHECK
  1986.     if (counterclockwise(m, b, rightvertex, leftvertex, botvertex) < 0.0) {
  1987.       printf("Internal error in insertvertex():n");
  1988.       printf("  Clockwise triangle prior to vertex insertion.n");
  1989.     }
  1990.     if (counterclockwise(m, b, rightvertex, leftvertex, newvertex) < 0.0) {
  1991.       printf("Internal error in insertvertex():n");
  1992.       printf("  Clockwise triangle after vertex insertion (top).n");
  1993.     }
  1994.     if (counterclockwise(m, b, leftvertex, botvertex, newvertex) < 0.0) {
  1995.       printf("Internal error in insertvertex():n");
  1996.       printf("  Clockwise triangle after vertex insertion (left).n");
  1997.     }
  1998.     if (counterclockwise(m, b, botvertex, rightvertex, newvertex) < 0.0) {
  1999.       printf("Internal error in insertvertex():n");
  2000.       printf("  Clockwise triangle after vertex insertion (right).n");
  2001.     }
  2002. #endif /* SELF_CHECK */
  2003.     if (b->verbose > 2) {
  2004.       printf("  Updating top ");
  2005.       printtriangle(m, b, &horiz);
  2006.       printf("  Creating left ");
  2007.       printtriangle(m, b, &newbotleft);
  2008.       printf("  Creating right ");
  2009.       printtriangle(m, b, &newbotright);
  2010.     }
  2011.   }
  2012.   /* The insertion is successful by default, unless an encroached */
  2013.   /*   subsegment is found.                                       */
  2014.   success = SUCCESSFULVERTEX;
  2015.   /* Circle around the newly inserted vertex, checking each edge opposite */
  2016.   /*   it for the Delaunay property.  Non-Delaunay edges are flipped.     */
  2017.   /*   `horiz' is always the edge being checked.  `first' marks where to  */
  2018.   /*   stop circling.                                                     */
  2019.   org(horiz, first);
  2020.   rightvertex = first;
  2021.   dest(horiz, leftvertex);
  2022.   /* Circle until finished. */
  2023.   while (1) {
  2024.     /* By default, the edge will be flipped. */
  2025.     doflip = 1;
  2026.     if (m->checksegments) {
  2027.       /* Check for a subsegment, which cannot be flipped. */
  2028.       tspivot(horiz, checksubseg);
  2029.       if (checksubseg.ss != m->dummysub) {
  2030.         /* The edge is a subsegment and cannot be flipped. */
  2031.         doflip = 0;
  2032. #ifndef CDT_ONLY
  2033.         if (segmentflaws) {
  2034.           /* Does the new vertex encroach upon this subsegment? */
  2035.           if (checkseg4encroach(m, b, &checksubseg)) {
  2036.             success = ENCROACHINGVERTEX;
  2037.           }
  2038.         }
  2039. #endif /* not CDT_ONLY */
  2040.       }
  2041.     }
  2042.     if (doflip) {
  2043.       /* Check if the edge is a boundary edge. */
  2044.       sym(horiz, top);
  2045.       if (top.tri == m->dummytri) {
  2046.         /* The edge is a boundary edge and cannot be flipped. */
  2047.         doflip = 0;
  2048.       } else {
  2049.         /* Find the vertex on the other side of the edge. */
  2050.         apex(top, farvertex);
  2051.         /* In the incremental Delaunay triangulation algorithm, any of      */
  2052.         /*   `leftvertex', `rightvertex', and `farvertex' could be vertices */
  2053.         /*   of the triangular bounding box.  These vertices must be        */
  2054.         /*   treated as if they are infinitely distant, even though their   */
  2055.         /*   "coordinates" are not.                                         */
  2056.         if ((leftvertex == m->infvertex1) || (leftvertex == m->infvertex2) ||
  2057.             (leftvertex == m->infvertex3)) {
  2058.           /* `leftvertex' is infinitely distant.  Check the convexity of  */
  2059.           /*   the boundary of the triangulation.  'farvertex' might be   */
  2060.           /*   infinite as well, but trust me, this same condition should */
  2061.           /*   be applied.                                                */
  2062.           doflip = counterclockwise(m, b, newvertex, rightvertex, farvertex)
  2063.                    > 0.0;
  2064.         } else if ((rightvertex == m->infvertex1) ||
  2065.                    (rightvertex == m->infvertex2) ||
  2066.                    (rightvertex == m->infvertex3)) {
  2067.           /* `rightvertex' is infinitely distant.  Check the convexity of */
  2068.           /*   the boundary of the triangulation.  'farvertex' might be   */
  2069.           /*   infinite as well, but trust me, this same condition should */
  2070.           /*   be applied.                                                */
  2071.           doflip = counterclockwise(m, b, farvertex, leftvertex, newvertex)
  2072.                    > 0.0;
  2073.         } else if ((farvertex == m->infvertex1) ||
  2074.                    (farvertex == m->infvertex2) ||
  2075.                    (farvertex == m->infvertex3)) {
  2076.           /* `farvertex' is infinitely distant and cannot be inside */
  2077.           /*   the circumcircle of the triangle `horiz'.            */
  2078.           doflip = 0;
  2079.         } else {
  2080.           /* Test whether the edge is locally Delaunay. */
  2081.           doflip = incircle(m, b, leftvertex, newvertex, rightvertex,
  2082.                             farvertex) > 0.0;
  2083.         }
  2084.         if (doflip) {
  2085.           /* We made it!  Flip the edge `horiz' by rotating its containing */
  2086.           /*   quadrilateral (the two triangles adjacent to `horiz').      */
  2087.           /* Identify the casing of the quadrilateral. */
  2088.           lprev(top, topleft);
  2089.           sym(topleft, toplcasing);
  2090.           lnext(top, topright);
  2091.           sym(topright, toprcasing);
  2092.           lnext(horiz, botleft);
  2093.           sym(botleft, botlcasing);
  2094.           lprev(horiz, botright);
  2095.           sym(botright, botrcasing);
  2096.           /* Rotate the quadrilateral one-quarter turn counterclockwise. */
  2097.           bond(topleft, botlcasing);
  2098.           bond(botleft, botrcasing);
  2099.           bond(botright, toprcasing);
  2100.           bond(topright, toplcasing);
  2101.           if (m->checksegments) {
  2102.             /* Check for subsegments and rebond them to the quadrilateral. */
  2103.             tspivot(topleft, toplsubseg);
  2104.             tspivot(botleft, botlsubseg);
  2105.             tspivot(botright, botrsubseg);
  2106.             tspivot(topright, toprsubseg);
  2107.             if (toplsubseg.ss == m->dummysub) {
  2108.               tsdissolve(topright);
  2109.             } else {
  2110.               tsbond(topright, toplsubseg);
  2111.             }
  2112.             if (botlsubseg.ss == m->dummysub) {
  2113.               tsdissolve(topleft);
  2114.             } else {
  2115.               tsbond(topleft, botlsubseg);
  2116.             }
  2117.             if (botrsubseg.ss == m->dummysub) {
  2118.               tsdissolve(botleft);
  2119.             } else {
  2120.               tsbond(botleft, botrsubseg);
  2121.             }
  2122.             if (toprsubseg.ss == m->dummysub) {
  2123.               tsdissolve(botright);
  2124.             } else {
  2125.               tsbond(botright, toprsubseg);
  2126.             }
  2127.           }
  2128.           /* New vertex assignments for the rotated quadrilateral. */
  2129.           setorg(horiz, farvertex);
  2130.           setdest(horiz, newvertex);
  2131.           setapex(horiz, rightvertex);
  2132.           setorg(top, newvertex);
  2133.           setdest(top, farvertex);
  2134.           setapex(top, leftvertex);
  2135.           for (i = 0; i < m->eextras; i++) {
  2136.             /* Take the average of the two triangles' attributes. */
  2137.             attrib = 0.5 * (elemattribute(top, i) + elemattribute(horiz, i));
  2138.             setelemattribute(top, i, attrib);
  2139.             setelemattribute(horiz, i, attrib);
  2140.           }
  2141.           if (b->vararea) {
  2142.             if ((areabound(top) <= 0.0) || (areabound(horiz) <= 0.0)) {
  2143.               area = -1.0;
  2144.             } else {
  2145.               /* Take the average of the two triangles' area constraints.    */
  2146.               /*   This prevents small area constraints from migrating a     */
  2147.               /*   long, long way from their original location due to flips. */
  2148.               area = 0.5 * (areabound(top) + areabound(horiz));
  2149.             }
  2150.             setareabound(top, area);
  2151.             setareabound(horiz, area);
  2152.           }
  2153.           if (m->checkquality) {
  2154.             newflip = (struct flipstacker *) poolalloc(&m->flipstackers);
  2155.             newflip->flippedtri = encode(horiz);
  2156.             newflip->prevflip = m->lastflip;
  2157.             m->lastflip = newflip;
  2158.           }
  2159. #ifdef SELF_CHECK
  2160.           if (newvertex != (vertex) NULL) {
  2161.             if (counterclockwise(m, b, leftvertex, newvertex, rightvertex) <
  2162.                 0.0) {
  2163.               printf("Internal error in insertvertex():n");
  2164.               printf("  Clockwise triangle prior to edge flip (bottom).n");
  2165.             }
  2166.             /* The following test has been removed because constrainededge() */
  2167.             /*   sometimes generates inverted triangles that insertvertex()  */
  2168.             /*   removes.                                                    */
  2169. /*
  2170.             if (counterclockwise(m, b, rightvertex, farvertex, leftvertex) <
  2171.                 0.0) {
  2172.               printf("Internal error in insertvertex():n");
  2173.               printf("  Clockwise triangle prior to edge flip (top).n");
  2174.             }
  2175. */
  2176.             if (counterclockwise(m, b, farvertex, leftvertex, newvertex) <
  2177.                 0.0) {
  2178.               printf("Internal error in insertvertex():n");
  2179.               printf("  Clockwise triangle after edge flip (left).n");
  2180.             }
  2181.             if (counterclockwise(m, b, newvertex, rightvertex, farvertex) <
  2182.                 0.0) {
  2183.               printf("Internal error in insertvertex():n");
  2184.               printf("  Clockwise triangle after edge flip (right).n");
  2185.             }
  2186.           }
  2187. #endif /* SELF_CHECK */
  2188.           if (b->verbose > 2) {
  2189.             printf("  Edge flip results in left ");
  2190.             lnextself(topleft);
  2191.             printtriangle(m, b, &topleft);
  2192.             printf("  and right ");
  2193.             printtriangle(m, b, &horiz);
  2194.           }
  2195.           /* On the next iterations, consider the two edges that were  */
  2196.           /*   exposed (this is, are now visible to the newly inserted */
  2197.           /*   vertex) by the edge flip.                               */
  2198.           lprevself(horiz);
  2199.           leftvertex = farvertex;
  2200.         }
  2201.       }
  2202.     }
  2203.     if (!doflip) {
  2204.       /* The handle `horiz' is accepted as locally Delaunay. */
  2205. #ifndef CDT_ONLY
  2206.       if (triflaws) {
  2207.         /* Check the triangle `horiz' for quality. */
  2208.         testtriangle(m, b, &horiz);
  2209.       }
  2210. #endif /* not CDT_ONLY */
  2211.       /* Look for the next edge around the newly inserted vertex. */
  2212.       lnextself(horiz);
  2213.       sym(horiz, testtri);
  2214.       /* Check for finishing a complete revolution about the new vertex, or */
  2215.       /*   falling outside  of the triangulation.  The latter will happen   */
  2216.       /*   when a vertex is inserted at a boundary.                         */
  2217.       if ((leftvertex == first) || (testtri.tri == m->dummytri)) {
  2218.         /* We're done.  Return a triangle whose origin is the new vertex. */
  2219.         lnext(horiz, *searchtri);
  2220.         lnext(horiz, m->recenttri);
  2221.         return success;
  2222.       }
  2223.       /* Finish finding the next edge around the newly inserted vertex. */
  2224.       lnext(testtri, horiz);
  2225.       rightvertex = leftvertex;
  2226.       dest(horiz, leftvertex);
  2227.     }
  2228.   }
  2229. }
  2230. /*****************************************************************************/
  2231. /*                                                                           */
  2232. /*  triangulatepolygon()   Find the Delaunay triangulation of a polygon that */
  2233. /*                         has a certain "nice" shape.  This includes the    */
  2234. /*                         polygons that result from deletion of a vertex or */
  2235. /*                         insertion of a segment.                           */
  2236. /*                                                                           */
  2237. /*  This is a conceptually difficult routine.  The starting assumption is    */
  2238. /*  that we have a polygon with n sides.  n - 1 of these sides are currently */
  2239. /*  represented as edges in the mesh.  One side, called the "base", need not */
  2240. /*  be.                                                                      */
  2241. /*                                                                           */
  2242. /*  Inside the polygon is a structure I call a "fan", consisting of n - 1    */
  2243. /*  triangles that share a common origin.  For each of these triangles, the  */
  2244. /*  edge opposite the origin is one of the sides of the polygon.  The        */
  2245. /*  primary edge of each triangle is the edge directed from the origin to    */
  2246. /*  the destination; note that this is not the same edge that is a side of   */
  2247. /*  the polygon.  `firstedge' is the primary edge of the first triangle.     */
  2248. /*  From there, the triangles follow in counterclockwise order about the     */
  2249. /*  polygon, until `lastedge', the primary edge of the last triangle.        */
  2250. /*  `firstedge' and `lastedge' are probably connected to other triangles     */
  2251. /*  beyond the extremes of the fan, but their identity is not important, as  */
  2252. /*  long as the fan remains connected to them.                               */
  2253. /*                                                                           */
  2254. /*  Imagine the polygon oriented so that its base is at the bottom.  This    */
  2255. /*  puts `firstedge' on the far right, and `lastedge' on the far left.       */
  2256. /*  The right vertex of the base is the destination of `firstedge', and the  */
  2257. /*  left vertex of the base is the apex of `lastedge'.                       */
  2258. /*                                                                           */
  2259. /*  The challenge now is to find the right sequence of edge flips to         */
  2260. /*  transform the fan into a Delaunay triangulation of the polygon.  Each    */
  2261. /*  edge flip effectively removes one triangle from the fan, committing it   */
  2262. /*  to the polygon.  The resulting polygon has one fewer edge.  If `doflip'  */
  2263. /*  is set, the final flip will be performed, resulting in a fan of one      */
  2264. /*  (useless?) triangle.  If `doflip' is not set, the final flip is not      */
  2265. /*  performed, resulting in a fan of two triangles, and an unfinished        */
  2266. /*  triangular polygon that is not yet filled out with a single triangle.    */
  2267. /*  On completion of the routine, `lastedge' is the last remaining triangle, */
  2268. /*  or the leftmost of the last two.                                         */
  2269. /*                                                                           */
  2270. /*  Although the flips are performed in the order described above, the       */
  2271. /*  decisions about what flips to perform are made in precisely the reverse  */
  2272. /*  order.  The recursive triangulatepolygon() procedure makes a decision,   */
  2273. /*  uses up to two recursive calls to triangulate the "subproblems"          */
  2274. /*  (polygons with fewer edges), and then performs an edge flip.             */
  2275. /*                                                                           */
  2276. /*  The "decision" it makes is which vertex of the polygon should be         */
  2277. /*  connected to the base.  This decision is made by testing every possible  */
  2278. /*  vertex.  Once the best vertex is found, the two edges that connect this  */
  2279. /*  vertex to the base become the bases for two smaller polygons.  These     */
  2280. /*  are triangulated recursively.  Unfortunately, this approach can take     */
  2281. /*  O(n^2) time not only in the worst case, but in many common cases.  It's  */
  2282. /*  rarely a big deal for vertex deletion, where n is rarely larger than     */
  2283. /*  ten, but it could be a big deal for segment insertion, especially if     */
  2284. /*  there's a lot of long segments that each cut many triangles.  I ought to */
  2285. /*  code a faster algorithm some day.                                        */
  2286. /*                                                                           */
  2287. /*  The `edgecount' parameter is the number of sides of the polygon,         */
  2288. /*  including its base.  `triflaws' is a flag that determines whether the    */
  2289. /*  new triangles should be tested for quality, and enqueued if they are     */
  2290. /*  bad.                                                                     */
  2291. /*                                                                           */
  2292. /*****************************************************************************/
  2293. #ifdef ANSI_DECLARATORS
  2294. void triangulatepolygon(struct mesh *m, struct behavior *b,
  2295.                         struct otri *firstedge, struct otri *lastedge,
  2296.                         int edgecount, int doflip, int triflaws)
  2297. #else /* not ANSI_DECLARATORS */
  2298. void triangulatepolygon(m, b, firstedge, lastedge, edgecount, doflip, triflaws)
  2299. struct mesh *m;
  2300. struct behavior *b;
  2301. struct otri *firstedge;
  2302. struct otri *lastedge;
  2303. int edgecount;
  2304. int doflip;
  2305. int triflaws;
  2306. #endif /* not ANSI_DECLARATORS */
  2307. {
  2308.   struct otri testtri;
  2309.   struct otri besttri;
  2310.   struct otri tempedge;
  2311.   vertex leftbasevertex, rightbasevertex;
  2312.   vertex testvertex;
  2313.   vertex bestvertex;
  2314.   int bestnumber;
  2315.   int i;
  2316.   triangle ptr;   /* Temporary variable used by sym(), onext(), and oprev(). */
  2317.   /* Identify the base vertices. */
  2318.   apex(*lastedge, leftbasevertex);
  2319.   dest(*firstedge, rightbasevertex);
  2320.   if (b->verbose > 2) {
  2321.     printf("  Triangulating interior polygon at edgen");
  2322.     printf("    (%.12g, %.12g) (%.12g, %.12g)n", leftbasevertex[0],
  2323.            leftbasevertex[1], rightbasevertex[0], rightbasevertex[1]);
  2324.   }
  2325.   /* Find the best vertex to connect the base to. */
  2326.   onext(*firstedge, besttri);
  2327.   dest(besttri, bestvertex);
  2328.   otricopy(besttri, testtri);
  2329.   bestnumber = 1;
  2330.   for (i = 2; i <= edgecount - 2; i++) {
  2331.     onextself(testtri);
  2332.     dest(testtri, testvertex);
  2333.     /* Is this a better vertex? */
  2334.     if (incircle(m, b, leftbasevertex, rightbasevertex, bestvertex,
  2335.                  testvertex) > 0.0) {
  2336.       otricopy(testtri, besttri);
  2337.       bestvertex = testvertex;
  2338.       bestnumber = i;
  2339.     }
  2340.   }
  2341.   if (b->verbose > 2) {
  2342.     printf("    Connecting edge to (%.12g, %.12g)n", bestvertex[0],
  2343.            bestvertex[1]);
  2344.   }
  2345.   if (bestnumber > 1) {
  2346.     /* Recursively triangulate the smaller polygon on the right. */
  2347.     oprev(besttri, tempedge);
  2348.     triangulatepolygon(m, b, firstedge, &tempedge, bestnumber + 1, 1,
  2349.                        triflaws);
  2350.   }
  2351.   if (bestnumber < edgecount - 2) {
  2352.     /* Recursively triangulate the smaller polygon on the left. */
  2353.     sym(besttri, tempedge);
  2354.     triangulatepolygon(m, b, &besttri, lastedge, edgecount - bestnumber, 1,
  2355.                        triflaws);
  2356.     /* Find `besttri' again; it may have been lost to edge flips. */
  2357.     sym(tempedge, besttri);
  2358.   }
  2359.   if (doflip) {
  2360.     /* Do one final edge flip. */
  2361.     flip(m, b, &besttri);
  2362. #ifndef CDT_ONLY
  2363.     if (triflaws) {
  2364.       /* Check the quality of the newly committed triangle. */
  2365.       sym(besttri, testtri);
  2366.       testtriangle(m, b, &testtri);
  2367.     }
  2368. #endif /* not CDT_ONLY */
  2369.   }
  2370.   /* Return the base triangle. */
  2371.   otricopy(besttri, *lastedge);
  2372. }
  2373. /*****************************************************************************/
  2374. /*                                                                           */
  2375. /*  deletevertex()   Delete a vertex from a Delaunay triangulation, ensuring */
  2376. /*                   that the triangulation remains Delaunay.                */
  2377. /*                                                                           */
  2378. /*  The origin of `deltri' is deleted.  The union of the triangles adjacent  */
  2379. /*  to this vertex is a polygon, for which the Delaunay triangulation is     */
  2380. /*  found.  Two triangles are removed from the mesh.                         */
  2381. /*                                                                           */
  2382. /*  Only interior vertices that do not lie on segments or boundaries may be  */
  2383. /*  deleted.                                                                 */
  2384. /*                                                                           */
  2385. /*****************************************************************************/
  2386. #ifndef CDT_ONLY
  2387. #ifdef ANSI_DECLARATORS
  2388. void deletevertex(struct mesh *m, struct behavior *b, struct otri *deltri)
  2389. #else /* not ANSI_DECLARATORS */
  2390. void deletevertex(m, b, deltri)
  2391. struct mesh *m;
  2392. struct behavior *b;
  2393. struct otri *deltri;
  2394. #endif /* not ANSI_DECLARATORS */
  2395. {
  2396.   struct otri countingtri;
  2397.   struct otri firstedge, lastedge;
  2398.   struct otri deltriright;
  2399.   struct otri lefttri, righttri;
  2400.   struct otri leftcasing, rightcasing;
  2401.   struct osub leftsubseg, rightsubseg;
  2402.   vertex delvertex;
  2403.   vertex neworg;
  2404.   int edgecount;
  2405.   triangle ptr;   /* Temporary variable used by sym(), onext(), and oprev(). */
  2406.   subseg sptr;                      /* Temporary variable used by tspivot(). */
  2407.   org(*deltri, delvertex);
  2408.   if (b->verbose > 1) {
  2409.     printf("  Deleting (%.12g, %.12g).n", delvertex[0], delvertex[1]);
  2410.   }
  2411.   vertexdealloc(m, delvertex);
  2412.   /* Count the degree of the vertex being deleted. */
  2413.   onext(*deltri, countingtri);
  2414.   edgecount = 1;
  2415.   while (!otriequal(*deltri, countingtri)) {
  2416. #ifdef SELF_CHECK
  2417.     if (countingtri.tri == m->dummytri) {
  2418.       printf("Internal error in deletevertex():n");
  2419.       printf("  Attempt to delete boundary vertex.n");
  2420.       internalerror();
  2421.     }
  2422. #endif /* SELF_CHECK */
  2423.     edgecount++;
  2424.     onextself(countingtri);
  2425.   }
  2426. #ifdef SELF_CHECK
  2427.   if (edgecount < 3) {
  2428.     printf("Internal error in deletevertex():n  Vertex has degree %d.n",
  2429.            edgecount);
  2430.     internalerror();
  2431.   }
  2432. #endif /* SELF_CHECK */
  2433.   if (edgecount > 3) {
  2434.     /* Triangulate the polygon defined by the union of all triangles */
  2435.     /*   adjacent to the vertex being deleted.  Check the quality of */
  2436.     /*   the resulting triangles.                                    */
  2437.     onext(*deltri, firstedge);
  2438.     oprev(*deltri, lastedge);
  2439.     triangulatepolygon(m, b, &firstedge, &lastedge, edgecount, 0,
  2440.                        !b->nobisect);
  2441.   }
  2442.   /* Splice out two triangles. */
  2443.   lprev(*deltri, deltriright);
  2444.   dnext(*deltri, lefttri);
  2445.   sym(lefttri, leftcasing);
  2446.   oprev(deltriright, righttri);
  2447.   sym(righttri, rightcasing);
  2448.   bond(*deltri, leftcasing);
  2449.   bond(deltriright, rightcasing);
  2450.   tspivot(lefttri, leftsubseg);
  2451.   if (leftsubseg.ss != m->dummysub) {
  2452.     tsbond(*deltri, leftsubseg);
  2453.   }
  2454.   tspivot(righttri, rightsubseg);
  2455.   if (rightsubseg.ss != m->dummysub) {
  2456.     tsbond(deltriright, rightsubseg);
  2457.   }
  2458.   /* Set the new origin of `deltri' and check its quality. */
  2459.   org(lefttri, neworg);
  2460.   setorg(*deltri, neworg);
  2461.   if (!b->nobisect) {
  2462.     testtriangle(m, b, deltri);
  2463.   }
  2464.   /* Delete the two spliced-out triangles. */
  2465.   triangledealloc(m, lefttri.tri);
  2466.   triangledealloc(m, righttri.tri);
  2467. }
  2468. #endif /* not CDT_ONLY */
  2469. /*****************************************************************************/
  2470. /*                                                                           */
  2471. /*  undovertex()   Undo the most recent vertex insertion.                    */
  2472. /*                                                                           */
  2473. /*  Walks through the list of transformations (flips and a vertex insertion) */
  2474. /*  in the reverse of the order in which they were done, and undoes them.    */
  2475. /*  The inserted vertex is removed from the triangulation and deallocated.   */
  2476. /*  Two triangles (possibly just one) are also deallocated.                  */
  2477. /*                                                                           */
  2478. /*****************************************************************************/
  2479. #ifndef CDT_ONLY
  2480. #ifdef ANSI_DECLARATORS
  2481. void undovertex(struct mesh *m, struct behavior *b)
  2482. #else /* not ANSI_DECLARATORS */
  2483. void undovertex(m, b)
  2484. struct mesh *m;
  2485. struct behavior *b;
  2486. #endif /* not ANSI_DECLARATORS */
  2487. {
  2488.   struct otri fliptri;
  2489.   struct otri botleft, botright, topright;
  2490.   struct otri botlcasing, botrcasing, toprcasing;
  2491.   struct otri gluetri;
  2492.   struct osub botlsubseg, botrsubseg, toprsubseg;
  2493.   vertex botvertex, rightvertex;
  2494.   triangle ptr;                         /* Temporary variable used by sym(). */
  2495.   subseg sptr;                      /* Temporary variable used by tspivot(). */
  2496.   /* Walk through the list of transformations (flips and a vertex insertion) */
  2497.   /*   in the reverse of the order in which they were done, and undo them.   */
  2498.   while (m->lastflip != (struct flipstacker *) NULL) {
  2499.     /* Find a triangle involved in the last unreversed transformation. */
  2500.     decode(m->lastflip->flippedtri, fliptri);
  2501.     /* We are reversing one of three transformations:  a trisection of one */
  2502.     /*   triangle into three (by inserting a vertex in the triangle), a    */
  2503.     /*   bisection of two triangles into four (by inserting a vertex in an */
  2504.     /*   edge), or an edge flip.                                           */
  2505.     if (m->lastflip->prevflip == (struct flipstacker *) NULL) {
  2506.       /* Restore a triangle that was split into three triangles, */
  2507.       /*   so it is again one triangle.                          */
  2508.       dprev(fliptri, botleft);
  2509.       lnextself(botleft);
  2510.       onext(fliptri, botright);
  2511.       lprevself(botright);
  2512.       sym(botleft, botlcasing);
  2513.       sym(botright, botrcasing);
  2514.       dest(botleft, botvertex);
  2515.       setapex(fliptri, botvertex);
  2516.       lnextself(fliptri);
  2517.       bond(fliptri, botlcasing);
  2518.       tspivot(botleft, botlsubseg);
  2519.       tsbond(fliptri, botlsubseg);
  2520.       lnextself(fliptri);
  2521.       bond(fliptri, botrcasing);
  2522.       tspivot(botright, botrsubseg);
  2523.       tsbond(fliptri, botrsubseg);
  2524.       /* Delete the two spliced-out triangles. */
  2525.       triangledealloc(m, botleft.tri);
  2526.       triangledealloc(m, botright.tri);
  2527.     } else if (m->lastflip->prevflip == (struct flipstacker *) &insertvertex) {
  2528.       /* Restore two triangles that were split into four triangles, */
  2529.       /*   so they are again two triangles.                         */
  2530.       lprev(fliptri, gluetri);
  2531.       sym(gluetri, botright);
  2532.       lnextself(botright);
  2533.       sym(botright, botrcasing);
  2534.       dest(botright, rightvertex);
  2535.       setorg(fliptri, rightvertex);
  2536.       bond(gluetri, botrcasing);
  2537.       tspivot(botright, botrsubseg);
  2538.       tsbond(gluetri, botrsubseg);
  2539.       /* Delete the spliced-out triangle. */
  2540.       triangledealloc(m, botright.tri);
  2541.       sym(fliptri, gluetri);
  2542.       if (gluetri.tri != m->dummytri) {
  2543.         lnextself(gluetri);
  2544.         dnext(gluetri, topright);
  2545.         sym(topright, toprcasing);
  2546.         setorg(gluetri, rightvertex);
  2547.         bond(gluetri, toprcasing);
  2548.         tspivot(topright, toprsubseg);
  2549.         tsbond(gluetri, toprsubseg);
  2550.         /* Delete the spliced-out triangle. */
  2551.         triangledealloc(m, topright.tri);
  2552.       }
  2553.       /* This is the end of the list, sneakily encoded. */
  2554.       m->lastflip->prevflip = (struct flipstacker *) NULL;
  2555.     } else {
  2556.       /* Undo an edge flip. */
  2557.       unflip(m, b, &fliptri);
  2558.     }
  2559.     /* Go on and process the next transformation. */
  2560.     m->lastflip = m->lastflip->prevflip;
  2561.   }
  2562. }
  2563. #endif /* not CDT_ONLY */
  2564. /**                                                                         **/
  2565. /**                                                                         **/
  2566. /********* Mesh transformation routines end here                     *********/
  2567. /********* Divide-and-conquer Delaunay triangulation begins here     *********/
  2568. /**                                                                         **/
  2569. /**                                                                         **/
  2570. /*****************************************************************************/
  2571. /*                                                                           */
  2572. /*  The divide-and-conquer bounding box                                      */
  2573. /*                                                                           */
  2574. /*  I originally implemented the divide-and-conquer and incremental Delaunay */
  2575. /*  triangulations using the edge-based data structure presented by Guibas   */
  2576. /*  and Stolfi.  Switching to a triangle-based data structure doubled the    */
  2577. /*  speed.  However, I had to think of a few extra tricks to maintain the    */
  2578. /*  elegance of the original algorithms.                                     */
  2579. /*                                                                           */
  2580. /*  The "bounding box" used by my variant of the divide-and-conquer          */
  2581. /*  algorithm uses one triangle for each edge of the convex hull of the      */
  2582. /*  triangulation.  These bounding triangles all share a common apical       */
  2583. /*  vertex, which is represented by NULL and which represents nothing.       */
  2584. /*  The bounding triangles are linked in a circular fan about this NULL      */
  2585. /*  vertex, and the edges on the convex hull of the triangulation appear     */
  2586. /*  opposite the NULL vertex.  You might find it easiest to imagine that     */
  2587. /*  the NULL vertex is a point in 3D space behind the center of the          */
  2588. /*  triangulation, and that the bounding triangles form a sort of cone.      */
  2589. /*                                                                           */
  2590. /*  This bounding box makes it easy to represent degenerate cases.  For      */
  2591. /*  instance, the triangulation of two vertices is a single edge.  This edge */
  2592. /*  is represented by two bounding box triangles, one on each "side" of the  */
  2593. /*  edge.  These triangles are also linked together in a fan about the NULL  */
  2594. /*  vertex.                                                                  */
  2595. /*                                                                           */
  2596. /*  The bounding box also makes it easy to traverse the convex hull, as the  */
  2597. /*  divide-and-conquer algorithm needs to do.                                */
  2598. /*                                                                           */
  2599. /*****************************************************************************/
  2600. /*****************************************************************************/
  2601. /*                                                                           */
  2602. /*  vertexsort()   Sort an array of vertices by x-coordinate, using the      */
  2603. /*                 y-coordinate as a secondary key.                          */
  2604. /*                                                                           */
  2605. /*  Uses quicksort.  Randomized O(n log n) time.  No, I did not make any of  */
  2606. /*  the usual quicksort mistakes.                                            */
  2607. /*                                                                           */
  2608. /*****************************************************************************/
  2609. #ifdef ANSI_DECLARATORS
  2610. void vertexsort(vertex *sortarray, int arraysize)
  2611. #else /* not ANSI_DECLARATORS */
  2612. void vertexsort(sortarray, arraysize)
  2613. vertex *sortarray;
  2614. int arraysize;
  2615. #endif /* not ANSI_DECLARATORS */
  2616. {
  2617.   int left, right;
  2618.   int pivot;
  2619.   REAL pivotx, pivoty;
  2620.   vertex temp;
  2621.   if (arraysize == 2) {
  2622.     /* Recursive base case. */
  2623.     if ((sortarray[0][0] > sortarray[1][0]) ||
  2624.         ((sortarray[0][0] == sortarray[1][0]) &&
  2625.          (sortarray[0][1] > sortarray[1][1]))) {
  2626.       temp = sortarray[1];
  2627.       sortarray[1] = sortarray[0];
  2628.       sortarray[0] = temp;
  2629.     }
  2630.     return;
  2631.   }
  2632.   /* Choose a random pivot to split the array. */
  2633.   pivot = (int) randomnation((unsigned int) arraysize);
  2634.   pivotx = sortarray[pivot][0];
  2635.   pivoty = sortarray[pivot][1];
  2636.   /* Split the array. */
  2637.   left = -1;
  2638.   right = arraysize;
  2639.   while (left < right) {
  2640.     /* Search for a vertex whose x-coordinate is too large for the left. */
  2641.     do {
  2642.       left++;
  2643.     } while ((left <= right) && ((sortarray[left][0] < pivotx) ||
  2644.                                  ((sortarray[left][0] == pivotx) &&
  2645.                                   (sortarray[left][1] < pivoty))));
  2646.     /* Search for a vertex whose x-coordinate is too small for the right. */
  2647.     do {
  2648.       right--;
  2649.     } while ((left <= right) && ((sortarray[right][0] > pivotx) ||
  2650.                                  ((sortarray[right][0] == pivotx) &&
  2651.                                   (sortarray[right][1] > pivoty))));
  2652.     if (left < right) {
  2653.       /* Swap the left and right vertices. */
  2654.       temp = sortarray[left];
  2655.       sortarray[left] = sortarray[right];
  2656.       sortarray[right] = temp;
  2657.     }
  2658.   }
  2659.   if (left > 1) {
  2660.     /* Recursively sort the left subset. */
  2661.     vertexsort(sortarray, left);
  2662.   }
  2663.   if (right < arraysize - 2) {
  2664.     /* Recursively sort the right subset. */
  2665.     vertexsort(&sortarray[right + 1], arraysize - right - 1);
  2666.   }
  2667. }
  2668. /*****************************************************************************/
  2669. /*                                                                           */
  2670. /*  vertexmedian()   An order statistic algorithm, almost.  Shuffles an      */
  2671. /*                   array of vertices so that the first `median' vertices   */
  2672. /*                   occur lexicographically before the remaining vertices.  */
  2673. /*                                                                           */
  2674. /*  Uses the x-coordinate as the primary key if axis == 0; the y-coordinate  */
  2675. /*  if axis == 1.  Very similar to the vertexsort() procedure, but runs in   */
  2676. /*  randomized linear time.                                                  */
  2677. /*                                                                           */
  2678. /*****************************************************************************/
  2679. #ifdef ANSI_DECLARATORS
  2680. void vertexmedian(vertex *sortarray, int arraysize, int median, int axis)
  2681. #else /* not ANSI_DECLARATORS */
  2682. void vertexmedian(sortarray, arraysize, median, axis)
  2683. vertex *sortarray;
  2684. int arraysize;
  2685. int median;
  2686. int axis;
  2687. #endif /* not ANSI_DECLARATORS */
  2688. {
  2689.   int left, right;
  2690.   int pivot;
  2691.   REAL pivot1, pivot2;
  2692.   vertex temp;
  2693.   if (arraysize == 2) {
  2694.     /* Recursive base case. */
  2695.     if ((sortarray[0][axis] > sortarray[1][axis]) ||
  2696.         ((sortarray[0][axis] == sortarray[1][axis]) &&
  2697.          (sortarray[0][1 - axis] > sortarray[1][1 - axis]))) {
  2698.       temp = sortarray[1];
  2699.       sortarray[1] = sortarray[0];
  2700.       sortarray[0] = temp;
  2701.     }
  2702.     return;
  2703.   }
  2704.   /* Choose a random pivot to split the array. */
  2705.   pivot = (int) randomnation((unsigned int) arraysize);
  2706.   pivot1 = sortarray[pivot][axis];
  2707.   pivot2 = sortarray[pivot][1 - axis];
  2708.   /* Split the array. */
  2709.   left = -1;
  2710.   right = arraysize;
  2711.   while (left < right) {
  2712.     /* Search for a vertex whose x-coordinate is too large for the left. */
  2713.     do {
  2714.       left++;
  2715.     } while ((left <= right) && ((sortarray[left][axis] < pivot1) ||
  2716.                                  ((sortarray[left][axis] == pivot1) &&
  2717.                                   (sortarray[left][1 - axis] < pivot2))));
  2718.     /* Search for a vertex whose x-coordinate is too small for the right. */
  2719.     do {
  2720.       right--;
  2721.     } while ((left <= right) && ((sortarray[right][axis] > pivot1) ||
  2722.                                  ((sortarray[right][axis] == pivot1) &&
  2723.                                   (sortarray[right][1 - axis] > pivot2))));
  2724.     if (left < right) {
  2725.       /* Swap the left and right vertices. */
  2726.       temp = sortarray[left];
  2727.       sortarray[left] = sortarray[right];
  2728.       sortarray[right] = temp;
  2729.     }
  2730.   }
  2731.   /* Unlike in vertexsort(), at most one of the following */
  2732.   /*   conditionals is true.                             */
  2733.   if (left > median) {
  2734.     /* Recursively shuffle the left subset. */
  2735.     vertexmedian(sortarray, left, median, axis);
  2736.   }
  2737.   if (right < median - 1) {
  2738.     /* Recursively shuffle the right subset. */
  2739.     vertexmedian(&sortarray[right + 1], arraysize - right - 1,
  2740.                  median - right - 1, axis);
  2741.   }
  2742. }
  2743. /*****************************************************************************/
  2744. /*                                                                           */
  2745. /*  alternateaxes()   Sorts the vertices as appropriate for the divide-and-  */
  2746. /*                    conquer algorithm with alternating cuts.               */
  2747. /*                                                                           */
  2748. /*  Partitions by x-coordinate if axis == 0; by y-coordinate if axis == 1.   */
  2749. /*  For the base case, subsets containing only two or three vertices are     */
  2750. /*  always sorted by x-coordinate.                                           */
  2751. /*                                                                           */
  2752. /*****************************************************************************/
  2753. #ifdef ANSI_DECLARATORS
  2754. void alternateaxes(vertex *sortarray, int arraysize, int axis)
  2755. #else /* not ANSI_DECLARATORS */
  2756. void alternateaxes(sortarray, arraysize, axis)
  2757. vertex *sortarray;
  2758. int arraysize;
  2759. int axis;
  2760. #endif /* not ANSI_DECLARATORS */
  2761. {
  2762.   int divider;
  2763.   divider = arraysize >> 1;
  2764.   if (arraysize <= 3) {
  2765.     /* Recursive base case:  subsets of two or three vertices will be    */
  2766.     /*   handled specially, and should always be sorted by x-coordinate. */
  2767.     axis = 0;
  2768.   }
  2769.   /* Partition with a horizontal or vertical cut. */
  2770.   vertexmedian(sortarray, arraysize, divider, axis);
  2771.   /* Recursively partition the subsets with a cross cut. */
  2772.   if (arraysize - divider >= 2) {
  2773.     if (divider >= 2) {
  2774.       alternateaxes(sortarray, divider, 1 - axis);
  2775.     }
  2776.     alternateaxes(&sortarray[divider], arraysize - divider, 1 - axis);
  2777.   }
  2778. }
  2779. /*****************************************************************************/
  2780. /*                                                                           */
  2781. /*  mergehulls()   Merge two adjacent Delaunay triangulations into a         */
  2782. /*                 single Delaunay triangulation.                            */
  2783. /*                                                                           */
  2784. /*  This is similar to the algorithm given by Guibas and Stolfi, but uses    */
  2785. /*  a triangle-based, rather than edge-based, data structure.                */
  2786. /*                                                                           */
  2787. /*  The algorithm walks up the gap between the two triangulations, knitting  */
  2788. /*  them together.  As they are merged, some of their bounding triangles     */
  2789. /*  are converted into real triangles of the triangulation.  The procedure   */
  2790. /*  pulls each hull's bounding triangles apart, then knits them together     */
  2791. /*  like the teeth of two gears.  The Delaunay property determines, at each  */
  2792. /*  step, whether the next "tooth" is a bounding triangle of the left hull   */
  2793. /*  or the right.  When a bounding triangle becomes real, its apex is        */
  2794. /*  changed from NULL to a real vertex.                                      */
  2795. /*                                                                           */
  2796. /*  Only two new triangles need to be allocated.  These become new bounding  */
  2797. /*  triangles at the top and bottom of the seam.  They are used to connect   */
  2798. /*  the remaining bounding triangles (those that have not been converted     */
  2799. /*  into real triangles) into a single fan.                                  */
  2800. /*                                                                           */
  2801. /*  On entry, `farleft' and `innerleft' are bounding triangles of the left   */
  2802. /*  triangulation.  The origin of `farleft' is the leftmost vertex, and      */
  2803. /*  the destination of `innerleft' is the rightmost vertex of the            */
  2804. /*  triangulation.  Similarly, `innerright' and `farright' are bounding      */
  2805. /*  triangles of the right triangulation.  The origin of `innerright' and    */
  2806. /*  destination of `farright' are the leftmost and rightmost vertices.       */
  2807. /*                                                                           */
  2808. /*  On completion, the origin of `farleft' is the leftmost vertex of the     */
  2809. /*  merged triangulation, and the destination of `farright' is the rightmost */
  2810. /*  vertex.                                                                  */
  2811. /*                                                                           */
  2812. /*****************************************************************************/
  2813. #ifdef ANSI_DECLARATORS
  2814. void mergehulls(struct mesh *m, struct behavior *b, struct otri *farleft,
  2815.                 struct otri *innerleft, struct otri *innerright,
  2816.                 struct otri *farright, int axis)
  2817. #else /* not ANSI_DECLARATORS */
  2818. void mergehulls(m, b, farleft, innerleft, innerright, farright, axis)
  2819. struct mesh *m;
  2820. struct behavior *b;
  2821. struct otri *farleft;
  2822. struct otri *innerleft;
  2823. struct otri *innerright;
  2824. struct otri *farright;
  2825. int axis;
  2826. #endif /* not ANSI_DECLARATORS */
  2827. {
  2828.   struct otri leftcand, rightcand;
  2829.   struct otri baseedge;
  2830.   struct otri nextedge;
  2831.   struct otri sidecasing, topcasing, outercasing;
  2832.   struct otri checkedge;
  2833.   vertex innerleftdest;
  2834.   vertex innerrightorg;
  2835.   vertex innerleftapex, innerrightapex;
  2836.   vertex farleftpt, farrightpt;
  2837.   vertex farleftapex, farrightapex;
  2838.   vertex lowerleft, lowerright;
  2839.   vertex upperleft, upperright;
  2840.   vertex nextapex;
  2841.   vertex checkvertex;
  2842.   int changemade;
  2843.   int badedge;
  2844.   int leftfinished, rightfinished;
  2845.   triangle ptr;                         /* Temporary variable used by sym(). */
  2846.   dest(*innerleft, innerleftdest);
  2847.   apex(*innerleft, innerleftapex);
  2848.   org(*innerright, innerrightorg);
  2849.   apex(*innerright, innerrightapex);
  2850.   /* Special treatment for horizontal cuts. */
  2851.   if (b->dwyer && (axis == 1)) {
  2852.     org(*farleft, farleftpt);
  2853.     apex(*farleft, farleftapex);
  2854.     dest(*farright, farrightpt);
  2855.     apex(*farright, farrightapex);
  2856.     /* The pointers to the extremal vertices are shifted to point to the */
  2857.     /*   topmost and bottommost vertex of each hull, rather than the     */
  2858.     /*   leftmost and rightmost vertices.                                */
  2859.     while (farleftapex[1] < farleftpt[1]) {
  2860.       lnextself(*farleft);
  2861.       symself(*farleft);
  2862.       farleftpt = farleftapex;
  2863.       apex(*farleft, farleftapex);
  2864.     }
  2865.     sym(*innerleft, checkedge);
  2866.     apex(checkedge, checkvertex);
  2867.     while (checkvertex[1] > innerleftdest[1]) {
  2868.       lnext(checkedge, *innerleft);
  2869.       innerleftapex = innerleftdest;
  2870.       innerleftdest = checkvertex;
  2871.       sym(*innerleft, checkedge);
  2872.       apex(checkedge, checkvertex);
  2873.     }
  2874.     while (innerrightapex[1] < innerrightorg[1]) {
  2875.       lnextself(*innerright);
  2876.       symself(*innerright);
  2877.       innerrightorg = innerrightapex;
  2878.       apex(*innerright, innerrightapex);
  2879.     }
  2880.     sym(*farright, checkedge);
  2881.     apex(checkedge, checkvertex);
  2882.     while (checkvertex[1] > farrightpt[1]) {
  2883.       lnext(checkedge, *farright);
  2884.       farrightapex = farrightpt;
  2885.       farrightpt = checkvertex;
  2886.       sym(*farright, checkedge);
  2887.       apex(checkedge, checkvertex);
  2888.     }
  2889.   }
  2890.   /* Find a line tangent to and below both hulls. */
  2891.   do {
  2892.     changemade = 0;
  2893.     /* Make innerleftdest the "bottommost" vertex of the left hull. */
  2894.     if (counterclockwise(m, b, innerleftdest, innerleftapex, innerrightorg) >
  2895.         0.0) {
  2896.       lprevself(*innerleft);
  2897.       symself(*innerleft);
  2898.       innerleftdest = innerleftapex;
  2899.       apex(*innerleft, innerleftapex);
  2900.       changemade = 1;
  2901.     }
  2902.     /* Make innerrightorg the "bottommost" vertex of the right hull. */
  2903.     if (counterclockwise(m, b, innerrightapex, innerrightorg, innerleftdest) >
  2904.         0.0) {
  2905.       lnextself(*innerright);
  2906.       symself(*innerright);
  2907.       innerrightorg = innerrightapex;
  2908.       apex(*innerright, innerrightapex);
  2909.       changemade = 1;
  2910.     }
  2911.   } while (changemade);
  2912.   /* Find the two candidates to be the next "gear tooth." */
  2913.   sym(*innerleft, leftcand);
  2914.   sym(*innerright, rightcand);
  2915.   /* Create the bottom new bounding triangle. */
  2916.   maketriangle(m, b, &baseedge);
  2917.   /* Connect it to the bounding boxes of the left and right triangulations. */
  2918.   bond(baseedge, *innerleft);
  2919.   lnextself(baseedge);
  2920.   bond(baseedge, *innerright);
  2921.   lnextself(baseedge);
  2922.   setorg(baseedge, innerrightorg);
  2923.   setdest(baseedge, innerleftdest);
  2924.   /* Apex is intentionally left NULL. */
  2925.   if (b->verbose > 2) {
  2926.     printf("  Creating base bounding ");
  2927.     printtriangle(m, b, &baseedge);
  2928.   }
  2929.   /* Fix the extreme triangles if necessary. */
  2930.   org(*farleft, farleftpt);
  2931.   if (innerleftdest == farleftpt) {
  2932.     lnext(baseedge, *farleft);
  2933.   }
  2934.   dest(*farright, farrightpt);
  2935.   if (innerrightorg == farrightpt) {
  2936.     lprev(baseedge, *farright);
  2937.   }
  2938.   /* The vertices of the current knitting edge. */
  2939.   lowerleft = innerleftdest;
  2940.   lowerright = innerrightorg;
  2941.   /* The candidate vertices for knitting. */
  2942.   apex(leftcand, upperleft);
  2943.   apex(rightcand, upperright);
  2944.   /* Walk up the gap between the two triangulations, knitting them together. */
  2945.   while (1) {
  2946.     /* Have we reached the top?  (This isn't quite the right question,       */
  2947.     /*   because even though the left triangulation might seem finished now, */
  2948.     /*   moving up on the right triangulation might reveal a new vertex of   */
  2949.     /*   the left triangulation.  And vice-versa.)                           */
  2950.     leftfinished = counterclockwise(m, b, upperleft, lowerleft, lowerright) <=
  2951.                    0.0;
  2952.     rightfinished = counterclockwise(m, b, upperright, lowerleft, lowerright)
  2953.                  <= 0.0;
  2954.     if (leftfinished && rightfinished) {
  2955.       /* Create the top new bounding triangle. */
  2956.       maketriangle(m, b, &nextedge);
  2957.       setorg(nextedge, lowerleft);
  2958.       setdest(nextedge, lowerright);
  2959.       /* Apex is intentionally left NULL. */
  2960.       /* Connect it to the bounding boxes of the two triangulations. */
  2961.       bond(nextedge, baseedge);
  2962.       lnextself(nextedge);
  2963.       bond(nextedge, rightcand);
  2964.       lnextself(nextedge);
  2965.       bond(nextedge, leftcand);
  2966.       if (b->verbose > 2) {
  2967.         printf("  Creating top bounding ");
  2968.         printtriangle(m, b, &nextedge);
  2969.       }
  2970.       /* Special treatment for horizontal cuts. */
  2971.       if (b->dwyer && (axis == 1)) {
  2972.         org(*farleft, farleftpt);
  2973.         apex(*farleft, farleftapex);
  2974.         dest(*farright, farrightpt);
  2975.         apex(*farright, farrightapex);
  2976.         sym(*farleft, checkedge);
  2977.         apex(checkedge, checkvertex);
  2978.         /* The pointers to the extremal vertices are restored to the  */
  2979.         /*   leftmost and rightmost vertices (rather than topmost and */
  2980.         /*   bottommost).                                             */
  2981.         while (checkvertex[0] < farleftpt[0]) {
  2982.           lprev(checkedge, *farleft);
  2983.           farleftapex = farleftpt;
  2984.           farleftpt = checkvertex;
  2985.           sym(*farleft, checkedge);
  2986.           apex(checkedge, checkvertex);
  2987.         }
  2988.         while (farrightapex[0] > farrightpt[0]) {
  2989.           lprevself(*farright);
  2990.           symself(*farright);
  2991.           farrightpt = farrightapex;
  2992.           apex(*farright, farrightapex);
  2993.         }
  2994.       }
  2995.       return;
  2996.     }
  2997.     /* Consider eliminating edges from the left triangulation. */
  2998.     if (!leftfinished) {
  2999.       /* What vertex would be exposed if an edge were deleted? */
  3000.       lprev(leftcand, nextedge);