Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Triangle/Triangle.cpp
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: Triangle.cpp
4 //
5 // For more information, please see: http://www.nektar.info/
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description: class for triangle, originally the code of Jonathan Shewchuk
33 // but heavily modified.
34 // original file header below
35 //
36 ////////////////////////////////////////////////////////////////////////////////
37 /*****************************************************************************/
38 /* */
39 /* 888888888 ,o, / 888 */
40 /* 888 88o88o " o8888o 88o8888o o88888o 888 o88888o */
41 /* 888 888 888 88b 888 888 888 888 888 d888 88b */
42 /* 888 888 888 o88^o888 888 888 "88888" 888 8888oo888 */
43 /* 888 888 888 C888 888 888 888 / 888 q888 */
44 /* 888 888 888 "88o^888 888 888 Cb 888 "88oooo" */
45 /* "8oo8D */
46 /* */
47 /* A Two-Dimensional Quality Mesh Generator and Delaunay Triangulator. */
48 /* (triangle.c) */
49 /* */
50 /* Version 1.6 */
51 /* July 28, 2005 */
52 /* */
53 /* Copyright 1993, 1995, 1997, 1998, 2002, 2005 */
54 /* Jonathan Richard Shewchuk */
55 /* 2360 Woolsey #H */
56 /* Berkeley, California 94705-1927 */
57 /* jrs@cs.berkeley.edu */
58 /* */
59 /* This program may be freely redistributed under the condition that the */
60 /* copyright notices (including this entire header and the copyright */
61 /* notice printed when the `-h' switch is selected) are not removed, and */
62 /* no compensation is received. Private, research, and institutional */
63 /* use is free. You may distribute modified versions of this code UNDER */
64 /* THE CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE TO IT IN THE */
65 /* SAME FILE REMAIN UNDER COPYRIGHT OF THE ORIGINAL AUTHOR, BOTH SOURCE */
66 /* AND OBJECT CODE ARE MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR */
67 /* NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution of this code as */
68 /* part of a commercial system is permissible ONLY BY DIRECT ARRANGEMENT */
69 /* WITH THE AUTHOR. (If you are not directly supplying this code to a */
70 /* customer, and you are instead telling them how they can obtain it for */
71 /* free, then you are not required to make any arrangement with me.) */
72 /* */
73 /* Hypertext instructions for Triangle are available on the Web at */
74 /* */
75 /* http://www.cs.cmu.edu/~quake/triangle.html */
76 /* */
77 /* Disclaimer: Neither I nor Carnegie Mellon warrant this code in any way */
78 /* whatsoever. This code is provided "as-is". Use at your own risk. */
79 /* */
80 /* Some of the references listed below are marked with an asterisk. [*] */
81 /* These references are available for downloading from the Web page */
82 /* */
83 /* http://www.cs.cmu.edu/~quake/triangle.research.html */
84 /* */
85 /* Three papers discussing aspects of Triangle are available. A short */
86 /* overview appears in "Triangle: Engineering a 2D Quality Mesh */
87 /* Generator and Delaunay Triangulator," in Applied Computational */
88 /* Geometry: Towards Geometric Engineering, Ming C. Lin and Dinesh */
89 /* Manocha, editors, Lecture Notes in Computer Science volume 1148, */
90 /* pages 203-222, Springer-Verlag, Berlin, May 1996 (from the First ACM */
91 /* Workshop on Applied Computational Geometry). [*] */
92 /* */
93 /* The algorithms are discussed in the greatest detail in "Delaunay */
94 /* Refinement Algorithms for Triangular Mesh Generation," Computational */
95 /* Geometry: Theory and Applications 22(1-3):21-74, May 2002. [*] */
96 /* */
97 /* More detail about the data structures may be found in my dissertation: */
98 /* "Delaunay Refinement Mesh Generation," Ph.D. thesis, Technical Report */
99 /* CMU-CS-97-137, School of Computer Science, Carnegie Mellon University, */
100 /* Pittsburgh, Pennsylvania, 18 May 1997. [*] */
101 /* */
102 /* Triangle was created as part of the Quake Project in the School of */
103 /* Computer Science at Carnegie Mellon University. For further */
104 /* information, see Hesheng Bao, Jacobo Bielak, Omar Ghattas, Loukas F. */
105 /* Kallivokas, David R. O'Hallaron, Jonathan R. Shewchuk, and Jifeng Xu, */
106 /* "Large-scale Simulation of Elastic Wave Propagation in Heterogeneous */
107 /* Media on Parallel Computers," Computer Methods in Applied Mechanics */
108 /* and Engineering 152(1-2):85-102, 22 January 1998. */
109 /* */
110 /* Triangle's Delaunay refinement algorithm for quality mesh generation is */
111 /* a hybrid of one due to Jim Ruppert, "A Delaunay Refinement Algorithm */
112 /* for Quality 2-Dimensional Mesh Generation," Journal of Algorithms */
113 /* 18(3):548-585, May 1995 [*], and one due to L. Paul Chew, "Guaranteed- */
114 /* Quality Mesh Generation for Curved Surfaces," Proceedings of the Ninth */
115 /* Annual Symposium on Computational Geometry (San Diego, California), */
116 /* pages 274-280, Association for Computing Machinery, May 1993, */
117 /* http://portal.acm.org/citation.cfm?id=161150 . */
118 /* */
119 /* The Delaunay refinement algorithm has been modified so that it meshes */
120 /* domains with small input angles well, as described in Gary L. Miller, */
121 /* Steven E. Pav, and Noel J. Walkington, "When and Why Ruppert's */
122 /* Algorithm Works," Twelfth International Meshing Roundtable, pages */
123 /* 91-102, Sandia National Laboratories, September 2003. [*] */
124 /* */
125 /* My implementation of the divide-and-conquer and incremental Delaunay */
126 /* triangulation algorithms follows closely the presentation of Guibas */
127 /* and Stolfi, even though I use a triangle-based data structure instead */
128 /* of their quad-edge data structure. (In fact, I originally implemented */
129 /* Triangle using the quad-edge data structure, but the switch to a */
130 /* triangle-based data structure sped Triangle by a factor of two.) The */
131 /* mesh manipulation primitives and the two aforementioned Delaunay */
132 /* triangulation algorithms are described by Leonidas J. Guibas and Jorge */
133 /* Stolfi, "Primitives for the Manipulation of General Subdivisions and */
134 /* the Computation of Voronoi Diagrams," ACM Transactions on Graphics */
135 /* 4(2):74-123, April 1985, http://portal.acm.org/citation.cfm?id=282923 .*/
136 /* */
137 /* Their O(n log n) divide-and-conquer algorithm is adapted from Der-Tsai */
138 /* Lee and Bruce J. Schachter, "Two Algorithms for Constructing the */
139 /* Delaunay Triangulation," International Journal of Computer and */
140 /* Information Science 9(3):219-242, 1980. Triangle's improvement of the */
141 /* divide-and-conquer algorithm by alternating between vertical and */
142 /* horizontal cuts was introduced by Rex A. Dwyer, "A Faster Divide-and- */
143 /* Conquer Algorithm for Constructing Delaunay Triangulations," */
144 /* Algorithmica 2(2):137-151, 1987. */
145 /* */
146 /* The incremental insertion algorithm was first proposed by C. L. Lawson, */
147 /* "Software for C1 Surface Interpolation," in Mathematical Software III, */
148 /* John R. Rice, editor, Academic Press, New York, pp. 161-194, 1977. */
149 /* For point location, I use the algorithm of Ernst P. Mucke, Isaac */
150 /* Saias, and Binhai Zhu, "Fast Randomized Point Location Without */
151 /* Preprocessing in Two- and Three-Dimensional Delaunay Triangulations," */
152 /* Proceedings of the Twelfth Annual Symposium on Computational Geometry, */
153 /* ACM, May 1996. [*] If I were to randomize the order of vertex */
154 /* insertion (I currently don't bother), their result combined with the */
155 /* result of Kenneth L. Clarkson and Peter W. Shor, "Applications of */
156 /* Random Sampling in Computational Geometry II," Discrete & */
157 /* Computational Geometry 4(1):387-421, 1989, would yield an expected */
158 /* O(n^{4/3}) bound on running time. */
159 /* */
160 /* The O(n log n) sweepline Delaunay triangulation algorithm is taken from */
161 /* Steven Fortune, "A Sweepline Algorithm for Voronoi Diagrams", */
162 /* Algorithmica 2(2):153-174, 1987. A random sample of edges on the */
163 /* boundary of the triangulation are maintained in a splay tree for the */
164 /* purpose of point location. Splay trees are described by Daniel */
165 /* Dominic Sleator and Robert Endre Tarjan, "Self-Adjusting Binary Search */
166 /* Trees," Journal of the ACM 32(3):652-686, July 1985, */
167 /* http://portal.acm.org/citation.cfm?id=3835 . */
168 /* */
169 /* The algorithms for exact computation of the signs of determinants are */
170 /* described in Jonathan Richard Shewchuk, "Adaptive Precision Floating- */
171 /* Point Arithmetic and Fast Robust Geometric Predicates," Discrete & */
172 /* Computational Geometry 18(3):305-363, October 1997. (Also available */
173 /* as Technical Report CMU-CS-96-140, School of Computer Science, */
174 /* Carnegie Mellon University, Pittsburgh, Pennsylvania, May 1996.) [*] */
175 /* An abbreviated version appears as Jonathan Richard Shewchuk, "Robust */
176 /* Adaptive Floating-Point Geometric Predicates," Proceedings of the */
177 /* Twelfth Annual Symposium on Computational Geometry, ACM, May 1996. [*] */
178 /* Many of the ideas for my exact arithmetic routines originate with */
179 /* Douglas M. Priest, "Algorithms for Arbitrary Precision Floating Point */
180 /* Arithmetic," Tenth Symposium on Computer Arithmetic, pp. 132-143, IEEE */
181 /* Computer Society Press, 1991. [*] Many of the ideas for the correct */
182 /* evaluation of the signs of determinants are taken from Steven Fortune */
183 /* and Christopher J. Van Wyk, "Efficient Exact Arithmetic for Computa- */
184 /* tional Geometry," Proceedings of the Ninth Annual Symposium on */
185 /* Computational Geometry, ACM, pp. 163-172, May 1993, and from Steven */
186 /* Fortune, "Numerical Stability of Algorithms for 2D Delaunay Triangu- */
187 /* lations," International Journal of Computational Geometry & Applica- */
188 /* tions 5(1-2):193-213, March-June 1995. */
189 /* */
190 /* The method of inserting new vertices off-center (not precisely at the */
191 /* circumcenter of every poor-quality triangle) is from Alper Ungor, */
192 /* "Off-centers: A New Type of Steiner Points for Computing Size-Optimal */
193 /* Quality-Guaranteed Delaunay Triangulations," Proceedings of LATIN */
194 /* 2004 (Buenos Aires, Argentina), April 2004. */
195 /* */
196 /* For definitions of and results involving Delaunay triangulations, */
197 /* constrained and conforming versions thereof, and other aspects of */
198 /* triangular mesh generation, see the excellent survey by Marshall Bern */
199 /* and David Eppstein, "Mesh Generation and Optimal Triangulation," in */
200 /* Computing and Euclidean Geometry, Ding-Zhu Du and Frank Hwang, */
201 /* editors, World Scientific, Singapore, pp. 23-90, 1992. [*] */
202 /* */
203 /* The time for incrementally adding PSLG (planar straight line graph) */
204 /* segments to create a constrained Delaunay triangulation is probably */
205 /* O(t^2) per segment in the worst case and O(t) per segment in the */
206 /* common case, where t is the number of triangles that intersect the */
207 /* segment before it is inserted. This doesn't count point location, */
208 /* which can be much more expensive. I could improve this to O(d log d) */
209 /* time, but d is usually quite small, so it's not worth the bother. */
210 /* (This note does not apply when the -s switch is used, invoking a */
211 /* different method is used to insert segments.) */
212 /* */
213 /* The time for deleting a vertex from a Delaunay triangulation is O(d^2) */
214 /* in the worst case and O(d) in the common case, where d is the degree */
215 /* of the vertex being deleted. I could improve this to O(d log d) time, */
216 /* but d is usually quite small, so it's not worth the bother. */
217 /* */
218 /* Ruppert's Delaunay refinement algorithm typically generates triangles */
219 /* at a linear rate (constant time per triangle) after the initial */
220 /* triangulation is formed. There may be pathological cases where */
221 /* quadratic time is required, but these never arise in practice. */
222 /* */
223 /* The geometric predicates (circumcenter calculations, segment */
224 /* intersection formulae, etc.) appear in my "Lecture Notes on Geometric */
225 /* Robustness" at http://www.cs.berkeley.edu/~jrs/mesh . */
226 /* */
227 /* If you make any improvements to this code, please please please let me */
228 /* know, so that I may obtain the improvements. Even if you don't change */
229 /* the code, I'd still love to hear what it's being used for. */
230 /* */
231 /*****************************************************************************/
232 
234 
235 /*****************************************************************************/
236 /* */
237 /* Mesh manipulation primitives. Each triangle contains three pointers to */
238 /* other triangles, with orientations. Each pointer points not to the */
239 /* first byte of a triangle, but to one of the first three bytes of a */
240 /* triangle. It is necessary to extract both the triangle itself and the */
241 /* orientation. To save memory, I keep both pieces of information in one */
242 /* pointer. To make this possible, I assume that all triangles are aligned */
243 /* to four-byte boundaries. The decode() routine below decodes a pointer, */
244 /* extracting an orientation (in the range 0 to 2) and a pointer to the */
245 /* beginning of a triangle. The encode() routine compresses a pointer to a */
246 /* triangle and an orientation into a single pointer. My assumptions that */
247 /* triangles are four-byte-aligned and that the `unsigned long' type is */
248 /* long enough to hold a pointer are two of the few kludges in this program.*/
249 /* */
250 /* Subsegments are manipulated similarly. A pointer to a subsegment */
251 /* carries both an address and an orientation in the range 0 to 1. */
252 /* */
253 /* The other primitives take an oriented triangle or oriented subsegment, */
254 /* and return an oriented triangle or oriented subsegment or vertex; or */
255 /* they change the connections in the data structure. */
256 /* */
257 /* Below, triangles and subsegments are denoted by their vertices. The */
258 /* triangle abc has origin (org) a, destination (dest) b, and apex (apex) */
259 /* c. These vertices occur in counterclockwise order about the triangle. */
260 /* The handle abc may simultaneously denote vertex a, edge ab, and triangle */
261 /* abc. */
262 /* */
263 /* Similarly, the subsegment ab has origin (sorg) a and destination (sdest) */
264 /* b. If ab is thought to be directed upward (with b directly above a), */
265 /* then the handle ab is thought to grasp the right side of ab, and may */
266 /* simultaneously denote vertex a and edge ab. */
267 /* */
268 /* An asterisk (*) denotes a vertex whose identity is unknown. */
269 /* */
270 /* Given this notation, a partial list of mesh manipulation primitives */
271 /* follows. */
272 /* */
273 /* */
274 /* For triangles: */
275 /* */
276 /* sym: Find the abutting triangle; same edge. */
277 /* sym(abc) -> ba* */
278 /* */
279 /* lnext: Find the next edge (counterclockwise) of a triangle. */
280 /* lnext(abc) -> bca */
281 /* */
282 /* lprev: Find the previous edge (clockwise) of a triangle. */
283 /* lprev(abc) -> cab */
284 /* */
285 /* onext: Find the next edge counterclockwise with the same origin. */
286 /* onext(abc) -> ac* */
287 /* */
288 /* oprev: Find the next edge clockwise with the same origin. */
289 /* oprev(abc) -> a*b */
290 /* */
291 /* dnext: Find the next edge counterclockwise with the same destination. */
292 /* dnext(abc) -> *ba */
293 /* */
294 /* dprev: Find the next edge clockwise with the same destination. */
295 /* dprev(abc) -> cb* */
296 /* */
297 /* rnext: Find the next edge (counterclockwise) of the adjacent triangle. */
298 /* rnext(abc) -> *a* */
299 /* */
300 /* rprev: Find the previous edge (clockwise) of the adjacent triangle. */
301 /* rprev(abc) -> b** */
302 /* */
303 /* org: Origin dest: Destination apex: Apex */
304 /* org(abc) -> a dest(abc) -> b apex(abc) -> c */
305 /* */
306 /* bond: Bond two triangles together at the resepective handles. */
307 /* bond(abc, bad) */
308 /* */
309 /* */
310 /* For subsegments: */
311 /* */
312 /* ssym: Reverse the orientation of a subsegment. */
313 /* ssym(ab) -> ba */
314 /* */
315 /* spivot: Find adjoining subsegment with the same origin. */
316 /* spivot(ab) -> a* */
317 /* */
318 /* snext: Find next subsegment in sequence. */
319 /* snext(ab) -> b* */
320 /* */
321 /* sorg: Origin sdest: Destination */
322 /* sorg(ab) -> a sdest(ab) -> b */
323 /* */
324 /* sbond: Bond two subsegments together at the respective origins. */
325 /* sbond(ab, ac) */
326 /* */
327 /* */
328 /* For interacting tetrahedra and subfacets: */
329 /* */
330 /* tspivot: Find a subsegment abutting a triangle. */
331 /* tspivot(abc) -> ba */
332 /* */
333 /* stpivot: Find a triangle abutting a subsegment. */
334 /* stpivot(ab) -> ba* */
335 /* */
336 /* tsbond: Bond a triangle to a subsegment. */
337 /* tsbond(abc, ba) */
338 /* */
339 /*****************************************************************************/
340 
341 namespace Nektar
342 {
343 namespace NekMeshUtils
344 {
345 
346 /********* User-defined triangle evaluation routine begins here *********/
347 /** **/
348 /** **/
349 
350 /*****************************************************************************/
351 /* */
352 /* triunsuitable() Determine if a triangle is unsuitable, and thus must */
353 /* be further refined. */
354 /* */
355 /* You may write your own procedure that decides whether or not a selected */
356 /* triangle is too big (and needs to be refined). There are two ways to do */
357 /* this. */
358 /* */
359 /* (1) Modify the procedure `triunsuitable' below, then recompile */
360 /* Triangle. */
361 /* */
362 /* (2) Define the symbol EXTERNAL_TEST (either by adding the definition */
363 /* to this file, or by using the appropriate compiler switch). This way, */
364 /* you can compile triangle.c separately from your test. Write your own */
365 /* `triunsuitable' procedure in a separate C file (using the same prototype */
366 /* as below). Compile it and link the object code with triangle.o. */
367 /* */
368 /* This procedure returns 1 if the triangle is too large and should be */
369 /* refined; 0 otherwise. */
370 /* */
371 /*****************************************************************************/
372 
373 #ifdef EXTERNAL_TEST
374 
375 int triunsuitable();
376 
377 #else /* not EXTERNAL_TEST */
378 
379 int DelaunayTriangle::triunsuitable(vertex triorg, vertex tridest, vertex triapex, double area)
380 {
381  double dxoa, dxda, dxod;
382  double dyoa, dyda, dyod;
383  double oalen, dalen, odlen;
384  double maxlen;
385 
386  dxoa = triorg[0] - triapex[0];
387  dyoa = triorg[1] - triapex[1];
388  dxda = tridest[0] - triapex[0];
389  dyda = tridest[1] - triapex[1];
390  dxod = triorg[0] - tridest[0];
391  dyod = triorg[1] - tridest[1];
392  /* Find the squares of the lengths of the triangle's three edges. */
393  oalen = dxoa * dxoa + dyoa * dyoa;
394  dalen = dxda * dxda + dyda * dyda;
395  odlen = dxod * dxod + dyod * dyod;
396  /* Find the square of the length of the longest edge. */
397  maxlen = (dalen > oalen) ? dalen : oalen;
398  maxlen = (odlen > maxlen) ? odlen : maxlen;
399 
400  if (maxlen > 0.05 * (triorg[0] * triorg[0] + triorg[1] * triorg[1]) + 0.02)
401  {
402  return 1;
403  }
404  else
405  {
406  return 0;
407  }
408 }
409 
410 #endif /* not EXTERNAL_TEST */
411 
412 /** **/
413 /** **/
414 /********* User-defined triangle evaluation routine ends here *********/
415 
416 /********* Memory allocation and program exit wrappers begin here *********/
417 /** **/
418 /** **/
419 
421 {
422  exit(status);
423 }
424 
426 {
427  void *memptr;
428 
429  memptr = (void *)malloc((unsigned int)size);
430  if (memptr == (void *)NULL)
431  {
432  printf("Error: Out of memory.\n");
433  triexit(1);
434  }
435  return (memptr);
436 }
437 
438 void DelaunayTriangle::trifree(void *memptr)
439 {
440  free(memptr);
441 }
442 
443 /** **/
444 /** **/
445 /********* Memory allocation and program exit wrappers end here *********/
446 
447 /********* User interaction routines begin here *********/
448 /** **/
449 /** **/
450 
451 /*****************************************************************************/
452 /* */
453 /* internalerror() Ask the user to send me the defective product. Exit. */
454 /* */
455 /*****************************************************************************/
456 
458 {
459  printf(" Please report this bug to jrs@cs.berkeley.edu\n");
460  printf(" Include the message above, your input data set, and the exact\n");
461  printf(" command line you used to run Triangle.\n");
462  triexit(1);
463 }
464 
465 /*****************************************************************************/
466 /* */
467 /* parsecommandline() Read the command line, identify switches, and set */
468 /* up options and file names. */
469 /* */
470 /*****************************************************************************/
471 
472 void DelaunayTriangle::parsecommandline(int argc, char **argv, struct behavior *b)
473 {
474  int i, j, k;
475  char workstring[2048];
476 
477  b->poly = b->quality = 0;
478  b->usertest = 0;
479  b->weighted = b->jettison = 0;
480  b->nobisect = 0;
481  b->minangle = 0.0;
482 
483  for (i = 0; i < argc; i++)
484  {
485  for (j = 0; argv[i][j] != '\0'; j++)
486  {
487  if (argv[i][j] == 'p')
488  {
489  b->poly = 1;
490  }
491  if (argv[i][j] == 'q')
492  {
493  b->quality = 1;
494  if (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) ||
495  (argv[i][j + 1] == '.'))
496  {
497  k = 0;
498  while (
499  ((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) ||
500  (argv[i][j + 1] == '.'))
501  {
502  j++;
503  workstring[k] = argv[i][j];
504  k++;
505  }
506  workstring[k] = '\0';
507  b->minangle = (double)strtod(workstring, (char **)NULL);
508  }
509  else
510  {
511  b->minangle = 20.0;
512  }
513  }
514  if (argv[i][j] == 'u')
515  {
516  b->quality = 1;
517  b->usertest = 1;
518  }
519  if (argv[i][j] == 'w')
520  {
521  b->weighted = 1;
522  }
523  if (argv[i][j] == 'W')
524  {
525  b->weighted = 2;
526  }
527  if (argv[i][j] == 'j')
528  {
529  b->jettison = 1;
530  }
531  if (argv[i][j] == 'Y')
532  {
533  b->nobisect++;
534  }
535  }
536  }
537 
538  b->usesegments = b->poly || b->quality;
539  b->goodangle = cos(b->minangle * PI / 180.0);
540  if (b->goodangle == 1.0)
541  {
542  b->offconstant = 0.0;
543  }
544  else
545  {
546  b->offconstant =
547  0.475 * sqrt((1.0 + b->goodangle) / (1.0 - b->goodangle));
548  }
549  b->goodangle *= b->goodangle;
550 
551  /* Regular/weighted triangulations are incompatible with PSLGs */
552  /* and meshing. */
553  if (b->weighted && (b->poly || b->quality))
554  {
555  b->weighted = 0;
556  }
557 }
558 
559 /********* Memory management routines begin here *********/
560 /** **/
561 /** **/
562 
563 /*****************************************************************************/
564 /* */
565 /* poolzero() Set all of a pool's fields to zero. */
566 /* */
567 /* This procedure should never be called on a pool that has any memory */
568 /* allocated to it, as that memory would leak. */
569 /* */
570 /*****************************************************************************/
571 
573 {
574  pool->firstblock = (void **)NULL;
575  pool->nowblock = (void **)NULL;
576  pool->nextitem = (void *)NULL;
577  pool->deaditemstack = (void *)NULL;
578  pool->pathblock = (void **)NULL;
579  pool->pathitem = (void *)NULL;
580  pool->alignbytes = 0;
581  pool->itembytes = 0;
582  pool->itemsperblock = 0;
583  pool->itemsfirstblock = 0;
584  pool->items = 0;
585  pool->maxitems = 0;
586  pool->unallocateditems = 0;
587  pool->pathitemsleft = 0;
588 }
589 
590 /*****************************************************************************/
591 /* */
592 /* poolrestart() Deallocate all items in a pool. */
593 /* */
594 /* The pool is returned to its starting state, except that no memory is */
595 /* freed to the operating system. Rather, the previously allocated blocks */
596 /* are ready to be reused. */
597 /* */
598 /*****************************************************************************/
599 
601 {
602  unsigned long alignptr;
603 
604  pool->items = 0;
605  pool->maxitems = 0;
606 
607  /* Set the currently active block. */
608  pool->nowblock = pool->firstblock;
609  /* Find the first item in the pool. Increment by the size of (void *). */
610  alignptr = (unsigned long)(pool->nowblock + 1);
611  /* Align the item on an `alignbytes'-byte boundary. */
612  pool->nextitem = (void *)(alignptr + (unsigned long)pool->alignbytes -
613  (alignptr % (unsigned long)pool->alignbytes));
614  /* There are lots of unallocated items left in this block. */
615  pool->unallocateditems = pool->itemsfirstblock;
616  /* The stack of deallocated items is empty. */
617  pool->deaditemstack = (void *)NULL;
618 }
619 
620 /*****************************************************************************/
621 /* */
622 /* poolinit() Initialize a pool of memory for allocation of items. */
623 /* */
624 /* This routine initializes the machinery for allocating items. A `pool' */
625 /* is created whose records have size at least `bytecount'. Items will be */
626 /* allocated in `itemcount'-item blocks. Each item is assumed to be a */
627 /* collection of words, and either pointers or floating-point values are */
628 /* assumed to be the "primary" word type. (The "primary" word type is used */
629 /* to determine alignment of items.) If `alignment' isn't zero, all items */
630 /* will be `alignment'-byte aligned in memory. `alignment' must be either */
631 /* a multiple or a factor of the primary word size; powers of two are safe. */
632 /* `alignment' is normally used to create a few unused bits at the bottom */
633 /* of each item's pointer, in which information may be stored. */
634 /* */
635 /* Don't change this routine unless you understand it. */
636 /* */
637 /*****************************************************************************/
638 
640  int bytecount,
641  int itemcount,
642  int firstitemcount,
643  int alignment)
644 {
645  /* Find the proper alignment, which must be at least as large as: */
646  /* - The parameter `alignment'. */
647  /* - sizeof(void *), so the stack of dead items can be maintained */
648  /* without unaligned accesses. */
649  if (alignment > sizeof(void *))
650  {
651  pool->alignbytes = alignment;
652  }
653  else
654  {
655  pool->alignbytes = sizeof(void *);
656  }
657  pool->itembytes =
658  ((bytecount - 1) / pool->alignbytes + 1) * pool->alignbytes;
659  pool->itemsperblock = itemcount;
660  if (firstitemcount == 0)
661  {
662  pool->itemsfirstblock = itemcount;
663  }
664  else
665  {
666  pool->itemsfirstblock = firstitemcount;
667  }
668 
669  /* Allocate a block of items. Space for `itemsfirstblock' items and one */
670  /* pointer (to point to the next block) are allocated, as well as space */
671  /* to ensure alignment of the items. */
672  pool->firstblock =
673  (void **)trimalloc(pool->itemsfirstblock * pool->itembytes +
674  (int)sizeof(void *) + pool->alignbytes);
675  /* Set the next block pointer to NULL. */
676  *(pool->firstblock) = (void *)NULL;
677  poolrestart(pool);
678 }
679 
680 /*****************************************************************************/
681 /* */
682 /* pooldeinit() Free to the operating system all memory taken by a pool. */
683 /* */
684 /*****************************************************************************/
685 
687 {
688  while (pool->firstblock != (void **)NULL)
689  {
690  pool->nowblock = (void **)*(pool->firstblock);
691  trifree((void *)pool->firstblock);
692  pool->firstblock = pool->nowblock;
693  }
694 }
695 
696 /*****************************************************************************/
697 /* */
698 /* poolalloc() Allocate space for an item. */
699 /* */
700 /*****************************************************************************/
701 
703 {
704  void *newitem;
705  void **newblock;
706  unsigned long alignptr;
707 
708  /* First check the linked list of dead items. If the list is not */
709  /* empty, allocate an item from the list rather than a fresh one. */
710  if (pool->deaditemstack != (void *)NULL)
711  {
712  newitem = pool->deaditemstack; /* Take first item in list. */
713  pool->deaditemstack = *(void **)pool->deaditemstack;
714  }
715  else
716  {
717  /* Check if there are any free items left in the current block. */
718  if (pool->unallocateditems == 0)
719  {
720  /* Check if another block must be allocated. */
721  if (*(pool->nowblock) == (void *)NULL)
722  {
723  /* Allocate a new block of items, pointed to by the previous
724  * block. */
725  newblock =
726  (void **)trimalloc(pool->itemsperblock * pool->itembytes +
727  (int)sizeof(void *) + pool->alignbytes);
728  *(pool->nowblock) = (void *)newblock;
729  /* The next block pointer is NULL. */
730  *newblock = (void *)NULL;
731  }
732 
733  /* Move to the new block. */
734  pool->nowblock = (void **)*(pool->nowblock);
735  /* Find the first item in the block. */
736  /* Increment by the size of (void *). */
737  alignptr = (unsigned long)(pool->nowblock + 1);
738  /* Align the item on an `alignbytes'-byte boundary. */
739  pool->nextitem =
740  (void *)(alignptr + (unsigned long)pool->alignbytes -
741  (alignptr % (unsigned long)pool->alignbytes));
742  /* There are lots of unallocated items left in this block. */
743  pool->unallocateditems = pool->itemsperblock;
744  }
745 
746  /* Allocate a new item. */
747  newitem = pool->nextitem;
748  /* Advance `nextitem' pointer to next free item in block. */
749  pool->nextitem = (void *)((char *)pool->nextitem + pool->itembytes);
750  pool->unallocateditems--;
751  pool->maxitems++;
752  }
753  pool->items++;
754  return newitem;
755 }
756 
757 /*****************************************************************************/
758 /* */
759 /* pooldealloc() Deallocate space for an item. */
760 /* */
761 /* The deallocated space is stored in a queue for later reuse. */
762 /* */
763 /*****************************************************************************/
764 
765 void DelaunayTriangle::pooldealloc(struct memorypool *pool, void *dyingitem)
766 {
767  /* Push freshly killed item onto stack. */
768  *((void **)dyingitem) = pool->deaditemstack;
769  pool->deaditemstack = dyingitem;
770  pool->items--;
771 }
772 
773 /*****************************************************************************/
774 /* */
775 /* traversalinit() Prepare to traverse the entire list of items. */
776 /* */
777 /* This routine is used in conjunction with traverse(). */
778 /* */
779 /*****************************************************************************/
780 
782 {
783  unsigned long alignptr;
784 
785  /* Begin the traversal in the first block. */
786  pool->pathblock = pool->firstblock;
787  /* Find the first item in the block. Increment by the size of (void *). */
788  alignptr = (unsigned long)(pool->pathblock + 1);
789  /* Align with item on an `alignbytes'-byte boundary. */
790  pool->pathitem = (void *)(alignptr + (unsigned long)pool->alignbytes -
791  (alignptr % (unsigned long)pool->alignbytes));
792  /* Set the number of items left in the current block. */
793  pool->pathitemsleft = pool->itemsfirstblock;
794 }
795 
796 /*****************************************************************************/
797 /* */
798 /* traverse() Find the next item in the list. */
799 /* */
800 /* This routine is used in conjunction with traversalinit(). Be forewarned */
801 /* that this routine successively returns all items in the list, including */
802 /* deallocated ones on the deaditemqueue. It's up to you to figure out */
803 /* which ones are actually dead. Why? I don't want to allocate extra */
804 /* space just to demarcate dead items. It can usually be done more */
805 /* space-efficiently by a routine that knows something about the structure */
806 /* of the item. */
807 /* */
808 /*****************************************************************************/
809 
811 {
812  void *newitem;
813  unsigned long alignptr;
814 
815  /* Stop upon exhausting the list of items. */
816  if (pool->pathitem == pool->nextitem)
817  {
818  return (void *)NULL;
819  }
820 
821  /* Check whether any untraversed items remain in the current block. */
822  if (pool->pathitemsleft == 0)
823  {
824  /* Find the next block. */
825  pool->pathblock = (void **)*(pool->pathblock);
826  /* Find the first item in the block. Increment by the size of (void *).
827  */
828  alignptr = (unsigned long)(pool->pathblock + 1);
829  /* Align with item on an `alignbytes'-byte boundary. */
830  pool->pathitem = (void *)(alignptr + (unsigned long)pool->alignbytes -
831  (alignptr % (unsigned long)pool->alignbytes));
832  /* Set the number of items left in the current block. */
833  pool->pathitemsleft = pool->itemsperblock;
834  }
835 
836  newitem = pool->pathitem;
837  /* Find the next item in the block. */
838  pool->pathitem = (void *)((char *)pool->pathitem + pool->itembytes);
839  pool->pathitemsleft--;
840  return newitem;
841 }
842 
843 /*****************************************************************************/
844 /* */
845 /* dummyinit() Initialize the triangle that fills "outer space" and the */
846 /* omnipresent subsegment. */
847 /* */
848 /* The triangle that fills "outer space," called `dummytri', is pointed to */
849 /* by every triangle and subsegment on a boundary (be it outer or inner) of */
850 /* the triangulation. Also, `dummytri' points to one of the triangles on */
851 /* the convex hull (until the holes and concavities are carved), making it */
852 /* possible to find a starting triangle for point location. */
853 /* */
854 /* The omnipresent subsegment, `dummysub', is pointed to by every triangle */
855 /* or subsegment that doesn't have a full complement of double subsegments */
856 /* to point to. */
857 /* */
858 /* `dummytri' and `dummysub' are generally required to fulfill only a few */
859 /* invariants: their vertices must remain NULL and `dummytri' must always */
860 /* be bonded (at offset zero) to some triangle on the convex hull of the */
861 /* mesh, via a boundary edge. Otherwise, the connections of `dummytri' and */
862 /* `dummysub' may change willy-nilly. This makes it possible to avoid */
863 /* writing a good deal of special-case code (in the edge flip, for example) */
864 /* for dealing with the boundary of the mesh, places where no subsegment is */
865 /* present, and so forth. Other entities are frequently bonded to */
866 /* `dummytri' and `dummysub' as if they were double mesh entities, with no */
867 /* harm done. */
868 /* */
869 /*****************************************************************************/
870 
872  struct behavior *b,
873  int trianglebytes,
874  int subsegbytes)
875 {
876  unsigned long alignptr;
877 
878  /* Set up `dummytri', the `triangle' that occupies "outer space." */
879  m->dummytribase =
880  (triangle *)trimalloc(trianglebytes + m->triangles.alignbytes);
881  /* Align `dummytri' on a `triangles.alignbytes'-byte boundary. */
882  alignptr = (unsigned long)m->dummytribase;
883  m->dummytri =
884  (triangle *)(alignptr + (unsigned long)m->triangles.alignbytes -
885  (alignptr % (unsigned long)m->triangles.alignbytes));
886  /* Initialize the three adjoining triangles to be "outer space." These */
887  /* will eventually be changed by various bonding operations, but their */
888  /* values don't really matter, as long as they can legally be */
889  /* dereferenced. */
890  m->dummytri[0] = (triangle)m->dummytri;
891  m->dummytri[1] = (triangle)m->dummytri;
892  m->dummytri[2] = (triangle)m->dummytri;
893  /* Three NULL vertices. */
894  m->dummytri[3] = (triangle)NULL;
895  m->dummytri[4] = (triangle)NULL;
896  m->dummytri[5] = (triangle)NULL;
897 
898  if (b->usesegments)
899  {
900  /* Set up `dummysub', the omnipresent subsegment pointed to by any */
901  /* triangle side or subsegment end that isn't attached to a double */
902  /* subsegment. */
903  m->dummysubbase =
904  (subseg *)trimalloc(subsegbytes + m->subsegs.alignbytes);
905  /* Align `dummysub' on a `subsegs.alignbytes'-byte boundary. */
906  alignptr = (unsigned long)m->dummysubbase;
907  m->dummysub =
908  (subseg *)(alignptr + (unsigned long)m->subsegs.alignbytes -
909  (alignptr % (unsigned long)m->subsegs.alignbytes));
910  /* Initialize the two adjoining subsegments to be the omnipresent */
911  /* subsegment. These will eventually be changed by various bonding */
912  /* operations, but their values don't really matter, as long as they
913  */
914  /* can legally be dereferenced. */
915  m->dummysub[0] = (subseg)m->dummysub;
916  m->dummysub[1] = (subseg)m->dummysub;
917  /* Four NULL vertices. */
918  m->dummysub[2] = (subseg)NULL;
919  m->dummysub[3] = (subseg)NULL;
920  m->dummysub[4] = (subseg)NULL;
921  m->dummysub[5] = (subseg)NULL;
922  /* Initialize the two adjoining triangles to be "outer space." */
923  m->dummysub[6] = (subseg)m->dummytri;
924  m->dummysub[7] = (subseg)m->dummytri;
925  /* Set the boundary marker to zero. */
926  *(int *)(m->dummysub + 8) = 0;
927 
928  /* Initialize the three adjoining subsegments of `dummytri' to be */
929  /* the omnipresent subsegment. */
930  m->dummytri[6] = (triangle)m->dummysub;
931  m->dummytri[7] = (triangle)m->dummysub;
932  m->dummytri[8] = (triangle)m->dummysub;
933  }
934 }
935 
936 /*****************************************************************************/
937 /* */
938 /* initializevertexpool() Calculate the size of the vertex data structure */
939 /* and initialize its memory pool. */
940 /* */
941 /* This routine also computes the `vertexmarkindex' and `vertex2triindex' */
942 /* indices used to find values within each vertex. */
943 /* */
944 /*****************************************************************************/
945 
947 {
948  int vertexsize;
949 
950  /* The index within each vertex at which the boundary marker is found, */
951  /* followed by the vertex type. Ensure the vertex marker is aligned to */
952  /* a sizeof(int)-byte address. */
953  m->vertexmarkindex =
954  ((m->mesh_dim + m->nextras) * sizeof(double) + sizeof(int) - 1) /
955  sizeof(int);
956  vertexsize = (m->vertexmarkindex + 2) * sizeof(int);
957  if (b->poly)
958  {
959  /* The index within each vertex at which a triangle pointer is found. */
960  /* Ensure the pointer is aligned to a sizeof(triangle)-byte address.
961  */
962  m->vertex2triindex =
963  (vertexsize + sizeof(triangle) - 1) / sizeof(triangle);
964  vertexsize = (m->vertex2triindex + 1) * sizeof(triangle);
965  }
966 
967  /* Initialize the pool of vertices. */
968  poolinit(&m->vertices,
969  vertexsize,
972  sizeof(double));
973 }
974 
975 /*****************************************************************************/
976 /* */
977 /* initializetrisubpools() Calculate the sizes of the triangle and */
978 /* subsegment data structures and initialize */
979 /* their memory pools. */
980 /* */
981 /* This routine also computes the `highorderindex', `elemattribindex', and */
982 /* `areaboundindex' indices used to find values within each triangle. */
983 /* */
984 /*****************************************************************************/
985 
987 {
988  int trisize;
989 
990  /* The index within each triangle at which the extra nodes (above three) */
991  /* associated with high order elements are found. There are three */
992  /* pointers to other triangles, three pointers to corners, and possibly */
993  /* three pointers to subsegments before the extra nodes. */
994  m->highorderindex = 6 + (b->usesegments * 3);
995  /* The number of bytes occupied by a triangle. */
996  trisize = (3 + (m->highorderindex - 3)) *
997  sizeof(triangle);
998  /* The index within each triangle at which its attributes are found, */
999  /* where the index is measured in doubles. */
1000  m->elemattribindex = (trisize + sizeof(double) - 1) / sizeof(double);
1001  /* The index within each triangle at which the maximum area constraint */
1002  /* is found, where the index is measured in doubles. Note that if the */
1003  /* `regionattrib' flag is set, an additional attribute will be added. */
1004  m->areaboundindex = m->elemattribindex + m->eextras;
1005  /* If triangle attributes or an area bound are needed, increase the number
1006  */
1007  /* of bytes occupied by a triangle. */
1008  trisize = m->areaboundindex * sizeof(double);
1009 
1010  /* Having determined the memory size of a triangle, initialize the pool. */
1011  poolinit(&m->triangles,
1012  trisize,
1013  TRIPERBLOCK,
1014  (2 * m->invertices - 2) > TRIPERBLOCK ? (2 * m->invertices - 2)
1015  : TRIPERBLOCK,
1016  4);
1017 
1018  if (b->usesegments)
1019  {
1020  /* Initialize the pool of subsegments. Take into account all eight */
1021  /* pointers and one boundary marker. */
1022  poolinit(&m->subsegs,
1023  8 * sizeof(triangle) + sizeof(int),
1026  4);
1027 
1028  /* Initialize the "outer space" triangle and omnipresent subsegment. */
1030  }
1031  else
1032  {
1033  /* Initialize the "outer space" triangle. */
1034  dummyinit(m, b, m->triangles.itembytes, 0);
1035  }
1036 }
1037 
1038 /*****************************************************************************/
1039 /* */
1040 /* triangledealloc() Deallocate space for a triangle, marking it dead. */
1041 /* */
1042 /*****************************************************************************/
1043 
1044 void DelaunayTriangle::triangledealloc(struct mesh *m, triangle *dyingtriangle)
1045 {
1046  /* Mark the triangle as dead. This makes it possible to detect dead */
1047  /* triangles when traversing the list of all triangles. */
1048  killtri(dyingtriangle);
1049  pooldealloc(&m->triangles, (void *)dyingtriangle);
1050 }
1051 
1052 /*****************************************************************************/
1053 /* */
1054 /* triangletraverse() Traverse the triangles, skipping dead ones. */
1055 /* */
1056 /*****************************************************************************/
1057 
1059 {
1060  triangle *newtriangle;
1061 
1062  do
1063  {
1064  newtriangle = (triangle *)traverse(&m->triangles);
1065  if (newtriangle == (triangle *)NULL)
1066  {
1067  return (triangle *)NULL;
1068  }
1069  } while (deadtri(newtriangle)); /* Skip dead ones. */
1070  return newtriangle;
1071 }
1072 
1073 /*****************************************************************************/
1074 /* */
1075 /* subsegdealloc() Deallocate space for a subsegment, marking it dead. */
1076 /* */
1077 /*****************************************************************************/
1078 
1079 void DelaunayTriangle::subsegdealloc(struct mesh *m, subseg *dyingsubseg)
1080 {
1081  /* Mark the subsegment as dead. This makes it possible to detect dead */
1082  /* subsegments when traversing the list of all subsegments. */
1083  killsubseg(dyingsubseg);
1084  pooldealloc(&m->subsegs, (void *)dyingsubseg);
1085 }
1086 
1087 /*****************************************************************************/
1088 /* */
1089 /* subsegtraverse() Traverse the subsegments, skipping dead ones. */
1090 /* */
1091 /*****************************************************************************/
1092 
1094 {
1095  subseg *newsubseg;
1096 
1097  do
1098  {
1099  newsubseg = (subseg *)traverse(&m->subsegs);
1100  if (newsubseg == (subseg *)NULL)
1101  {
1102  return (subseg *)NULL;
1103  }
1104  } while (deadsubseg(newsubseg)); /* Skip dead ones. */
1105  return newsubseg;
1106 }
1107 
1108 /*****************************************************************************/
1109 /* */
1110 /* vertexdealloc() Deallocate space for a vertex, marking it dead. */
1111 /* */
1112 /*****************************************************************************/
1113 
1114 void DelaunayTriangle::vertexdealloc(struct mesh *m, vertex dyingvertex)
1115 {
1116  /* Mark the vertex as dead. This makes it possible to detect dead */
1117  /* vertices when traversing the list of all vertices. */
1118  setvertextype(dyingvertex, DEADVERTEX);
1119  pooldealloc(&m->vertices, (void *)dyingvertex);
1120 }
1121 
1122 /*****************************************************************************/
1123 /* */
1124 /* vertextraverse() Traverse the vertices, skipping dead ones. */
1125 /* */
1126 /*****************************************************************************/
1127 
1129 {
1130  vertex newvertex;
1131 
1132  do
1133  {
1134  newvertex = (vertex)traverse(&m->vertices);
1135  if (newvertex == (vertex)NULL)
1136  {
1137  return (vertex)NULL;
1138  }
1139  } while (vertextype(newvertex) == DEADVERTEX); /* Skip dead ones. */
1140  return newvertex;
1141 }
1142 
1143 /*****************************************************************************/
1144 /* */
1145 /* badsubsegdealloc() Deallocate space for a bad subsegment, marking it */
1146 /* dead. */
1147 /* */
1148 /*****************************************************************************/
1149 
1150 void DelaunayTriangle::badsubsegdealloc(struct mesh *m, struct badsubseg *dyingseg)
1151 {
1152  /* Set subsegment's origin to NULL. This makes it possible to detect dead
1153  */
1154  /* badsubsegs when traversing the list of all badsubsegs . */
1155  dyingseg->subsegorg = (vertex)NULL;
1156  pooldealloc(&m->badsubsegs, (void *)dyingseg);
1157 }
1158 
1159 /*****************************************************************************/
1160 /* */
1161 /* badsubsegtraverse() Traverse the bad subsegments, skipping dead ones. */
1162 /* */
1163 /*****************************************************************************/
1164 
1166 {
1167  struct badsubseg *newseg;
1168 
1169  do
1170  {
1171  newseg = (struct badsubseg *)traverse(&m->badsubsegs);
1172  if (newseg == (struct badsubseg *)NULL)
1173  {
1174  return (struct badsubseg *)NULL;
1175  }
1176  } while (newseg->subsegorg == (vertex)NULL); /* Skip dead ones. */
1177  return newseg;
1178 }
1179 
1180 /*****************************************************************************/
1181 /* */
1182 /* getvertex() Get a specific vertex, by number, from the list. */
1183 /* */
1184 /* The first vertex is number 'firstnumber'. */
1185 /* */
1186 /* Note that this takes O(n) time (with a small constant, if VERTEXPERBLOCK */
1187 /* is large). I don't care to take the trouble to make it work in constant */
1188 /* time. */
1189 /* */
1190 /*****************************************************************************/
1191 
1192 vertex DelaunayTriangle::getvertex(struct mesh *m, struct behavior *b, int number)
1193 {
1194  void **getblock;
1195  char *foundvertex;
1196  unsigned long alignptr;
1197  int current;
1198 
1199  getblock = m->vertices.firstblock;
1200  current = 0;
1201 
1202  /* Find the right block. */
1203  if (current + m->vertices.itemsfirstblock <= number)
1204  {
1205  getblock = (void **)*getblock;
1206  current += m->vertices.itemsfirstblock;
1207  while (current + m->vertices.itemsperblock <= number)
1208  {
1209  getblock = (void **)*getblock;
1210  current += m->vertices.itemsperblock;
1211  }
1212  }
1213 
1214  /* Now find the right vertex. */
1215  alignptr = (unsigned long)(getblock + 1);
1216  foundvertex = (char *)(alignptr + (unsigned long)m->vertices.alignbytes -
1217  (alignptr % (unsigned long)m->vertices.alignbytes));
1218  return (vertex)(foundvertex + m->vertices.itembytes * (number - current));
1219 }
1220 
1221 /*****************************************************************************/
1222 /* */
1223 /* triangledeinit() Free all remaining allocated memory. */
1224 /* */
1225 /*****************************************************************************/
1226 
1228 {
1229  pooldeinit(&m->triangles);
1230  trifree((void *)m->dummytribase);
1231  if (b->usesegments)
1232  {
1233  pooldeinit(&m->subsegs);
1234  trifree((void *)m->dummysubbase);
1235  }
1236  pooldeinit(&m->vertices);
1237  if (b->quality)
1238  {
1239  pooldeinit(&m->badsubsegs);
1240  if ((b->minangle > 0.0) || b->usertest)
1241  {
1242  pooldeinit(&m->badtriangles);
1243  pooldeinit(&m->flipstackers);
1244  }
1245  }
1246 }
1247 
1248 /** **/
1249 /** **/
1250 /********* Memory management routines end here *********/
1251 
1252 /********* Constructors begin here *********/
1253 /** **/
1254 /** **/
1255 
1256 /*****************************************************************************/
1257 /* */
1258 /* maketriangle() Create a new triangle with orientation zero. */
1259 /* */
1260 /*****************************************************************************/
1261 
1262 void DelaunayTriangle::maketriangle(struct mesh *m, struct behavior *b, struct otri *newotri)
1263 {
1264  int i;
1265 
1266  newotri->tri = (triangle *)poolalloc(&m->triangles);
1267  /* Initialize the three adjoining triangles to be "outer space". */
1268  newotri->tri[0] = (triangle)m->dummytri;
1269  newotri->tri[1] = (triangle)m->dummytri;
1270  newotri->tri[2] = (triangle)m->dummytri;
1271  /* Three NULL vertices. */
1272  newotri->tri[3] = (triangle)NULL;
1273  newotri->tri[4] = (triangle)NULL;
1274  newotri->tri[5] = (triangle)NULL;
1275  if (b->usesegments)
1276  {
1277  /* Initialize the three adjoining subsegments to be the omnipresent */
1278  /* subsegment. */
1279  newotri->tri[6] = (triangle)m->dummysub;
1280  newotri->tri[7] = (triangle)m->dummysub;
1281  newotri->tri[8] = (triangle)m->dummysub;
1282  }
1283  for (i = 0; i < m->eextras; i++)
1284  {
1285  setelemattribute(*newotri, i, 0.0);
1286  }
1287 
1288  newotri->orient = 0;
1289 }
1290 
1291 /*****************************************************************************/
1292 /* */
1293 /* makesubseg() Create a new subsegment with orientation zero. */
1294 /* */
1295 /*****************************************************************************/
1296 
1297 void DelaunayTriangle::makesubseg(struct mesh *m, struct osub *newsubseg)
1298 {
1299  newsubseg->ss = (subseg *)poolalloc(&m->subsegs);
1300  /* Initialize the two adjoining subsegments to be the omnipresent */
1301  /* subsegment. */
1302  newsubseg->ss[0] = (subseg)m->dummysub;
1303  newsubseg->ss[1] = (subseg)m->dummysub;
1304  /* Four NULL vertices. */
1305  newsubseg->ss[2] = (subseg)NULL;
1306  newsubseg->ss[3] = (subseg)NULL;
1307  newsubseg->ss[4] = (subseg)NULL;
1308  newsubseg->ss[5] = (subseg)NULL;
1309  /* Initialize the two adjoining triangles to be "outer space." */
1310  newsubseg->ss[6] = (subseg)m->dummytri;
1311  newsubseg->ss[7] = (subseg)m->dummytri;
1312  /* Set the boundary marker to zero. */
1313  setmark(*newsubseg, 0);
1314 
1315  newsubseg->ssorient = 0;
1316 }
1317 
1318 /** **/
1319 /** **/
1320 /********* Constructors end here *********/
1321 
1322 /********* Geometric primitives begin here *********/
1323 /** **/
1324 /** **/
1325 
1326 /* The adaptive exact arithmetic geometric predicates implemented herein are */
1327 /* described in detail in my paper, "Adaptive Precision Floating-Point */
1328 /* Arithmetic and Fast Robust Geometric Predicates." See the header for a */
1329 /* full citation. */
1330 
1331 /* Which of the following two methods of finding the absolute values is */
1332 /* fastest is compiler-dependent. A few compilers can inline and optimize */
1333 /* the fabs() call; but most will incur the overhead of a function call, */
1334 /* which is disastrously slow. A faster way on IEEE machines might be to */
1335 /* mask the appropriate bit, but that's difficult to do in C without */
1336 /* forcing the value to be stored to memory (rather than be kept in the */
1337 /* register to which the optimizer assigned it). */
1338 
1339 #define Absolute(a) ((a) >= 0.0 ? (a) : -(a))
1340 /* #define Absolute(a) fabs(a) */
1341 
1342 /* Many of the operations are broken up into two pieces, a main part that */
1343 /* performs an approximate operation, and a "tail" that computes the */
1344 /* roundoff error of that operation. */
1345 /* */
1346 /* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(), */
1347 /* Split(), and Two_Product() are all implemented as described in the */
1348 /* reference. Each of these macros requires certain variables to be */
1349 /* defined in the calling routine. The variables `bvirt', `c', `abig', */
1350 /* `_i', `_j', `_k', `_l', `_m', and `_n' are declared `' because */
1351 /* they store the result of an operation that may incur roundoff error. */
1352 /* The input parameter `x' (or the highest numbered `x_' parameter) must */
1353 /* also be declared `'. */
1354 
1355 #define Fast_Two_Sum_Tail(a, b, x, y) \
1356  bvirt = x - a; \
1357  y = b - bvirt
1358 
1359 #define Fast_Two_Sum(a, b, x, y) \
1360  x = (double)(a + b); \
1361  Fast_Two_Sum_Tail(a, b, x, y)
1362 
1363 #define Two_Sum_Tail(a, b, x, y) \
1364  bvirt = (double)(x - a); \
1365  avirt = x - bvirt; \
1366  bround = b - bvirt; \
1367  around = a - avirt; \
1368  y = around + bround
1369 
1370 #define Two_Sum(a, b, x, y) \
1371  x = (double)(a + b); \
1372  Two_Sum_Tail(a, b, x, y)
1373 
1374 #define Two_Diff_Tail(a, b, x, y) \
1375  bvirt = (double)(a - x); \
1376  avirt = x + bvirt; \
1377  bround = bvirt - b; \
1378  around = a - avirt; \
1379  y = around + bround
1380 
1381 #define Two_Diff(a, b, x, y) \
1382  x = (double)(a - b); \
1383  Two_Diff_Tail(a, b, x, y)
1384 
1385 #define Split(a, ahi, alo) \
1386  c = (double)(splitter * a); \
1387  abig = (double)(c - a); \
1388  ahi = c - abig; \
1389  alo = a - ahi
1390 
1391 #define Two_Product_Tail(a, b, x, y) \
1392  Split(a, ahi, alo); \
1393  Split(b, bhi, blo); \
1394  err1 = x - (ahi * bhi); \
1395  err2 = err1 - (alo * bhi); \
1396  err3 = err2 - (ahi * blo); \
1397  y = (alo * blo) - err3
1398 
1399 #define Two_Product(a, b, x, y) \
1400  x = (double)(a * b); \
1401  Two_Product_Tail(a, b, x, y)
1402 
1403 /* Two_Product_Presplit() is Two_Product() where one of the inputs has */
1404 /* already been split. Avoids redundant splitting. */
1405 
1406 #define Two_Product_Presplit(a, b, bhi, blo, x, y) \
1407  x = (double)(a * b); \
1408  Split(a, ahi, alo); \
1409  err1 = x - (ahi * bhi); \
1410  err2 = err1 - (alo * bhi); \
1411  err3 = err2 - (ahi * blo); \
1412  y = (alo * blo) - err3
1413 
1414 /* Square() can be done more quickly than Two_Product(). */
1415 
1416 #define Square_Tail(a, x, y) \
1417  Split(a, ahi, alo); \
1418  err1 = x - (ahi * ahi); \
1419  err3 = err1 - ((ahi + ahi) * alo); \
1420  y = (alo * alo) - err3
1421 
1422 #define Square(a, x, y) \
1423  x = (double)(a * a); \
1424  Square_Tail(a, x, y)
1425 
1426 /* Macros for summing expansions of various fixed lengths. These are all */
1427 /* unrolled versions of Expansion_Sum(). */
1428 
1429 #define Two_One_Sum(a1, a0, b, x2, x1, x0) \
1430  Two_Sum(a0, b, _i, x0); \
1431  Two_Sum(a1, _i, x2, x1)
1432 
1433 #define Two_One_Diff(a1, a0, b, x2, x1, x0) \
1434  Two_Diff(a0, b, _i, x0); \
1435  Two_Sum(a1, _i, x2, x1)
1436 
1437 #define Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0) \
1438  Two_One_Sum(a1, a0, b0, _j, _0, x0); \
1439  Two_One_Sum(_j, _0, b1, x3, x2, x1)
1440 
1441 #define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0) \
1442  Two_One_Diff(a1, a0, b0, _j, _0, x0); \
1443  Two_One_Diff(_j, _0, b1, x3, x2, x1)
1444 
1445 /* Macro for multiplying a two-component expansion by a single component. */
1446 
1447 #define Two_One_Product(a1, a0, b, x3, x2, x1, x0) \
1448  Split(b, bhi, blo); \
1449  Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \
1450  Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \
1451  Two_Sum(_i, _0, _k, x1); \
1452  Fast_Two_Sum(_j, _k, x3, x2)
1453 
1454 /*****************************************************************************/
1455 /* */
1456 /* exactinit() Initialize the variables used for exact arithmetic. */
1457 /* */
1458 /* `epsilon' is the largest power of two such that 1.0 + epsilon = 1.0 in */
1459 /* floating-point arithmetic. `epsilon' bounds the relative roundoff */
1460 /* error. It is used for floating-point error analysis. */
1461 /* */
1462 /* `splitter' is used to split floating-point numbers into two half- */
1463 /* length significands for exact multiplication. */
1464 /* */
1465 /* I imagine that a highly optimizing compiler might be too smart for its */
1466 /* own good, and somehow cause this routine to fail, if it pretends that */
1467 /* floating-point arithmetic is too much like double arithmetic. */
1468 /* */
1469 /* Don't change this routine unless you fully understand it. */
1470 /* */
1471 /*****************************************************************************/
1472 
1474 {
1475  double half;
1476  double check, lastcheck;
1477  int every_other;
1478 
1479  every_other = 1;
1480  half = 0.5;
1481  epsilon = 1.0;
1482  splitter = 1.0;
1483  check = 1.0;
1484  /* Repeatedly divide `epsilon' by two until it is too small to add to */
1485  /* one without causing roundoff. (Also check if the sum is equal to */
1486  /* the previous sum, for machines that round up instead of using exact */
1487  /* rounding. Not that these routines will work on such machines.) */
1488  do
1489  {
1490  lastcheck = check;
1491  epsilon *= half;
1492  if (every_other)
1493  {
1494  splitter *= 2.0;
1495  }
1496  every_other = !every_other;
1497  check = 1.0 + epsilon;
1498  } while ((check != 1.0) && (check != lastcheck));
1499  splitter += 1.0;
1500  /* Error bounds for orientation and incircle tests. */
1501  resulterrbound = (3.0 + 8.0 * epsilon) * epsilon;
1502  ccwerrboundA = (3.0 + 16.0 * epsilon) * epsilon;
1503  ccwerrboundB = (2.0 + 12.0 * epsilon) * epsilon;
1504  ccwerrboundC = (9.0 + 64.0 * epsilon) * epsilon * epsilon;
1505  iccerrboundA = (10.0 + 96.0 * epsilon) * epsilon;
1506  iccerrboundB = (4.0 + 48.0 * epsilon) * epsilon;
1507  iccerrboundC = (44.0 + 576.0 * epsilon) * epsilon * epsilon;
1508  o3derrboundA = (7.0 + 56.0 * epsilon) * epsilon;
1509  o3derrboundB = (3.0 + 28.0 * epsilon) * epsilon;
1510  o3derrboundC = (26.0 + 288.0 * epsilon) * epsilon * epsilon;
1511 }
1512 
1513 /*****************************************************************************/
1514 /* */
1515 /* fast_expansion_sum_zeroelimTRI() Sum two expansions, eliminating zero */
1516 /* components from the output expansion. */
1517 /* */
1518 /* Sets h = e + f. See my Robust Predicates paper for details. */
1519 /* */
1520 /* If round-to-even is used (as with IEEE 754), maintains the strongly */
1521 /* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */
1522 /* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */
1523 /* properties. */
1524 /* */
1525 /*****************************************************************************/
1526 
1528  int elen, double *e, int flen, double *f, double *h)
1529 {
1530  double Q;
1531  double Qnew;
1532  double hh;
1533  double bvirt;
1534  double avirt, bround, around;
1535  int eindex, findex, hindex;
1536  double enow, fnow;
1537 
1538  enow = e[0];
1539  fnow = f[0];
1540  eindex = findex = 0;
1541  if ((fnow > enow) == (fnow > -enow))
1542  {
1543  Q = enow;
1544  enow = e[++eindex];
1545  }
1546  else
1547  {
1548  Q = fnow;
1549  fnow = f[++findex];
1550  }
1551  hindex = 0;
1552  if ((eindex < elen) && (findex < flen))
1553  {
1554  if ((fnow > enow) == (fnow > -enow))
1555  {
1556  Fast_Two_Sum(enow, Q, Qnew, hh);
1557  enow = e[++eindex];
1558  }
1559  else
1560  {
1561  Fast_Two_Sum(fnow, Q, Qnew, hh);
1562  fnow = f[++findex];
1563  }
1564  Q = Qnew;
1565  if (hh != 0.0)
1566  {
1567  h[hindex++] = hh;
1568  }
1569  while ((eindex < elen) && (findex < flen))
1570  {
1571  if ((fnow > enow) == (fnow > -enow))
1572  {
1573  Two_Sum(Q, enow, Qnew, hh);
1574  enow = e[++eindex];
1575  }
1576  else
1577  {
1578  Two_Sum(Q, fnow, Qnew, hh);
1579  fnow = f[++findex];
1580  }
1581  Q = Qnew;
1582  if (hh != 0.0)
1583  {
1584  h[hindex++] = hh;
1585  }
1586  }
1587  }
1588  while (eindex < elen)
1589  {
1590  Two_Sum(Q, enow, Qnew, hh);
1591  enow = e[++eindex];
1592  Q = Qnew;
1593  if (hh != 0.0)
1594  {
1595  h[hindex++] = hh;
1596  }
1597  }
1598  while (findex < flen)
1599  {
1600  Two_Sum(Q, fnow, Qnew, hh);
1601  fnow = f[++findex];
1602  Q = Qnew;
1603  if (hh != 0.0)
1604  {
1605  h[hindex++] = hh;
1606  }
1607  }
1608  if ((Q != 0.0) || (hindex == 0))
1609  {
1610  h[hindex++] = Q;
1611  }
1612  return hindex;
1613 }
1614 
1615 /*****************************************************************************/
1616 /* */
1617 /* scale_expansion_zeroelimTRI() Multiply an expansion by a scalar, */
1618 /* eliminating zero components from the */
1619 /* output expansion. */
1620 /* */
1621 /* Sets h = be. See my Robust Predicates paper for details. */
1622 /* */
1623 /* Maintains the nonoverlapping property. If round-to-even is used (as */
1624 /* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */
1625 /* properties as well. (That is, if e has one of these properties, so */
1626 /* will h.) */
1627 /* */
1628 /*****************************************************************************/
1629 
1630 int DelaunayTriangle::scale_expansion_zeroelimTRI(int elen, double *e, double b, double *h)
1631 {
1632  double Q, sum;
1633  double hh;
1634  double product1;
1635  double product0;
1636  int eindex, hindex;
1637  double enow;
1638  double bvirt;
1639  double avirt, bround, around;
1640  double c;
1641  double abig;
1642  double ahi, alo, bhi, blo;
1643  double err1, err2, err3;
1644 
1645  Split(b, bhi, blo);
1646  Two_Product_Presplit(e[0], b, bhi, blo, Q, hh);
1647  hindex = 0;
1648  if (hh != 0)
1649  {
1650  h[hindex++] = hh;
1651  }
1652  for (eindex = 1; eindex < elen; eindex++)
1653  {
1654  enow = e[eindex];
1655  Two_Product_Presplit(enow, b, bhi, blo, product1, product0);
1656  Two_Sum(Q, product0, sum, hh);
1657  if (hh != 0)
1658  {
1659  h[hindex++] = hh;
1660  }
1661  Fast_Two_Sum(product1, sum, Q, hh);
1662  if (hh != 0)
1663  {
1664  h[hindex++] = hh;
1665  }
1666  }
1667  if ((Q != 0.0) || (hindex == 0))
1668  {
1669  h[hindex++] = Q;
1670  }
1671  return hindex;
1672 }
1673 
1674 /*****************************************************************************/
1675 /* */
1676 /* estimateTRI() Produce a one-word estimateTRI of an expansion's value. */
1677 /* */
1678 /* See my Robust Predicates paper for details. */
1679 /* */
1680 /*****************************************************************************/
1681 
1682 double DelaunayTriangle::estimateTRI(int elen, double *e)
1683 {
1684  double Q;
1685  int eindex;
1686 
1687  Q = e[0];
1688  for (eindex = 1; eindex < elen; eindex++)
1689  {
1690  Q += e[eindex];
1691  }
1692  return Q;
1693 }
1694 
1695 /*****************************************************************************/
1696 /* */
1697 /* counterclockwise() Return a positive value if the points pa, pb, and */
1698 /* pc occur in counterclockwise order; a negative */
1699 /* value if they occur in clockwise order; and zero */
1700 /* if they are collinear. The result is also a rough */
1701 /* approximation of twice the signed area of the */
1702 /* triangle defined by the three points. */
1703 /* */
1704 /* Uses exact arithmetic if necessary to ensure a correct answer. The */
1705 /* result returned is the determinant of a matrix. This determinant is */
1706 /* computed adaptively, in the sense that exact arithmetic is used only to */
1707 /* the degree it is needed to ensure that the returned value has the */
1708 /* correct sign. Hence, this function is usually quite fast, but will run */
1709 /* more slowly when the input points are collinear or nearly so. */
1710 /* */
1711 /* See my Robust Predicates paper for details. */
1712 /* */
1713 /*****************************************************************************/
1714 
1716 {
1717  double acx, acy, bcx, bcy;
1718  double acxtail, acytail, bcxtail, bcytail;
1719  double detleft, detright;
1720  double detlefttail, detrighttail;
1721  double det, errbound;
1722  double B[4], C1[8], C2[12], D[16];
1723  double B3;
1724  int C1length, C2length, Dlength;
1725  double u[4];
1726  double u3;
1727  double s1, t1;
1728  double s0, t0;
1729 
1730  double bvirt;
1731  double avirt, bround, around;
1732  double c;
1733  double abig;
1734  double ahi, alo, bhi, blo;
1735  double err1, err2, err3;
1736  double _i, _j;
1737  double _0;
1738 
1739  acx = (double)(pa[0] - pc[0]);
1740  bcx = (double)(pb[0] - pc[0]);
1741  acy = (double)(pa[1] - pc[1]);
1742  bcy = (double)(pb[1] - pc[1]);
1743 
1744  Two_Product(acx, bcy, detleft, detlefttail);
1745  Two_Product(acy, bcx, detright, detrighttail);
1746 
1747  Two_Two_Diff(
1748  detleft, detlefttail, detright, detrighttail, B3, B[2], B[1], B[0]);
1749  B[3] = B3;
1750 
1751  det = estimateTRI(4, B);
1752  errbound = ccwerrboundB * detsum;
1753  if ((det >= errbound) || (-det >= errbound))
1754  {
1755  return det;
1756  }
1757 
1758  Two_Diff_Tail(pa[0], pc[0], acx, acxtail);
1759  Two_Diff_Tail(pb[0], pc[0], bcx, bcxtail);
1760  Two_Diff_Tail(pa[1], pc[1], acy, acytail);
1761  Two_Diff_Tail(pb[1], pc[1], bcy, bcytail);
1762 
1763  if ((acxtail == 0.0) && (acytail == 0.0) && (bcxtail == 0.0) &&
1764  (bcytail == 0.0))
1765  {
1766  return det;
1767  }
1768 
1769  errbound = ccwerrboundC * detsum + resulterrbound * Absolute(det);
1770  det += (acx * bcytail + bcy * acxtail) - (acy * bcxtail + bcx * acytail);
1771  if ((det >= errbound) || (-det >= errbound))
1772  {
1773  return det;
1774  }
1775 
1776  Two_Product(acxtail, bcy, s1, s0);
1777  Two_Product(acytail, bcx, t1, t0);
1778  Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
1779  u[3] = u3;
1780  C1length = fast_expansion_sum_zeroelimTRI(4, B, 4, u, C1);
1781 
1782  Two_Product(acx, bcytail, s1, s0);
1783  Two_Product(acy, bcxtail, t1, t0);
1784  Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
1785  u[3] = u3;
1786  C2length = fast_expansion_sum_zeroelimTRI(C1length, C1, 4, u, C2);
1787 
1788  Two_Product(acxtail, bcytail, s1, s0);
1789  Two_Product(acytail, bcxtail, t1, t0);
1790  Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
1791  u[3] = u3;
1792  Dlength = fast_expansion_sum_zeroelimTRI(C2length, C2, 4, u, D);
1793 
1794  return (D[Dlength - 1]);
1795 }
1796 
1798  struct mesh *m, struct behavior *b, vertex pa, vertex pb, vertex pc)
1799 {
1800  double detleft, detright, det;
1801  double detsum, errbound;
1802 
1803  m->counterclockcount++;
1804 
1805  detleft = (pa[0] - pc[0]) * (pb[1] - pc[1]);
1806  detright = (pa[1] - pc[1]) * (pb[0] - pc[0]);
1807  det = detleft - detright;
1808 
1809  if (detleft > 0.0)
1810  {
1811  if (detright <= 0.0)
1812  {
1813  return det;
1814  }
1815  else
1816  {
1817  detsum = detleft + detright;
1818  }
1819  }
1820  else if (detleft < 0.0)
1821  {
1822  if (detright >= 0.0)
1823  {
1824  return det;
1825  }
1826  else
1827  {
1828  detsum = -detleft - detright;
1829  }
1830  }
1831  else
1832  {
1833  return det;
1834  }
1835 
1836  errbound = ccwerrboundA * detsum;
1837  if ((det >= errbound) || (-det >= errbound))
1838  {
1839  return det;
1840  }
1841 
1842  return counterclockwiseadapt(pa, pb, pc, detsum);
1843 }
1844 
1845 /*****************************************************************************/
1846 /* */
1847 /* incircle() Return a positive value if the point pd lies inside the */
1848 /* circle passing through pa, pb, and pc; a negative value if */
1849 /* it lies outside; and zero if the four points are cocircular.*/
1850 /* The points pa, pb, and pc must be in counterclockwise */
1851 /* order, or the sign of the result will be reversed. */
1852 /* */
1853 /* Uses exact arithmetic if necessary to ensure a correct answer. The */
1854 /* result returned is the determinant of a matrix. This determinant is */
1855 /* computed adaptively, in the sense that exact arithmetic is used only to */
1856 /* the degree it is needed to ensure that the returned value has the */
1857 /* correct sign. Hence, this function is usually quite fast, but will run */
1858 /* more slowly when the input points are cocircular or nearly so. */
1859 /* */
1860 /* See my Robust Predicates paper for details. */
1861 /* */
1862 /*****************************************************************************/
1863 
1865  vertex pa, vertex pb, vertex pc, vertex pd, double permanent)
1866 {
1867  double adx, bdx, cdx, ady, bdy, cdy;
1868  double det, errbound;
1869 
1870  double bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1;
1871  double bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0;
1872  double bc[4], ca[4], ab[4];
1873  double bc3, ca3, ab3;
1874  double axbc[8], axxbc[16], aybc[8], ayybc[16], adet[32];
1875  int axbclen, axxbclen, aybclen, ayybclen, alen;
1876  double bxca[8], bxxca[16], byca[8], byyca[16], bdet[32];
1877  int bxcalen, bxxcalen, bycalen, byycalen, blen;
1878  double cxab[8], cxxab[16], cyab[8], cyyab[16], cdet[32];
1879  int cxablen, cxxablen, cyablen, cyyablen, clen;
1880  double abdet[64];
1881  int ablen;
1882  double fin1[1152], fin2[1152];
1883  double *finnow, *finother, *finswap;
1884  int finlength;
1885 
1886  double adxtail, bdxtail, cdxtail, adytail, bdytail, cdytail;
1887  double adxadx1, adyady1, bdxbdx1, bdybdy1, cdxcdx1, cdycdy1;
1888  double adxadx0, adyady0, bdxbdx0, bdybdy0, cdxcdx0, cdycdy0;
1889  double aa[4], bb[4], cc[4];
1890  double aa3, bb3, cc3;
1891  double ti1, tj1;
1892  double ti0, tj0;
1893  double u[4], v[4];
1894  double u3, v3;
1895  double temp8[8], temp16a[16], temp16b[16], temp16c[16];
1896  double temp32a[32], temp32b[32], temp48[48], temp64[64];
1897  int temp8len, temp16alen, temp16blen, temp16clen;
1898  int temp32alen, temp32blen, temp48len, temp64len;
1899  double axtbb[8], axtcc[8], aytbb[8], aytcc[8];
1900  int axtbblen, axtcclen, aytbblen, aytcclen;
1901  double bxtaa[8], bxtcc[8], bytaa[8], bytcc[8];
1902  int bxtaalen, bxtcclen, bytaalen, bytcclen;
1903  double cxtaa[8], cxtbb[8], cytaa[8], cytbb[8];
1904  int cxtaalen, cxtbblen, cytaalen, cytbblen;
1905  double axtbc[8], aytbc[8], bxtca[8], bytca[8], cxtab[8], cytab[8];
1906  int axtbclen, aytbclen, bxtcalen, bytcalen, cxtablen, cytablen;
1907  double axtbct[16], aytbct[16], bxtcat[16], bytcat[16], cxtabt[16],
1908  cytabt[16];
1909  int axtbctlen, aytbctlen, bxtcatlen, bytcatlen, cxtabtlen, cytabtlen;
1910  double axtbctt[8], aytbctt[8], bxtcatt[8];
1911  double bytcatt[8], cxtabtt[8], cytabtt[8];
1912  int axtbcttlen, aytbcttlen, bxtcattlen, bytcattlen, cxtabttlen, cytabttlen;
1913  double abt[8], bct[8], cat[8];
1914  int abtlen, bctlen, catlen;
1915  double abtt[4], bctt[4], catt[4];
1916  int abttlen, bcttlen, cattlen;
1917  double abtt3, bctt3, catt3;
1918  double negate;
1919 
1920  double bvirt;
1921  double avirt, bround, around;
1922  double c;
1923  double abig;
1924  double ahi, alo, bhi, blo;
1925  double err1, err2, err3;
1926  double _i, _j;
1927  double _0;
1928 
1929  adx = (double)(pa[0] - pd[0]);
1930  bdx = (double)(pb[0] - pd[0]);
1931  cdx = (double)(pc[0] - pd[0]);
1932  ady = (double)(pa[1] - pd[1]);
1933  bdy = (double)(pb[1] - pd[1]);
1934  cdy = (double)(pc[1] - pd[1]);
1935 
1936  Two_Product(bdx, cdy, bdxcdy1, bdxcdy0);
1937  Two_Product(cdx, bdy, cdxbdy1, cdxbdy0);
1938  Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]);
1939  bc[3] = bc3;
1940  axbclen = scale_expansion_zeroelimTRI(4, bc, adx, axbc);
1941  axxbclen = scale_expansion_zeroelimTRI(axbclen, axbc, adx, axxbc);
1942  aybclen = scale_expansion_zeroelimTRI(4, bc, ady, aybc);
1943  ayybclen = scale_expansion_zeroelimTRI(aybclen, aybc, ady, ayybc);
1944  alen = fast_expansion_sum_zeroelimTRI(axxbclen, axxbc, ayybclen, ayybc, adet);
1945 
1946  Two_Product(cdx, ady, cdxady1, cdxady0);
1947  Two_Product(adx, cdy, adxcdy1, adxcdy0);
1948  Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]);
1949  ca[3] = ca3;
1950  bxcalen = scale_expansion_zeroelimTRI(4, ca, bdx, bxca);
1951  bxxcalen = scale_expansion_zeroelimTRI(bxcalen, bxca, bdx, bxxca);
1952  bycalen = scale_expansion_zeroelimTRI(4, ca, bdy, byca);
1953  byycalen = scale_expansion_zeroelimTRI(bycalen, byca, bdy, byyca);
1954  blen = fast_expansion_sum_zeroelimTRI(bxxcalen, bxxca, byycalen, byyca, bdet);
1955 
1956  Two_Product(adx, bdy, adxbdy1, adxbdy0);
1957  Two_Product(bdx, ady, bdxady1, bdxady0);
1958  Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]);
1959  ab[3] = ab3;
1960  cxablen = scale_expansion_zeroelimTRI(4, ab, cdx, cxab);
1961  cxxablen = scale_expansion_zeroelimTRI(cxablen, cxab, cdx, cxxab);
1962  cyablen = scale_expansion_zeroelimTRI(4, ab, cdy, cyab);
1963  cyyablen = scale_expansion_zeroelimTRI(cyablen, cyab, cdy, cyyab);
1964  clen = fast_expansion_sum_zeroelimTRI(cxxablen, cxxab, cyyablen, cyyab, cdet);
1965 
1966  ablen = fast_expansion_sum_zeroelimTRI(alen, adet, blen, bdet, abdet);
1967  finlength = fast_expansion_sum_zeroelimTRI(ablen, abdet, clen, cdet, fin1);
1968 
1969  det = estimateTRI(finlength, fin1);
1970  errbound = iccerrboundB * permanent;
1971  if ((det >= errbound) || (-det >= errbound))
1972  {
1973  return det;
1974  }
1975 
1976  Two_Diff_Tail(pa[0], pd[0], adx, adxtail);
1977  Two_Diff_Tail(pa[1], pd[1], ady, adytail);
1978  Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail);
1979  Two_Diff_Tail(pb[1], pd[1], bdy, bdytail);
1980  Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail);
1981  Two_Diff_Tail(pc[1], pd[1], cdy, cdytail);
1982  if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0) &&
1983  (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0))
1984  {
1985  return det;
1986  }
1987 
1988  errbound = iccerrboundC * permanent + resulterrbound * Absolute(det);
1989  det += ((adx * adx + ady * ady) * ((bdx * cdytail + cdy * bdxtail) -
1990  (bdy * cdxtail + cdx * bdytail)) +
1991  2.0 * (adx * adxtail + ady * adytail) * (bdx * cdy - bdy * cdx)) +
1992  ((bdx * bdx + bdy * bdy) * ((cdx * adytail + ady * cdxtail) -
1993  (cdy * adxtail + adx * cdytail)) +
1994  2.0 * (bdx * bdxtail + bdy * bdytail) * (cdx * ady - cdy * adx)) +
1995  ((cdx * cdx + cdy * cdy) * ((adx * bdytail + bdy * adxtail) -
1996  (ady * bdxtail + bdx * adytail)) +
1997  2.0 * (cdx * cdxtail + cdy * cdytail) * (adx * bdy - ady * bdx));
1998  if ((det >= errbound) || (-det >= errbound))
1999  {
2000  return det;
2001  }
2002 
2003  finnow = fin1;
2004  finother = fin2;
2005 
2006  if ((bdxtail != 0.0) || (bdytail != 0.0) || (cdxtail != 0.0) ||
2007  (cdytail != 0.0))
2008  {
2009  Square(adx, adxadx1, adxadx0);
2010  Square(ady, adyady1, adyady0);
2011  Two_Two_Sum(
2012  adxadx1, adxadx0, adyady1, adyady0, aa3, aa[2], aa[1], aa[0]);
2013  aa[3] = aa3;
2014  }
2015  if ((cdxtail != 0.0) || (cdytail != 0.0) || (adxtail != 0.0) ||
2016  (adytail != 0.0))
2017  {
2018  Square(bdx, bdxbdx1, bdxbdx0);
2019  Square(bdy, bdybdy1, bdybdy0);
2020  Two_Two_Sum(
2021  bdxbdx1, bdxbdx0, bdybdy1, bdybdy0, bb3, bb[2], bb[1], bb[0]);
2022  bb[3] = bb3;
2023  }
2024  if ((adxtail != 0.0) || (adytail != 0.0) || (bdxtail != 0.0) ||
2025  (bdytail != 0.0))
2026  {
2027  Square(cdx, cdxcdx1, cdxcdx0);
2028  Square(cdy, cdycdy1, cdycdy0);
2029  Two_Two_Sum(
2030  cdxcdx1, cdxcdx0, cdycdy1, cdycdy0, cc3, cc[2], cc[1], cc[0]);
2031  cc[3] = cc3;
2032  }
2033 
2034  if (adxtail != 0.0)
2035  {
2036  axtbclen = scale_expansion_zeroelimTRI(4, bc, adxtail, axtbc);
2037  temp16alen =
2038  scale_expansion_zeroelimTRI(axtbclen, axtbc, 2.0 * adx, temp16a);
2039 
2040  axtcclen = scale_expansion_zeroelimTRI(4, cc, adxtail, axtcc);
2041  temp16blen = scale_expansion_zeroelimTRI(axtcclen, axtcc, bdy, temp16b);
2042 
2043  axtbblen = scale_expansion_zeroelimTRI(4, bb, adxtail, axtbb);
2044  temp16clen = scale_expansion_zeroelimTRI(axtbblen, axtbb, -cdy, temp16c);
2045 
2046  temp32alen = fast_expansion_sum_zeroelimTRI(
2047  temp16alen, temp16a, temp16blen, temp16b, temp32a);
2048  temp48len = fast_expansion_sum_zeroelimTRI(
2049  temp16clen, temp16c, temp32alen, temp32a, temp48);
2050  finlength = fast_expansion_sum_zeroelimTRI(
2051  finlength, finnow, temp48len, temp48, finother);
2052  finswap = finnow;
2053  finnow = finother;
2054  finother = finswap;
2055  }
2056  if (adytail != 0.0)
2057  {
2058  aytbclen = scale_expansion_zeroelimTRI(4, bc, adytail, aytbc);
2059  temp16alen =
2060  scale_expansion_zeroelimTRI(aytbclen, aytbc, 2.0 * ady, temp16a);
2061 
2062  aytbblen = scale_expansion_zeroelimTRI(4, bb, adytail, aytbb);
2063  temp16blen = scale_expansion_zeroelimTRI(aytbblen, aytbb, cdx, temp16b);
2064 
2065  aytcclen = scale_expansion_zeroelimTRI(4, cc, adytail, aytcc);
2066  temp16clen = scale_expansion_zeroelimTRI(aytcclen, aytcc, -bdx, temp16c);
2067 
2068  temp32alen = fast_expansion_sum_zeroelimTRI(
2069  temp16alen, temp16a, temp16blen, temp16b, temp32a);
2070  temp48len = fast_expansion_sum_zeroelimTRI(
2071  temp16clen, temp16c, temp32alen, temp32a, temp48);
2072  finlength = fast_expansion_sum_zeroelimTRI(
2073  finlength, finnow, temp48len, temp48, finother);
2074  finswap = finnow;
2075  finnow = finother;
2076  finother = finswap;
2077  }
2078  if (bdxtail != 0.0)
2079  {
2080  bxtcalen = scale_expansion_zeroelimTRI(4, ca, bdxtail, bxtca);
2081  temp16alen =
2082  scale_expansion_zeroelimTRI(bxtcalen, bxtca, 2.0 * bdx, temp16a);
2083 
2084  bxtaalen = scale_expansion_zeroelimTRI(4, aa, bdxtail, bxtaa);
2085  temp16blen = scale_expansion_zeroelimTRI(bxtaalen, bxtaa, cdy, temp16b);
2086 
2087  bxtcclen = scale_expansion_zeroelimTRI(4, cc, bdxtail, bxtcc);
2088  temp16clen = scale_expansion_zeroelimTRI(bxtcclen, bxtcc, -ady, temp16c);
2089 
2090  temp32alen = fast_expansion_sum_zeroelimTRI(
2091  temp16alen, temp16a, temp16blen, temp16b, temp32a);
2092  temp48len = fast_expansion_sum_zeroelimTRI(
2093  temp16clen, temp16c, temp32alen, temp32a, temp48);
2094  finlength = fast_expansion_sum_zeroelimTRI(
2095  finlength, finnow, temp48len, temp48, finother);
2096  finswap = finnow;
2097  finnow = finother;
2098  finother = finswap;
2099  }
2100  if (bdytail != 0.0)
2101  {
2102  bytcalen = scale_expansion_zeroelimTRI(4, ca, bdytail, bytca);
2103  temp16alen =
2104  scale_expansion_zeroelimTRI(bytcalen, bytca, 2.0 * bdy, temp16a);
2105 
2106  bytcclen = scale_expansion_zeroelimTRI(4, cc, bdytail, bytcc);
2107  temp16blen = scale_expansion_zeroelimTRI(bytcclen, bytcc, adx, temp16b);
2108 
2109  bytaalen = scale_expansion_zeroelimTRI(4, aa, bdytail, bytaa);
2110  temp16clen = scale_expansion_zeroelimTRI(bytaalen, bytaa, -cdx, temp16c);
2111 
2112  temp32alen = fast_expansion_sum_zeroelimTRI(
2113  temp16alen, temp16a, temp16blen, temp16b, temp32a);
2114  temp48len = fast_expansion_sum_zeroelimTRI(
2115  temp16clen, temp16c, temp32alen, temp32a, temp48);
2116  finlength = fast_expansion_sum_zeroelimTRI(
2117  finlength, finnow, temp48len, temp48, finother);
2118  finswap = finnow;
2119  finnow = finother;
2120  finother = finswap;
2121  }
2122  if (cdxtail != 0.0)
2123  {
2124  cxtablen = scale_expansion_zeroelimTRI(4, ab, cdxtail, cxtab);
2125  temp16alen =
2126  scale_expansion_zeroelimTRI(cxtablen, cxtab, 2.0 * cdx, temp16a);
2127 
2128  cxtbblen = scale_expansion_zeroelimTRI(4, bb, cdxtail, cxtbb);
2129  temp16blen = scale_expansion_zeroelimTRI(cxtbblen, cxtbb, ady, temp16b);
2130 
2131  cxtaalen = scale_expansion_zeroelimTRI(4, aa, cdxtail, cxtaa);
2132  temp16clen = scale_expansion_zeroelimTRI(cxtaalen, cxtaa, -bdy, temp16c);
2133 
2134  temp32alen = fast_expansion_sum_zeroelimTRI(
2135  temp16alen, temp16a, temp16blen, temp16b, temp32a);
2136  temp48len = fast_expansion_sum_zeroelimTRI(
2137  temp16clen, temp16c, temp32alen, temp32a, temp48);
2138  finlength = fast_expansion_sum_zeroelimTRI(
2139  finlength, finnow, temp48len, temp48, finother);
2140  finswap = finnow;
2141  finnow = finother;
2142  finother = finswap;
2143  }
2144  if (cdytail != 0.0)
2145  {
2146  cytablen = scale_expansion_zeroelimTRI(4, ab, cdytail, cytab);
2147  temp16alen =
2148  scale_expansion_zeroelimTRI(cytablen, cytab, 2.0 * cdy, temp16a);
2149 
2150  cytaalen = scale_expansion_zeroelimTRI(4, aa, cdytail, cytaa);
2151  temp16blen = scale_expansion_zeroelimTRI(cytaalen, cytaa, bdx, temp16b);
2152 
2153  cytbblen = scale_expansion_zeroelimTRI(4, bb, cdytail, cytbb);
2154  temp16clen = scale_expansion_zeroelimTRI(cytbblen, cytbb, -adx, temp16c);
2155 
2156  temp32alen = fast_expansion_sum_zeroelimTRI(
2157  temp16alen, temp16a, temp16blen, temp16b, temp32a);
2158  temp48len = fast_expansion_sum_zeroelimTRI(
2159  temp16clen, temp16c, temp32alen, temp32a, temp48);
2160  finlength = fast_expansion_sum_zeroelimTRI(
2161  finlength, finnow, temp48len, temp48, finother);
2162  finswap = finnow;
2163  finnow = finother;
2164  finother = finswap;
2165  }
2166 
2167  if ((adxtail != 0.0) || (adytail != 0.0))
2168  {
2169  if ((bdxtail != 0.0) || (bdytail != 0.0) || (cdxtail != 0.0) ||
2170  (cdytail != 0.0))
2171  {
2172  Two_Product(bdxtail, cdy, ti1, ti0);
2173  Two_Product(bdx, cdytail, tj1, tj0);
2174  Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
2175  u[3] = u3;
2176  negate = -bdy;
2177  Two_Product(cdxtail, negate, ti1, ti0);
2178  negate = -bdytail;
2179  Two_Product(cdx, negate, tj1, tj0);
2180  Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
2181  v[3] = v3;
2182  bctlen = fast_expansion_sum_zeroelimTRI(4, u, 4, v, bct);
2183 
2184  Two_Product(bdxtail, cdytail, ti1, ti0);
2185  Two_Product(cdxtail, bdytail, tj1, tj0);
2186  Two_Two_Diff(ti1, ti0, tj1, tj0, bctt3, bctt[2], bctt[1], bctt[0]);
2187  bctt[3] = bctt3;
2188  bcttlen = 4;
2189  }
2190  else
2191  {
2192  bct[0] = 0.0;
2193  bctlen = 1;
2194  bctt[0] = 0.0;
2195  bcttlen = 1;
2196  }
2197 
2198  if (adxtail != 0.0)
2199  {
2200  temp16alen =
2201  scale_expansion_zeroelimTRI(axtbclen, axtbc, adxtail, temp16a);
2202  axtbctlen = scale_expansion_zeroelimTRI(bctlen, bct, adxtail, axtbct);
2203  temp32alen =
2204  scale_expansion_zeroelimTRI(axtbctlen, axtbct, 2.0 * adx, temp32a);
2205  temp48len = fast_expansion_sum_zeroelimTRI(
2206  temp16alen, temp16a, temp32alen, temp32a, temp48);
2207  finlength = fast_expansion_sum_zeroelimTRI(
2208  finlength, finnow, temp48len, temp48, finother);
2209  finswap = finnow;
2210  finnow = finother;
2211  finother = finswap;
2212  if (bdytail != 0.0)
2213  {
2214  temp8len = scale_expansion_zeroelimTRI(4, cc, adxtail, temp8);
2215  temp16alen =
2216  scale_expansion_zeroelimTRI(temp8len, temp8, bdytail, temp16a);
2217  finlength = fast_expansion_sum_zeroelimTRI(
2218  finlength, finnow, temp16alen, temp16a, finother);
2219  finswap = finnow;
2220  finnow = finother;
2221  finother = finswap;
2222  }
2223  if (cdytail != 0.0)
2224  {
2225  temp8len = scale_expansion_zeroelimTRI(4, bb, -adxtail, temp8);
2226  temp16alen =
2227  scale_expansion_zeroelimTRI(temp8len, temp8, cdytail, temp16a);
2228  finlength = fast_expansion_sum_zeroelimTRI(
2229  finlength, finnow, temp16alen, temp16a, finother);
2230  finswap = finnow;
2231  finnow = finother;
2232  finother = finswap;
2233  }
2234 
2235  temp32alen =
2236  scale_expansion_zeroelimTRI(axtbctlen, axtbct, adxtail, temp32a);
2237  axtbcttlen =
2238  scale_expansion_zeroelimTRI(bcttlen, bctt, adxtail, axtbctt);
2239  temp16alen = scale_expansion_zeroelimTRI(
2240  axtbcttlen, axtbctt, 2.0 * adx, temp16a);
2241  temp16blen =
2242  scale_expansion_zeroelimTRI(axtbcttlen, axtbctt, adxtail, temp16b);
2243  temp32blen = fast_expansion_sum_zeroelimTRI(
2244  temp16alen, temp16a, temp16blen, temp16b, temp32b);
2245  temp64len = fast_expansion_sum_zeroelimTRI(
2246  temp32alen, temp32a, temp32blen, temp32b, temp64);
2247  finlength = fast_expansion_sum_zeroelimTRI(
2248  finlength, finnow, temp64len, temp64, finother);
2249  finswap = finnow;
2250  finnow = finother;
2251  finother = finswap;
2252  }
2253  if (adytail != 0.0)
2254  {
2255  temp16alen =
2256  scale_expansion_zeroelimTRI(aytbclen, aytbc, adytail, temp16a);
2257  aytbctlen = scale_expansion_zeroelimTRI(bctlen, bct, adytail, aytbct);
2258  temp32alen =
2259  scale_expansion_zeroelimTRI(aytbctlen, aytbct, 2.0 * ady, temp32a);
2260  temp48len = fast_expansion_sum_zeroelimTRI(
2261  temp16alen, temp16a, temp32alen, temp32a, temp48);
2262  finlength = fast_expansion_sum_zeroelimTRI(
2263  finlength, finnow, temp48len, temp48, finother);
2264  finswap = finnow;
2265  finnow = finother;
2266  finother = finswap;
2267 
2268  temp32alen =
2269  scale_expansion_zeroelimTRI(aytbctlen, aytbct, adytail, temp32a);
2270  aytbcttlen =
2271  scale_expansion_zeroelimTRI(bcttlen, bctt, adytail, aytbctt);
2272  temp16alen = scale_expansion_zeroelimTRI(
2273  aytbcttlen, aytbctt, 2.0 * ady, temp16a);
2274  temp16blen =
2275  scale_expansion_zeroelimTRI(aytbcttlen, aytbctt, adytail, temp16b);
2276  temp32blen = fast_expansion_sum_zeroelimTRI(
2277  temp16alen, temp16a, temp16blen, temp16b, temp32b);
2278  temp64len = fast_expansion_sum_zeroelimTRI(
2279  temp32alen, temp32a, temp32blen, temp32b, temp64);
2280  finlength = fast_expansion_sum_zeroelimTRI(
2281  finlength, finnow, temp64len, temp64, finother);
2282  finswap = finnow;
2283  finnow = finother;
2284  finother = finswap;
2285  }
2286  }
2287  if ((bdxtail != 0.0) || (bdytail != 0.0))
2288  {
2289  if ((cdxtail != 0.0) || (cdytail != 0.0) || (adxtail != 0.0) ||
2290  (adytail != 0.0))
2291  {
2292  Two_Product(cdxtail, ady, ti1, ti0);
2293  Two_Product(cdx, adytail, tj1, tj0);
2294  Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
2295  u[3] = u3;
2296  negate = -cdy;
2297  Two_Product(adxtail, negate, ti1, ti0);
2298  negate = -cdytail;
2299  Two_Product(adx, negate, tj1, tj0);
2300  Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
2301  v[3] = v3;
2302  catlen = fast_expansion_sum_zeroelimTRI(4, u, 4, v, cat);
2303 
2304  Two_Product(cdxtail, adytail, ti1, ti0);
2305  Two_Product(adxtail, cdytail, tj1, tj0);
2306  Two_Two_Diff(ti1, ti0, tj1, tj0, catt3, catt[2], catt[1], catt[0]);
2307  catt[3] = catt3;
2308  cattlen = 4;
2309  }
2310  else
2311  {
2312  cat[0] = 0.0;
2313  catlen = 1;
2314  catt[0] = 0.0;
2315  cattlen = 1;
2316  }
2317 
2318  if (bdxtail != 0.0)
2319  {
2320  temp16alen =
2321  scale_expansion_zeroelimTRI(bxtcalen, bxtca, bdxtail, temp16a);
2322  bxtcatlen = scale_expansion_zeroelimTRI(catlen, cat, bdxtail, bxtcat);
2323  temp32alen =
2324  scale_expansion_zeroelimTRI(bxtcatlen, bxtcat, 2.0 * bdx, temp32a);
2325  temp48len = fast_expansion_sum_zeroelimTRI(
2326  temp16alen, temp16a, temp32alen, temp32a, temp48);
2327  finlength = fast_expansion_sum_zeroelimTRI(
2328  finlength, finnow, temp48len, temp48, finother);
2329  finswap = finnow;
2330  finnow = finother;
2331  finother = finswap;
2332  if (cdytail != 0.0)
2333  {
2334  temp8len = scale_expansion_zeroelimTRI(4, aa, bdxtail, temp8);
2335  temp16alen =
2336  scale_expansion_zeroelimTRI(temp8len, temp8, cdytail, temp16a);
2337  finlength = fast_expansion_sum_zeroelimTRI(
2338  finlength, finnow, temp16alen, temp16a, finother);
2339  finswap = finnow;
2340  finnow = finother;
2341  finother = finswap;
2342  }
2343  if (adytail != 0.0)
2344  {
2345  temp8len = scale_expansion_zeroelimTRI(4, cc, -bdxtail, temp8);
2346  temp16alen =
2347  scale_expansion_zeroelimTRI(temp8len, temp8, adytail, temp16a);
2348  finlength = fast_expansion_sum_zeroelimTRI(
2349  finlength, finnow, temp16alen, temp16a, finother);
2350  finswap = finnow;
2351  finnow = finother;
2352  finother = finswap;
2353  }
2354 
2355  temp32alen =
2356  scale_expansion_zeroelimTRI(bxtcatlen, bxtcat, bdxtail, temp32a);
2357  bxtcattlen =
2358  scale_expansion_zeroelimTRI(cattlen, catt, bdxtail, bxtcatt);
2359  temp16alen = scale_expansion_zeroelimTRI(
2360  bxtcattlen, bxtcatt, 2.0 * bdx, temp16a);
2361  temp16blen =
2362  scale_expansion_zeroelimTRI(bxtcattlen, bxtcatt, bdxtail, temp16b);
2363  temp32blen = fast_expansion_sum_zeroelimTRI(
2364  temp16alen, temp16a, temp16blen, temp16b, temp32b);
2365  temp64len = fast_expansion_sum_zeroelimTRI(
2366  temp32alen, temp32a, temp32blen, temp32b, temp64);
2367  finlength = fast_expansion_sum_zeroelimTRI(
2368  finlength, finnow, temp64len, temp64, finother);
2369  finswap = finnow;
2370  finnow = finother;
2371  finother = finswap;
2372  }
2373  if (bdytail != 0.0)
2374  {
2375  temp16alen =
2376  scale_expansion_zeroelimTRI(bytcalen, bytca, bdytail, temp16a);
2377  bytcatlen = scale_expansion_zeroelimTRI(catlen, cat, bdytail, bytcat);
2378  temp32alen =
2379  scale_expansion_zeroelimTRI(bytcatlen, bytcat, 2.0 * bdy, temp32a);
2380  temp48len = fast_expansion_sum_zeroelimTRI(
2381  temp16alen, temp16a, temp32alen, temp32a, temp48);
2382  finlength = fast_expansion_sum_zeroelimTRI(
2383  finlength, finnow, temp48len, temp48, finother);
2384  finswap = finnow;
2385  finnow = finother;
2386  finother = finswap;
2387 
2388  temp32alen =
2389  scale_expansion_zeroelimTRI(bytcatlen, bytcat, bdytail, temp32a);
2390  bytcattlen =
2391  scale_expansion_zeroelimTRI(cattlen, catt, bdytail, bytcatt);
2392  temp16alen = scale_expansion_zeroelimTRI(
2393  bytcattlen, bytcatt, 2.0 * bdy, temp16a);
2394  temp16blen =
2395  scale_expansion_zeroelimTRI(bytcattlen, bytcatt, bdytail, temp16b);
2396  temp32blen = fast_expansion_sum_zeroelimTRI(
2397  temp16alen, temp16a, temp16blen, temp16b, temp32b);
2398  temp64len = fast_expansion_sum_zeroelimTRI(
2399  temp32alen, temp32a, temp32blen, temp32b, temp64);
2400  finlength = fast_expansion_sum_zeroelimTRI(
2401  finlength, finnow, temp64len, temp64, finother);
2402  finswap = finnow;
2403  finnow = finother;
2404  finother = finswap;
2405  }
2406  }
2407  if ((cdxtail != 0.0) || (cdytail != 0.0))
2408  {
2409  if ((adxtail != 0.0) || (adytail != 0.0) || (bdxtail != 0.0) ||
2410  (bdytail != 0.0))
2411  {
2412  Two_Product(adxtail, bdy, ti1, ti0);
2413  Two_Product(adx, bdytail, tj1, tj0);
2414  Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
2415  u[3] = u3;
2416  negate = -ady;
2417  Two_Product(bdxtail, negate, ti1, ti0);
2418  negate = -adytail;
2419  Two_Product(bdx, negate, tj1, tj0);
2420  Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
2421  v[3] = v3;
2422  abtlen = fast_expansion_sum_zeroelimTRI(4, u, 4, v, abt);
2423 
2424  Two_Product(adxtail, bdytail, ti1, ti0);
2425  Two_Product(bdxtail, adytail, tj1, tj0);
2426  Two_Two_Diff(ti1, ti0, tj1, tj0, abtt3, abtt[2], abtt[1], abtt[0]);
2427  abtt[3] = abtt3;
2428  abttlen = 4;
2429  }
2430  else
2431  {
2432  abt[0] = 0.0;
2433  abtlen = 1;
2434  abtt[0] = 0.0;
2435  abttlen = 1;
2436  }
2437 
2438  if (cdxtail != 0.0)
2439  {
2440  temp16alen =
2441  scale_expansion_zeroelimTRI(cxtablen, cxtab, cdxtail, temp16a);
2442  cxtabtlen = scale_expansion_zeroelimTRI(abtlen, abt, cdxtail, cxtabt);
2443  temp32alen =
2444  scale_expansion_zeroelimTRI(cxtabtlen, cxtabt, 2.0 * cdx, temp32a);
2445  temp48len = fast_expansion_sum_zeroelimTRI(
2446  temp16alen, temp16a, temp32alen, temp32a, temp48);
2447  finlength = fast_expansion_sum_zeroelimTRI(
2448  finlength, finnow, temp48len, temp48, finother);
2449  finswap = finnow;
2450  finnow = finother;
2451  finother = finswap;
2452  if (adytail != 0.0)
2453  {
2454  temp8len = scale_expansion_zeroelimTRI(4, bb, cdxtail, temp8);
2455  temp16alen =
2456  scale_expansion_zeroelimTRI(temp8len, temp8, adytail, temp16a);
2457  finlength = fast_expansion_sum_zeroelimTRI(
2458  finlength, finnow, temp16alen, temp16a, finother);
2459  finswap = finnow;
2460  finnow = finother;
2461  finother = finswap;
2462  }
2463  if (bdytail != 0.0)
2464  {
2465  temp8len = scale_expansion_zeroelimTRI(4, aa, -cdxtail, temp8);
2466  temp16alen =
2467  scale_expansion_zeroelimTRI(temp8len, temp8, bdytail, temp16a);
2468  finlength = fast_expansion_sum_zeroelimTRI(
2469  finlength, finnow, temp16alen, temp16a, finother);
2470  finswap = finnow;
2471  finnow = finother;
2472  finother = finswap;
2473  }
2474 
2475  temp32alen =
2476  scale_expansion_zeroelimTRI(cxtabtlen, cxtabt, cdxtail, temp32a);
2477  cxtabttlen =
2478  scale_expansion_zeroelimTRI(abttlen, abtt, cdxtail, cxtabtt);
2479  temp16alen = scale_expansion_zeroelimTRI(
2480  cxtabttlen, cxtabtt, 2.0 * cdx, temp16a);
2481  temp16blen =
2482  scale_expansion_zeroelimTRI(cxtabttlen, cxtabtt, cdxtail, temp16b);
2483  temp32blen = fast_expansion_sum_zeroelimTRI(
2484  temp16alen, temp16a, temp16blen, temp16b, temp32b);
2485  temp64len = fast_expansion_sum_zeroelimTRI(
2486  temp32alen, temp32a, temp32blen, temp32b, temp64);
2487  finlength = fast_expansion_sum_zeroelimTRI(
2488  finlength, finnow, temp64len, temp64, finother);
2489  finswap = finnow;
2490  finnow = finother;
2491  finother = finswap;
2492  }
2493  if (cdytail != 0.0)
2494  {
2495  temp16alen =
2496  scale_expansion_zeroelimTRI(cytablen, cytab, cdytail, temp16a);
2497  cytabtlen = scale_expansion_zeroelimTRI(abtlen, abt, cdytail, cytabt);
2498  temp32alen =
2499  scale_expansion_zeroelimTRI(cytabtlen, cytabt, 2.0 * cdy, temp32a);
2500  temp48len = fast_expansion_sum_zeroelimTRI(
2501  temp16alen, temp16a, temp32alen, temp32a, temp48);
2502  finlength = fast_expansion_sum_zeroelimTRI(
2503  finlength, finnow, temp48len, temp48, finother);
2504  finswap = finnow;
2505  finnow = finother;
2506  finother = finswap;
2507 
2508  temp32alen =
2509  scale_expansion_zeroelimTRI(cytabtlen, cytabt, cdytail, temp32a);
2510  cytabttlen =
2511  scale_expansion_zeroelimTRI(abttlen, abtt, cdytail, cytabtt);
2512  temp16alen = scale_expansion_zeroelimTRI(
2513  cytabttlen, cytabtt, 2.0 * cdy, temp16a);
2514  temp16blen =
2515  scale_expansion_zeroelimTRI(cytabttlen, cytabtt, cdytail, temp16b);
2516  temp32blen = fast_expansion_sum_zeroelimTRI(
2517  temp16alen, temp16a, temp16blen, temp16b, temp32b);
2518  temp64len = fast_expansion_sum_zeroelimTRI(
2519  temp32alen, temp32a, temp32blen, temp32b, temp64);
2520  finlength = fast_expansion_sum_zeroelimTRI(
2521  finlength, finnow, temp64len, temp64, finother);
2522  finswap = finnow;
2523  finnow = finother;
2524  finother = finswap;
2525  }
2526  }
2527 
2528  return finnow[finlength - 1];
2529 }
2530 
2532  struct behavior *b,
2533  vertex pa,
2534  vertex pb,
2535  vertex pc,
2536  vertex pd)
2537 {
2538  double adx, bdx, cdx, ady, bdy, cdy;
2539  double bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
2540  double alift, blift, clift;
2541  double det;
2542  double permanent, errbound;
2543 
2544  m->incirclecount++;
2545 
2546  adx = pa[0] - pd[0];
2547  bdx = pb[0] - pd[0];
2548  cdx = pc[0] - pd[0];
2549  ady = pa[1] - pd[1];
2550  bdy = pb[1] - pd[1];
2551  cdy = pc[1] - pd[1];
2552 
2553  bdxcdy = bdx * cdy;
2554  cdxbdy = cdx * bdy;
2555  alift = adx * adx + ady * ady;
2556 
2557  cdxady = cdx * ady;
2558  adxcdy = adx * cdy;
2559  blift = bdx * bdx + bdy * bdy;
2560 
2561  adxbdy = adx * bdy;
2562  bdxady = bdx * ady;
2563  clift = cdx * cdx + cdy * cdy;
2564 
2565  det = alift * (bdxcdy - cdxbdy) + blift * (cdxady - adxcdy) +
2566  clift * (adxbdy - bdxady);
2567 
2568  permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * alift +
2569  (Absolute(cdxady) + Absolute(adxcdy)) * blift +
2570  (Absolute(adxbdy) + Absolute(bdxady)) * clift;
2571  errbound = iccerrboundA * permanent;
2572  if ((det > errbound) || (-det > errbound))
2573  {
2574  return det;
2575  }
2576 
2577  return incircleadaptTRI(pa, pb, pc, pd, permanent);
2578 }
2579 
2580 /*****************************************************************************/
2581 /* */
2582 /* orient3d() Return a positive value if the point pd lies below the */
2583 /* plane passing through pa, pb, and pc; "below" is defined so */
2584 /* that pa, pb, and pc appear in counterclockwise order when */
2585 /* viewed from above the plane. Returns a negative value if */
2586 /* pd lies above the plane. Returns zero if the points are */
2587 /* coplanar. The result is also a rough approximation of six */
2588 /* times the signed volume of the tetrahedron defined by the */
2589 /* four points. */
2590 /* */
2591 /* Uses exact arithmetic if necessary to ensure a correct answer. The */
2592 /* result returned is the determinant of a matrix. This determinant is */
2593 /* computed adaptively, in the sense that exact arithmetic is used only to */
2594 /* the degree it is needed to ensure that the returned value has the */
2595 /* correct sign. Hence, this function is usually quite fast, but will run */
2596 /* more slowly when the input points are coplanar or nearly so. */
2597 /* */
2598 /* See my Robust Predicates paper for details. */
2599 /* */
2600 /*****************************************************************************/
2601 
2603  vertex pb,
2604  vertex pc,
2605  vertex pd,
2606  double aheight,
2607  double bheight,
2608  double cheight,
2609  double dheight,
2610  double permanent)
2611 {
2612  double adx, bdx, cdx, ady, bdy, cdy, adheight, bdheight, cdheight;
2613  double det, errbound;
2614 
2615  double bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1;
2616  double bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0;
2617  double bc[4], ca[4], ab[4];
2618  double bc3, ca3, ab3;
2619  double adet[8], bdet[8], cdet[8];
2620  int alen, blen, clen;
2621  double abdet[16];
2622  int ablen;
2623  double *finnow, *finother, *finswap;
2624  double fin1[192], fin2[192];
2625  int finlength;
2626 
2627  double adxtail, bdxtail, cdxtail;
2628  double adytail, bdytail, cdytail;
2629  double adheighttail, bdheighttail, cdheighttail;
2630  double at_blarge, at_clarge;
2631  double bt_clarge, bt_alarge;
2632  double ct_alarge, ct_blarge;
2633  double at_b[4], at_c[4], bt_c[4], bt_a[4], ct_a[4], ct_b[4];
2634  int at_blen, at_clen, bt_clen, bt_alen, ct_alen, ct_blen;
2635  double bdxt_cdy1, cdxt_bdy1, cdxt_ady1;
2636  double adxt_cdy1, adxt_bdy1, bdxt_ady1;
2637  double bdxt_cdy0, cdxt_bdy0, cdxt_ady0;
2638  double adxt_cdy0, adxt_bdy0, bdxt_ady0;
2639  double bdyt_cdx1, cdyt_bdx1, cdyt_adx1;
2640  double adyt_cdx1, adyt_bdx1, bdyt_adx1;
2641  double bdyt_cdx0, cdyt_bdx0, cdyt_adx0;
2642  double adyt_cdx0, adyt_bdx0, bdyt_adx0;
2643  double bct[8], cat[8], abt[8];
2644  int bctlen, catlen, abtlen;
2645  double bdxt_cdyt1, cdxt_bdyt1, cdxt_adyt1;
2646  double adxt_cdyt1, adxt_bdyt1, bdxt_adyt1;
2647  double bdxt_cdyt0, cdxt_bdyt0, cdxt_adyt0;
2648  double adxt_cdyt0, adxt_bdyt0, bdxt_adyt0;
2649  double u[4], v[12], w[16];
2650  double u3;
2651  int vlength, wlength;
2652  double negate;
2653 
2654  double bvirt;
2655  double avirt, bround, around;
2656  double c;
2657  double abig;
2658  double ahi, alo, bhi, blo;
2659  double err1, err2, err3;
2660  double _i, _j, _k;
2661  double _0;
2662 
2663  adx = (double)(pa[0] - pd[0]);
2664  bdx = (double)(pb[0] - pd[0]);
2665  cdx = (double)(pc[0] - pd[0]);
2666  ady = (double)(pa[1] - pd[1]);
2667  bdy = (double)(pb[1] - pd[1]);
2668  cdy = (double)(pc[1] - pd[1]);
2669  adheight = (double)(aheight - dheight);
2670  bdheight = (double)(bheight - dheight);
2671  cdheight = (double)(cheight - dheight);
2672 
2673  Two_Product(bdx, cdy, bdxcdy1, bdxcdy0);
2674  Two_Product(cdx, bdy, cdxbdy1, cdxbdy0);
2675  Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]);
2676  bc[3] = bc3;
2677  alen = scale_expansion_zeroelimTRI(4, bc, adheight, adet);
2678 
2679  Two_Product(cdx, ady, cdxady1, cdxady0);
2680  Two_Product(adx, cdy, adxcdy1, adxcdy0);
2681  Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]);
2682  ca[3] = ca3;
2683  blen = scale_expansion_zeroelimTRI(4, ca, bdheight, bdet);
2684 
2685  Two_Product(adx, bdy, adxbdy1, adxbdy0);
2686  Two_Product(bdx, ady, bdxady1, bdxady0);
2687  Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]);
2688  ab[3] = ab3;
2689  clen = scale_expansion_zeroelimTRI(4, ab, cdheight, cdet);
2690 
2691  ablen = fast_expansion_sum_zeroelimTRI(alen, adet, blen, bdet, abdet);
2692  finlength = fast_expansion_sum_zeroelimTRI(ablen, abdet, clen, cdet, fin1);
2693 
2694  det = estimateTRI(finlength, fin1);
2695  errbound = o3derrboundB * permanent;
2696  if ((det >= errbound) || (-det >= errbound))
2697  {
2698  return det;
2699  }
2700 
2701  Two_Diff_Tail(pa[0], pd[0], adx, adxtail);
2702  Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail);
2703  Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail);
2704  Two_Diff_Tail(pa[1], pd[1], ady, adytail);
2705  Two_Diff_Tail(pb[1], pd[1], bdy, bdytail);
2706  Two_Diff_Tail(pc[1], pd[1], cdy, cdytail);
2707  Two_Diff_Tail(aheight, dheight, adheight, adheighttail);
2708  Two_Diff_Tail(bheight, dheight, bdheight, bdheighttail);
2709  Two_Diff_Tail(cheight, dheight, cdheight, cdheighttail);
2710 
2711  if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0) &&
2712  (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0) &&
2713  (adheighttail == 0.0) && (bdheighttail == 0.0) && (cdheighttail == 0.0))
2714  {
2715  return det;
2716  }
2717 
2718  errbound = o3derrboundC * permanent + resulterrbound * Absolute(det);
2719  det += (adheight * ((bdx * cdytail + cdy * bdxtail) -
2720  (bdy * cdxtail + cdx * bdytail)) +
2721  adheighttail * (bdx * cdy - bdy * cdx)) +
2722  (bdheight * ((cdx * adytail + ady * cdxtail) -
2723  (cdy * adxtail + adx * cdytail)) +
2724  bdheighttail * (cdx * ady - cdy * adx)) +
2725  (cdheight * ((adx * bdytail + bdy * adxtail) -
2726  (ady * bdxtail + bdx * adytail)) +
2727  cdheighttail * (adx * bdy - ady * bdx));
2728  if ((det >= errbound) || (-det >= errbound))
2729  {
2730  return det;
2731  }
2732 
2733  finnow = fin1;
2734  finother = fin2;
2735 
2736  if (adxtail == 0.0)
2737  {
2738  if (adytail == 0.0)
2739  {
2740  at_b[0] = 0.0;
2741  at_blen = 1;
2742  at_c[0] = 0.0;
2743  at_clen = 1;
2744  }
2745  else
2746  {
2747  negate = -adytail;
2748  Two_Product(negate, bdx, at_blarge, at_b[0]);
2749  at_b[1] = at_blarge;
2750  at_blen = 2;
2751  Two_Product(adytail, cdx, at_clarge, at_c[0]);
2752  at_c[1] = at_clarge;
2753  at_clen = 2;
2754  }
2755  }
2756  else
2757  {
2758  if (adytail == 0.0)
2759  {
2760  Two_Product(adxtail, bdy, at_blarge, at_b[0]);
2761  at_b[1] = at_blarge;
2762  at_blen = 2;
2763  negate = -adxtail;
2764  Two_Product(negate, cdy, at_clarge, at_c[0]);
2765  at_c[1] = at_clarge;
2766  at_clen = 2;
2767  }
2768  else
2769  {
2770  Two_Product(adxtail, bdy, adxt_bdy1, adxt_bdy0);
2771  Two_Product(adytail, bdx, adyt_bdx1, adyt_bdx0);
2772  Two_Two_Diff(adxt_bdy1,
2773  adxt_bdy0,
2774  adyt_bdx1,
2775  adyt_bdx0,
2776  at_blarge,
2777  at_b[2],
2778  at_b[1],
2779  at_b[0]);
2780  at_b[3] = at_blarge;
2781  at_blen = 4;
2782  Two_Product(adytail, cdx, adyt_cdx1, adyt_cdx0);
2783  Two_Product(adxtail, cdy, adxt_cdy1, adxt_cdy0);
2784  Two_Two_Diff(adyt_cdx1,
2785  adyt_cdx0,
2786  adxt_cdy1,
2787  adxt_cdy0,
2788  at_clarge,
2789  at_c[2],
2790  at_c[1],
2791  at_c[0]);
2792  at_c[3] = at_clarge;
2793  at_clen = 4;
2794  }
2795  }
2796  if (bdxtail == 0.0)
2797  {
2798  if (bdytail == 0.0)
2799  {
2800  bt_c[0] = 0.0;
2801  bt_clen = 1;
2802  bt_a[0] = 0.0;
2803  bt_alen = 1;
2804  }
2805  else
2806  {
2807  negate = -bdytail;
2808  Two_Product(negate, cdx, bt_clarge, bt_c[0]);
2809  bt_c[1] = bt_clarge;
2810  bt_clen = 2;
2811  Two_Product(bdytail, adx, bt_alarge, bt_a[0]);
2812  bt_a[1] = bt_alarge;
2813  bt_alen = 2;
2814  }
2815  }
2816  else
2817  {
2818  if (bdytail == 0.0)
2819  {
2820  Two_Product(bdxtail, cdy, bt_clarge, bt_c[0]);
2821  bt_c[1] = bt_clarge;
2822  bt_clen = 2;
2823  negate = -bdxtail;
2824  Two_Product(negate, ady, bt_alarge, bt_a[0]);
2825  bt_a[1] = bt_alarge;
2826  bt_alen = 2;
2827  }
2828  else
2829  {
2830  Two_Product(bdxtail, cdy, bdxt_cdy1, bdxt_cdy0);
2831  Two_Product(bdytail, cdx, bdyt_cdx1, bdyt_cdx0);
2832  Two_Two_Diff(bdxt_cdy1,
2833  bdxt_cdy0,
2834  bdyt_cdx1,
2835  bdyt_cdx0,
2836  bt_clarge,
2837  bt_c[2],
2838  bt_c[1],
2839  bt_c[0]);
2840  bt_c[3] = bt_clarge;
2841  bt_clen = 4;
2842  Two_Product(bdytail, adx, bdyt_adx1, bdyt_adx0);
2843  Two_Product(bdxtail, ady, bdxt_ady1, bdxt_ady0);
2844  Two_Two_Diff(bdyt_adx1,
2845  bdyt_adx0,
2846  bdxt_ady1,
2847  bdxt_ady0,
2848  bt_alarge,
2849  bt_a[2],
2850  bt_a[1],
2851  bt_a[0]);
2852  bt_a[3] = bt_alarge;
2853  bt_alen = 4;
2854  }
2855  }
2856  if (cdxtail == 0.0)
2857  {
2858  if (cdytail == 0.0)
2859  {
2860  ct_a[0] = 0.0;
2861  ct_alen = 1;
2862  ct_b[0] = 0.0;
2863  ct_blen = 1;
2864  }
2865  else
2866  {
2867  negate = -cdytail;
2868  Two_Product(negate, adx, ct_alarge, ct_a[0]);
2869  ct_a[1] = ct_alarge;
2870  ct_alen = 2;
2871  Two_Product(cdytail, bdx, ct_blarge, ct_b[0]);
2872  ct_b[1] = ct_blarge;
2873  ct_blen = 2;
2874  }
2875  }
2876  else
2877  {
2878  if (cdytail == 0.0)
2879  {
2880  Two_Product(cdxtail, ady, ct_alarge, ct_a[0]);
2881  ct_a[1] = ct_alarge;
2882  ct_alen = 2;
2883  negate = -cdxtail;
2884  Two_Product(negate, bdy, ct_blarge, ct_b[0]);
2885  ct_b[1] = ct_blarge;
2886  ct_blen = 2;
2887  }
2888  else
2889  {
2890  Two_Product(cdxtail, ady, cdxt_ady1, cdxt_ady0);
2891  Two_Product(cdytail, adx, cdyt_adx1, cdyt_adx0);
2892  Two_Two_Diff(cdxt_ady1,
2893  cdxt_ady0,
2894  cdyt_adx1,
2895  cdyt_adx0,
2896  ct_alarge,
2897  ct_a[2],
2898  ct_a[1],
2899  ct_a[0]);
2900  ct_a[3] = ct_alarge;
2901  ct_alen = 4;
2902  Two_Product(cdytail, bdx, cdyt_bdx1, cdyt_bdx0);
2903  Two_Product(cdxtail, bdy, cdxt_bdy1, cdxt_bdy0);
2904  Two_Two_Diff(cdyt_bdx1,
2905  cdyt_bdx0,
2906  cdxt_bdy1,
2907  cdxt_bdy0,
2908  ct_blarge,
2909  ct_b[2],
2910  ct_b[1],
2911  ct_b[0]);
2912  ct_b[3] = ct_blarge;
2913  ct_blen = 4;
2914  }
2915  }
2916 
2917  bctlen = fast_expansion_sum_zeroelimTRI(bt_clen, bt_c, ct_blen, ct_b, bct);
2918  wlength = scale_expansion_zeroelimTRI(bctlen, bct, adheight, w);
2919  finlength =
2920  fast_expansion_sum_zeroelimTRI(finlength, finnow, wlength, w, finother);
2921  finswap = finnow;
2922  finnow = finother;
2923  finother = finswap;
2924 
2925  catlen = fast_expansion_sum_zeroelimTRI(ct_alen, ct_a, at_clen, at_c, cat);
2926  wlength = scale_expansion_zeroelimTRI(catlen, cat, bdheight, w);
2927  finlength =
2928  fast_expansion_sum_zeroelimTRI(finlength, finnow, wlength, w, finother);
2929  finswap = finnow;
2930  finnow = finother;
2931  finother = finswap;
2932 
2933  abtlen = fast_expansion_sum_zeroelimTRI(at_blen, at_b, bt_alen, bt_a, abt);
2934  wlength = scale_expansion_zeroelimTRI(abtlen, abt, cdheight, w);
2935  finlength =
2936  fast_expansion_sum_zeroelimTRI(finlength, finnow, wlength, w, finother);
2937  finswap = finnow;
2938  finnow = finother;
2939  finother = finswap;
2940 
2941  if (adheighttail != 0.0)
2942  {
2943  vlength = scale_expansion_zeroelimTRI(4, bc, adheighttail, v);
2944  finlength = fast_expansion_sum_zeroelimTRI(
2945  finlength, finnow, vlength, v, finother);
2946  finswap = finnow;
2947  finnow = finother;
2948  finother = finswap;
2949  }
2950  if (bdheighttail != 0.0)
2951  {
2952  vlength = scale_expansion_zeroelimTRI(4, ca, bdheighttail, v);
2953  finlength = fast_expansion_sum_zeroelimTRI(
2954  finlength, finnow, vlength, v, finother);
2955  finswap = finnow;
2956  finnow = finother;
2957  finother = finswap;
2958  }
2959  if (cdheighttail != 0.0)
2960  {
2961  vlength = scale_expansion_zeroelimTRI(4, ab, cdheighttail, v);
2962  finlength = fast_expansion_sum_zeroelimTRI(
2963  finlength, finnow, vlength, v, finother);
2964  finswap = finnow;
2965  finnow = finother;
2966  finother = finswap;
2967  }
2968 
2969  if (adxtail != 0.0)
2970  {
2971  if (bdytail != 0.0)
2972  {
2973  Two_Product(adxtail, bdytail, adxt_bdyt1, adxt_bdyt0);
2975  adxt_bdyt1, adxt_bdyt0, cdheight, u3, u[2], u[1], u[0]);
2976  u[3] = u3;
2977  finlength =
2978  fast_expansion_sum_zeroelimTRI(finlength, finnow, 4, u, finother);
2979  finswap = finnow;
2980  finnow = finother;
2981  finother = finswap;
2982  if (cdheighttail != 0.0)
2983  {
2985  adxt_bdyt1, adxt_bdyt0, cdheighttail, u3, u[2], u[1], u[0]);
2986  u[3] = u3;
2987  finlength = fast_expansion_sum_zeroelimTRI(
2988  finlength, finnow, 4, u, finother);
2989  finswap = finnow;
2990  finnow = finother;
2991  finother = finswap;
2992  }
2993  }
2994  if (cdytail != 0.0)
2995  {
2996  negate = -adxtail;
2997  Two_Product(negate, cdytail, adxt_cdyt1, adxt_cdyt0);
2999  adxt_cdyt1, adxt_cdyt0, bdheight, u3, u[2], u[1], u[0]);
3000  u[3] = u3;
3001  finlength =
3002  fast_expansion_sum_zeroelimTRI(finlength, finnow, 4, u, finother);
3003  finswap = finnow;
3004  finnow = finother;
3005  finother = finswap;
3006  if (bdheighttail != 0.0)
3007  {
3009  adxt_cdyt1, adxt_cdyt0, bdheighttail, u3, u[2], u[1], u[0]);
3010  u[3] = u3;
3011  finlength = fast_expansion_sum_zeroelimTRI(
3012  finlength, finnow, 4, u, finother);
3013  finswap = finnow;
3014  finnow = finother;
3015  finother = finswap;
3016  }
3017  }
3018  }
3019  if (bdxtail != 0.0)
3020  {
3021  if (cdytail != 0.0)
3022  {
3023  Two_Product(bdxtail, cdytail, bdxt_cdyt1, bdxt_cdyt0);
3025  bdxt_cdyt1, bdxt_cdyt0, adheight, u3, u[2], u[1], u[0]);
3026  u[3] = u3;
3027  finlength =
3028  fast_expansion_sum_zeroelimTRI(finlength, finnow, 4, u, finother);
3029  finswap = finnow;
3030  finnow = finother;
3031  finother = finswap;
3032  if (adheighttail != 0.0)
3033  {
3035  bdxt_cdyt1, bdxt_cdyt0, adheighttail, u3, u[2], u[1], u[0]);
3036  u[3] = u3;
3037  finlength = fast_expansion_sum_zeroelimTRI(
3038  finlength, finnow, 4, u, finother);
3039  finswap = finnow;
3040  finnow = finother;
3041  finother = finswap;
3042  }
3043  }
3044  if (adytail != 0.0)
3045  {
3046  negate = -bdxtail;
3047  Two_Product(negate, adytail, bdxt_adyt1, bdxt_adyt0);
3049  bdxt_adyt1, bdxt_adyt0, cdheight, u3, u[2], u[1], u[0]);
3050  u[3] = u3;
3051  finlength =
3052  fast_expansion_sum_zeroelimTRI(finlength, finnow, 4, u, finother);
3053  finswap = finnow;
3054  finnow = finother;
3055  finother = finswap;
3056  if (cdheighttail != 0.0)
3057  {
3059  bdxt_adyt1, bdxt_adyt0, cdheighttail, u3, u[2], u[1], u[0]);
3060  u[3] = u3;
3061  finlength = fast_expansion_sum_zeroelimTRI(
3062  finlength, finnow, 4, u, finother);
3063  finswap = finnow;
3064  finnow = finother;
3065  finother = finswap;
3066  }
3067  }
3068  }
3069  if (cdxtail != 0.0)
3070  {
3071  if (adytail != 0.0)
3072  {
3073  Two_Product(cdxtail, adytail, cdxt_adyt1, cdxt_adyt0);
3075  cdxt_adyt1, cdxt_adyt0, bdheight, u3, u[2], u[1], u[0]);
3076  u[3] = u3;
3077  finlength =
3078  fast_expansion_sum_zeroelimTRI(finlength, finnow, 4, u, finother);
3079  finswap = finnow;
3080  finnow = finother;
3081  finother = finswap;
3082  if (bdheighttail != 0.0)
3083  {
3085  cdxt_adyt1, cdxt_adyt0, bdheighttail, u3, u[2], u[1], u[0]);
3086  u[3] = u3;
3087  finlength = fast_expansion_sum_zeroelimTRI(
3088  finlength, finnow, 4, u, finother);
3089  finswap = finnow;
3090  finnow = finother;
3091  finother = finswap;
3092  }
3093  }
3094  if (bdytail != 0.0)
3095  {
3096  negate = -cdxtail;
3097  Two_Product(negate, bdytail, cdxt_bdyt1, cdxt_bdyt0);
3099  cdxt_bdyt1, cdxt_bdyt0, adheight, u3, u[2], u[1], u[0]);
3100  u[3] = u3;
3101  finlength =
3102  fast_expansion_sum_zeroelimTRI(finlength, finnow, 4, u, finother);
3103  finswap = finnow;
3104  finnow = finother;
3105  finother = finswap;
3106  if (adheighttail != 0.0)
3107  {
3109  cdxt_bdyt1, cdxt_bdyt0, adheighttail, u3, u[2], u[1], u[0]);
3110  u[3] = u3;
3111  finlength = fast_expansion_sum_zeroelimTRI(
3112  finlength, finnow, 4, u, finother);
3113  finswap = finnow;
3114  finnow = finother;
3115  finother = finswap;
3116  }
3117  }
3118  }
3119 
3120  if (adheighttail != 0.0)
3121  {
3122  wlength = scale_expansion_zeroelimTRI(bctlen, bct, adheighttail, w);
3123  finlength = fast_expansion_sum_zeroelimTRI(
3124  finlength, finnow, wlength, w, finother);
3125  finswap = finnow;
3126  finnow = finother;
3127  finother = finswap;
3128  }
3129  if (bdheighttail != 0.0)
3130  {
3131  wlength = scale_expansion_zeroelimTRI(catlen, cat, bdheighttail, w);
3132  finlength = fast_expansion_sum_zeroelimTRI(
3133  finlength, finnow, wlength, w, finother);
3134  finswap = finnow;
3135  finnow = finother;
3136  finother = finswap;
3137  }
3138  if (cdheighttail != 0.0)
3139  {
3140  wlength = scale_expansion_zeroelimTRI(abtlen, abt, cdheighttail, w);
3141  finlength = fast_expansion_sum_zeroelimTRI(
3142  finlength, finnow, wlength, w, finother);
3143  finswap = finnow;
3144  finnow = finother;
3145  finother = finswap;
3146  }
3147 
3148  return finnow[finlength - 1];
3149 }
3150 
3152  struct behavior *b,
3153  vertex pa,
3154  vertex pb,
3155  vertex pc,
3156  vertex pd,
3157  double aheight,
3158  double bheight,
3159  double cheight,
3160  double dheight)
3161 {
3162  double adx, bdx, cdx, ady, bdy, cdy, adheight, bdheight, cdheight;
3163  double bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
3164  double det;
3165  double permanent, errbound;
3166 
3167  m->orient3dcount++;
3168 
3169  adx = pa[0] - pd[0];
3170  bdx = pb[0] - pd[0];
3171  cdx = pc[0] - pd[0];
3172  ady = pa[1] - pd[1];
3173  bdy = pb[1] - pd[1];
3174  cdy = pc[1] - pd[1];
3175  adheight = aheight - dheight;
3176  bdheight = bheight - dheight;
3177  cdheight = cheight - dheight;
3178 
3179  bdxcdy = bdx * cdy;
3180  cdxbdy = cdx * bdy;
3181 
3182  cdxady = cdx * ady;
3183  adxcdy = adx * cdy;
3184 
3185  adxbdy = adx * bdy;
3186  bdxady = bdx * ady;
3187 
3188  det = adheight * (bdxcdy - cdxbdy) + bdheight * (cdxady - adxcdy) +
3189  cdheight * (adxbdy - bdxady);
3190 
3191  permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * Absolute(adheight) +
3192  (Absolute(cdxady) + Absolute(adxcdy)) * Absolute(bdheight) +
3193  (Absolute(adxbdy) + Absolute(bdxady)) * Absolute(cdheight);
3194  errbound = o3derrboundA * permanent;
3195  if ((det > errbound) || (-det > errbound))
3196  {
3197  return det;
3198  }
3199 
3200  return orient3dadapt(
3201  pa, pb, pc, pd, aheight, bheight, cheight, dheight, permanent);
3202 }
3203 
3204 /*****************************************************************************/
3205 /* */
3206 /* nonregular() Return a positive value if the point pd is incompatible */
3207 /* with the circle or plane passing through pa, pb, and pc */
3208 /* (meaning that pd is inside the circle or below the */
3209 /* plane); a negative value if it is compatible; and zero if */
3210 /* the four points are cocircular/coplanar. The points pa, */
3211 /* pb, and pc must be in counterclockwise order, or the sign */
3212 /* of the result will be reversed. */
3213 /* */
3214 /* If the -w switch is used, the points are lifted onto the parabolic */
3215 /* lifting map, then they are dropped according to their weights, then the */
3216 /* 3D orientation test is applied. If the -W switch is used, the points' */
3217 /* heights are already provided, so the 3D orientation test is applied */
3218 /* directly. If neither switch is used, the incircle test is applied. */
3219 /* */
3220 /*****************************************************************************/
3221 
3223  struct behavior *b,
3224  vertex pa,
3225  vertex pb,
3226  vertex pc,
3227  vertex pd)
3228 {
3229  if (b->weighted == 0)
3230  {
3231  return incircle(m, b, pa, pb, pc, pd);
3232  }
3233  else if (b->weighted == 1)
3234  {
3235  return orient3d(m,
3236  b,
3237  pa,
3238  pb,
3239  pc,
3240  pd,
3241  pa[0] * pa[0] + pa[1] * pa[1] - pa[2],
3242  pb[0] * pb[0] + pb[1] * pb[1] - pb[2],
3243  pc[0] * pc[0] + pc[1] * pc[1] - pc[2],
3244  pd[0] * pd[0] + pd[1] * pd[1] - pd[2]);
3245  }
3246  else
3247  {
3248  return orient3d(m, b, pa, pb, pc, pd, pa[2], pb[2], pc[2], pd[2]);
3249  }
3250 }
3251 
3252 /*****************************************************************************/
3253 /* */
3254 /* findcircumcenter() Find the circumcenter of a triangle. */
3255 /* */
3256 /* The result is returned both in terms of x-y coordinates and xi-eta */
3257 /* (barycentric) coordinates. The xi-eta coordinate system is defined in */
3258 /* terms of the triangle: the origin of the triangle is the origin of the */
3259 /* coordinate system; the destination of the triangle is one unit along the */
3260 /* xi axis; and the apex of the triangle is one unit along the eta axis. */
3261 /* This procedure also returns the square of the length of the triangle's */
3262 /* shortest edge. */
3263 /* */
3264 /*****************************************************************************/
3265 
3267  struct behavior *b,
3268  vertex torg,
3269  vertex tdest,
3270  vertex tapex,
3271  vertex circumcenter,
3272  double *xi,
3273  double *eta,
3274  int offcenter)
3275 {
3276  double xdo, ydo, xao, yao;
3277  double dodist, aodist, dadist;
3278  double denominator;
3279  double dx, dy, dxoff, dyoff;
3280 
3281  m->circumcentercount++;
3282 
3283  /* Compute the circumcenter of the triangle. */
3284  xdo = tdest[0] - torg[0];
3285  ydo = tdest[1] - torg[1];
3286  xao = tapex[0] - torg[0];
3287  yao = tapex[1] - torg[1];
3288  dodist = xdo * xdo + ydo * ydo;
3289  aodist = xao * xao + yao * yao;
3290  dadist = (tdest[0] - tapex[0]) * (tdest[0] - tapex[0]) +
3291  (tdest[1] - tapex[1]) * (tdest[1] - tapex[1]);
3292 
3293  /* Use the counterclockwise() routine to ensure a positive (and */
3294  /* reasonably accurate) result, avoiding any possibility of */
3295  /* division by zero. */
3296  denominator = 0.5 / counterclockwise(m, b, tdest, tapex, torg);
3297  /* Don't count the above as an orientation test. */
3298  m->counterclockcount--;
3299 
3300  dx = (yao * dodist - ydo * aodist) * denominator;
3301  dy = (xdo * aodist - xao * dodist) * denominator;
3302 
3303  /* Find the (squared) length of the triangle's shortest edge. This */
3304  /* serves as a conservative estimateTRI of the insertion radius of the */
3305  /* circumcenter's parent. The estimateTRI is used to ensure that */
3306  /* the algorithm terminates even if very small angles appear in */
3307  /* the input PSLG. */
3308  if ((dodist < aodist) && (dodist < dadist))
3309  {
3310  if (offcenter && (b->offconstant > 0.0))
3311  {
3312  /* Find the position of the off-center, as described by Alper Ungor.
3313  */
3314  dxoff = 0.5 * xdo - b->offconstant * ydo;
3315  dyoff = 0.5 * ydo + b->offconstant * xdo;
3316  /* If the off-center is closer to the origin than the */
3317  /* circumcenter, use the off-center instead. */
3318  if (dxoff * dxoff + dyoff * dyoff < dx * dx + dy * dy)
3319  {
3320  dx = dxoff;
3321  dy = dyoff;
3322  }
3323  }
3324  }
3325  else if (aodist < dadist)
3326  {
3327  if (offcenter && (b->offconstant > 0.0))
3328  {
3329  dxoff = 0.5 * xao + b->offconstant * yao;
3330  dyoff = 0.5 * yao - b->offconstant * xao;
3331  /* If the off-center is closer to the origin than the */
3332  /* circumcenter, use the off-center instead. */
3333  if (dxoff * dxoff + dyoff * dyoff < dx * dx + dy * dy)
3334  {
3335  dx = dxoff;
3336  dy = dyoff;
3337  }
3338  }
3339  }
3340  else
3341  {
3342  if (offcenter && (b->offconstant > 0.0))
3343  {
3344  dxoff = 0.5 * (tapex[0] - tdest[0]) -
3345  b->offconstant * (tapex[1] - tdest[1]);
3346  dyoff = 0.5 * (tapex[1] - tdest[1]) +
3347  b->offconstant * (tapex[0] - tdest[0]);
3348  /* If the off-center is closer to the destination than the */
3349  /* circumcenter, use the off-center instead. */
3350  if (dxoff * dxoff + dyoff * dyoff <
3351  (dx - xdo) * (dx - xdo) + (dy - ydo) * (dy - ydo))
3352  {
3353  dx = xdo + dxoff;
3354  dy = ydo + dyoff;
3355  }
3356  }
3357  }
3358 
3359  circumcenter[0] = torg[0] + dx;
3360  circumcenter[1] = torg[1] + dy;
3361 
3362  /* To interpolate vertex attributes for the new vertex inserted at */
3363  /* the circumcenter, define a coordinate system with a xi-axis, */
3364  /* directed from the triangle's origin to its destination, and */
3365  /* an eta-axis, directed from its origin to its apex. */
3366  /* Calculate the xi and eta coordinates of the circumcenter. */
3367  *xi = (yao * dx - xao * dy) * (2.0 * denominator);
3368  *eta = (xdo * dy - ydo * dx) * (2.0 * denominator);
3369 }
3370 
3371 /** **/
3372 /** **/
3373 /********* Geometric primitives end here *********/
3374 
3375 /*****************************************************************************/
3376 /* */
3377 /* triangleinit() Initialize some variables. */
3378 /* */
3379 /*****************************************************************************/
3380 
3382 {
3383  poolzero(&m->vertices);
3384  poolzero(&m->triangles);
3385  poolzero(&m->subsegs);
3386  poolzero(&m->viri);
3387  poolzero(&m->badsubsegs);
3388  poolzero(&m->badtriangles);
3389  poolzero(&m->flipstackers);
3390  poolzero(&m->splaynodes);
3391 
3392  m->recenttri.tri = (triangle *)NULL; /* No triangle has been visited yet. */
3393  m->undeads = 0; /* No eliminated input vertices yet. */
3394  m->samples = 1; /* Point location should take at least one sample. */
3395  m->checksegments = 0; /* There are no segments in the triangulation yet. */
3396  m->checkquality = 0; /* The quality triangulation stage has not begun. */
3399  randomseed = 1;
3400 
3401  exactinit(); /* Initialize exact arithmetic constants. */
3402 }
3403 
3404 /*****************************************************************************/
3405 /* */
3406 /* randomnation() Generate a random number between 0 and `choices' - 1. */
3407 /* */
3408 /* This is a simple linear congruential random number generator. Hence, it */
3409 /* is a bad random number generator, but good enough for most randomized */
3410 /* geometric algorithms. */
3411 /* */
3412 /*****************************************************************************/
3413 
3414 unsigned long DelaunayTriangle::randomnation(unsigned int choices)
3415 {
3416  randomseed = (randomseed * 1366l + 150889l) % 714025l;
3417  return randomseed / (714025l / choices + 1);
3418 }
3419 
3420 /*****************************************************************************/
3421 /* */
3422 /* enqueuebadtriang() Add a bad triangle data structure to the end of a */
3423 /* queue. */
3424 /* */
3425 /* The queue is actually a set of 4096 queues. I use multiple queues to */
3426 /* give priority to smaller angles. I originally implemented a heap, but */
3427 /* the queues are faster by a larger margin than I'd suspected. */
3428 /* */
3429 /*****************************************************************************/
3430 
3432  struct behavior *b,
3433  struct badtriang *badtri)
3434 {
3435  double length, multiplier;
3436  int exponent, expincrement;
3437  int queuenumber;
3438  int posexponent;
3439  int i;
3440 
3441  /* Determine the appropriate queue to put the bad triangle into. */
3442  /* Recall that the key is the square of its shortest edge length. */
3443  if (badtri->key >= 1.0)
3444  {
3445  length = badtri->key;
3446  posexponent = 1;
3447  }
3448  else
3449  {
3450  /* `badtri->key' is 2.0 to a negative exponent, so we'll record that */
3451  /* fact and use the reciprocal of `badtri->key', which is > 1.0. */
3452  length = 1.0 / badtri->key;
3453  posexponent = 0;
3454  }
3455  /* `length' is approximately 2.0 to what exponent? The following code */
3456  /* determines the answer in time logarithmic in the exponent. */
3457  exponent = 0;
3458  while (length > 2.0)
3459  {
3460  /* Find an approximation by repeated squaring of two. */
3461  expincrement = 1;
3462  multiplier = 0.5;
3463  while (length * multiplier * multiplier > 1.0)
3464  {
3465  expincrement *= 2;
3466  multiplier *= multiplier;
3467  }
3468  /* Reduce the value of `length', then iterate if necessary. */
3469  exponent += expincrement;
3470  length *= multiplier;
3471  }
3472  /* `length' is approximately squareroot(2.0) to what exponent? */
3473  exponent = 2.0 * exponent + (length > SQUAREROOTTWO);
3474  /* `exponent' is now in the range 0...2047 for IEEE double precision. */
3475  /* Choose a queue in the range 0...4095. The shortest edges have the */
3476  /* highest priority (queue 4095). */
3477  if (posexponent)
3478  {
3479  queuenumber = 2047 - exponent;
3480  }
3481  else
3482  {
3483  queuenumber = 2048 + exponent;
3484  }
3485 
3486  /* Are we inserting into an empty queue? */
3487  if (m->queuefront[queuenumber] == (struct badtriang *)NULL)
3488  {
3489  /* Yes, we are inserting into an empty queue. */
3490  /* Will this become the highest-priority queue? */
3491  if (queuenumber > m->firstnonemptyq)
3492  {
3493  /* Yes, this is the highest-priority queue. */
3494  m->nextnonemptyq[queuenumber] = m->firstnonemptyq;
3495  m->firstnonemptyq = queuenumber;
3496  }
3497  else
3498  {
3499  /* No, this is not the highest-priority queue. */
3500  /* Find the queue with next higher priority. */
3501  i = queuenumber + 1;
3502  while (m->queuefront[i] == (struct badtriang *)NULL)
3503  {
3504  i++;
3505  }
3506  /* Mark the newly nonempty queue as following a higher-priority
3507  * queue. */
3508  m->nextnonemptyq[queuenumber] = m->nextnonemptyq[i];
3509  m->nextnonemptyq[i] = queuenumber;
3510  }
3511  /* Put the bad triangle at the beginning of the (empty) queue. */
3512  m->queuefront[queuenumber] = badtri;
3513  }
3514  else
3515  {
3516  /* Add the bad triangle to the end of an already nonempty queue. */
3517  m->queuetail[queuenumber]->nexttriang = badtri;
3518  }
3519  /* Maintain a pointer to the last triangle of the queue. */
3520  m->queuetail[queuenumber] = badtri;
3521  /* Newly enqueued bad triangle has no successor in the queue. */
3522  badtri->nexttriang = (struct badtriang *)NULL;
3523 }
3524 
3525 /*****************************************************************************/
3526 /* */
3527 /* enqueuebadtri() Add a bad triangle to the end of a queue. */
3528 /* */
3529 /* Allocates a badtriang data structure for the triangle, then passes it to */
3530 /* enqueuebadtriang(). */
3531 /* */
3532 /*****************************************************************************/
3533 
3535  struct behavior *b,
3536  struct otri *enqtri,
3537  double minedge,
3538  vertex enqapex,
3539  vertex enqorg,
3540  vertex enqdest)
3541 {
3542  struct badtriang *newbad;
3543 
3544  /* Allocate space for the bad triangle. */
3545  newbad = (struct badtriang *)poolalloc(&m->badtriangles);
3546  newbad->poortri = encode(*enqtri);
3547  newbad->key = minedge;
3548  newbad->triangapex = enqapex;
3549  newbad->triangorg = enqorg;
3550  newbad->triangdest = enqdest;
3551  enqueuebadtriang(m, b, newbad);
3552 }
3553 
3554 /*****************************************************************************/
3555 /* */
3556 /* dequeuebadtriang() Remove a triangle from the front of the queue. */
3557 /* */
3558 /*****************************************************************************/
3559 
3561 {
3562  struct badtriang *result;
3563 
3564  /* If no queues are nonempty, return NULL. */
3565  if (m->firstnonemptyq < 0)
3566  {
3567  return (struct badtriang *)NULL;
3568  }
3569  /* Find the first triangle of the highest-priority queue. */
3570  result = m->queuefront[m->firstnonemptyq];
3571  /* Remove the triangle from the queue. */
3572  m->queuefront[m->firstnonemptyq] = result->nexttriang;
3573  /* If this queue is now empty, note the new highest-priority */
3574  /* nonempty queue. */
3575  if (result == m->queuetail[m->firstnonemptyq])
3576  {
3578  }
3579  return result;
3580 }
3581 
3582 /*****************************************************************************/
3583 /* */
3584 /* checkseg4encroach() Check a subsegment to see if it is encroached; add */
3585 /* it to the list if it is. */
3586 /* */
3587 /* A subsegment is encroached if there is a vertex in its diametral lens. */
3588 /* For Ruppert's algorithm (-D switch), the "diametral lens" is the */
3589 /* diametral circle. For Chew's algorithm (default), the diametral lens is */
3590 /* just big enough to enclose two isosceles triangles whose bases are the */
3591 /* subsegment. Each of the two isosceles triangles has two angles equal */
3592 /* to `b->minangle'. */
3593 /* */
3594 /* Chew's algorithm does not require diametral lenses at all--but they save */
3595 /* time. Any vertex inside a subsegment's diametral lens implies that the */
3596 /* triangle adjoining the subsegment will be too skinny, so it's only a */
3597 /* matter of time before the encroaching vertex is deleted by Chew's */
3598 /* algorithm. It's faster to simply not insert the doomed vertex in the */
3599 /* first place, which is why I use diametral lenses with Chew's algorithm. */
3600 /* */
3601 /* Returns a nonzero value if the subsegment is encroached. */
3602 /* */
3603 /*****************************************************************************/
3604 
3606  struct behavior *b,
3607  struct osub *testsubseg)
3608 {
3609  struct otri neighbortri;
3610  struct osub testsym;
3611  struct badsubseg *encroachedseg;
3612  double dotproduct;
3613  int encroached;
3614  int sides;
3615  vertex eorg, edest, eapex;
3616  triangle ptr; /* Temporary variable used by stpivot(). */
3617 
3618  encroached = 0;
3619  sides = 0;
3620 
3621  sorg(*testsubseg, eorg);
3622  sdest(*testsubseg, edest);
3623  /* Check one neighbor of the subsegment. */
3624  stpivot(*testsubseg, neighbortri);
3625  /* Does the neighbor exist, or is this a boundary edge? */
3626  if (neighbortri.tri != m->dummytri)
3627  {
3628  sides++;
3629  /* Find a vertex opposite this subsegment. */
3630  apex(neighbortri, eapex);
3631  /* Check whether the apex is in the diametral lens of the subsegment */
3632  /* (the diametral circle if `conformdel' is set). A dot product */
3633  /* of two sides of the triangle is used to check whether the angle */
3634  /* at the apex is greater than (180 - 2 `minangle') degrees (for */
3635  /* lenses; 90 degrees for diametral circles). */
3636  dotproduct = (eorg[0] - eapex[0]) * (edest[0] - eapex[0]) +
3637  (eorg[1] - eapex[1]) * (edest[1] - eapex[1]);
3638  if (dotproduct < 0.0)
3639  {
3640  if (dotproduct * dotproduct >=
3641  (2.0 * b->goodangle - 1.0) * (2.0 * b->goodangle - 1.0) *
3642  ((eorg[0] - eapex[0]) * (eorg[0] - eapex[0]) +
3643  (eorg[1] - eapex[1]) * (eorg[1] - eapex[1])) *
3644  ((edest[0] - eapex[0]) * (edest[0] - eapex[0]) +
3645  (edest[1] - eapex[1]) * (edest[1] - eapex[1])))
3646  {
3647  encroached = 1;
3648  }
3649  }
3650  }
3651  /* Check the other neighbor of the subsegment. */
3652  ssym(*testsubseg, testsym);
3653  stpivot(testsym, neighbortri);
3654  /* Does the neighbor exist, or is this a boundary edge? */
3655  if (neighbortri.tri != m->dummytri)
3656  {
3657  sides++;
3658  /* Find the other vertex opposite this subsegment. */
3659  apex(neighbortri, eapex);
3660  /* Check whether the apex is in the diametral lens of the subsegment */
3661  /* (or the diametral circle, if `conformdel' is set). */
3662  dotproduct = (eorg[0] - eapex[0]) * (edest[0] - eapex[0]) +
3663  (eorg[1] - eapex[1]) * (edest[1] - eapex[1]);
3664  if (dotproduct < 0.0)
3665  {
3666  if (dotproduct * dotproduct >=
3667  (2.0 * b->goodangle - 1.0) * (2.0 * b->goodangle - 1.0) *
3668  ((eorg[0] - eapex[0]) * (eorg[0] - eapex[0]) +
3669  (eorg[1] - eapex[1]) * (eorg[1] - eapex[1])) *
3670  ((edest[0] - eapex[0]) * (edest[0] - eapex[0]) +
3671  (edest[1] - eapex[1]) * (edest[1] - eapex[1])))
3672  {
3673  encroached += 2;
3674  }
3675  }
3676  }
3677 
3678  if (encroached && (!b->nobisect || ((b->nobisect == 1) && (sides == 2))))
3679  {
3680  /* Add the subsegment to the list of encroached subsegments. */
3681  /* Be sure to get the orientation right. */
3682  encroachedseg = (struct badsubseg *)poolalloc(&m->badsubsegs);
3683  if (encroached == 1)
3684  {
3685  encroachedseg->encsubseg = sencode(*testsubseg);
3686  encroachedseg->subsegorg = eorg;
3687  encroachedseg->subsegdest = edest;
3688  }
3689  else
3690  {
3691  encroachedseg->encsubseg = sencode(testsym);
3692  encroachedseg->subsegorg = edest;
3693  encroachedseg->subsegdest = eorg;
3694  }
3695  }
3696 
3697  return encroached;
3698 }
3699 
3700 /*****************************************************************************/
3701 /* */
3702 /* testtriangle() Test a triangle for quality and size. */
3703 /* */
3704 /* Tests a triangle to see if it satisfies the minimum angle condition and */
3705 /* the maximum area condition. Triangles that aren't up to spec are added */
3706 /* to the bad triangle queue. */
3707 /* */
3708 /*****************************************************************************/
3709 
3710 void DelaunayTriangle::testtriangle(struct mesh *m, struct behavior *b, struct otri *testtri)
3711 {
3712  struct otri tri1, tri2;
3713  struct osub testsub;
3714  vertex torg, tdest, tapex;
3715  vertex base1, base2;
3716  vertex org1, dest1, org2, dest2;
3717  vertex joinvertex;
3718  double dxod, dyod, dxda, dyda, dxao, dyao;
3719  double dxod2, dyod2, dxda2, dyda2, dxao2, dyao2;
3720  double apexlen, orglen, destlen, minedge;
3721  double angle;
3722  double area=0.0;
3723  double dist1, dist2;
3724  subseg sptr; /* Temporary variable used by tspivot(). */
3725  triangle ptr; /* Temporary variable used by oprev() and dnext(). */
3726 
3727  org(*testtri, torg);
3728  dest(*testtri, tdest);
3729  apex(*testtri, tapex);
3730  dxod = torg[0] - tdest[0];
3731  dyod = torg[1] - tdest[1];
3732  dxda = tdest[0] - tapex[0];
3733  dyda = tdest[1] - tapex[1];
3734  dxao = tapex[0] - torg[0];
3735  dyao = tapex[1] - torg[1];
3736  dxod2 = dxod * dxod;
3737  dyod2 = dyod * dyod;
3738  dxda2 = dxda * dxda;
3739  dyda2 = dyda * dyda;
3740  dxao2 = dxao * dxao;
3741  dyao2 = dyao * dyao;
3742  /* Find the lengths of the triangle's three edges. */
3743  apexlen = dxod2 + dyod2;
3744  orglen = dxda2 + dyda2;
3745  destlen = dxao2 + dyao2;
3746 
3747  if ((apexlen < orglen) && (apexlen < destlen))
3748  {
3749  /* The edge opposite the apex is shortest. */
3750  minedge = apexlen;
3751  /* Find the square of the cosine of the angle at the apex. */
3752  angle = dxda * dxao + dyda * dyao;
3753  angle = angle * angle / (orglen * destlen);
3754  base1 = torg;
3755  base2 = tdest;
3756  otricopy(*testtri, tri1);
3757  }
3758  else if (orglen < destlen)
3759  {
3760  /* The edge opposite the origin is shortest. */
3761  minedge = orglen;
3762  /* Find the square of the cosine of the angle at the origin. */
3763  angle = dxod * dxao + dyod * dyao;
3764  angle = angle * angle / (apexlen * destlen);
3765  base1 = tdest;
3766  base2 = tapex;
3767  lnext(*testtri, tri1);
3768  }
3769  else
3770  {
3771  /* The edge opposite the destination is shortest. */
3772  minedge = destlen;
3773  /* Find the square of the cosine of the angle at the destination. */
3774  angle = dxod * dxda + dyod * dyda;
3775  angle = angle * angle / (apexlen * orglen);
3776  base1 = tapex;
3777  base2 = torg;
3778  lprev(*testtri, tri1);
3779  }
3780 
3781  if (b->usertest)
3782  {
3783  if (b->usertest)
3784  {
3785  /* Check whether the user thinks this triangle is too large. */
3786  if (triunsuitable(torg, tdest, tapex, area))
3787  {
3788  enqueuebadtri(m, b, testtri, minedge, tapex, torg, tdest);
3789  return;
3790  }
3791  }
3792  }
3793 
3794  /* Check whether the angle is smaller than permitted. */
3795  if (angle > b->goodangle)
3796  {
3797  /* Use the rules of Miller, Pav, and Walkington to decide that certain
3798  */
3799  /* triangles should not be split, even if they have bad angles. */
3800  /* A skinny triangle is not split if its shortest edge subtends a */
3801  /* small input angle, and both endpoints of the edge lie on a */
3802  /* concentric circular shell. For convenience, I make a small */
3803  /* adjustment to that rule: I check if the endpoints of the edge */
3804  /* both lie in segment interiors, equidistant from the apex where */
3805  /* the two segments meet. */
3806  /* First, check if both points lie in segment interiors. */
3807  if ((vertextype(base1) == SEGMENTVERTEX) &&
3808  (vertextype(base2) == SEGMENTVERTEX))
3809  {
3810  /* Check if both points lie in a common segment. If they do, the */
3811  /* skinny triangle is enqueued to be split as usual. */
3812  tspivot(tri1, testsub);
3813  if (testsub.ss == m->dummysub)
3814  {
3815  /* No common segment. Find a subsegment that contains `torg'.
3816  */
3817  otricopy(tri1, tri2);
3818  do
3819  {
3820  oprevself(tri1);
3821  tspivot(tri1, testsub);
3822  } while (testsub.ss == m->dummysub);
3823  /* Find the endpoints of the containing segment. */
3824  segorg(testsub, org1);
3825  segdest(testsub, dest1);
3826  /* Find a subsegment that contains `tdest'. */
3827  do
3828  {
3829  dnextself(tri2);
3830  tspivot(tri2, testsub);
3831  } while (testsub.ss == m->dummysub);
3832  /* Find the endpoints of the containing segment. */
3833  segorg(testsub, org2);
3834  segdest(testsub, dest2);
3835  /* Check if the two containing segments have an endpoint in
3836  * common. */
3837  joinvertex = (vertex)NULL;
3838  if ((dest1[0] == org2[0]) && (dest1[1] == org2[1]))
3839  {
3840  joinvertex = dest1;
3841  }
3842  else if ((org1[0] == dest2[0]) && (org1[1] == dest2[1]))
3843  {
3844  joinvertex = org1;
3845  }
3846  if (joinvertex != (vertex)NULL)
3847  {
3848  /* Compute the distance from the common endpoint (of the two
3849  */
3850  /* segments) to each of the endpoints of the shortest
3851  * edge. */
3852  dist1 = ((base1[0] - joinvertex[0]) *
3853  (base1[0] - joinvertex[0]) +
3854  (base1[1] - joinvertex[1]) *
3855  (base1[1] - joinvertex[1]));
3856  dist2 = ((base2[0] - joinvertex[0]) *
3857  (base2[0] - joinvertex[0]) +
3858  (base2[1] - joinvertex[1]) *
3859  (base2[1] - joinvertex[1]));
3860  /* If the two distances are equal, don't split the triangle.
3861  */
3862  if ((dist1 < 1.001 * dist2) && (dist1 > 0.999 * dist2))
3863  {
3864  /* Return now to avoid enqueueing the bad triangle. */
3865  return;
3866  }
3867  }
3868  }
3869  }
3870 
3871  /* Add this triangle to the list of bad triangles. */
3872  enqueuebadtri(m, b, testtri, minedge, tapex, torg, tdest);
3873  }
3874 }
3875 
3876 /** **/
3877 /** **/
3878 /********* Mesh quality testing routines end here *********/
3879 
3880 /********* Point location routines begin here *********/
3881 /** **/
3882 /** **/
3883 
3884 /*****************************************************************************/
3885 /* */
3886 /* makevertexmap() Construct a mapping from vertices to triangles to */
3887 /* improve the speed of point location for segment */
3888 /* insertion. */
3889 /* */
3890 /* Traverses all the triangles, and provides each corner of each triangle */
3891 /* with a pointer to that triangle. Of course, pointers will be */
3892 /* overwritten by other pointers because (almost) each vertex is a corner */
3893 /* of several triangles, but in the end every vertex will point to some */
3894 /* triangle that contains it. */
3895 /* */
3896 /*****************************************************************************/
3897 
3899 {
3900  struct otri triangleloop;
3901  vertex triorg;
3902 
3903  traversalinit(&m->triangles);
3904  triangleloop.tri = triangletraverse(m);
3905  while (triangleloop.tri != (triangle *)NULL)
3906  {
3907  /* Check all three vertices of the triangle. */
3908  for (triangleloop.orient = 0; triangleloop.orient < 3;
3909  triangleloop.orient++)
3910  {
3911  org(triangleloop, triorg);
3912  setvertex2tri(triorg, encode(triangleloop));
3913  }
3914  triangleloop.tri = triangletraverse(m);
3915  }
3916 }
3917 
3918 /*****************************************************************************/
3919 /* */
3920 /* preciselocate() Find a triangle or edge containing a given point. */
3921 /* */
3922 /* Begins its search from `searchtri'. It is important that `searchtri' */
3923 /* be a handle with the property that `searchpoint' is strictly to the left */
3924 /* of the edge denoted by `searchtri', or is collinear with that edge and */
3925 /* does not intersect that edge. (In particular, `searchpoint' should not */
3926 /* be the origin or destination of that edge.) */
3927 /* */
3928 /* These conditions are imposed because preciselocate() is normally used in */
3929 /* one of two situations: */
3930 /* */
3931 /* (1) To try to find the location to insert a new point. Normally, we */
3932 /* know an edge that the point is strictly to the left of. In the */
3933 /* incremental Delaunay algorithm, that edge is a bounding box edge. */
3934 /* In Ruppert's Delaunay refinement algorithm for quality meshing, */
3935 /* that edge is the shortest edge of the triangle whose circumcenter */
3936 /* is being inserted. */
3937 /* */
3938 /* (2) To try to find an existing point. In this case, any edge on the */
3939 /* convex hull is a good starting edge. You must screen out the */
3940 /* possibility that the vertex sought is an endpoint of the starting */
3941 /* edge before you call preciselocate(). */
3942 /* */
3943 /* On completion, `searchtri' is a triangle that contains `searchpoint'. */
3944 /* */
3945 /* This implementation differs from that given by Guibas and Stolfi. It */
3946 /* walks from triangle to triangle, crossing an edge only if `searchpoint' */
3947 /* is on the other side of the line containing that edge. After entering */
3948 /* a triangle, there are two edges by which one can leave that triangle. */
3949 /* If both edges are valid (`searchpoint' is on the other side of both */
3950 /* edges), one of the two is chosen by drawing a line perpendicular to */
3951 /* the entry edge (whose endpoints are `forg' and `fdest') passing through */
3952 /* `fapex'. Depending on which side of this perpendicular `searchpoint' */
3953 /* falls on, an exit edge is chosen. */
3954 /* */
3955 /* This implementation is empirically faster than the Guibas and Stolfi */
3956 /* point location routine (which I originally used), which tends to spiral */
3957 /* in toward its target. */
3958 /* */
3959 /* Returns ONVERTEX if the point lies on an existing vertex. `searchtri' */
3960 /* is a handle whose origin is the existing vertex. */
3961 /* */
3962 /* Returns ONEDGE if the point lies on a mesh edge. `searchtri' is a */
3963 /* handle whose primary edge is the edge on which the point lies. */
3964 /* */
3965 /* Returns INTRIANGLE if the point lies strictly within a triangle. */
3966 /* `searchtri' is a handle on the triangle that contains the point. */
3967 /* */
3968 /* Returns OUTSIDE if the point lies outside the mesh. `searchtri' is a */
3969 /* handle whose primary edge the point is to the right of. This might */
3970 /* occur when the circumcenter of a triangle falls just slightly outside */
3971 /* the mesh due to floating-point roundoff error. It also occurs when */
3972 /* seeking a hole or region point that a foolish user has placed outside */
3973 /* the mesh. */
3974 /* */
3975 /* If `stopatsubsegment' is nonzero, the search will stop if it tries to */
3976 /* walk through a subsegment, and will return OUTSIDE. */
3977 /* */
3978 /* WARNING: This routine is designed for convex triangulations, and will */
3979 /* not generally work after the holes and concavities have been carved. */
3980 /* However, it can still be used to find the circumcenter of a triangle, as */
3981 /* long as the search is begun from the triangle in question. */
3982 /* */
3983 /*****************************************************************************/
3984 
3986  struct behavior *b,
3987  vertex searchpoint,
3988  struct otri *searchtri,
3989  int stopatsubsegment)
3990 {
3991  struct otri backtracktri;
3992  struct osub checkedge;
3993  vertex forg, fdest, fapex;
3994  double orgorient, destorient;
3995  int moveleft;
3996  triangle ptr; /* Temporary variable used by sym(). */
3997  subseg sptr; /* Temporary variable used by tspivot(). */
3998 
3999  /* Where are we? */
4000  org(*searchtri, forg);
4001  dest(*searchtri, fdest);
4002  apex(*searchtri, fapex);
4003  while (1)
4004  {
4005  /* Check whether the apex is the point we seek. */
4006  if ((fapex[0] == searchpoint[0]) && (fapex[1] == searchpoint[1]))
4007  {
4008  lprevself(*searchtri);
4009  return ONVERTEX;
4010  }
4011  /* Does the point lie on the other side of the line defined by the */
4012  /* triangle edge opposite the triangle's destination? */
4013  destorient = counterclockwise(m, b, forg, fapex, searchpoint);
4014  /* Does the point lie on the other side of the line defined by the */
4015  /* triangle edge opposite the triangle's origin? */
4016  orgorient = counterclockwise(m, b, fapex, fdest, searchpoint);
4017  if (destorient > 0.0)
4018  {
4019  if (orgorient > 0.0)
4020  {
4021  /* Move left if the inner product of (fapex - searchpoint) and
4022  */
4023  /* (fdest - forg) is positive. This is equivalent to drawing
4024  */
4025  /* a line perpendicular to the line (forg, fdest) and passing
4026  */
4027  /* through `fapex', and determining which side of this line */
4028  /* `searchpoint' falls on. */
4029  moveleft =
4030  (fapex[0] - searchpoint[0]) * (fdest[0] - forg[0]) +
4031  (fapex[1] - searchpoint[1]) * (fdest[1] - forg[1]) >
4032  0.0;
4033  }
4034  else
4035  {
4036  moveleft = 1;
4037  }
4038  }
4039  else
4040  {
4041  if (orgorient > 0.0)
4042  {
4043  moveleft = 0;
4044  }
4045  else
4046  {
4047  /* The point we seek must be on the boundary of or inside this
4048  */
4049  /* triangle. */
4050  if (destorient == 0.0)
4051  {
4052  lprevself(*searchtri);
4053  return ONEDGE;
4054  }
4055  if (orgorient == 0.0)
4056  {
4057  lnextself(*searchtri);
4058  return ONEDGE;
4059  }
4060  return INTRIANGLE;
4061  }
4062  }
4063 
4064  /* Move to another triangle. Leave a trace `backtracktri' in case */
4065  /* floating-point roundoff or some such bogey causes us to walk */
4066  /* off a boundary of the triangulation. */
4067  if (moveleft)
4068  {
4069  lprev(*searchtri, backtracktri);
4070  fdest = fapex;
4071  }
4072  else
4073  {
4074  lnext(*searchtri, backtracktri);
4075  forg = fapex;
4076  }
4077  sym(backtracktri, *searchtri);
4078 
4079  if (m->checksegments && stopatsubsegment)
4080  {
4081  /* Check for walking through a subsegment. */
4082  tspivot(backtracktri, checkedge);
4083  if (checkedge.ss != m->dummysub)
4084  {
4085  /* Go back to the last triangle. */
4086  otricopy(backtracktri, *searchtri);
4087  return OUTSIDE;
4088  }
4089  }
4090  /* Check for walking right out of the triangulation. */
4091  if (searchtri->tri == m->dummytri)
4092  {
4093  /* Go back to the last triangle. */
4094  otricopy(backtracktri, *searchtri);
4095  return OUTSIDE;
4096  }
4097 
4098  apex(*searchtri, fapex);
4099  }
4100 }
4101 
4102 /*****************************************************************************/
4103 /* */
4104 /* locate() Find a triangle or edge containing a given point. */
4105 /* */
4106 /* Searching begins from one of: the input `searchtri', a recently */
4107 /* encountered triangle `recenttri', or from a triangle chosen from a */
4108 /* random sample. The choice is made by determining which triangle's */
4109 /* origin is closest to the point we are searching for. Normally, */
4110 /* `searchtri' should be a handle on the convex hull of the triangulation. */
4111 /* */
4112 /* Details on the random sampling method can be found in the Mucke, Saias, */
4113 /* and Zhu paper cited in the header of this code. */
4114 /* */
4115 /* On completion, `searchtri' is a triangle that contains `searchpoint'. */
4116 /* */
4117 /* Returns ONVERTEX if the point lies on an existing vertex. `searchtri' */
4118 /* is a handle whose origin is the existing vertex. */
4119 /* */
4120 /* Returns ONEDGE if the point lies on a mesh edge. `searchtri' is a */
4121 /* handle whose primary edge is the edge on which the point lies. */
4122 /* */
4123 /* Returns INTRIANGLE if the point lies strictly within a triangle. */
4124 /* `searchtri' is a handle on the triangle that contains the point. */
4125 /* */
4126 /* Returns OUTSIDE if the point lies outside the mesh. `searchtri' is a */
4127 /* handle whose primary edge the point is to the right of. This might */
4128 /* occur when the circumcenter of a triangle falls just slightly outside */
4129 /* the mesh due to floating-point roundoff error. It also occurs when */
4130 /* seeking a hole or region point that a foolish user has placed outside */
4131 /* the mesh. */
4132 /* */
4133 /* WARNING: This routine is designed for convex triangulations, and will */
4134 /* not generally work after the holes and concavities have been carved. */
4135 /* */
4136 /*****************************************************************************/
4137 
4139  struct behavior *b,
4140  vertex searchpoint,
4141  struct otri *searchtri)
4142 {
4143  void **sampleblock;
4144  char *firsttri;
4145  struct otri sampletri;
4146  vertex torg, tdest;
4147  unsigned long alignptr;
4148  double searchdist, dist;
4149  double ahead;
4150  long samplesperblock, totalsamplesleft, samplesleft;
4151  long population, totalpopulation;
4152  triangle ptr; /* Temporary variable used by sym(). */
4153 
4154  /* Record the distance from the suggested starting triangle to the */
4155  /* point we seek. */
4156  org(*searchtri, torg);
4157  searchdist = (searchpoint[0] - torg[0]) * (searchpoint[0] - torg[0]) +
4158  (searchpoint[1] - torg[1]) * (searchpoint[1] - torg[1]);
4159 
4160  /* If a recently encountered triangle has been recorded and has not been */
4161  /* deallocated, test it as a good starting point. */
4162  if (m->recenttri.tri != (triangle *)NULL)
4163  {
4164  if (!deadtri(m->recenttri.tri))
4165  {
4166  org(m->recenttri, torg);
4167  if ((torg[0] == searchpoint[0]) && (torg[1] == searchpoint[1]))
4168  {
4169  otricopy(m->recenttri, *searchtri);
4170  return ONVERTEX;
4171  }
4172  dist = (searchpoint[0] - torg[0]) * (searchpoint[0] - torg[0]) +
4173  (searchpoint[1] - torg[1]) * (searchpoint[1] - torg[1]);
4174  if (dist < searchdist)
4175  {
4176  otricopy(m->recenttri, *searchtri);
4177  searchdist = dist;
4178  }
4179  }
4180  }
4181 
4182  /* The number of random samples taken is proportional to the cube root of */
4183  /* the number of triangles in the mesh. The next bit of code assumes */
4184  /* that the number of triangles increases monotonically (or at least */
4185  /* doesn't decrease enough to matter). */
4186  while (SAMPLEFACTOR * m->samples * m->samples * m->samples <
4187  m->triangles.items)
4188  {
4189  m->samples++;
4190  }
4191 
4192  /* We'll draw ceiling(samples * TRIPERBLOCK / maxitems) random samples */
4193  /* from each block of triangles (except the first)--until we meet the */
4194  /* sample quota. The ceiling means that blocks at the end might be */
4195  /* neglected, but I don't care. */
4196  samplesperblock =
4197  (m->samples * TRIPERBLOCK - 1) / m->triangles.maxitems + 1;
4198  /* We'll draw ceiling(samples * itemsfirstblock / maxitems) random samples
4199  */
4200  /* from the first block of triangles. */
4201  samplesleft = (m->samples * m->triangles.itemsfirstblock - 1) /
4202  m->triangles.maxitems +
4203  1;
4204  totalsamplesleft = m->samples;
4205  population = m->triangles.itemsfirstblock;
4206  totalpopulation = m->triangles.maxitems;
4207  sampleblock = m->triangles.firstblock;
4208  sampletri.orient = 0;
4209  while (totalsamplesleft > 0)
4210  {
4211  /* If we're in the last block, `population' needs to be corrected. */
4212  if (population > totalpopulation)
4213  {
4214  population = totalpopulation;
4215  }
4216  /* Find a pointer to the first triangle in the block. */
4217  alignptr = (unsigned long)(sampleblock + 1);
4218  firsttri =
4219  (char *)(alignptr + (unsigned long)m->triangles.alignbytes -
4220  (alignptr % (unsigned long)m->triangles.alignbytes));
4221 
4222  /* Choose `samplesleft' randomly sampled triangles in this block. */
4223  do
4224  {
4225  sampletri.tri =
4226  (triangle *)(firsttri +
4227  (randomnation((unsigned int)population) *
4228  m->triangles.itembytes));
4229  if (!deadtri(sampletri.tri))
4230  {
4231  org(sampletri, torg);
4232  dist = (searchpoint[0] - torg[0]) * (searchpoint[0] - torg[0]) +
4233  (searchpoint[1] - torg[1]) * (searchpoint[1] - torg[1]);
4234  if (dist < searchdist)
4235  {
4236  otricopy(sampletri, *searchtri);
4237  searchdist = dist;
4238  }
4239  }
4240 
4241  samplesleft--;
4242  totalsamplesleft--;
4243  } while ((samplesleft > 0) && (totalsamplesleft > 0));
4244 
4245  if (totalsamplesleft > 0)
4246  {
4247  sampleblock = (void **)*sampleblock;
4248  samplesleft = samplesperblock;
4249  totalpopulation -= population;
4250  population = TRIPERBLOCK;
4251  }
4252  }
4253 
4254  /* Where are we? */
4255  org(*searchtri, torg);
4256  dest(*searchtri, tdest);
4257  /* Check the starting triangle's vertices. */
4258  if ((torg[0] == searchpoint[0]) && (torg[1] == searchpoint[1]))
4259  {
4260  return ONVERTEX;
4261  }
4262  if ((tdest[0] == searchpoint[0]) && (tdest[1] == searchpoint[1]))
4263  {
4264  lnextself(*searchtri);
4265  return ONVERTEX;
4266  }
4267  /* Orient `searchtri' to fit the preconditions of calling preciselocate().
4268  */
4269  ahead = counterclockwise(m, b, torg, tdest, searchpoint);
4270  if (ahead < 0.0)
4271  {
4272  /* Turn around so that `searchpoint' is to the left of the */
4273  /* edge specified by `searchtri'. */
4274  symself(*searchtri);
4275  }
4276  else if (ahead == 0.0)
4277  {
4278  /* Check if `searchpoint' is between `torg' and `tdest'. */
4279  if (((torg[0] < searchpoint[0]) == (searchpoint[0] < tdest[0])) &&
4280  ((torg[1] < searchpoint[1]) == (searchpoint[1] < tdest[1])))
4281  {
4282  return ONEDGE;
4283  }
4284  }
4285  return preciselocate(m, b, searchpoint, searchtri, 0);
4286 }
4287 
4288 /** **/
4289 /** **/
4290 /********* Point location routines end here *********/
4291 
4292 /********* Mesh transformation routines begin here *********/
4293 /** **/
4294 /** **/
4295 
4296 /*****************************************************************************/
4297 /* */
4298 /* insertsubseg() Create a new subsegment and insert it between two */
4299 /* triangles. */
4300 /* */
4301 /* The new subsegment is inserted at the edge described by the handle */
4302 /* `tri'. Its vertices are properly initialized. The marker `subsegmark' */
4303 /* is applied to the subsegment and, if appropriate, its vertices. */
4304 /* */
4305 /*****************************************************************************/
4306 
4308  struct behavior *b,
4309  struct otri *tri,
4310  int subsegmark)
4311 {
4312  struct otri oppotri;
4313  struct osub newsubseg;
4314  vertex triorg, tridest;
4315  triangle ptr; /* Temporary variable used by sym(). */
4316  subseg sptr; /* Temporary variable used by tspivot(). */
4317 
4318  org(*tri, triorg);
4319  dest(*tri, tridest);
4320  /* Mark vertices if possible. */
4321  if (vertexmark(triorg) == 0)
4322  {
4323  setvertexmark(triorg, subsegmark);
4324  }
4325  if (vertexmark(tridest) == 0)
4326  {
4327  setvertexmark(tridest, subsegmark);
4328  }
4329  /* Check if there's already a subsegment here. */
4330  tspivot(*tri, newsubseg);
4331  if (newsubseg.ss == m->dummysub)
4332  {
4333  /* Make new subsegment and initialize its vertices. */
4334  makesubseg(m, &newsubseg);
4335  setsorg(newsubseg, tridest);
4336  setsdest(newsubseg, triorg);
4337  setsegorg(newsubseg, tridest);
4338  setsegdest(newsubseg, triorg);
4339  /* Bond new subsegment to the two triangles it is sandwiched between. */
4340  /* Note that the facing triangle `oppotri' might be equal to */
4341  /* `dummytri' (outer space), but the new subsegment is bonded to it */
4342  /* all the same. */
4343  tsbond(*tri, newsubseg);
4344  sym(*tri, oppotri);
4345  ssymself(newsubseg);
4346  tsbond(oppotri, newsubseg);
4347  setmark(newsubseg, subsegmark);
4348  }
4349  else
4350  {
4351  if (mark(newsubseg) == 0)
4352  {
4353  setmark(newsubseg, subsegmark);
4354  }
4355  }
4356 }
4357 
4358 /*****************************************************************************/
4359 /* */
4360 /* Terminology */
4361 /* */
4362 /* A "local transformation" replaces a small set of triangles with another */
4363 /* set of triangles. This may or may not involve inserting or deleting a */
4364 /* vertex. */
4365 /* */
4366 /* The term "casing" is used to describe the set of triangles that are */
4367 /* attached to the triangles being transformed, but are not transformed */
4368 /* themselves. Think of the casing as a fixed hollow structure inside */
4369 /* which all the action happens. A "casing" is only defined relative to */
4370 /* a single transformation; each occurrence of a transformation will */
4371 /* involve a different casing. */
4372 /* */
4373 /*****************************************************************************/
4374 
4375 /*****************************************************************************/
4376 /* */
4377 /* flip() Transform two triangles to two different triangles by flipping */
4378 /* an edge counterclockwise within a quadrilateral. */
4379 /* */
4380 /* Imagine the original triangles, abc and bad, oriented so that the */
4381 /* shared edge ab lies in a horizontal plane, with the vertex b on the left */
4382 /* and the vertex a on the right. The vertex c lies below the edge, and */
4383 /* the vertex d lies above the edge. The `flipedge' handle holds the edge */
4384 /* ab of triangle abc, and is directed left, from vertex a to vertex b. */
4385 /* */
4386 /* The triangles abc and bad are deleted and replaced by the triangles cdb */
4387 /* and dca. The triangles that represent abc and bad are NOT deallocated; */
4388 /* they are reused for dca and cdb, respectively. Hence, any handles that */
4389 /* may have held the original triangles are still valid, although not */
4390 /* directed as they were before. */
4391 /* */
4392 /* Upon completion of this routine, the `flipedge' handle holds the edge */
4393 /* dc of triangle dca, and is directed down, from vertex d to vertex c. */
4394 /* (Hence, the two triangles have rotated counterclockwise.) */
4395 /* */
4396 /* WARNING: This transformation is geometrically valid only if the */
4397 /* quadrilateral adbc is convex. Furthermore, this transformation is */
4398 /* valid only if there is not a subsegment between the triangles abc and */
4399 /* bad. This routine does not check either of these preconditions, and */
4400 /* it is the responsibility of the calling routine to ensure that they are */
4401 /* met. If they are not, the streets shall be filled with wailing and */
4402 /* gnashing of teeth. */
4403 /* */
4404 /*****************************************************************************/
4405 
4406 void DelaunayTriangle::flip(struct mesh *m, struct behavior *b, struct otri *flipedge)
4407 {
4408  struct otri botleft, botright;
4409  struct otri topleft, topright;
4410  struct otri top;
4411  struct otri botlcasing, botrcasing;
4412  struct otri toplcasing, toprcasing;
4413  struct osub botlsubseg, botrsubseg;
4414  struct osub toplsubseg, toprsubseg;
4415  vertex leftvertex, rightvertex, botvertex;
4416  vertex farvertex;
4417  triangle ptr; /* Temporary variable used by sym(). */
4418  subseg sptr; /* Temporary variable used by tspivot(). */
4419 
4420  /* Identify the vertices of the quadrilateral. */
4421  org(*flipedge, rightvertex);
4422  dest(*flipedge, leftvertex);
4423  apex(*flipedge, botvertex);
4424  sym(*flipedge, top);
4425  apex(top, farvertex);
4426 
4427  /* Identify the casing of the quadrilateral. */
4428  lprev(top, topleft);
4429  sym(topleft, toplcasing);
4430  lnext(top, topright);
4431  sym(topright, toprcasing);
4432  lnext(*flipedge, botleft);
4433  sym(botleft, botlcasing);
4434  lprev(*flipedge, botright);
4435  sym(botright, botrcasing);
4436  /* Rotate the quadrilateral one-quarter turn counterclockwise. */
4437  bond(topleft, botlcasing);
4438  bond(botleft, botrcasing);
4439  bond(botright, toprcasing);
4440  bond(topright, toplcasing);
4441 
4442  if (m->checksegments)
4443  {
4444  /* Check for subsegments and rebond them to the quadrilateral. */
4445  tspivot(topleft, toplsubseg);
4446  tspivot(botleft, botlsubseg);
4447  tspivot(botright, botrsubseg);
4448  tspivot(topright, toprsubseg);
4449  if (toplsubseg.ss == m->dummysub)
4450  {
4451  tsdissolve(topright);
4452  }
4453  else
4454  {
4455  tsbond(topright, toplsubseg);
4456  }
4457  if (botlsubseg.ss == m->dummysub)
4458  {
4459  tsdissolve(topleft);
4460  }
4461  else
4462  {
4463  tsbond(topleft, botlsubseg);
4464  }
4465  if (botrsubseg.ss == m->dummysub)
4466  {
4467  tsdissolve(botleft);
4468  }
4469  else
4470  {
4471  tsbond(botleft, botrsubseg);
4472  }
4473  if (toprsubseg.ss == m->dummysub)
4474  {
4475  tsdissolve(botright);
4476  }
4477  else
4478  {
4479  tsbond(botright, toprsubseg);
4480  }
4481  }
4482 
4483  /* New vertex assignments for the rotated quadrilateral. */
4484  setorg(*flipedge, farvertex);
4485  setdest(*flipedge, botvertex);
4486  setapex(*flipedge, rightvertex);
4487  setorg(top, botvertex);
4488  setdest(top, farvertex);
4489  setapex(top, leftvertex);
4490 }
4491 
4492 /*****************************************************************************/
4493 /* */
4494 /* unflip() Transform two triangles to two different triangles by */
4495 /* flipping an edge clockwise within a quadrilateral. Reverses */
4496 /* the flip() operation so that the data structures representing */
4497 /* the triangles are back where they were before the flip(). */
4498 /* */
4499 /* Imagine the original triangles, abc and bad, oriented so that the */
4500 /* shared edge ab lies in a horizontal plane, with the vertex b on the left */
4501 /* and the vertex a on the right. The vertex c lies below the edge, and */
4502 /* the vertex d lies above the edge. The `flipedge' handle holds the edge */
4503 /* ab of triangle abc, and is directed left, from vertex a to vertex b. */
4504 /* */
4505 /* The triangles abc and bad are deleted and replaced by the triangles cdb */
4506 /* and dca. The triangles that represent abc and bad are NOT deallocated; */
4507 /* they are reused for cdb and dca, respectively. Hence, any handles that */
4508 /* may have held the original triangles are still valid, although not */
4509 /* directed as they were before. */
4510 /* */
4511 /* Upon completion of this routine, the `flipedge' handle holds the edge */
4512 /* cd of triangle cdb, and is directed up, from vertex c to vertex d. */
4513 /* (Hence, the two triangles have rotated clockwise.) */
4514 /* */
4515 /* WARNING: This transformation is geometrically valid only if the */
4516 /* quadrilateral adbc is convex. Furthermore, this transformation is */
4517 /* valid only if there is not a subsegment between the triangles abc and */
4518 /* bad. This routine does not check either of these preconditions, and */
4519 /* it is the responsibility of the calling routine to ensure that they are */
4520 /* met. If they are not, the streets shall be filled with wailing and */
4521 /* gnashing of teeth. */
4522 /* */
4523 /*****************************************************************************/
4524 
4525 void DelaunayTriangle::unflip(struct mesh *m, struct behavior *b, struct otri *flipedge)
4526 {
4527  struct otri botleft, botright;
4528  struct otri topleft, topright;
4529  struct otri top;
4530  struct otri botlcasing, botrcasing;
4531  struct otri toplcasing, toprcasing;
4532  struct osub botlsubseg, botrsubseg;
4533  struct osub toplsubseg, toprsubseg;
4534  vertex leftvertex, rightvertex, botvertex;
4535  vertex farvertex;
4536  triangle ptr; /* Temporary variable used by sym(). */
4537  subseg sptr; /* Temporary variable used by tspivot(). */
4538 
4539  /* Identify the vertices of the quadrilateral. */
4540  org(*flipedge, rightvertex);
4541  dest(*flipedge, leftvertex);
4542  apex(*flipedge, botvertex);
4543  sym(*flipedge, top);
4544  apex(top, farvertex);
4545 
4546  /* Identify the casing of the quadrilateral. */
4547  lprev(top, topleft);
4548  sym(topleft, toplcasing);
4549  lnext(top, topright);
4550  sym(topright, toprcasing);
4551  lnext(*flipedge, botleft);
4552  sym(botleft, botlcasing);
4553  lprev(*flipedge, botright);
4554  sym(botright, botrcasing);
4555  /* Rotate the quadrilateral one-quarter turn clockwise. */
4556  bond(topleft, toprcasing);
4557  bond(botleft, toplcasing);
4558  bond(botright, botlcasing);
4559  bond(topright, botrcasing);
4560 
4561  if (m->checksegments)
4562  {
4563  /* Check for subsegments and rebond them to the quadrilateral. */
4564  tspivot(topleft, toplsubseg);
4565  tspivot(botleft, botlsubseg);
4566  tspivot(botright, botrsubseg);
4567  tspivot(topright, toprsubseg);
4568  if (toplsubseg.ss == m->dummysub)
4569  {
4570  tsdissolve(botleft);
4571  }
4572  else
4573  {
4574  tsbond(botleft, toplsubseg);
4575  }
4576  if (botlsubseg.ss == m->dummysub)
4577  {
4578  tsdissolve(botright);
4579  }
4580  else
4581  {
4582  tsbond(botright, botlsubseg);
4583  }
4584  if (botrsubseg.ss == m->dummysub)
4585  {
4586  tsdissolve(topright);
4587  }
4588  else
4589  {
4590  tsbond(topright, botrsubseg);
4591  }
4592  if (toprsubseg.ss == m->dummysub)
4593  {
4594  tsdissolve(topleft);
4595  }
4596  else
4597  {
4598  tsbond(topleft, toprsubseg);
4599  }
4600  }
4601 
4602  /* New vertex assignments for the rotated quadrilateral. */
4603  setorg(*flipedge, botvertex);
4604  setdest(*flipedge, farvertex);
4605  setapex(*flipedge, leftvertex);
4606  setorg(top, farvertex);
4607  setdest(top, botvertex);
4608  setapex(top, rightvertex);
4609 }
4610 
4611 /*****************************************************************************/
4612 /* */
4613 /* insertvertex() Insert a vertex into a Delaunay triangulation, */
4614 /* performing flips as necessary to maintain the Delaunay */
4615 /* property. */
4616 /* */
4617 /* The point `insertvertex' is located. If `searchtri.tri' is not NULL, */
4618 /* the search for the containing triangle begins from `searchtri'. If */
4619 /* `searchtri.tri' is NULL, a full point location procedure is called. */
4620 /* If `insertvertex' is found inside a triangle, the triangle is split into */
4621 /* three; if `insertvertex' lies on an edge, the edge is split in two, */
4622 /* thereby splitting the two adjacent triangles into four. Edge flips are */
4623 /* used to restore the Delaunay property. If `insertvertex' lies on an */
4624 /* existing vertex, no action is taken, and the value DUPLICATEVERTEX is */
4625 /* returned. On return, `searchtri' is set to a handle whose origin is the */
4626 /* existing vertex. */
4627 /* */
4628 /* Normally, the parameter `splitseg' is set to NULL, implying that no */
4629 /* subsegment should be split. In this case, if `insertvertex' is found to */
4630 /* lie on a segment, no action is taken, and the value VIOLATINGVERTEX is */
4631 /* returned. On return, `searchtri' is set to a handle whose primary edge */
4632 /* is the violated subsegment. */
4633 /* */
4634 /* If the calling routine wishes to split a subsegment by inserting a */
4635 /* vertex in it, the parameter `splitseg' should be that subsegment. In */
4636 /* this case, `searchtri' MUST be the triangle handle reached by pivoting */
4637 /* from that subsegment; no point location is done. */
4638 /* */
4639 /* `segmentflaws' and `triflaws' are flags that indicate whether or not */
4640 /* there should be checks for the creation of encroached subsegments or bad */
4641 /* quality triangles. If a newly inserted vertex encroaches upon */
4642 /* subsegments, these subsegments are added to the list of subsegments to */
4643 /* be split if `segmentflaws' is set. If bad triangles are created, these */
4644 /* are added to the queue if `triflaws' is set. */
4645 /* */
4646 /* If a duplicate vertex or violated segment does not prevent the vertex */
4647 /* from being inserted, the return value will be ENCROACHINGVERTEX if the */
4648 /* vertex encroaches upon a subsegment (and checking is enabled), or */
4649 /* SUCCESSFULVERTEX otherwise. In either case, `searchtri' is set to a */
4650 /* handle whose origin is the newly inserted vertex. */
4651 /* */
4652 /* insertvertex() does not use flip() for reasons of speed; some */
4653 /* information can be reused from edge flip to edge flip, like the */
4654 /* locations of subsegments. */
4655 /* */
4656 /*****************************************************************************/
4657 
4659  struct behavior *b,
4660  vertex newvertex,
4661  struct otri *searchtri,
4662  struct osub *splitseg,
4663  int segmentflaws,
4664  int triflaws)
4665 {
4666  struct otri horiz;
4667  struct otri top;
4668  struct otri botleft, botright;
4669  struct otri topleft, topright;
4670  struct otri newbotleft, newbotright;
4671  struct otri newtopright;
4672  struct otri botlcasing, botrcasing;
4673  struct otri toplcasing, toprcasing;
4674  struct otri testtri;
4675  struct osub botlsubseg, botrsubseg;
4676  struct osub toplsubseg, toprsubseg;
4677  struct osub brokensubseg;
4678  struct osub checksubseg;
4679  struct osub rightsubseg;
4680  struct osub newsubseg;
4681  struct badsubseg *encroached;
4682  struct flipstacker *newflip;
4683  vertex first;
4684  vertex leftvertex, rightvertex, botvertex, topvertex, farvertex;
4685  vertex segmentorg, segmentdest;
4686  double attrib;
4687  enum insertvertexresult success;
4688  enum locateresult intersect;
4689  int doflip;
4690  int mirrorflag;
4691  int enq;
4692  int i;
4693  triangle ptr; /* Temporary variable used by sym(). */
4694  subseg sptr; /* Temporary variable used by spivot() and tspivot(). */
4695 
4696  if (splitseg == (struct osub *)NULL)
4697  {
4698  /* Find the location of the vertex to be inserted. Check if a good */
4699  /* starting triangle has already been provided by the caller. */
4700  if (searchtri->tri == m->dummytri)
4701  {
4702  /* Find a boundary triangle. */
4703  horiz.tri = m->dummytri;
4704  horiz.orient = 0;
4705  symself(horiz);
4706  /* Search for a triangle containing `newvertex'. */
4707  intersect = locate(m, b, newvertex, &horiz);
4708  }
4709  else
4710  {
4711  /* Start searching from the triangle provided by the caller. */
4712  otricopy(*searchtri, horiz);
4713  intersect = preciselocate(m, b, newvertex, &horiz, 1);
4714  }
4715  }
4716  else
4717  {
4718  /* The calling routine provides the subsegment in which */
4719  /* the vertex is inserted. */
4720  otricopy(*searchtri, horiz);
4721  intersect = ONEDGE;
4722  }
4723 
4724  if (intersect == ONVERTEX)
4725  {
4726  /* There's already a vertex there. Return in `searchtri' a triangle */
4727  /* whose origin is the existing vertex. */
4728  otricopy(horiz, *searchtri);
4729  otricopy(horiz, m->recenttri);
4730  return DUPLICATEVERTEX;
4731  }
4732  if ((intersect == ONEDGE) || (intersect == OUTSIDE))
4733  {
4734  /* The vertex falls on an edge or boundary. */
4735  if (m->checksegments && (splitseg == (struct osub *)NULL))
4736  {
4737  /* Check whether the vertex falls on a subsegment. */
4738  tspivot(horiz, brokensubseg);
4739  if (brokensubseg.ss != m->dummysub)
4740  {
4741  /* The vertex falls on a subsegment, and hence will not be
4742  * inserted. */
4743  if (segmentflaws)
4744  {
4745  enq = b->nobisect != 2;
4746  if (enq && (b->nobisect == 1))
4747  {
4748  /* This subsegment may be split only if it is an */
4749  /* internal boundary. */
4750  sym(horiz, testtri);
4751  enq = testtri.tri != m->dummytri;
4752  }
4753  if (enq)
4754  {
4755  /* Add the subsegment to the list of encroached
4756  * subsegments. */
4757  encroached =
4758  (struct badsubseg *)poolalloc(&m->badsubsegs);
4759  encroached->encsubseg = sencode(brokensubseg);
4760  sorg(brokensubseg, encroached->subsegorg);
4761  sdest(brokensubseg, encroached->subsegdest);
4762 
4763  }
4764  }
4765  /* Return a handle whose primary edge contains the vertex, */
4766  /* which has not been inserted. */
4767  otricopy(horiz, *searchtri);
4768  otricopy(horiz, m->recenttri);
4769  return VIOLATINGVERTEX;
4770  }
4771  }
4772 
4773  /* Insert the vertex on an edge, dividing one triangle into two (if */
4774  /* the edge lies on a boundary) or two triangles into four. */
4775  lprev(horiz, botright);
4776  sym(botright, botrcasing);
4777  sym(horiz, topright);
4778  /* Is there a second triangle? (Or does this edge lie on a boundary?)
4779  */
4780  mirrorflag = topright.tri != m->dummytri;
4781  if (mirrorflag)
4782  {
4783  lnextself(topright);
4784  sym(topright, toprcasing);
4785  maketriangle(m, b, &newtopright);
4786  }
4787  else
4788  {
4789  /* Splitting a boundary edge increases the number of boundary edges.
4790  */
4791  m->hullsize++;
4792  }
4793  maketriangle(m, b, &newbotright);
4794 
4795  /* Set the vertices of changed and new triangles. */
4796  org(horiz, rightvertex);
4797  dest(horiz, leftvertex);
4798  apex(horiz, botvertex);
4799  setorg(newbotright, botvertex);
4800  setdest(newbotright, rightvertex);
4801  setapex(newbotright, newvertex);
4802  setorg(horiz, newvertex);
4803  for (i = 0; i < m->eextras; i++)
4804  {
4805  /* Set the element attributes of a new triangle. */
4806  setelemattribute(newbotright, i, elemattribute(botright, i));
4807  }
4808 
4809  if (mirrorflag)
4810  {
4811  dest(topright, topvertex);
4812  setorg(newtopright, rightvertex);
4813  setdest(newtopright, topvertex);
4814  setapex(newtopright, newvertex);
4815  setorg(topright, newvertex);
4816  for (i = 0; i < m->eextras; i++)
4817  {
4818  /* Set the element attributes of another new triangle. */
4819  setelemattribute(newtopright, i, elemattribute(topright, i));
4820  }
4821  }
4822 
4823  /* There may be subsegments that need to be bonded */
4824  /* to the new triangle(s). */
4825  if (m->checksegments)
4826  {
4827  tspivot(botright, botrsubseg);
4828  if (botrsubseg.ss != m->dummysub)
4829  {
4830  tsdissolve(botright);
4831  tsbond(newbotright, botrsubseg);
4832  }
4833  if (mirrorflag)
4834  {
4835  tspivot(topright, toprsubseg);
4836  if (toprsubseg.ss != m->dummysub)
4837  {
4838  tsdissolve(topright);
4839  tsbond(newtopright, toprsubseg);
4840  }
4841  }
4842  }
4843 
4844  /* Bond the new triangle(s) to the surrounding triangles. */
4845  bond(newbotright, botrcasing);
4846  lprevself(newbotright);
4847  bond(newbotright, botright);
4848  lprevself(newbotright);
4849  if (mirrorflag)
4850  {
4851  bond(newtopright, toprcasing);
4852  lnextself(newtopright);
4853  bond(newtopright, topright);
4854  lnextself(newtopright);
4855  bond(newtopright, newbotright);
4856  }
4857 
4858  if (splitseg != (struct osub *)NULL)
4859  {
4860  /* Split the subsegment into two. */
4861  setsdest(*splitseg, newvertex);
4862  segorg(*splitseg, segmentorg);
4863  segdest(*splitseg, segmentdest);
4864  ssymself(*splitseg);
4865  spivot(*splitseg, rightsubseg);
4866  insertsubseg(m, b, &newbotright, mark(*splitseg));
4867  tspivot(newbotright, newsubseg);
4868  setsegorg(newsubseg, segmentorg);
4869  setsegdest(newsubseg, segmentdest);
4870  sbond(*splitseg, newsubseg);
4871  ssymself(newsubseg);
4872  sbond(newsubseg, rightsubseg);
4873  ssymself(*splitseg);
4874  /* Transfer the subsegment's boundary marker to the vertex */
4875  /* if required. */
4876  if (vertexmark(newvertex) == 0)
4877  {
4878  setvertexmark(newvertex, mark(*splitseg));
4879  }
4880  }
4881 
4882  if (m->checkquality)
4883  {
4885  m->lastflip = (struct flipstacker *)poolalloc(&m->flipstackers);
4886  m->lastflip->flippedtri = encode(horiz);
4887  m->lastflip->prevflip = (struct flipstacker *)1;
4888  }
4889 
4890  /* Position `horiz' on the first edge to check for */
4891  /* the Delaunay property. */
4892  lnextself(horiz);
4893  }
4894  else
4895  {
4896  /* Insert the vertex in a triangle, splitting it into three. */
4897  lnext(horiz, botleft);
4898  lprev(horiz, botright);
4899  sym(botleft, botlcasing);
4900  sym(botright, botrcasing);
4901  maketriangle(m, b, &newbotleft);
4902  maketriangle(m, b, &newbotright);
4903 
4904  /* Set the vertices of changed and new triangles. */
4905  org(horiz, rightvertex);
4906  dest(horiz, leftvertex);
4907  apex(horiz, botvertex);
4908  setorg(newbotleft, leftvertex);
4909  setdest(newbotleft, botvertex);
4910  setapex(newbotleft, newvertex);
4911  setorg(newbotright, botvertex);
4912  setdest(newbotright, rightvertex);
4913  setapex(newbotright, newvertex);
4914  setapex(horiz, newvertex);
4915  for (i = 0; i < m->eextras; i++)
4916  {
4917  /* Set the element attributes of the new triangles. */
4918  attrib = elemattribute(horiz, i);
4919  setelemattribute(newbotleft, i, attrib);
4920  setelemattribute(newbotright, i, attrib);
4921  }
4922 
4923  /* There may be subsegments that need to be bonded */
4924  /* to the new triangles. */
4925  if (m->checksegments)
4926  {
4927  tspivot(botleft, botlsubseg);
4928  if (botlsubseg.ss != m->dummysub)
4929  {
4930  tsdissolve(botleft);
4931  tsbond(newbotleft, botlsubseg);
4932  }
4933  tspivot(botright, botrsubseg);
4934  if (botrsubseg.ss != m->dummysub)
4935  {
4936  tsdissolve(botright);
4937  tsbond(newbotright, botrsubseg);
4938  }
4939  }
4940 
4941  /* Bond the new triangles to the surrounding triangles. */
4942  bond(newbotleft, botlcasing);
4943  bond(newbotright, botrcasing);
4944  lnextself(newbotleft);
4945  lprevself(newbotright);
4946  bond(newbotleft, newbotright);
4947  lnextself(newbotleft);
4948  bond(botleft, newbotleft);
4949  lprevself(newbotright);
4950  bond(botright, newbotright);
4951 
4952  if (m->checkquality)
4953  {
4955  m->lastflip = (struct flipstacker *)poolalloc(&m->flipstackers);
4956  m->lastflip->flippedtri = encode(horiz);
4957  m->lastflip->prevflip = (struct flipstacker *)NULL;
4958  }
4959 
4960  }
4961 
4962  /* The insertion is successful by default, unless an encroached */
4963  /* subsegment is found. */
4964  success = SUCCESSFULVERTEX;
4965  /* Circle around the newly inserted vertex, checking each edge opposite */
4966  /* it for the Delaunay property. Non-Delaunay edges are flipped. */
4967  /* `horiz' is always the edge being checked. `first' marks where to */
4968  /* stop circling. */
4969  org(horiz, first);
4970  rightvertex = first;
4971  dest(horiz, leftvertex);
4972  /* Circle until finished. */
4973  while (1)
4974  {
4975  /* By default, the edge will be flipped. */
4976  doflip = 1;
4977 
4978  if (m->checksegments)
4979  {
4980  /* Check for a subsegment, which cannot be flipped. */
4981  tspivot(horiz, checksubseg);
4982  if (checksubseg.ss != m->dummysub)
4983  {
4984  /* The edge is a subsegment and cannot be flipped. */
4985  doflip = 0;
4986  if (segmentflaws)
4987  {
4988  /* Does the new vertex encroach upon this subsegment? */
4989  if (checkseg4encroach(m, b, &checksubseg))
4990  {
4991  success = ENCROACHINGVERTEX;
4992  }
4993  }
4994  }
4995  }
4996 
4997  if (doflip)
4998  {
4999  /* Check if the edge is a boundary edge. */
5000  sym(horiz, top);
5001  if (top.tri == m->dummytri)
5002  {
5003  /* The edge is a boundary edge and cannot be flipped. */
5004  doflip = 0;
5005  }
5006  else
5007  {
5008  /* Find the vertex on the other side of the edge. */
5009  apex(top, farvertex);
5010  /* In the incremental Delaunay triangulation algorithm, any of
5011  */
5012  /* `leftvertex', `rightvertex', and `farvertex' could be
5013  * vertices */
5014  /* of the triangular bounding box. These vertices must be */
5015  /* treated as if they are infinitely distant, even though
5016  * their */
5017  /* "coordinates" are not. */
5018  if ((leftvertex == m->infvertex1) ||
5019  (leftvertex == m->infvertex2) ||
5020  (leftvertex == m->infvertex3))
5021  {
5022  /* `leftvertex' is infinitely distant. Check the convexity
5023  * of */
5024  /* the boundary of the triangulation. 'farvertex' might
5025  * be */
5026  /* infinite as well, but trust me, this same condition
5027  * should */
5028  /* be applied. */
5029  doflip = counterclockwise(
5030  m, b, newvertex, rightvertex, farvertex) > 0.0;
5031  }
5032  else if ((rightvertex == m->infvertex1) ||
5033  (rightvertex == m->infvertex2) ||
5034  (rightvertex == m->infvertex3))
5035  {
5036  /* `rightvertex' is infinitely distant. Check the convexity
5037  * of */
5038  /* the boundary of the triangulation. 'farvertex' might
5039  * be */
5040  /* infinite as well, but trust me, this same condition
5041  * should */
5042  /* be applied. */
5043  doflip = counterclockwise(
5044  m, b, farvertex, leftvertex, newvertex) > 0.0;
5045  }
5046  else if ((farvertex == m->infvertex1) ||
5047  (farvertex == m->infvertex2) ||
5048  (farvertex == m->infvertex3))
5049  {
5050  /* `farvertex' is infinitely distant and cannot be inside */
5051  /* the circumcircle of the triangle `horiz'. */
5052  doflip = 0;
5053  }
5054  else
5055  {
5056  /* Test whether the edge is locally Delaunay. */
5057  doflip = incircle(m,
5058  b,
5059  leftvertex,
5060  newvertex,
5061  rightvertex,
5062  farvertex) > 0.0;
5063  }
5064  if (doflip)
5065  {
5066  /* We made it! Flip the edge `horiz' by rotating its
5067  * containing */
5068  /* quadrilateral (the two triangles adjacent to `horiz').
5069  */
5070  /* Identify the casing of the quadrilateral. */
5071  lprev(top, topleft);
5072  sym(topleft, toplcasing);
5073  lnext(top, topright);
5074  sym(topright, toprcasing);
5075  lnext(horiz, botleft);
5076  sym(botleft, botlcasing);
5077  lprev(horiz, botright);
5078  sym(botright, botrcasing);
5079  /* Rotate the quadrilateral one-quarter turn
5080  * counterclockwise. */
5081  bond(topleft, botlcasing);
5082  bond(botleft, botrcasing);
5083  bond(botright, toprcasing);
5084  bond(topright, toplcasing);
5085  if (m->checksegments)
5086  {
5087  /* Check for subsegments and rebond them to the
5088  * quadrilateral. */
5089  tspivot(topleft, toplsubseg);
5090  tspivot(botleft, botlsubseg);
5091  tspivot(botright, botrsubseg);
5092  tspivot(topright, toprsubseg);
5093  if (toplsubseg.ss == m->dummysub)
5094  {
5095  tsdissolve(topright);
5096  }
5097  else
5098  {
5099  tsbond(topright, toplsubseg);
5100  }
5101  if (botlsubseg.ss == m->dummysub)
5102  {
5103  tsdissolve(topleft);
5104  }
5105  else
5106  {
5107  tsbond(topleft, botlsubseg);
5108  }
5109  if (botrsubseg.ss == m->dummysub)
5110  {
5111  tsdissolve(botleft);
5112  }
5113  else
5114  {
5115  tsbond(botleft, botrsubseg);
5116  }
5117  if (toprsubseg.ss == m->dummysub)
5118  {
5119  tsdissolve(botright);
5120  }
5121  else
5122  {
5123  tsbond(botright, toprsubseg);
5124  }
5125  }
5126  /* New vertex assignments for the rotated quadrilateral. */
5127  setorg(horiz, farvertex);
5128  setdest(horiz, newvertex);
5129  setapex(horiz, rightvertex);
5130  setorg(top, newvertex);
5131  setdest(top, farvertex);
5132  setapex(top, leftvertex);
5133  for (i = 0; i < m->eextras; i++)
5134  {
5135  /* Take the average of the two triangles' attributes. */
5136  attrib = 0.5 * (elemattribute(top, i) +
5137  elemattribute(horiz, i));
5138  setelemattribute(top, i, attrib);
5139  setelemattribute(horiz, i, attrib);
5140  }
5141 
5142  if (m->checkquality)
5143  {
5144  newflip =
5145  (struct flipstacker *)poolalloc(&m->flipstackers);
5146  newflip->flippedtri = encode(horiz);
5147  newflip->prevflip = m->lastflip;
5148  m->lastflip = newflip;
5149  }
5150 
5151  /* On the next iterations, consider the two edges that were
5152  */
5153  /* exposed (this is, are now visible to the newly inserted
5154  */
5155  /* vertex) by the edge flip. */
5156  lprevself(horiz);
5157  leftvertex = farvertex;
5158  }
5159  }
5160  }
5161  if (!doflip)
5162  {
5163 /* The handle `horiz' is accepted as locally Delaunay. */
5164  if (triflaws)
5165  {
5166  /* Check the triangle `horiz' for quality. */
5167  testtriangle(m, b, &horiz);
5168  }
5169  /* Look for the next edge around the newly inserted vertex. */
5170  lnextself(horiz);
5171  sym(horiz, testtri);
5172  /* Check for finishing a complete revolution about the new vertex,
5173  * or */
5174  /* falling outside of the triangulation. The latter will happen
5175  */
5176  /* when a vertex is inserted at a boundary. */
5177  if ((leftvertex == first) || (testtri.tri == m->dummytri))
5178  {
5179  /* We're done. Return a triangle whose origin is the new
5180  * vertex. */
5181  lnext(horiz, *searchtri);
5182  lnext(horiz, m->recenttri);
5183  return success;
5184  }
5185  /* Finish finding the next edge around the newly inserted vertex. */
5186  lnext(testtri, horiz);
5187  rightvertex = leftvertex;
5188  dest(horiz, leftvertex);
5189  }
5190  }
5191 }
5192 
5193 /*****************************************************************************/
5194 /* */
5195 /* triangulatepolygon() Find the Delaunay triangulation of a polygon that */
5196 /* has a certain "nice" shape. This includes the */
5197 /* polygons that result from deletion of a vertex or */
5198 /* insertion of a segment. */
5199 /* */
5200 /* This is a conceptually difficult routine. The starting assumption is */
5201 /* that we have a polygon with n sides. n - 1 of these sides are currently */
5202 /* represented as edges in the mesh. One side, called the "base", need not */
5203 /* be. */
5204 /* */
5205 /* Inside the polygon is a structure I call a "fan", consisting of n - 1 */
5206 /* triangles that share a common origin. For each of these triangles, the */
5207 /* edge opposite the origin is one of the sides of the polygon. The */
5208 /* primary edge of each triangle is the edge directed from the origin to */
5209 /* the destination; note that this is not the same edge that is a side of */
5210 /* the polygon. `firstedge' is the primary edge of the first triangle. */
5211 /* From there, the triangles follow in counterclockwise order about the */
5212 /* polygon, until `lastedge', the primary edge of the last triangle. */
5213 /* `firstedge' and `lastedge' are probably connected to other triangles */
5214 /* beyond the extremes of the fan, but their identity is not important, as */
5215 /* long as the fan remains connected to them. */
5216 /* */
5217 /* Imagine the polygon oriented so that its base is at the bottom. This */
5218 /* puts `firstedge' on the far right, and `lastedge' on the far left. */
5219 /* The right vertex of the base is the destination of `firstedge', and the */
5220 /* left vertex of the base is the apex of `lastedge'. */
5221 /* */
5222 /* The challenge now is to find the right sequence of edge flips to */
5223 /* transform the fan into a Delaunay triangulation of the polygon. Each */
5224 /* edge flip effectively removes one triangle from the fan, committing it */
5225 /* to the polygon. The resulting polygon has one fewer edge. If `doflip' */
5226 /* is set, the final flip will be performed, resulting in a fan of one */
5227 /* (useless?) triangle. If `doflip' is not set, the final flip is not */
5228 /* performed, resulting in a fan of two triangles, and an unfinished */
5229 /* triangular polygon that is not yet filled out with a single triangle. */
5230 /* On completion of the routine, `lastedge' is the last remaining triangle, */
5231 /* or the leftmost of the last two. */
5232 /* */
5233 /* Although the flips are performed in the order described above, the */
5234 /* decisions about what flips to perform are made in precisely the reverse */
5235 /* order. The recursive triangulatepolygon() procedure makes a decision, */
5236 /* uses up to two recursive calls to triangulate the "subproblems" */
5237 /* (polygons with fewer edges), and then performs an edge flip. */
5238 /* */
5239 /* The "decision" it makes is which vertex of the polygon should be */
5240 /* connected to the base. This decision is made by testing every possible */
5241 /* vertex. Once the best vertex is found, the two edges that connect this */
5242 /* vertex to the base become the bases for two smaller polygons. These */
5243 /* are triangulated recursively. Unfortunately, this approach can take */
5244 /* O(n^2) time not only in the worst case, but in many common cases. It's */
5245 /* rarely a big deal for vertex deletion, where n is rarely larger than */
5246 /* ten, but it could be a big deal for segment insertion, especially if */
5247 /* there's a lot of long segments that each cut many triangles. I ought to */
5248 /* code a faster algorithm some day. */
5249 /* */
5250 /* The `edgecount' parameter is the number of sides of the polygon, */
5251 /* including its base. `triflaws' is a flag that determines whether the */
5252 /* new triangles should be tested for quality, and enqueued if they are */
5253 /* bad. */
5254 /* */
5255 /*****************************************************************************/
5256 
5258  struct behavior *b,
5259  struct otri *firstedge,
5260  struct otri *lastedge,
5261  int edgecount,
5262  int doflip,
5263  int triflaws)
5264 {
5265  struct otri testtri;
5266  struct otri besttri;
5267  struct otri tempedge;
5268  vertex leftbasevertex, rightbasevertex;
5269  vertex testvertex;
5270  vertex bestvertex;
5271  int bestnumber;
5272  int i;
5273  triangle ptr; /* Temporary variable used by sym(), onext(), and oprev(). */
5274 
5275  /* Identify the base vertices. */
5276  apex(*lastedge, leftbasevertex);
5277  dest(*firstedge, rightbasevertex);
5278 
5279  /* Find the best vertex to connect the base to. */
5280  onext(*firstedge, besttri);
5281  dest(besttri, bestvertex);
5282  otricopy(besttri, testtri);
5283  bestnumber = 1;
5284  for (i = 2; i <= edgecount - 2; i++)
5285  {
5286  onextself(testtri);
5287  dest(testtri, testvertex);
5288  /* Is this a better vertex? */
5289  if (incircle(
5290  m, b, leftbasevertex, rightbasevertex, bestvertex, testvertex) >
5291  0.0)
5292  {
5293  otricopy(testtri, besttri);
5294  bestvertex = testvertex;
5295  bestnumber = i;
5296  }
5297  }
5298 
5299  if (bestnumber > 1)
5300  {
5301  /* Recursively triangulate the smaller polygon on the right. */
5302  oprev(besttri, tempedge);
5304  m, b, firstedge, &tempedge, bestnumber + 1, 1, triflaws);
5305  }
5306  if (bestnumber < edgecount - 2)
5307  {
5308  /* Recursively triangulate the smaller polygon on the left. */
5309  sym(besttri, tempedge);
5311  m, b, &besttri, lastedge, edgecount - bestnumber, 1, triflaws);
5312  /* Find `besttri' again; it may have been lost to edge flips. */
5313  sym(tempedge, besttri);
5314  }
5315  if (doflip)
5316  {
5317  /* Do one final edge flip. */
5318  flip(m, b, &besttri);
5319  if (triflaws)
5320  {
5321  /* Check the quality of the newly committed triangle. */
5322  sym(besttri, testtri);
5323  testtriangle(m, b, &testtri);
5324  }
5325  }
5326  /* Return the base triangle. */
5327  otricopy(besttri, *lastedge);
5328 }
5329 
5330 /*****************************************************************************/
5331 /* */
5332 /* deletevertex() Delete a vertex from a Delaunay triangulation, ensuring */
5333 /* that the triangulation remains Delaunay. */
5334 /* */
5335 /* The origin of `deltri' is deleted. The union of the triangles adjacent */
5336 /* to this vertex is a polygon, for which the Delaunay triangulation is */
5337 /* found. Two triangles are removed from the mesh. */
5338 /* */
5339 /* Only interior vertices that do not lie on segments or boundaries may be */
5340 /* deleted. */
5341 /* */
5342 /*****************************************************************************/
5343 
5344 void DelaunayTriangle::deletevertex(struct mesh *m, struct behavior *b, struct otri *deltri)
5345 {
5346  struct otri countingtri;
5347  struct otri firstedge, lastedge;
5348  struct otri deltriright;
5349  struct otri lefttri, righttri;
5350  struct otri leftcasing, rightcasing;
5351  struct osub leftsubseg, rightsubseg;
5352  vertex delvertex;
5353  vertex neworg;
5354  int edgecount;
5355  triangle ptr; /* Temporary variable used by sym(), onext(), and oprev(). */
5356  subseg sptr; /* Temporary variable used by tspivot(). */
5357 
5358  org(*deltri, delvertex);
5359 
5360  vertexdealloc(m, delvertex);
5361 
5362  /* Count the degree of the vertex being deleted. */
5363  onext(*deltri, countingtri);
5364  edgecount = 1;
5365  while (!otriequal(*deltri, countingtri))
5366  {
5367  edgecount++;
5368  onextself(countingtri);
5369  }
5370 
5371  if (edgecount > 3)
5372  {
5373  /* Triangulate the polygon defined by the union of all triangles */
5374  /* adjacent to the vertex being deleted. Check the quality of */
5375  /* the resulting triangles. */
5376  onext(*deltri, firstedge);
5377  oprev(*deltri, lastedge);
5379  m, b, &firstedge, &lastedge, edgecount, 0, !b->nobisect);
5380  }
5381  /* Splice out two triangles. */
5382  lprev(*deltri, deltriright);
5383  dnext(*deltri, lefttri);
5384  sym(lefttri, leftcasing);
5385  oprev(deltriright, righttri);
5386  sym(righttri, rightcasing);
5387  bond(*deltri, leftcasing);
5388  bond(deltriright, rightcasing);
5389  tspivot(lefttri, leftsubseg);
5390  if (leftsubseg.ss != m->dummysub)
5391  {
5392  tsbond(*deltri, leftsubseg);
5393  }
5394  tspivot(righttri, rightsubseg);
5395  if (rightsubseg.ss != m->dummysub)
5396  {
5397  tsbond(deltriright, rightsubseg);
5398  }
5399 
5400  /* Set the new origin of `deltri' and check its quality. */
5401  org(lefttri, neworg);
5402  setorg(*deltri, neworg);
5403  if (!b->nobisect)
5404  {
5405  testtriangle(m, b, deltri);
5406  }
5407 
5408  /* Delete the two spliced-out triangles. */
5409  triangledealloc(m, lefttri.tri);
5410  triangledealloc(m, righttri.tri);
5411 }
5412 
5413 /*****************************************************************************/
5414 /* */
5415 /* undovertex() Undo the most recent vertex insertion. */
5416 /* */
5417 /* Walks through the list of transformations (flips and a vertex insertion) */
5418 /* in the reverse of the order in which they were done, and undoes them. */
5419 /* The inserted vertex is removed from the triangulation and deallocated. */
5420 /* Two triangles (possibly just one) are also deallocated. */
5421 /* */
5422 /*****************************************************************************/
5423 
5424 void DelaunayTriangle::undovertex(struct mesh *m, struct behavior *b)
5425 {
5426  struct otri fliptri;
5427  struct otri botleft, botright, topright;
5428  struct otri botlcasing, botrcasing, toprcasing;
5429  struct otri gluetri;
5430  struct osub botlsubseg, botrsubseg, toprsubseg;
5431  vertex botvertex, rightvertex;
5432  triangle ptr; /* Temporary variable used by sym(). */
5433  subseg sptr; /* Temporary variable used by tspivot(). */
5434 
5435  /* Walk through the list of transformations (flips and a vertex insertion)
5436  */
5437  /* in the reverse of the order in which they were done, and undo them. */
5438  while (m->lastflip != (struct flipstacker *)NULL)
5439  {
5440  /* Find a triangle involved in the last unreversed transformation. */
5441  decode(m->lastflip->flippedtri, fliptri);
5442 
5443  /* We are reversing one of three transformations: a trisection of one
5444  */
5445  /* triangle into three (by inserting a vertex in the triangle), a */
5446  /* bisection of two triangles into four (by inserting a vertex in an
5447  */
5448  /* edge), or an edge flip. */
5449  if (m->lastflip->prevflip == (struct flipstacker *)NULL)
5450  {
5451  /* Restore a triangle that was split into three triangles, */
5452  /* so it is again one triangle. */
5453  dprev(fliptri, botleft);
5454  lnextself(botleft);
5455  onext(fliptri, botright);
5456  lprevself(botright);
5457  sym(botleft, botlcasing);
5458  sym(botright, botrcasing);
5459  dest(botleft, botvertex);
5460 
5461  setapex(fliptri, botvertex);
5462  lnextself(fliptri);
5463  bond(fliptri, botlcasing);
5464  tspivot(botleft, botlsubseg);
5465  tsbond(fliptri, botlsubseg);
5466  lnextself(fliptri);
5467  bond(fliptri, botrcasing);
5468  tspivot(botright, botrsubseg);
5469  tsbond(fliptri, botrsubseg);
5470 
5471  /* Delete the two spliced-out triangles. */
5472  triangledealloc(m, botleft.tri);
5473  triangledealloc(m, botright.tri);
5474  }
5475  else if (m->lastflip->prevflip == (struct flipstacker *)1)
5476  {
5477  /* Restore two triangles that were split into four triangles, */
5478  /* so they are again two triangles. */
5479  lprev(fliptri, gluetri);
5480  sym(gluetri, botright);
5481  lnextself(botright);
5482  sym(botright, botrcasing);
5483  dest(botright, rightvertex);
5484 
5485  setorg(fliptri, rightvertex);
5486  bond(gluetri, botrcasing);
5487  tspivot(botright, botrsubseg);
5488  tsbond(gluetri, botrsubseg);
5489 
5490  /* Delete the spliced-out triangle. */
5491  triangledealloc(m, botright.tri);
5492 
5493  sym(fliptri, gluetri);
5494  if (gluetri.tri != m->dummytri)
5495  {
5496  lnextself(gluetri);
5497  dnext(gluetri, topright);
5498  sym(topright, toprcasing);
5499 
5500  setorg(gluetri, rightvertex);
5501  bond(gluetri, toprcasing);
5502  tspivot(topright, toprsubseg);
5503  tsbond(gluetri, toprsubseg);
5504 
5505  /* Delete the spliced-out triangle. */
5506  triangledealloc(m, topright.tri);
5507  }
5508 
5509  /* This is the end of the list, sneakily encoded. */
5510  m->lastflip->prevflip = (struct flipstacker *)NULL;
5511  }
5512  else
5513  {
5514  /* Undo an edge flip. */
5515  unflip(m, b, &fliptri);
5516  }
5517 
5518  /* Go on and process the next transformation. */
5519  m->lastflip = m->lastflip->prevflip;
5520  }
5521 }
5522 
5523 /** **/
5524 /** **/
5525 /********* Mesh transformation routines end here *********/
5526 
5527 /********* Divide-and-conquer Delaunay triangulation begins here *********/
5528 /** **/
5529 /** **/
5530 
5531 /*****************************************************************************/
5532 /* */
5533 /* The divide-and-conquer bounding box */
5534 /* */
5535 /* I originally implemented the divide-and-conquer and incremental Delaunay */
5536 /* triangulations using the edge-based data structure presented by Guibas */
5537 /* and Stolfi. Switching to a triangle-based data structure doubled the */
5538 /* speed. However, I had to think of a few extra tricks to maintain the */
5539 /* elegance of the original algorithms. */
5540 /* */
5541 /* The "bounding box" used by my variant of the divide-and-conquer */
5542 /* algorithm uses one triangle for each edge of the convex hull of the */
5543 /* triangulation. These bounding triangles all share a common apical */
5544 /* vertex, which is represented by NULL and which represents nothing. */
5545 /* The bounding triangles are linked in a circular fan about this NULL */
5546 /* vertex, and the edges on the convex hull of the triangulation appear */
5547 /* opposite the NULL vertex. You might find it easiest to imagine that */
5548 /* the NULL vertex is a point in 3D space behind the center of the */
5549 /* triangulation, and that the bounding triangles form a sort of cone. */
5550 /* */
5551 /* This bounding box makes it easy to represent degenerate cases. For */
5552 /* instance, the triangulation of two vertices is a single edge. This edge */
5553 /* is represented by two bounding box triangles, one on each "side" of the */
5554 /* edge. These triangles are also linked together in a fan about the NULL */
5555 /* vertex. */
5556 /* */
5557 /* The bounding box also makes it easy to traverse the convex hull, as the */
5558 /* divide-and-conquer algorithm needs to do. */
5559 /* */
5560 /*****************************************************************************/
5561 
5562 /*****************************************************************************/
5563 /* */
5564 /* vertexsort() Sort an array of vertices by x-coordinate, using the */
5565 /* y-coordinate as a secondary key. */
5566 /* */
5567 /* Uses quicksort. Randomized O(n log n) time. No, I did not make any of */
5568 /* the usual quicksort mistakes. */
5569 /* */
5570 /*****************************************************************************/
5571 
5572 void DelaunayTriangle::vertexsort(vertex *sortarray, unsigned int arraysize)
5573 {
5574  int left, right;
5575  int pivot;
5576  double pivotx, pivoty;
5577  vertex temp;
5578 
5579  if (arraysize == 2)
5580  {
5581  /* Recursive base case. */
5582  if ((sortarray[0][0] > sortarray[1][0]) ||
5583  ((sortarray[0][0] == sortarray[1][0]) &&
5584  (sortarray[0][1] > sortarray[1][1])))
5585  {
5586  temp = sortarray[1];
5587  sortarray[1] = sortarray[0];
5588  sortarray[0] = temp;
5589  }
5590  return;
5591  }
5592  /* Choose a random pivot to split the array. */
5593  pivot = (int)randomnation((unsigned int)arraysize);
5594  pivotx = sortarray[pivot][0];
5595  pivoty = sortarray[pivot][1];
5596  /* Split the array. */
5597  left = -1;
5598  right = arraysize;
5599  while (left < right)
5600  {
5601  /* Search for a vertex whose x-coordinate is too large for the left. */
5602  do
5603  {
5604  left++;
5605  } while ((left <= right) && ((sortarray[left][0] < pivotx) ||
5606  ((sortarray[left][0] == pivotx) &&
5607  (sortarray[left][1] < pivoty))));
5608  /* Search for a vertex whose x-coordinate is too small for the right. */
5609  do
5610  {
5611  right--;
5612  } while ((left <= right) && ((sortarray[right][0] > pivotx) ||
5613  ((sortarray[right][0] == pivotx) &&
5614  (sortarray[right][1] > pivoty))));
5615  if (left < right)
5616  {
5617  /* Swap the left and right vertices. */
5618  temp = sortarray[left];
5619  sortarray[left] = sortarray[right];
5620  sortarray[right] = temp;
5621  }
5622  }
5623  if (left > 1)
5624  {
5625  /* Recursively sort the left subset. */
5626  vertexsort(sortarray, left);
5627  }
5628  if (right < arraysize - 2)
5629  {
5630  /* Recursively sort the right subset. */
5631  vertexsort(&sortarray[right + 1], arraysize - right - 1);
5632  }
5633 }
5634 
5635 /*****************************************************************************/
5636 /* */
5637 /* vertexmedian() An order statistic algorithm, almost. Shuffles an */
5638 /* array of vertices so that the first `median' vertices */
5639 /* occur lexicographically before the remaining vertices. */
5640 /* */
5641 /* Uses the x-coordinate as the primary key if axis == 0; the y-coordinate */
5642 /* if axis == 1. Very similar to the vertexsort() procedure, but runs in */
5643 /* randomized linear time. */
5644 /* */
5645 /*****************************************************************************/
5646 
5647 void DelaunayTriangle::vertexmedian(vertex *sortarray, int arraysize, int median, int axis)
5648 {
5649  int left, right;
5650  int pivot;
5651  double pivot1, pivot2;
5652  vertex temp;
5653 
5654  if (arraysize == 2)
5655  {
5656  /* Recursive base case. */
5657  if ((sortarray[0][axis] > sortarray[1][axis]) ||
5658  ((sortarray[0][axis] == sortarray[1][axis]) &&
5659  (sortarray[0][1 - axis] > sortarray[1][1 - axis])))
5660  {
5661  temp = sortarray[1];
5662  sortarray[1] = sortarray[0];
5663  sortarray[0] = temp;
5664  }
5665  return;
5666  }
5667  /* Choose a random pivot to split the array. */
5668  pivot = (int)randomnation((unsigned int)arraysize);
5669  pivot1 = sortarray[pivot][axis];
5670  pivot2 = sortarray[pivot][1 - axis];
5671  /* Split the array. */
5672  left = -1;
5673  right = arraysize;
5674  while (left < right)
5675  {
5676  /* Search for a vertex whose x-coordinate is too large for the left. */
5677  do
5678  {
5679  left++;
5680  } while ((left <= right) && ((sortarray[left][axis] < pivot1) ||
5681  ((sortarray[left][axis] == pivot1) &&
5682  (sortarray[left][1 - axis] < pivot2))));
5683  /* Search for a vertex whose x-coordinate is too small for the right. */
5684  do
5685  {
5686  right--;
5687  } while ((left <= right) && ((sortarray[right][axis] > pivot1) ||
5688  ((sortarray[right][axis] == pivot1) &&
5689  (sortarray[right][1 - axis] > pivot2))));
5690  if (left < right)
5691  {
5692  /* Swap the left and right vertices. */
5693  temp = sortarray[left];
5694  sortarray[left] = sortarray[right];
5695  sortarray[right] = temp;
5696  }
5697  }
5698  /* Unlike in vertexsort(), at most one of the following */
5699  /* conditionals is true. */
5700  if (left > median)
5701  {
5702  /* Recursively shuffle the left subset. */
5703  vertexmedian(sortarray, left, median, axis);
5704  }
5705  if (right < median - 1)
5706  {
5707  /* Recursively shuffle the right subset. */
5708  vertexmedian(&sortarray[right + 1],
5709  arraysize - right - 1,
5710  median - right - 1,
5711  axis);
5712  }
5713 }
5714 
5715 /*****************************************************************************/
5716 /* */
5717 /* alternateaxes() Sorts the vertices as appropriate for the divide-and- */
5718 /* conquer algorithm with alternating cuts. */
5719 /* */
5720 /* Partitions by x-coordinate if axis == 0; by y-coordinate if axis == 1. */
5721 /* For the base case, subsets containing only two or three vertices are */
5722 /* always sorted by x-coordinate. */
5723 /* */
5724 /*****************************************************************************/
5725 
5726 void DelaunayTriangle::alternateaxes(vertex *sortarray, int arraysize, int axis)
5727 {
5728  int divider;
5729 
5730  divider = arraysize >> 1;
5731  if (arraysize <= 3)
5732  {
5733  /* Recursive base case: subsets of two or three vertices will be */
5734  /* handled specially, and should always be sorted by x-coordinate. */
5735  axis = 0;
5736  }
5737  /* Partition with a horizontal or vertical cut. */
5738  vertexmedian(sortarray, arraysize, divider, axis);
5739  /* Recursively partition the subsets with a cross cut. */
5740  if (arraysize - divider >= 2)
5741  {
5742  if (divider >= 2)
5743  {
5744  alternateaxes(sortarray, divider, 1 - axis);
5745  }
5746  alternateaxes(&sortarray[divider], arraysize - divider, 1 - axis);
5747  }
5748 }
5749 
5750 /*****************************************************************************/
5751 /* */
5752 /* mergehulls() Merge two adjacent Delaunay triangulations into a */
5753 /* single Delaunay triangulation. */
5754 /* */
5755 /* This is similar to the algorithm given by Guibas and Stolfi, but uses */
5756 /* a triangle-based, rather than edge-based, data structure. */
5757 /* */
5758 /* The algorithm walks up the gap between the two triangulations, knitting */
5759 /* them together. As they are merged, some of their bounding triangles */
5760 /* are converted into double triangles of the triangulation. The procedure */
5761 /* pulls each hull's bounding triangles apart, then knits them together */
5762 /* like the teeth of two gears. The Delaunay property determines, at each */
5763 /* step, whether the next "tooth" is a bounding triangle of the left hull */
5764 /* or the right. When a bounding triangle becomes real, its apex is */
5765 /* changed from NULL to a double vertex. */
5766 /* */
5767 /* Only two new triangles need to be allocated. These become new bounding */
5768 /* triangles at the top and bottom of the seam. They are used to connect */
5769 /* the remaining bounding triangles (those that have not been converted */
5770 /* into double triangles) into a single fan. */
5771 /* */
5772 /* On entry, `farleft' and `innerleft' are bounding triangles of the left */
5773 /* triangulation. The origin of `farleft' is the leftmost vertex, and */
5774 /* the destination of `innerleft' is the rightmost vertex of the */
5775 /* triangulation. Similarly, `innerright' and `farright' are bounding */
5776 /* triangles of the right triangulation. The origin of `innerright' and */
5777 /* destination of `farright' are the leftmost and rightmost vertices. */
5778 /* */
5779 /* On completion, the origin of `farleft' is the leftmost vertex of the */
5780 /* merged triangulation, and the destination of `farright' is the rightmost */
5781 /* vertex. */
5782 /* */
5783 /*****************************************************************************/
5784 
5786  struct behavior *b,
5787  struct otri *farleft,
5788  struct otri *innerleft,
5789  struct otri *innerright,
5790  struct otri *farright,
5791  int axis)
5792 {
5793  struct otri leftcand, rightcand;
5794  struct otri baseedge;
5795  struct otri nextedge;
5796  struct otri sidecasing, topcasing, outercasing;
5797  struct otri checkedge;
5798  vertex innerleftdest;
5799  vertex innerrightorg;
5800  vertex innerleftapex, innerrightapex;
5801  vertex farleftpt, farrightpt;
5802  vertex farleftapex, farrightapex;
5803  vertex lowerleft, lowerright;
5804  vertex upperleft, upperright;
5805  vertex nextapex;
5806  vertex checkvertex;
5807  int changemade;
5808  int badedge;
5809  int leftfinished, rightfinished;
5810  triangle ptr; /* Temporary variable used by sym(). */
5811 
5812  dest(*innerleft, innerleftdest);
5813  apex(*innerleft, innerleftapex);
5814  org(*innerright, innerrightorg);
5815  apex(*innerright, innerrightapex);
5816  /* Special treatment for horizontal cuts. */
5817  if (axis == 1)
5818  {
5819  org(*farleft, farleftpt);
5820  apex(*farleft, farleftapex);
5821  dest(*farright, farrightpt);
5822  apex(*farright, farrightapex);
5823  /* The pointers to the extremal vertices are shifted to point to the */
5824  /* topmost and bottommost vertex of each hull, rather than the */
5825  /* leftmost and rightmost vertices. */
5826  while (farleftapex[1] < farleftpt[1])
5827  {
5828  lnextself(*farleft);
5829  symself(*farleft);
5830  farleftpt = farleftapex;
5831  apex(*farleft, farleftapex);
5832  }
5833  sym(*innerleft, checkedge);
5834  apex(checkedge, checkvertex);
5835  while (checkvertex[1] > innerleftdest[1])
5836  {
5837  lnext(checkedge, *innerleft);
5838  innerleftapex = innerleftdest;
5839  innerleftdest = checkvertex;
5840  sym(*innerleft, checkedge);
5841  apex(checkedge, checkvertex);
5842  }
5843  while (innerrightapex[1] < innerrightorg[1])
5844  {
5845  lnextself(*innerright);
5846  symself(*innerright);
5847  innerrightorg = innerrightapex;
5848  apex(*innerright, innerrightapex);
5849  }
5850  sym(*farright, checkedge);
5851  apex(checkedge, checkvertex);
5852  while (checkvertex[1] > farrightpt[1])
5853  {
5854  lnext(checkedge, *farright);
5855  farrightapex = farrightpt;
5856  farrightpt = checkvertex;
5857  sym(*farright, checkedge);
5858  apex(checkedge, checkvertex);
5859  }
5860  }
5861  /* Find a line tangent to and below both hulls. */
5862  do
5863  {
5864  changemade = 0;
5865  /* Make innerleftdest the "bottommost" vertex of the left hull. */
5866  if (counterclockwise(
5867  m, b, innerleftdest, innerleftapex, innerrightorg) > 0.0)
5868  {
5869  lprevself(*innerleft);
5870  symself(*innerleft);
5871  innerleftdest = innerleftapex;
5872  apex(*innerleft, innerleftapex);
5873  changemade = 1;
5874  }
5875  /* Make innerrightorg the "bottommost" vertex of the right hull. */
5876  if (counterclockwise(
5877  m, b, innerrightapex, innerrightorg, innerleftdest) > 0.0)
5878  {
5879  lnextself(*innerright);
5880  symself(*innerright);
5881  innerrightorg = innerrightapex;
5882  apex(*innerright, innerrightapex);
5883  changemade = 1;
5884  }
5885  } while (changemade);
5886  /* Find the two candidates to be the next "gear tooth." */
5887  sym(*innerleft, leftcand);
5888  sym(*innerright, rightcand);
5889  /* Create the bottom new bounding triangle. */
5890  maketriangle(m, b, &baseedge);
5891  /* Connect it to the bounding boxes of the left and right triangulations. */
5892  bond(baseedge, *innerleft);
5893  lnextself(baseedge);
5894  bond(baseedge, *innerright);
5895  lnextself(baseedge);
5896  setorg(baseedge, innerrightorg);
5897  setdest(baseedge, innerleftdest);
5898  /* Apex is intentionally left NULL. */
5899 
5900  /* Fix the extreme triangles if necessary. */
5901  org(*farleft, farleftpt);
5902  if (innerleftdest == farleftpt)
5903  {
5904  lnext(baseedge, *farleft);
5905  }
5906  dest(*farright, farrightpt);
5907  if (innerrightorg == farrightpt)
5908  {
5909  lprev(baseedge, *farright);
5910  }
5911  /* The vertices of the current knitting edge. */
5912  lowerleft = innerleftdest;
5913  lowerright = innerrightorg;
5914  /* The candidate vertices for knitting. */
5915  apex(leftcand, upperleft);
5916  apex(rightcand, upperright);
5917  /* Walk up the gap between the two triangulations, knitting them together.
5918  */
5919  while (1)
5920  {
5921  /* Have we reached the top? (This isn't quite the right question, */
5922  /* because even though the left triangulation might seem finished now,
5923  */
5924  /* moving up on the right triangulation might reveal a new vertex of
5925  */
5926  /* the left triangulation. And vice-versa.) */
5927  leftfinished =
5928  counterclockwise(m, b, upperleft, lowerleft, lowerright) <= 0.0;
5929  rightfinished =
5930  counterclockwise(m, b, upperright, lowerleft, lowerright) <= 0.0;
5931  if (leftfinished && rightfinished)
5932  {
5933  /* Create the top new bounding triangle. */
5934  maketriangle(m, b, &nextedge);
5935  setorg(nextedge, lowerleft);
5936  setdest(nextedge, lowerright);
5937  /* Apex is intentionally left NULL. */
5938  /* Connect it to the bounding boxes of the two triangulations. */
5939  bond(nextedge, baseedge);
5940  lnextself(nextedge);
5941  bond(nextedge, rightcand);
5942  lnextself(nextedge);
5943  bond(nextedge, leftcand);
5944 
5945  /* Special treatment for horizontal cuts. */
5946  if (axis == 1)
5947  {
5948  org(*farleft, farleftpt);
5949  apex(*farleft, farleftapex);
5950  dest(*farright, farrightpt);
5951  apex(*farright, farrightapex);
5952  sym(*farleft, checkedge);
5953  apex(checkedge, checkvertex);
5954  /* The pointers to the extremal vertices are restored to the */
5955  /* leftmost and rightmost vertices (rather than topmost and */
5956  /* bottommost). */
5957  while (checkvertex[0] < farleftpt[0])
5958  {
5959  lprev(checkedge, *farleft);
5960  farleftapex = farleftpt;
5961  farleftpt = checkvertex;
5962  sym(*farleft, checkedge);
5963  apex(checkedge, checkvertex);
5964  }
5965  while (farrightapex[0] > farrightpt[0])
5966  {
5967  lprevself(*farright);
5968  symself(*farright);
5969  farrightpt = farrightapex;
5970  apex(*farright, farrightapex);
5971  }
5972  }
5973  return;
5974  }
5975  /* Consider eliminating edges from the left triangulation. */
5976  if (!leftfinished)
5977  {
5978  /* What vertex would be exposed if an edge were deleted? */
5979  lprev(leftcand, nextedge);
5980  symself(nextedge);
5981  apex(nextedge, nextapex);
5982  /* If nextapex is NULL, then no vertex would be exposed; the */
5983  /* triangulation would have been eaten right through. */
5984  if (nextapex != (vertex)NULL)
5985  {
5986  /* Check whether the edge is Delaunay. */
5987  badedge =
5988  incircle(m, b, lowerleft, lowerright, upperleft, nextapex) >
5989  0.0;
5990  while (badedge)
5991  {
5992  /* Eliminate the edge with an edge flip. As a result, the
5993  */
5994  /* left triangulation will have one more boundary
5995  * triangle. */
5996  lnextself(nextedge);
5997  sym(nextedge, topcasing);
5998  lnextself(nextedge);
5999  sym(nextedge, sidecasing);
6000  bond(nextedge, topcasing);
6001  bond(leftcand, sidecasing);
6002  lnextself(leftcand);
6003  sym(leftcand, outercasing);
6004  lprevself(nextedge);
6005  bond(nextedge, outercasing);
6006  /* Correct the vertices to reflect the edge flip. */
6007  setorg(leftcand, lowerleft);
6008  setdest(leftcand, NULL);
6009  setapex(leftcand, nextapex);
6010  setorg(nextedge, NULL);
6011  setdest(nextedge, upperleft);
6012  setapex(nextedge, nextapex);
6013  /* Consider the newly exposed vertex. */
6014  upperleft = nextapex;
6015  /* What vertex would be exposed if another edge were
6016  * deleted? */
6017  otricopy(sidecasing, nextedge);
6018  apex(nextedge, nextapex);
6019  if (nextapex != (vertex)NULL)
6020  {
6021  /* Check whether the edge is Delaunay. */
6022  badedge = incircle(m,
6023  b,
6024  lowerleft,
6025  lowerright,
6026  upperleft,
6027  nextapex) > 0.0;
6028  }
6029  else
6030  {
6031  /* Avoid eating right through the triangulation. */
6032  badedge = 0;
6033  }
6034  }
6035  }
6036  }
6037  /* Consider eliminating edges from the right triangulation. */
6038  if (!rightfinished)
6039  {
6040  /* What vertex would be exposed if an edge were deleted? */
6041  lnext(rightcand, nextedge);
6042  symself(nextedge);
6043  apex(nextedge, nextapex);
6044  /* If nextapex is NULL, then no vertex would be exposed; the */
6045  /* triangulation would have been eaten right through. */
6046  if (nextapex != (vertex)NULL)
6047  {
6048  /* Check whether the edge is Delaunay. */
6049  badedge =
6050  incircle(
6051  m, b, lowerleft, lowerright, upperright, nextapex) >
6052  0.0;
6053  while (badedge)
6054  {
6055  /* Eliminate the edge with an edge flip. As a result, the
6056  */
6057  /* right triangulation will have one more boundary
6058  * triangle. */
6059  lprevself(nextedge);
6060  sym(nextedge, topcasing);
6061  lprevself(nextedge);
6062  sym(nextedge, sidecasing);
6063  bond(nextedge, topcasing);
6064  bond(rightcand, sidecasing);
6065  lprevself(rightcand);
6066  sym(rightcand, outercasing);
6067  lnextself(nextedge);
6068  bond(nextedge, outercasing);
6069  /* Correct the vertices to reflect the edge flip. */
6070  setorg(rightcand, NULL);
6071  setdest(rightcand, lowerright);
6072  setapex(rightcand, nextapex);
6073  setorg(nextedge, upperright);
6074  setdest(nextedge, NULL);
6075  setapex(nextedge, nextapex);
6076  /* Consider the newly exposed vertex. */
6077  upperright = nextapex;
6078  /* What vertex would be exposed if another edge were
6079  * deleted? */
6080  otricopy(sidecasing, nextedge);
6081  apex(nextedge, nextapex);
6082  if (nextapex != (vertex)NULL)
6083  {
6084  /* Check whether the edge is Delaunay. */
6085  badedge = incircle(m,
6086  b,
6087  lowerleft,
6088  lowerright,
6089  upperright,
6090  nextapex) > 0.0;
6091  }
6092  else
6093  {
6094  /* Avoid eating right through the triangulation. */
6095  badedge = 0;
6096  }
6097  }
6098  }
6099  }
6100  if (leftfinished ||
6101  (!rightfinished &&
6102  (incircle(m, b, upperleft, lowerleft, lowerright, upperright) >
6103  0.0)))
6104  {
6105  /* Knit the triangulations, adding an edge from `lowerleft' */
6106  /* to `upperright'. */
6107  bond(baseedge, rightcand);
6108  lprev(rightcand, baseedge);
6109  setdest(baseedge, lowerleft);
6110  lowerright = upperright;
6111  sym(baseedge, rightcand);
6112  apex(rightcand, upperright);
6113  }
6114  else
6115  {
6116  /* Knit the triangulations, adding an edge from `upperleft' */
6117  /* to `lowerright'. */
6118  bond(baseedge, leftcand);
6119  lnext(leftcand, baseedge);
6120  setorg(baseedge, lowerright);
6121  lowerleft = upperleft;
6122  sym(baseedge, leftcand);
6123  apex(leftcand, upperleft);
6124  }
6125  }
6126 }
6127 
6128 /*****************************************************************************/
6129 /* */
6130 /* divconqrecurse() Recursively form a Delaunay triangulation by the */
6131 /* divide-and-conquer method. */
6132 /* */
6133 /* Recursively breaks down the problem into smaller pieces, which are */
6134 /* knitted together by mergehulls(). The base cases (problems of two or */
6135 /* three vertices) are handled specially here. */
6136 /* */
6137 /* On completion, `farleft' and `farright' are bounding triangles such that */
6138 /* the origin of `farleft' is the leftmost vertex (breaking ties by */
6139 /* choosing the highest leftmost vertex), and the destination of */
6140 /* `farright' is the rightmost vertex (breaking ties by choosing the */
6141 /* lowest rightmost vertex). */
6142 /* */
6143 /*****************************************************************************/
6144 
6146  struct behavior *b,
6147  vertex *sortarray,
6148  int vertices,
6149  int axis,
6150  struct otri *farleft,
6151  struct otri *farright)
6152 {
6153  struct otri midtri, tri1, tri2, tri3;
6154  struct otri innerleft, innerright;
6155  double area;
6156  int divider;
6157 
6158  if (vertices == 2)
6159  {
6160  /* The triangulation of two vertices is an edge. An edge is */
6161  /* represented by two bounding triangles. */
6162  maketriangle(m, b, farleft);
6163  setorg(*farleft, sortarray[0]);
6164  setdest(*farleft, sortarray[1]);
6165  /* The apex is intentionally left NULL. */
6166  maketriangle(m, b, farright);
6167  setorg(*farright, sortarray[1]);
6168  setdest(*farright, sortarray[0]);
6169  /* The apex is intentionally left NULL. */
6170  bond(*farleft, *farright);
6171  lprevself(*farleft);
6172  lnextself(*farright);
6173  bond(*farleft, *farright);
6174  lprevself(*farleft);
6175  lnextself(*farright);
6176  bond(*farleft, *farright);
6177 
6178  /* Ensure that the origin of `farleft' is sortarray[0]. */
6179  lprev(*farright, *farleft);
6180  return;
6181  }
6182  else if (vertices == 3)
6183  {
6184  /* The triangulation of three vertices is either a triangle (with */
6185  /* three bounding triangles) or two edges (with four bounding */
6186  /* triangles). In either case, four triangles are created. */
6187  maketriangle(m, b, &midtri);
6188  maketriangle(m, b, &tri1);
6189  maketriangle(m, b, &tri2);
6190  maketriangle(m, b, &tri3);
6191  area = counterclockwise(m, b, sortarray[0], sortarray[1], sortarray[2]);
6192  if (area == 0.0)
6193  {
6194  /* Three collinear vertices; the triangulation is two edges. */
6195  setorg(midtri, sortarray[0]);
6196  setdest(midtri, sortarray[1]);
6197  setorg(tri1, sortarray[1]);
6198  setdest(tri1, sortarray[0]);
6199  setorg(tri2, sortarray[2]);
6200  setdest(tri2, sortarray[1]);
6201  setorg(tri3, sortarray[1]);
6202  setdest(tri3, sortarray[2]);
6203  /* All apices are intentionally left NULL. */
6204  bond(midtri, tri1);
6205  bond(tri2, tri3);
6206  lnextself(midtri);
6207  lprevself(tri1);
6208  lnextself(tri2);
6209  lprevself(tri3);
6210  bond(midtri, tri3);
6211  bond(tri1, tri2);
6212  lnextself(midtri);
6213  lprevself(tri1);
6214  lnextself(tri2);
6215  lprevself(tri3);
6216  bond(midtri, tri1);
6217  bond(tri2, tri3);
6218  /* Ensure that the origin of `farleft' is sortarray[0]. */
6219  otricopy(tri1, *farleft);
6220  /* Ensure that the destination of `farright' is sortarray[2]. */
6221  otricopy(tri2, *farright);
6222  }
6223  else
6224  {
6225  /* The three vertices are not collinear; the triangulation is one */
6226  /* triangle, namely `midtri'. */
6227  setorg(midtri, sortarray[0]);
6228  setdest(tri1, sortarray[0]);
6229  setorg(tri3, sortarray[0]);
6230  /* Apices of tri1, tri2, and tri3 are left NULL. */
6231  if (area > 0.0)
6232  {
6233  /* The vertices are in counterclockwise order. */
6234  setdest(midtri, sortarray[1]);
6235  setorg(tri1, sortarray[1]);
6236  setdest(tri2, sortarray[1]);
6237  setapex(midtri, sortarray[2]);
6238  setorg(tri2, sortarray[2]);
6239  setdest(tri3, sortarray[2]);
6240  }
6241  else
6242  {
6243  /* The vertices are in clockwise order. */
6244  setdest(midtri, sortarray[2]);
6245  setorg(tri1, sortarray[2]);
6246  setdest(tri2, sortarray[2]);
6247  setapex(midtri, sortarray[1]);
6248  setorg(tri2, sortarray[1]);
6249  setdest(tri3, sortarray[1]);
6250  }
6251  /* The topology does not depend on how the vertices are ordered. */
6252  bond(midtri, tri1);
6253  lnextself(midtri);
6254  bond(midtri, tri2);
6255  lnextself(midtri);
6256  bond(midtri, tri3);
6257  lprevself(tri1);
6258  lnextself(tri2);
6259  bond(tri1, tri2);
6260  lprevself(tri1);
6261  lprevself(tri3);
6262  bond(tri1, tri3);
6263  lnextself(tri2);
6264  lprevself(tri3);
6265  bond(tri2, tri3);
6266  /* Ensure that the origin of `farleft' is sortarray[0]. */
6267  otricopy(tri1, *farleft);
6268  /* Ensure that the destination of `farright' is sortarray[2]. */
6269  if (area > 0.0)
6270  {
6271  otricopy(tri2, *farright);
6272  }
6273  else
6274  {
6275  lnext(*farleft, *farright);
6276  }
6277  }
6278 
6279  return;
6280  }
6281  else
6282  {
6283  /* Split the vertices in half. */
6284  divider = vertices >> 1;
6285  /* Recursively triangulate each half. */
6286  divconqrecurse(m, b, sortarray, divider, 1 - axis, farleft, &innerleft);
6287  divconqrecurse(m,
6288  b,
6289  &sortarray[divider],
6290  vertices - divider,
6291  1 - axis,
6292  &innerright,
6293  farright);
6294 
6295  /* Merge the two triangulations into one. */
6296  mergehulls(m, b, farleft, &innerleft, &innerright, farright, axis);
6297  }
6298 }
6299 
6300 long DelaunayTriangle::removeghosts(struct mesh *m, struct behavior *b, struct otri *startghost)
6301 {
6302  struct otri searchedge;
6303  struct otri dissolveedge;
6304  struct otri deadtriangle;
6305  vertex markorg;
6306  long hullsize;
6307  triangle ptr; /* Temporary variable used by sym(). */
6308 
6309 
6310  /* Find an edge on the convex hull to start point location from. */
6311  lprev(*startghost, searchedge);
6312  symself(searchedge);
6313  m->dummytri[0] = encode(searchedge);
6314  /* Remove the bounding box and count the convex hull edges. */
6315  otricopy(*startghost, dissolveedge);
6316  hullsize = 0;
6317  do
6318  {
6319  hullsize++;
6320  lnext(dissolveedge, deadtriangle);
6321  lprevself(dissolveedge);
6322  symself(dissolveedge);
6323  /* If no PSLG is involved, set the boundary markers of all the vertices
6324  */
6325  /* on the convex hull. If a PSLG is used, this step is done later. */
6326  if (!b->poly)
6327  {
6328  /* Watch out for the case where all the input vertices are
6329  * collinear. */
6330  if (dissolveedge.tri != m->dummytri)
6331  {
6332  org(dissolveedge, markorg);
6333  if (vertexmark(markorg) == 0)
6334  {
6335  setvertexmark(markorg, 1);
6336  }
6337  }
6338  }
6339  /* Remove a bounding triangle from a convex hull triangle. */
6340  dissolve(dissolveedge);
6341  /* Find the next bounding triangle. */
6342  sym(deadtriangle, dissolveedge);
6343  /* Delete the bounding triangle. */
6344  triangledealloc(m, deadtriangle.tri);
6345  } while (!otriequal(dissolveedge, *startghost));
6346  return hullsize;
6347 }
6348 
6349 /*****************************************************************************/
6350 /* */
6351 /* divconqdelaunay() Form a Delaunay triangulation by the divide-and- */
6352 /* conquer method. */
6353 /* */
6354 /* Sorts the vertices, calls a recursive procedure to triangulate them, and */
6355 /* removes the bounding box, setting boundary markers as appropriate. */
6356 /* */
6357 /*****************************************************************************/
6358 
6360 {
6361  vertex *sortarray;
6362  struct otri hullleft, hullright;
6363  int divider;
6364  int i, j;
6365 
6366  /* Allocate an array of pointers to vertices for sorting. */
6367  sortarray = (vertex *)trimalloc(m->invertices * (int)sizeof(vertex));
6368  traversalinit(&m->vertices);
6369  for (i = 0; i < m->invertices; i++)
6370  {
6371  sortarray[i] = vertextraverse(m);
6372  }
6373  /* Sort the vertices. */
6374  vertexsort(sortarray, m->invertices);
6375  /* Discard duplicate vertices, which can really mess up the algorithm. */
6376  i = 0;
6377  for (j = 1; j < m->invertices; j++)
6378  {
6379  if ((sortarray[i][0] == sortarray[j][0]) &&
6380  (sortarray[i][1] == sortarray[j][1]))
6381  {
6382  setvertextype(sortarray[j], UNDEADVERTEX);
6383  m->undeads++;
6384  }
6385  else
6386  {
6387  i++;
6388  sortarray[i] = sortarray[j];
6389  }
6390  }
6391  i++;
6392 
6393  /* Re-sort the array of vertices to accommodate alternating cuts. */
6394  divider = i >> 1;
6395  if (i - divider >= 2)
6396  {
6397  if (divider >= 2)
6398  {
6399  alternateaxes(sortarray, divider, 1);
6400  }
6401  alternateaxes(&sortarray[divider], i - divider, 1);
6402  }
6403 
6404  /* Form the Delaunay triangulation. */
6405  divconqrecurse(m, b, sortarray, i, 0, &hullleft, &hullright);
6406  trifree((void *)sortarray);
6407 
6408  return removeghosts(m, b, &hullleft);
6409 }
6410 
6411 /** **/
6412 /** **/
6413 /********* Divide-and-conquer Delaunay triangulation ends here *********/
6414 
6415 /********* General mesh construction routines begin here *********/
6416 /** **/
6417 /** **/
6418 
6419 /*****************************************************************************/
6420 /* */
6421 /* delaunay() Form a Delaunay triangulation. */
6422 /* */
6423 /*****************************************************************************/
6424 
6425 long DelaunayTriangle::delaunay(struct mesh *m, struct behavior *b)
6426 {
6427  long hulledges;
6428 
6429  m->eextras = 0;
6430  initializetrisubpools(m, b);
6431 
6432  hulledges = divconqdelaunay(m, b);
6433 
6434  if (m->triangles.items == 0)
6435  {
6436  /* The input vertices were all collinear, so there are no triangles. */
6437  return 0l;
6438  }
6439  else
6440  {
6441  return hulledges;
6442  }
6443 }
6444 
6445 /** **/
6446 /** **/
6447 /********* General mesh construction routines end here *********/
6448 
6449 /********* Segment insertion begins here *********/
6450 /** **/
6451 /** **/
6452 
6453 /*****************************************************************************/
6454 /* */
6455 /* finddirection() Find the first triangle on the path from one point */
6456 /* to another. */
6457 /* */
6458 /* Finds the triangle that intersects a line segment drawn from the */
6459 /* origin of `searchtri' to the point `searchpoint', and returns the result */
6460 /* in `searchtri'. The origin of `searchtri' does not change, even though */
6461 /* the triangle returned may differ from the one passed in. This routine */
6462 /* is used to find the direction to move in to get from one point to */
6463 /* another. */
6464 /* */
6465 /* The return value notes whether the destination or apex of the found */
6466 /* triangle is collinear with the two points in question. */
6467 /* */
6468 /*****************************************************************************/
6469 
6471  struct behavior *b,
6472  struct otri *searchtri,
6473  vertex searchpoint)
6474 {
6475  struct otri checktri;
6476  vertex startvertex;
6477  vertex leftvertex, rightvertex;
6478  double leftccw, rightccw;
6479  int leftflag, rightflag;
6480  triangle ptr; /* Temporary variable used by onext() and oprev(). */
6481 
6482  org(*searchtri, startvertex);
6483  dest(*searchtri, rightvertex);
6484  apex(*searchtri, leftvertex);
6485  /* Is `searchpoint' to the left? */
6486  leftccw = counterclockwise(m, b, searchpoint, startvertex, leftvertex);
6487  leftflag = leftccw > 0.0;
6488  /* Is `searchpoint' to the right? */
6489  rightccw = counterclockwise(m, b, startvertex, searchpoint, rightvertex);
6490  rightflag = rightccw > 0.0;
6491  if (leftflag && rightflag)
6492  {
6493  /* `searchtri' faces directly away from `searchpoint'. We could go left
6494  */
6495  /* or right. Ask whether it's a triangle or a boundary on the left.
6496  */
6497  onext(*searchtri, checktri);
6498  if (checktri.tri == m->dummytri)
6499  {
6500  leftflag = 0;
6501  }
6502  else
6503  {
6504  rightflag = 0;
6505  }
6506  }
6507  while (leftflag)
6508  {
6509  /* Turn left until satisfied. */
6510  onextself(*searchtri);
6511  if (searchtri->tri == m->dummytri)
6512  {
6513  printf("Internal error in finddirection(): Unable to find a\n");
6514  printf(" triangle leading from (%.12g, %.12g) to",
6515  startvertex[0],
6516  startvertex[1]);
6517  printf(" (%.12g, %.12g).\n", searchpoint[0], searchpoint[1]);
6518  internalerror();
6519  }
6520  apex(*searchtri, leftvertex);
6521  rightccw = leftccw;
6522  leftccw = counterclockwise(m, b, searchpoint, startvertex, leftvertex);
6523  leftflag = leftccw > 0.0;
6524  }
6525  while (rightflag)
6526  {
6527  /* Turn right until satisfied. */
6528  oprevself(*searchtri);
6529  if (searchtri->tri == m->dummytri)
6530  {
6531  printf("Internal error in finddirection(): Unable to find a\n");
6532  printf(" triangle leading from (%.12g, %.12g) to",
6533  startvertex[0],
6534  startvertex[1]);
6535  printf(" (%.12g, %.12g).\n", searchpoint[0], searchpoint[1]);
6536  internalerror();
6537  }
6538  dest(*searchtri, rightvertex);
6539  leftccw = rightccw;
6540  rightccw =
6541  counterclockwise(m, b, startvertex, searchpoint, rightvertex);
6542  rightflag = rightccw > 0.0;
6543  }
6544  if (leftccw == 0.0)
6545  {
6546  return LEFTCOLLINEAR;
6547  }
6548  else if (rightccw == 0.0)
6549  {
6550  return RIGHTCOLLINEAR;
6551  }
6552  else
6553  {
6554  return WITHIN;
6555  }
6556 }
6557 
6558 /*****************************************************************************/
6559 /* */
6560 /* segmentintersection() Find the intersection of an existing segment */
6561 /* and a segment that is being inserted. Insert */
6562 /* a vertex at the intersection, splitting an */
6563 /* existing subsegment. */
6564 /* */
6565 /* The segment being inserted connects the apex of splittri to endpoint2. */
6566 /* splitsubseg is the subsegment being split, and MUST adjoin splittri. */
6567 /* Hence, endpoints of the subsegment being split are the origin and */
6568 /* destination of splittri. */
6569 /* */
6570 /* On completion, splittri is a handle having the newly inserted */
6571 /* intersection point as its origin, and endpoint1 as its destination. */
6572 /* */
6573 /*****************************************************************************/
6574 
6576  struct behavior *b,
6577  struct otri *splittri,
6578  struct osub *splitsubseg,
6579  vertex endpoint2)
6580 {
6581  struct osub opposubseg;
6582  vertex endpoint1;
6583  vertex torg, tdest;
6584  vertex leftvertex, rightvertex;
6585  vertex newvertex;
6586  enum insertvertexresult success;
6587  double ex, ey;
6588  double tx, ty;
6589  double etx, ety;
6590  double split, denom;
6591  int i;
6592  triangle ptr; /* Temporary variable used by onext(). */
6593  subseg sptr; /* Temporary variable used by snext(). */
6594 
6595  /* Find the other three segment endpoints. */
6596  apex(*splittri, endpoint1);
6597  org(*splittri, torg);
6598  dest(*splittri, tdest);
6599  /* Segment intersection formulae; see the Antonio reference. */
6600  tx = tdest[0] - torg[0];
6601  ty = tdest[1] - torg[1];
6602  ex = endpoint2[0] - endpoint1[0];
6603  ey = endpoint2[1] - endpoint1[1];
6604  etx = torg[0] - endpoint2[0];
6605  ety = torg[1] - endpoint2[1];
6606  denom = ty * ex - tx * ey;
6607  if (denom == 0.0)
6608  {
6609  printf("Internal error in segmentintersection():");
6610  printf(" Attempt to find intersection of parallel segments.\n");
6611  internalerror();
6612  }
6613  split = (ey * etx - ex * ety) / denom;
6614  /* Create the new vertex. */
6615  newvertex = (vertex)poolalloc(&m->vertices);
6616  /* Interpolate its coordinate and attributes. */
6617  for (i = 0; i < 2 + m->nextras; i++)
6618  {
6619  newvertex[i] = torg[i] + split * (tdest[i] - torg[i]);
6620  }
6621  setvertexmark(newvertex, mark(*splitsubseg));
6622  setvertextype(newvertex, INPUTVERTEX);
6623 
6624  /* Insert the intersection vertex. This should always succeed. */
6625  success = insertvertex(m, b, newvertex, splittri, splitsubseg, 0, 0);
6626  if (success != SUCCESSFULVERTEX)
6627  {
6628  printf("Internal error in segmentintersection():\n");
6629  printf(" Failure to split a segment.\n");
6630  internalerror();
6631  }
6632  /* Record a triangle whose origin is the new vertex. */
6633  setvertex2tri(newvertex, encode(*splittri));
6634  if (m->steinerleft > 0)
6635  {
6636  m->steinerleft--;
6637  }
6638 
6639  /* Divide the segment into two, and correct the segment endpoints. */
6640  ssymself(*splitsubseg);
6641  spivot(*splitsubseg, opposubseg);
6642  sdissolve(*splitsubseg);
6643  sdissolve(opposubseg);
6644  do
6645  {
6646  setsegorg(*splitsubseg, newvertex);
6647  snextself(*splitsubseg);
6648  } while (splitsubseg->ss != m->dummysub);
6649  do
6650  {
6651  setsegorg(opposubseg, newvertex);
6652  snextself(opposubseg);
6653  } while (opposubseg.ss != m->dummysub);
6654 
6655  /* Inserting the vertex may have caused edge flips. We wish to rediscover
6656  */
6657  /* the edge connecting endpoint1 to the new intersection vertex. */
6658  finddirection(m, b, splittri, endpoint1);
6659  dest(*splittri, rightvertex);
6660  apex(*splittri, leftvertex);
6661  if ((leftvertex[0] == endpoint1[0]) && (leftvertex[1] == endpoint1[1]))
6662  {
6663  onextself(*splittri);
6664  }
6665  else if ((rightvertex[0] != endpoint1[0]) ||
6666  (rightvertex[1] != endpoint1[1]))
6667  {
6668  printf("Internal error in segmentintersection():\n");
6669  printf(" Topological inconsistency after splitting a segment.\n");
6670  internalerror();
6671  }
6672  /* `splittri' should have destination endpoint1. */
6673 }
6674 
6675 /*****************************************************************************/
6676 /* */
6677 /* scoutsegment() Scout the first triangle on the path from one endpoint */
6678 /* to another, and check for completion (reaching the */
6679 /* second endpoint), a collinear vertex, or the */
6680 /* intersection of two segments. */
6681 /* */
6682 /* Returns one if the entire segment is successfully inserted, and zero if */
6683 /* the job must be finished by conformingedge() or constrainededge(). */
6684 /* */
6685 /* If the first triangle on the path has the second endpoint as its */
6686 /* destination or apex, a subsegment is inserted and the job is done. */
6687 /* */
6688 /* If the first triangle on the path has a destination or apex that lies on */
6689 /* the segment, a subsegment is inserted connecting the first endpoint to */
6690 /* the collinear vertex, and the search is continued from the collinear */
6691 /* vertex. */
6692 /* */
6693 /* If the first triangle on the path has a subsegment opposite its origin, */
6694 /* then there is a segment that intersects the segment being inserted. */
6695 /* Their intersection vertex is inserted, splitting the subsegment. */
6696 /* */
6697 /*****************************************************************************/
6698 
6700  struct behavior *b,
6701  struct otri *searchtri,
6702  vertex endpoint2,
6703  int newmark)
6704 {
6705  struct otri crosstri;
6706  struct osub crosssubseg;
6707  vertex leftvertex, rightvertex;
6708  enum finddirectionresult collinear;
6709  subseg sptr; /* Temporary variable used by tspivot(). */
6710 
6711  collinear = finddirection(m, b, searchtri, endpoint2);
6712  dest(*searchtri, rightvertex);
6713  apex(*searchtri, leftvertex);
6714  if (((leftvertex[0] == endpoint2[0]) && (leftvertex[1] == endpoint2[1])) ||
6715  ((rightvertex[0] == endpoint2[0]) && (rightvertex[1] == endpoint2[1])))
6716  {
6717  /* The segment is already an edge in the mesh. */
6718  if ((leftvertex[0] == endpoint2[0]) && (leftvertex[1] == endpoint2[1]))
6719  {
6720  lprevself(*searchtri);
6721  }
6722  /* Insert a subsegment, if there isn't already one there. */
6723  insertsubseg(m, b, searchtri, newmark);
6724  return 1;
6725  }
6726  else if (collinear == LEFTCOLLINEAR)
6727  {
6728  /* We've collided with a vertex between the segment's endpoints. */
6729  /* Make the collinear vertex be the triangle's origin. */
6730  lprevself(*searchtri);
6731  insertsubseg(m, b, searchtri, newmark);
6732  /* Insert the remainder of the segment. */
6733  return scoutsegment(m, b, searchtri, endpoint2, newmark);
6734  }
6735  else if (collinear == RIGHTCOLLINEAR)
6736  {
6737  /* We've collided with a vertex between the segment's endpoints. */
6738  insertsubseg(m, b, searchtri, newmark);
6739  /* Make the collinear vertex be the triangle's origin. */
6740  lnextself(*searchtri);
6741  /* Insert the remainder of the segment. */
6742  return scoutsegment(m, b, searchtri, endpoint2, newmark);
6743  }
6744  else
6745  {
6746  lnext(*searchtri, crosstri);
6747  tspivot(crosstri, crosssubseg);
6748  /* Check for a crossing segment. */
6749  if (crosssubseg.ss == m->dummysub)
6750  {
6751  return 0;
6752  }
6753  else
6754  {
6755  /* Insert a vertex at the intersection. */
6756  segmentintersection(m, b, &crosstri, &crosssubseg, endpoint2);
6757  otricopy(crosstri, *searchtri);
6758  insertsubseg(m, b, searchtri, newmark);
6759  /* Insert the remainder of the segment. */
6760  return scoutsegment(m, b, searchtri, endpoint2, newmark);
6761  }
6762  }
6763 }
6764 
6765 /*****************************************************************************/
6766 /* */
6767 /* conformingedge() Force a segment into a conforming Delaunay */
6768 /* triangulation by inserting a vertex at its midpoint, */
6769 /* and recursively forcing in the two half-segments if */
6770 /* necessary. */
6771 /* */
6772 /* Generates a sequence of subsegments connecting `endpoint1' to */
6773 /* `endpoint2'. `newmark' is the boundary marker of the segment, assigned */
6774 /* to each new splitting vertex and subsegment. */
6775 /* */
6776 /* Note that conformingedge() does not always maintain the conforming */
6777 /* Delaunay property. Once inserted, segments are locked into place; */
6778 /* vertices inserted later (to force other segments in) may render these */
6779 /* fixed segments non-Delaunay. The conforming Delaunay property will be */
6780 /* restored by enforcequality() by splitting encroached subsegments. */
6781 /* */
6782 /*****************************************************************************/
6783 
6785  struct behavior *b,
6786  vertex endpoint1,
6787  vertex endpoint2,
6788  int newmark)
6789 {
6790  struct otri searchtri1, searchtri2;
6791  struct osub brokensubseg;
6792  vertex newvertex;
6793  vertex midvertex1, midvertex2;
6794  enum insertvertexresult success;
6795  int i;
6796  subseg sptr; /* Temporary variable used by tspivot(). */
6797 
6798  /* Create a new vertex to insert in the middle of the segment. */
6799  newvertex = (vertex)poolalloc(&m->vertices);
6800  /* Interpolate coordinates and attributes. */
6801  for (i = 0; i < 2 + m->nextras; i++)
6802  {
6803  newvertex[i] = 0.5 * (endpoint1[i] + endpoint2[i]);
6804  }
6805  setvertexmark(newvertex, newmark);
6806  setvertextype(newvertex, SEGMENTVERTEX);
6807  /* No known triangle to search from. */
6808  searchtri1.tri = m->dummytri;
6809  /* Attempt to insert the new vertex. */
6810  success =
6811  insertvertex(m, b, newvertex, &searchtri1, (struct osub *)NULL, 0, 0);
6812  if (success == DUPLICATEVERTEX)
6813  {
6814 
6815  /* Use the vertex that's already there. */
6816  vertexdealloc(m, newvertex);
6817  org(searchtri1, newvertex);
6818  }
6819  else
6820  {
6821  if (success == VIOLATINGVERTEX)
6822  {
6823 
6824  /* By fluke, we've landed right on another segment. Split it. */
6825  tspivot(searchtri1, brokensubseg);
6826  success =
6827  insertvertex(m, b, newvertex, &searchtri1, &brokensubseg, 0, 0);
6828  if (success != SUCCESSFULVERTEX)
6829  {
6830  printf("Internal error in conformingedge():\n");
6831  printf(" Failure to split a segment.\n");
6832  internalerror();
6833  }
6834  }
6835  /* The vertex has been inserted successfully. */
6836  if (m->steinerleft > 0)
6837  {
6838  m->steinerleft--;
6839  }
6840  }
6841  otricopy(searchtri1, searchtri2);
6842  /* `searchtri1' and `searchtri2' are fastened at their origins to */
6843  /* `newvertex', and will be directed toward `endpoint1' and `endpoint2' */
6844  /* respectively. First, we must get `searchtri2' out of the way so it */
6845  /* won't be invalidated during the insertion of the first half of the */
6846  /* segment. */
6847  finddirection(m, b, &searchtri2, endpoint2);
6848  if (!scoutsegment(m, b, &searchtri1, endpoint1, newmark))
6849  {
6850  /* The origin of searchtri1 may have changed if a collision with an */
6851  /* intervening vertex on the segment occurred. */
6852  org(searchtri1, midvertex1);
6853  conformingedge(m, b, midvertex1, endpoint1, newmark);
6854  }
6855  if (!scoutsegment(m, b, &searchtri2, endpoint2, newmark))
6856  {
6857  /* The origin of searchtri2 may have changed if a collision with an */
6858  /* intervening vertex on the segment occurred. */
6859  org(searchtri2, midvertex2);
6860  conformingedge(m, b, midvertex2, endpoint2, newmark);
6861  }
6862 }
6863 
6864 /*****************************************************************************/
6865 /* */
6866 /* delaunayfixup() Enforce the Delaunay condition at an edge, fanning out */
6867 /* recursively from an existing vertex. Pay special */
6868 /* attention to stacking inverted triangles. */
6869 /* */
6870 /* This is a support routine for inserting segments into a constrained */
6871 /* Delaunay triangulation. */
6872 /* */
6873 /* The origin of fixuptri is treated as if it has just been inserted, and */
6874 /* the local Delaunay condition needs to be enforced. It is only enforced */
6875 /* in one sector, however, that being the angular range defined by */
6876 /* fixuptri. */
6877 /* */
6878 /* This routine also needs to make decisions regarding the "stacking" of */
6879 /* triangles. (Read the description of constrainededge() below before */
6880 /* reading on here, so you understand the algorithm.) If the position of */
6881 /* the new vertex (the origin of fixuptri) indicates that the vertex before */
6882 /* it on the polygon is a reflex vertex, then "stack" the triangle by */
6883 /* doing nothing. (fixuptri is an inverted triangle, which is how stacked */
6884 /* triangles are identified.) */
6885 /* */
6886 /* Otherwise, check whether the vertex before that was a reflex vertex. */
6887 /* If so, perform an edge flip, thereby eliminating an inverted triangle */
6888 /* (popping it off the stack). The edge flip may result in the creation */
6889 /* of a new inverted triangle, depending on whether or not the new vertex */
6890 /* is visible to the vertex three edges behind on the polygon. */
6891 /* */
6892 /* If neither of the two vertices behind the new vertex are reflex */
6893 /* vertices, fixuptri and fartri, the triangle opposite it, are not */
6894 /* inverted; hence, ensure that the edge between them is locally Delaunay. */
6895 /* */
6896 /* `leftside' indicates whether or not fixuptri is to the left of the */
6897 /* segment being inserted. (Imagine that the segment is pointing up from */
6898 /* endpoint1 to endpoint2.) */
6899 /* */
6900 /*****************************************************************************/
6901 
6903  struct behavior *b,
6904  struct otri *fixuptri,
6905  int leftside)
6906 {
6907  struct otri neartri;
6908  struct otri fartri;
6909  struct osub faredge;
6910  vertex nearvertex, leftvertex, rightvertex, farvertex;
6911  triangle ptr; /* Temporary variable used by sym(). */
6912  subseg sptr; /* Temporary variable used by tspivot(). */
6913 
6914  lnext(*fixuptri, neartri);
6915  sym(neartri, fartri);
6916  /* Check if the edge opposite the origin of fixuptri can be flipped. */
6917  if (fartri.tri == m->dummytri)
6918  {
6919  return;
6920  }
6921  tspivot(neartri, faredge);
6922  if (faredge.ss != m->dummysub)
6923  {
6924  return;
6925  }
6926  /* Find all the relevant vertices. */
6927  apex(neartri, nearvertex);
6928  org(neartri, leftvertex);
6929  dest(neartri, rightvertex);
6930  apex(fartri, farvertex);
6931  /* Check whether the previous polygon vertex is a reflex vertex. */
6932  if (leftside)
6933  {
6934  if (counterclockwise(m, b, nearvertex, leftvertex, farvertex) <= 0.0)
6935  {
6936  /* leftvertex is a reflex vertex too. Nothing can */
6937  /* be done until a convex section is found. */
6938  return;
6939  }
6940  }
6941  else
6942  {
6943  if (counterclockwise(m, b, farvertex, rightvertex, nearvertex) <= 0.0)
6944  {
6945  /* rightvertex is a reflex vertex too. Nothing can */
6946  /* be done until a convex section is found. */
6947  return;
6948  }
6949  }
6950  if (counterclockwise(m, b, rightvertex, leftvertex, farvertex) > 0.0)
6951  {
6952  /* fartri is not an inverted triangle, and farvertex is not a reflex */
6953  /* vertex. As there are no reflex vertices, fixuptri isn't an */
6954  /* inverted triangle, either. Hence, test the edge between the */
6955  /* triangles to ensure it is locally Delaunay. */
6956  if (incircle(m, b, leftvertex, farvertex, rightvertex, nearvertex) <=
6957  0.0)
6958  {
6959  return;
6960  }
6961  /* Not locally Delaunay; go on to an edge flip. */
6962  } /* else fartri is inverted; remove it from the stack by flipping. */
6963  flip(m, b, &neartri);
6964  lprevself(*fixuptri); /* Restore the origin of fixuptri after the flip. */
6965  /* Recursively process the two triangles that result from the flip. */
6966  delaunayfixup(m, b, fixuptri, leftside);
6967  delaunayfixup(m, b, &fartri, leftside);
6968 }
6969 
6970 /*****************************************************************************/
6971 /* */
6972 /* constrainededge() Force a segment into a constrained Delaunay */
6973 /* triangulation by deleting the triangles it */
6974 /* intersects, and triangulating the polygons that */
6975 /* form on each side of it. */
6976 /* */
6977 /* Generates a single subsegment connecting `endpoint1' to `endpoint2'. */
6978 /* The triangle `starttri' has `endpoint1' as its origin. `newmark' is the */
6979 /* boundary marker of the segment. */
6980 /* */
6981 /* To insert a segment, every triangle whose interior intersects the */
6982 /* segment is deleted. The union of these deleted triangles is a polygon */
6983 /* (which is not necessarily monotone, but is close enough), which is */
6984 /* divided into two polygons by the new segment. This routine's task is */
6985 /* to generate the Delaunay triangulation of these two polygons. */
6986 /* */
6987 /* You might think of this routine's behavior as a two-step process. The */
6988 /* first step is to walk from endpoint1 to endpoint2, flipping each edge */
6989 /* encountered. This step creates a fan of edges connected to endpoint1, */
6990 /* including the desired edge to endpoint2. The second step enforces the */
6991 /* Delaunay condition on each side of the segment in an incremental manner: */
6992 /* proceeding along the polygon from endpoint1 to endpoint2 (this is done */
6993 /* independently on each side of the segment), each vertex is "enforced" */
6994 /* as if it had just been inserted, but affecting only the previous */
6995 /* vertices. The result is the same as if the vertices had been inserted */
6996 /* in the order they appear on the polygon, so the result is Delaunay. */
6997 /* */
6998 /* In truth, constrainededge() interleaves these two steps. The procedure */
6999 /* walks from endpoint1 to endpoint2, and each time an edge is encountered */
7000 /* and flipped, the newly exposed vertex (at the far end of the flipped */
7001 /* edge) is "enforced" upon the previously flipped edges, usually affecting */
7002 /* only one side of the polygon (depending upon which side of the segment */
7003 /* the vertex falls on). */
7004 /* */
7005 /* The algorithm is complicated by the need to handle polygons that are not */
7006 /* convex. Although the polygon is not necessarily monotone, it can be */
7007 /* triangulated in a manner similar to the stack-based algorithms for */
7008 /* monotone polygons. For each reflex vertex (local concavity) of the */
7009 /* polygon, there will be an inverted triangle formed by one of the edge */
7010 /* flips. (An inverted triangle is one with negative area - that is, its */
7011 /* vertices are arranged in clockwise order - and is best thought of as a */
7012 /* wrinkle in the fabric of the mesh.) Each inverted triangle can be */
7013 /* thought of as a reflex vertex pushed on the stack, waiting to be fixed */
7014 /* later. */
7015 /* */
7016 /* A reflex vertex is popped from the stack when a vertex is inserted that */
7017 /* is visible to the reflex vertex. (However, if the vertex behind the */
7018 /* reflex vertex is not visible to the reflex vertex, a new inverted */
7019 /* triangle will take its place on the stack.) These details are handled */
7020 /* by the delaunayfixup() routine above. */
7021 /* */
7022 /*****************************************************************************/
7023 
7025  struct behavior *b,
7026  struct otri *starttri,
7027  vertex endpoint2,
7028  int newmark)
7029 {
7030  struct otri fixuptri, fixuptri2;
7031  struct osub crosssubseg;
7032  vertex endpoint1;
7033  vertex farvertex;
7034  double area;
7035  int collision;
7036  int done;
7037  triangle ptr; /* Temporary variable used by sym() and oprev(). */
7038  subseg sptr; /* Temporary variable used by tspivot(). */
7039 
7040  org(*starttri, endpoint1);
7041  lnext(*starttri, fixuptri);
7042  flip(m, b, &fixuptri);
7043  /* `collision' indicates whether we have found a vertex directly */
7044  /* between endpoint1 and endpoint2. */
7045  collision = 0;
7046  done = 0;
7047  do
7048  {
7049  org(fixuptri, farvertex);
7050  /* `farvertex' is the extreme point of the polygon we are "digging" */
7051  /* to get from endpoint1 to endpoint2. */
7052  if ((farvertex[0] == endpoint2[0]) && (farvertex[1] == endpoint2[1]))
7053  {
7054  oprev(fixuptri, fixuptri2);
7055  /* Enforce the Delaunay condition around endpoint2. */
7056  delaunayfixup(m, b, &fixuptri, 0);
7057  delaunayfixup(m, b, &fixuptri2, 1);
7058  done = 1;
7059  }
7060  else
7061  {
7062  /* Check whether farvertex is to the left or right of the segment */
7063  /* being inserted, to decide which edge of fixuptri to dig */
7064  /* through next. */
7065  area = counterclockwise(m, b, endpoint1, endpoint2, farvertex);
7066  if (area == 0.0)
7067  {
7068  /* We've collided with a vertex between endpoint1 and endpoint2.
7069  */
7070  collision = 1;
7071  oprev(fixuptri, fixuptri2);
7072  /* Enforce the Delaunay condition around farvertex. */
7073  delaunayfixup(m, b, &fixuptri, 0);
7074  delaunayfixup(m, b, &fixuptri2, 1);
7075  done = 1;
7076  }
7077  else
7078  {
7079  if (area > 0.0)
7080  { /* farvertex is to the left of the segment. */
7081  oprev(fixuptri, fixuptri2);
7082  /* Enforce the Delaunay condition around farvertex, on the
7083  */
7084  /* left side of the segment only. */
7085  delaunayfixup(m, b, &fixuptri2, 1);
7086  /* Flip the edge that crosses the segment. After the edge
7087  * is */
7088  /* flipped, one of its endpoints is the fan vertex, and
7089  * the */
7090  /* destination of fixuptri is the fan vertex. */
7091  lprevself(fixuptri);
7092  }
7093  else
7094  { /* farvertex is to the right of the segment. */
7095  delaunayfixup(m, b, &fixuptri, 0);
7096  /* Flip the edge that crosses the segment. After the edge
7097  * is */
7098  /* flipped, one of its endpoints is the fan vertex, and
7099  * the */
7100  /* destination of fixuptri is the fan vertex. */
7101  oprevself(fixuptri);
7102  }
7103  /* Check for two intersecting segments. */
7104  tspivot(fixuptri, crosssubseg);
7105  if (crosssubseg.ss == m->dummysub)
7106  {
7107  flip(m,
7108  b,
7109  &fixuptri); /* May create inverted triangle at left. */
7110  }
7111  else
7112  {
7113  /* We've collided with a segment between endpoint1 and
7114  * endpoint2. */
7115  collision = 1;
7116  /* Insert a vertex at the intersection. */
7118  m, b, &fixuptri, &crosssubseg, endpoint2);
7119  done = 1;
7120  }
7121  }
7122  }
7123  } while (!done);
7124  /* Insert a subsegment to make the segment permanent. */
7125  insertsubseg(m, b, &fixuptri, newmark);
7126  /* If there was a collision with an interceding vertex, install another */
7127  /* segment connecting that vertex with endpoint2. */
7128  if (collision)
7129  {
7130  /* Insert the remainder of the segment. */
7131  if (!scoutsegment(m, b, &fixuptri, endpoint2, newmark))
7132  {
7133  constrainededge(m, b, &fixuptri, endpoint2, newmark);
7134  }
7135  }
7136 }
7137 
7138 /*****************************************************************************/
7139 /* */
7140 /* insertsegment() Insert a PSLG segment into a triangulation. */
7141 /* */
7142 /*****************************************************************************/
7143 
7145  struct behavior *b,
7146  vertex endpoint1,
7147  vertex endpoint2,
7148  int newmark)
7149 {
7150  struct otri searchtri1, searchtri2;
7151  triangle encodedtri;
7152  vertex checkvertex;
7153  triangle ptr; /* Temporary variable used by sym(). */
7154 
7155 
7156 
7157  /* Find a triangle whose origin is the segment's first endpoint. */
7158  checkvertex = (vertex)NULL;
7159  encodedtri = vertex2tri(endpoint1);
7160  if (encodedtri != (triangle)NULL)
7161  {
7162  decode(encodedtri, searchtri1);
7163  org(searchtri1, checkvertex);
7164  }
7165  if (checkvertex != endpoint1)
7166  {
7167  /* Find a boundary triangle to search from. */
7168  searchtri1.tri = m->dummytri;
7169  searchtri1.orient = 0;
7170  symself(searchtri1);
7171  /* Search for the segment's first endpoint by point location. */
7172  if (locate(m, b, endpoint1, &searchtri1) != ONVERTEX)
7173  {
7174  printf("Internal error in insertsegment(): Unable to locate PSLG "
7175  "vertex\n");
7176  printf(" (%.12g, %.12g) in triangulation.\n",
7177  endpoint1[0],
7178  endpoint1[1]);
7179  internalerror();
7180  }
7181  }
7182  /* Remember this triangle to improve subsequent point location. */
7183  otricopy(searchtri1, m->recenttri);
7184  /* Scout the beginnings of a path from the first endpoint */
7185  /* toward the second. */
7186  if (scoutsegment(m, b, &searchtri1, endpoint2, newmark))
7187  {
7188  /* The segment was easily inserted. */
7189  return;
7190  }
7191  /* The first endpoint may have changed if a collision with an intervening */
7192  /* vertex on the segment occurred. */
7193  org(searchtri1, endpoint1);
7194 
7195  /* Find a triangle whose origin is the segment's second endpoint. */
7196  checkvertex = (vertex)NULL;
7197  encodedtri = vertex2tri(endpoint2);
7198  if (encodedtri != (triangle)NULL)
7199  {
7200  decode(encodedtri, searchtri2);
7201  org(searchtri2, checkvertex);
7202  }
7203  if (checkvertex != endpoint2)
7204  {
7205  /* Find a boundary triangle to search from. */
7206  searchtri2.tri = m->dummytri;
7207  searchtri2.orient = 0;
7208  symself(searchtri2);
7209  /* Search for the segment's second endpoint by point location. */
7210  if (locate(m, b, endpoint2, &searchtri2) != ONVERTEX)
7211  {
7212  printf("Internal error in insertsegment(): Unable to locate PSLG "
7213  "vertex\n");
7214  printf(" (%.12g, %.12g) in triangulation.\n",
7215  endpoint2[0],
7216  endpoint2[1]);
7217  internalerror();
7218  }
7219  }
7220  /* Remember this triangle to improve subsequent point location. */
7221  otricopy(searchtri2, m->recenttri);
7222  /* Scout the beginnings of a path from the second endpoint */
7223  /* toward the first. */
7224  if (scoutsegment(m, b, &searchtri2, endpoint1, newmark))
7225  {
7226  /* The segment was easily inserted. */
7227  return;
7228  }
7229  /* The second endpoint may have changed if a collision with an intervening
7230  */
7231  /* vertex on the segment occurred. */
7232  org(searchtri2, endpoint2);
7233 
7234 
7235  /* Insert the segment directly into the triangulation. */
7236  constrainededge(m, b, &searchtri1, endpoint2, newmark);
7237 }
7238 
7239 /*****************************************************************************/
7240 /* */
7241 /* markhull() Cover the convex hull of a triangulation with subsegments. */
7242 /* */
7243 /*****************************************************************************/
7244 
7245 void DelaunayTriangle::markhull(struct mesh *m, struct behavior *b)
7246 {
7247  struct otri hulltri;
7248  struct otri nexttri;
7249  struct otri starttri;
7250  triangle ptr; /* Temporary variable used by sym() and oprev(). */
7251 
7252  /* Find a triangle handle on the hull. */
7253  hulltri.tri = m->dummytri;
7254  hulltri.orient = 0;
7255  symself(hulltri);
7256  /* Remember where we started so we know when to stop. */
7257  otricopy(hulltri, starttri);
7258  /* Go once counterclockwise around the convex hull. */
7259  do
7260  {
7261  /* Create a subsegment if there isn't already one here. */
7262  insertsubseg(m, b, &hulltri, 1);
7263  /* To find the next hull edge, go clockwise around the next vertex. */
7264  lnextself(hulltri);
7265  oprev(hulltri, nexttri);
7266  while (nexttri.tri != m->dummytri)
7267  {
7268  otricopy(nexttri, hulltri);
7269  oprev(hulltri, nexttri);
7270  }
7271  } while (!otriequal(hulltri, starttri));
7272 }
7273 
7274 /*****************************************************************************/
7275 /* */
7276 /* formskeleton() Create the segments of a triangulation, including PSLG */
7277 /* segments and edges on the convex hull. */
7278 /* */
7279 /* The PSLG segments are read from a .poly file. The return value is the */
7280 /* number of segments in the file. */
7281 /* */
7282 /*****************************************************************************/
7283 
7285  struct behavior *b,
7286  int *segmentlist,
7287  int *segmentmarkerlist,
7288  int numberofsegments)
7289 {
7290  char polyfilename[6];
7291  int index;
7292  vertex endpoint1, endpoint2;
7293  int segmentmarkers;
7294  int end1, end2;
7295  int boundmarker;
7296  int i;
7297 
7298  if (b->poly)
7299  {
7300  strcpy(polyfilename, "input");
7301  m->insegments = numberofsegments;
7302  segmentmarkers = segmentmarkerlist != (int *)NULL;
7303  index = 0;
7304  /* If the input vertices are collinear, there is no triangulation, */
7305  /* so don't try to insert segments. */
7306  if (m->triangles.items == 0)
7307  {
7308  return;
7309  }
7310 
7311  /* If segments are to be inserted, compute a mapping */
7312  /* from vertices to triangles. */
7313  if (m->insegments > 0)
7314  {
7315  makevertexmap(m, b);
7316 
7317  }
7318 
7319  boundmarker = 0;
7320  /* Read and insert the segments. */
7321  for (i = 0; i < m->insegments; i++)
7322  {
7323  end1 = segmentlist[index++];
7324  end2 = segmentlist[index++];
7325  if (segmentmarkers)
7326  {
7327  boundmarker = segmentmarkerlist[i];
7328  }
7329  if ((end1 < 0) ||
7330  (end1 >= 0 + m->invertices))
7331  {
7332 
7333  }
7334  else if ((end2 < 0) ||
7335  (end2 >= 0 + m->invertices))
7336  {
7337 
7338  }
7339  else
7340  {
7341  /* Find the vertices numbered `end1' and `end2'. */
7342  endpoint1 = getvertex(m, b, end1);
7343  endpoint2 = getvertex(m, b, end2);
7344  if ((endpoint1[0] == endpoint2[0]) &&
7345  (endpoint1[1] == endpoint2[1]))
7346  {
7347 
7348  }
7349  else
7350  {
7351  insertsegment(m, b, endpoint1, endpoint2, boundmarker);
7352  }
7353  }
7354  }
7355  }
7356  else
7357  {
7358  m->insegments = 0;
7359  }
7360  if (!b->poly)
7361  {
7362  /* Enclose the convex hull with subsegments. */
7363 
7364  markhull(m, b);
7365  }
7366 }
7367 
7368 /** **/
7369 /** **/
7370 /********* Segment insertion ends here *********/
7371 
7372 /********* Carving out holes and concavities begins here *********/
7373 /** **/
7374 /** **/
7375 
7376 /*****************************************************************************/
7377 /* */
7378 /* infecthull() Virally infect all of the triangles of the convex hull */
7379 /* that are not protected by subsegments. Where there are */
7380 /* subsegments, set boundary markers as appropriate. */
7381 /* */
7382 /*****************************************************************************/
7383 
7384 void DelaunayTriangle::infecthull(struct mesh *m, struct behavior *b)
7385 {
7386  struct otri hulltri;
7387  struct otri nexttri;
7388  struct otri starttri;
7389  struct osub hullsubseg;
7390  triangle **deadtriangle;
7391  vertex horg, hdest;
7392  triangle ptr; /* Temporary variable used by sym(). */
7393  subseg sptr; /* Temporary variable used by tspivot(). */
7394 
7395  /* Find a triangle handle on the hull. */
7396  hulltri.tri = m->dummytri;
7397  hulltri.orient = 0;
7398  symself(hulltri);
7399  /* Remember where we started so we know when to stop. */
7400  otricopy(hulltri, starttri);
7401  /* Go once counterclockwise around the convex hull. */
7402  do
7403  {
7404  /* Ignore triangles that are already infected. */
7405  if (!infected(hulltri))
7406  {
7407  /* Is the triangle protected by a subsegment? */
7408  tspivot(hulltri, hullsubseg);
7409  if (hullsubseg.ss == m->dummysub)
7410  {
7411  /* The triangle is not protected; infect it. */
7412  if (!infected(hulltri))
7413  {
7414  infect(hulltri);
7415  deadtriangle = (triangle **)poolalloc(&m->viri);
7416  *deadtriangle = hulltri.tri;
7417  }
7418  }
7419  else
7420  {
7421  /* The triangle is protected; set boundary markers if
7422  * appropriate. */
7423  if (mark(hullsubseg) == 0)
7424  {
7425  setmark(hullsubseg, 1);
7426  org(hulltri, horg);
7427  dest(hulltri, hdest);
7428  if (vertexmark(horg) == 0)
7429  {
7430  setvertexmark(horg, 1);
7431  }
7432  if (vertexmark(hdest) == 0)
7433  {
7434  setvertexmark(hdest, 1);
7435  }
7436  }
7437  }
7438  }
7439  /* To find the next hull edge, go clockwise around the next vertex. */
7440  lnextself(hulltri);
7441  oprev(hulltri, nexttri);
7442  while (nexttri.tri != m->dummytri)
7443  {
7444  otricopy(nexttri, hulltri);
7445  oprev(hulltri, nexttri);
7446  }
7447  } while (!otriequal(hulltri, starttri));
7448 }
7449 
7450 /*****************************************************************************/
7451 /* */
7452 /* plague() Spread the virus from all infected triangles to any neighbors */
7453 /* not protected by subsegments. Delete all infected triangles. */
7454 /* */
7455 /* This is the procedure that actually creates holes and concavities. */
7456 /* */
7457 /* This procedure operates in two phases. The first phase identifies all */
7458 /* the triangles that will die, and marks them as infected. They are */
7459 /* marked to ensure that each triangle is added to the virus pool only */
7460 /* once, so the procedure will terminate. */
7461 /* */
7462 /* The second phase actually eliminates the infected triangles. It also */
7463 /* eliminates orphaned vertices. */
7464 /* */
7465 /*****************************************************************************/
7466 
7467 void DelaunayTriangle::plague(struct mesh *m, struct behavior *b)
7468 {
7469  struct otri testtri;
7470  struct otri neighbor;
7471  triangle **virusloop;
7472  triangle **deadtriangle;
7473  struct osub neighborsubseg;
7474  vertex testvertex;
7475  vertex norg, ndest;
7476  int killorg;
7477  triangle ptr; /* Temporary variable used by sym() and onext(). */
7478  subseg sptr; /* Temporary variable used by tspivot(). */
7479 
7480  /* Loop through all the infected triangles, spreading the virus to */
7481  /* their neighbors, then to their neighbors' neighbors. */
7482  traversalinit(&m->viri);
7483  virusloop = (triangle **)traverse(&m->viri);
7484  while (virusloop != (triangle **)NULL)
7485  {
7486  testtri.tri = *virusloop;
7487  /* A triangle is marked as infected by messing with one of its pointers
7488  */
7489  /* to subsegments, setting it to an illegal value. Hence, we have to
7490  */
7491  /* temporarily uninfect this triangle so that we can examine its */
7492  /* adjacent subsegments. */
7493  uninfect(testtri);
7494 
7495  /* Check each of the triangle's three neighbors. */
7496  for (testtri.orient = 0; testtri.orient < 3; testtri.orient++)
7497  {
7498  /* Find the neighbor. */
7499  sym(testtri, neighbor);
7500  /* Check for a subsegment between the triangle and its neighbor. */
7501  tspivot(testtri, neighborsubseg);
7502  /* Check if the neighbor is nonexistent or already infected. */
7503  if ((neighbor.tri == m->dummytri) || infected(neighbor))
7504  {
7505  if (neighborsubseg.ss != m->dummysub)
7506  {
7507  /* There is a subsegment separating the triangle from its */
7508  /* neighbor, but both triangles are dying, so the
7509  * subsegment */
7510  /* dies too. */
7511  subsegdealloc(m, neighborsubseg.ss);
7512  if (neighbor.tri != m->dummytri)
7513  {
7514  /* Make sure the subsegment doesn't get deallocated
7515  * again */
7516  /* later when the infected neighbor is visited. */
7517  uninfect(neighbor);
7518  tsdissolve(neighbor);
7519  infect(neighbor);
7520  }
7521  }
7522  }
7523  else
7524  { /* The neighbor exists and is not infected. */
7525  if (neighborsubseg.ss == m->dummysub)
7526  {
7527  /* There is no subsegment protecting the neighbor, so */
7528  /* the neighbor becomes infected. */
7529 
7530  infect(neighbor);
7531  /* Ensure that the neighbor's neighbors will be infected. */
7532  deadtriangle = (triangle **)poolalloc(&m->viri);
7533  *deadtriangle = neighbor.tri;
7534  }
7535  else
7536  { /* The neighbor is protected by a subsegment. */
7537  /* Remove this triangle from the subsegment. */
7538  stdissolve(neighborsubseg);
7539  /* The subsegment becomes a boundary. Set markers
7540  * accordingly. */
7541  if (mark(neighborsubseg) == 0)
7542  {
7543  setmark(neighborsubseg, 1);
7544  }
7545  org(neighbor, norg);
7546  dest(neighbor, ndest);
7547  if (vertexmark(norg) == 0)
7548  {
7549  setvertexmark(norg, 1);
7550  }
7551  if (vertexmark(ndest) == 0)
7552  {
7553  setvertexmark(ndest, 1);
7554  }
7555  }
7556  }
7557  }
7558  /* Remark the triangle as infected, so it doesn't get added to the */
7559  /* virus pool again. */
7560  infect(testtri);
7561  virusloop = (triangle **)traverse(&m->viri);
7562  }
7563 
7564 
7565  traversalinit(&m->viri);
7566  virusloop = (triangle **)traverse(&m->viri);
7567  while (virusloop != (triangle **)NULL)
7568  {
7569  testtri.tri = *virusloop;
7570 
7571  /* Check each of the three corners of the triangle for elimination. */
7572  /* This is done by walking around each vertex, checking if it is */
7573  /* still connected to at least one live triangle. */
7574  for (testtri.orient = 0; testtri.orient < 3; testtri.orient++)
7575  {
7576  org(testtri, testvertex);
7577  /* Check if the vertex has already been tested. */
7578  if (testvertex != (vertex)NULL)
7579  {
7580  killorg = 1;
7581  /* Mark the corner of the triangle as having been tested. */
7582  setorg(testtri, NULL);
7583  /* Walk counterclockwise about the vertex. */
7584  onext(testtri, neighbor);
7585  /* Stop upon reaching a boundary or the starting triangle. */
7586  while ((neighbor.tri != m->dummytri) &&
7587  (!otriequal(neighbor, testtri)))
7588  {
7589  if (infected(neighbor))
7590  {
7591  /* Mark the corner of this triangle as having been
7592  * tested. */
7593  setorg(neighbor, NULL);
7594  }
7595  else
7596  {
7597  /* A live triangle. The vertex survives. */
7598  killorg = 0;
7599  }
7600  /* Walk counterclockwise about the vertex. */
7601  onextself(neighbor);
7602  }
7603  /* If we reached a boundary, we must walk clockwise as well. */
7604  if (neighbor.tri == m->dummytri)
7605  {
7606  /* Walk clockwise about the vertex. */
7607  oprev(testtri, neighbor);
7608  /* Stop upon reaching a boundary. */
7609  while (neighbor.tri != m->dummytri)
7610  {
7611  if (infected(neighbor))
7612  {
7613  /* Mark the corner of this triangle as having been
7614  * tested. */
7615  setorg(neighbor, NULL);
7616  }
7617  else
7618  {
7619  /* A live triangle. The vertex survives. */
7620  killorg = 0;
7621  }
7622  /* Walk clockwise about the vertex. */
7623  oprevself(neighbor);
7624  }
7625  }
7626  if (killorg)
7627  {
7628 
7629  setvertextype(testvertex, UNDEADVERTEX);
7630  m->undeads++;
7631  }
7632  }
7633  }
7634 
7635  /* Record changes in the number of boundary edges, and disconnect */
7636  /* dead triangles from their neighbors. */
7637  for (testtri.orient = 0; testtri.orient < 3; testtri.orient++)
7638  {
7639  sym(testtri, neighbor);
7640  if (neighbor.tri == m->dummytri)
7641  {
7642  /* There is no neighboring triangle on this edge, so this edge
7643  */
7644  /* is a boundary edge. This triangle is being deleted, so
7645  * this */
7646  /* boundary edge is deleted. */
7647  m->hullsize--;
7648  }
7649  else
7650  {
7651  /* Disconnect the triangle from its neighbor. */
7652  dissolve(neighbor);
7653  /* There is a neighboring triangle on this edge, so this edge */
7654  /* becomes a boundary edge when this triangle is deleted. */
7655  m->hullsize++;
7656  }
7657  }
7658  /* Return the dead triangle to the pool of triangles. */
7659  triangledealloc(m, testtri.tri);
7660  virusloop = (triangle **)traverse(&m->viri);
7661  }
7662  /* Empty the virus pool. */
7663  poolrestart(&m->viri);
7664 }
7665 
7666 /*****************************************************************************/
7667 /* */
7668 /* regionplague() Spread regional attributes and/or area constraints */
7669 /* (from a .poly file) throughout the mesh. */
7670 /* */
7671 /* This procedure operates in two phases. The first phase spreads an */
7672 /* attribute and/or an area constraint through a (segment-bounded) region. */
7673 /* The triangles are marked to ensure that each triangle is added to the */
7674 /* virus pool only once, so the procedure will terminate. */
7675 /* */
7676 /* The second phase uninfects all infected triangles, returning them to */
7677 /* normal. */
7678 /* */
7679 /*****************************************************************************/
7680 
7682  struct behavior *b,
7683  double attribute,
7684  double area)
7685 {
7686  struct otri testtri;
7687  struct otri neighbor;
7688  triangle **virusloop;
7689  triangle **regiontri;
7690  struct osub neighborsubseg;
7691  triangle ptr; /* Temporary variable used by sym() and onext(). */
7692  subseg sptr; /* Temporary variable used by tspivot(). */
7693 
7694 
7695  /* Loop through all the infected triangles, spreading the attribute */
7696  /* and/or area constraint to their neighbors, then to their neighbors' */
7697  /* neighbors. */
7698  traversalinit(&m->viri);
7699  virusloop = (triangle **)traverse(&m->viri);
7700  while (virusloop != (triangle **)NULL)
7701  {
7702  testtri.tri = *virusloop;
7703  /* A triangle is marked as infected by messing with one of its pointers
7704  */
7705  /* to subsegments, setting it to an illegal value. Hence, we have to
7706  */
7707  /* temporarily uninfect this triangle so that we can examine its */
7708  /* adjacent subsegments. */
7709  uninfect(testtri);
7710 
7711  /* Check each of the triangle's three neighbors. */
7712  for (testtri.orient = 0; testtri.orient < 3; testtri.orient++)
7713  {
7714  /* Find the neighbor. */
7715  sym(testtri, neighbor);
7716  /* Check for a subsegment between the triangle and its neighbor. */
7717  tspivot(testtri, neighborsubseg);
7718  /* Make sure the neighbor exists, is not already infected, and */
7719  /* isn't protected by a subsegment. */
7720  if ((neighbor.tri != m->dummytri) && !infected(neighbor) &&
7721  (neighborsubseg.ss == m->dummysub))
7722  {
7723 
7724  /* Infect the neighbor. */
7725  infect(neighbor);
7726  /* Ensure that the neighbor's neighbors will be infected. */
7727  regiontri = (triangle **)poolalloc(&m->viri);
7728  *regiontri = neighbor.tri;
7729  }
7730  }
7731  /* Remark the triangle as infected, so it doesn't get added to the */
7732  /* virus pool again. */
7733  infect(testtri);
7734  virusloop = (triangle **)traverse(&m->viri);
7735  }
7736 
7737  /* Uninfect all triangles. */
7738 
7739  traversalinit(&m->viri);
7740  virusloop = (triangle **)traverse(&m->viri);
7741  while (virusloop != (triangle **)NULL)
7742  {
7743  testtri.tri = *virusloop;
7744  uninfect(testtri);
7745  virusloop = (triangle **)traverse(&m->viri);
7746  }
7747  /* Empty the virus pool. */
7748  poolrestart(&m->viri);
7749 }
7750 
7751 /*****************************************************************************/
7752 /* */
7753 /* carveholes() Find the holes and infect them. Find the area */
7754 /* constraints and infect them. Infect the convex hull. */
7755 /* Spread the infection and kill triangles. Spread the */
7756 /* area constraints. */
7757 /* */
7758 /* This routine mainly calls other routines to carry out all these */
7759 /* functions. */
7760 /* */
7761 /*****************************************************************************/
7762 
7764  struct behavior *b,
7765  double *holelist,
7766  int holes,
7767  double *regionlist,
7768  int regions)
7769 {
7770  struct otri searchtri;
7771  struct otri *regiontris;
7772  triangle **holetri;
7773  triangle **regiontri;
7774  vertex searchorg, searchdest;
7775  enum locateresult intersect;
7776  int i;
7777  triangle ptr; /* Temporary variable used by sym(). */
7778 
7779  if (regions > 0)
7780  {
7781  /* Allocate storage for the triangles in which region points fall. */
7782  regiontris =
7783  (struct otri *)trimalloc(regions * (int)sizeof(struct otri));
7784  }
7785  else
7786  {
7787  regiontris = (struct otri *)NULL;
7788  }
7789 
7790 
7791  /* Initialize a pool of viri to be used for holes, concavities, */
7792  /* regional attributes, and/or regional area constraints. */
7793  poolinit(&m->viri, sizeof(triangle *), VIRUSPERBLOCK, VIRUSPERBLOCK, 0);
7794 
7795  /* Mark as infected any unprotected triangles on the boundary. */
7796  /* This is one way by which concavities are created. */
7797  infecthull(m, b);
7798 
7799  if (holes > 0)
7800  {
7801  /* Infect each triangle in which a hole lies. */
7802  for (i = 0; i < 2 * holes; i += 2)
7803  {
7804  /* Ignore holes that aren't within the bounds of the mesh. */
7805  if ((holelist[i] >= m->xmin) && (holelist[i] <= m->xmax) &&
7806  (holelist[i + 1] >= m->ymin) && (holelist[i + 1] <= m->ymax))
7807  {
7808  /* Start searching from some triangle on the outer boundary. */
7809  searchtri.tri = m->dummytri;
7810  searchtri.orient = 0;
7811  symself(searchtri);
7812  /* Ensure that the hole is to the left of this boundary edge; */
7813  /* otherwise, locate() will falsely report that the hole */
7814  /* falls within the starting triangle. */
7815  org(searchtri, searchorg);
7816  dest(searchtri, searchdest);
7817  if (counterclockwise(
7818  m, b, searchorg, searchdest, &holelist[i]) > 0.0)
7819  {
7820  /* Find a triangle that contains the hole. */
7821  intersect = locate(m, b, &holelist[i], &searchtri);
7822  if ((intersect != OUTSIDE) && (!infected(searchtri)))
7823  {
7824  /* Infect the triangle. This is done by marking the
7825  * triangle */
7826  /* as infected and including the triangle in the virus
7827  * pool. */
7828  infect(searchtri);
7829  holetri = (triangle **)poolalloc(&m->viri);
7830  *holetri = searchtri.tri;
7831  }
7832  }
7833  }
7834  }
7835  }
7836 
7837  /* Now, we have to find all the regions BEFORE we carve the holes, because
7838  */
7839  /* locate() won't work when the triangulation is no longer convex. */
7840  /* (Incidentally, this is the reason why regional attributes and area */
7841  /* constraints can't be used when refining a preexisting mesh, which */
7842  /* might not be convex; they can only be used with a freshly */
7843  /* triangulated PSLG.) */
7844  if (regions > 0)
7845  {
7846  /* Find the starting triangle for each region. */
7847  for (i = 0; i < regions; i++)
7848  {
7849  regiontris[i].tri = m->dummytri;
7850  /* Ignore region points that aren't within the bounds of the mesh.
7851  */
7852  if ((regionlist[4 * i] >= m->xmin) &&
7853  (regionlist[4 * i] <= m->xmax) &&
7854  (regionlist[4 * i + 1] >= m->ymin) &&
7855  (regionlist[4 * i + 1] <= m->ymax))
7856  {
7857  /* Start searching from some triangle on the outer boundary. */
7858  searchtri.tri = m->dummytri;
7859  searchtri.orient = 0;
7860  symself(searchtri);
7861  /* Ensure that the region point is to the left of this boundary
7862  */
7863  /* edge; otherwise, locate() will falsely report that the */
7864  /* region point falls within the starting triangle. */
7865  org(searchtri, searchorg);
7866  dest(searchtri, searchdest);
7867  if (counterclockwise(
7868  m, b, searchorg, searchdest, &regionlist[4 * i]) > 0.0)
7869  {
7870  /* Find a triangle that contains the region point. */
7871  intersect = locate(m, b, &regionlist[4 * i], &searchtri);
7872  if ((intersect != OUTSIDE) && (!infected(searchtri)))
7873  {
7874  /* Record the triangle for processing after the */
7875  /* holes have been carved. */
7876  otricopy(searchtri, regiontris[i]);
7877  }
7878  }
7879  }
7880  }
7881  }
7882 
7883  if (m->viri.items > 0)
7884  {
7885  /* Carve the holes and concavities. */
7886  plague(m, b);
7887  }
7888  /* The virus pool should be empty now. */
7889 
7890  if (regions > 0)
7891  {
7892  for (i = 0; i < regions; i++)
7893  {
7894  if (regiontris[i].tri != m->dummytri)
7895  {
7896  /* Make sure the triangle under consideration still exists. */
7897  /* It may have been eaten by the virus. */
7898  if (!deadtri(regiontris[i].tri))
7899  {
7900  /* Put one triangle in the virus pool. */
7901  infect(regiontris[i]);
7902  regiontri = (triangle **)poolalloc(&m->viri);
7903  *regiontri = regiontris[i].tri;
7904  /* Apply one region's attribute and/or area constraint. */
7905  regionplague(
7906  m, b, regionlist[4 * i + 2], regionlist[4 * i + 3]);
7907  /* The virus pool should be empty now. */
7908  }
7909  }
7910  }
7911  }
7912 
7913 
7914  pooldeinit(&m->viri);
7915 
7916  if (regions > 0)
7917  {
7918  trifree((void *)regiontris);
7919  }
7920 }
7921 
7922 /** **/
7923 /** **/
7924 /********* Carving out holes and concavities ends here *********/
7925 
7926 /********* Mesh quality maintenance begins here *********/
7927 /** **/
7928 /** **/
7929 
7930 /*****************************************************************************/
7931 /* */
7932 /* tallyencs() Traverse the entire list of subsegments, and check each */
7933 /* to see if it is encroached. If so, add it to the list. */
7934 /* */
7935 /*****************************************************************************/
7936 
7937 void DelaunayTriangle::tallyencs(struct mesh *m, struct behavior *b)
7938 {
7939  struct osub subsegloop;
7940 
7941  traversalinit(&m->subsegs);
7942  subsegloop.ssorient = 0;
7943  subsegloop.ss = subsegtraverse(m);
7944  while (subsegloop.ss != (subseg *)NULL)
7945  {
7946  /* If the segment is encroached, add it to the list. */
7947  checkseg4encroach(m, b, &subsegloop);
7948  subsegloop.ss = subsegtraverse(m);
7949  }
7950 }
7951 
7952 /*****************************************************************************/
7953 /* */
7954 /* precisionerror() Print an error message for precision problems. */
7955 /* */
7956 /*****************************************************************************/
7957 
7959 {
7960  printf("Try increasing the area criterion and/or reducing the minimum\n");
7961  printf(" allowable angle so that tiny triangles are not created.\n");
7962 #ifdef SINGLE
7963  printf("Alternatively, try recompiling me with double precision\n");
7964  printf(" arithmetic (by removing \"#define SINGLE\" from the\n");
7965  printf(" source file or \"-DSINGLE\" from the makefile).\n");
7966 #endif /* SINGLE */
7967 }
7968 
7969 /*****************************************************************************/
7970 /* */
7971 /* splitencsegs() Split all the encroached subsegments. */
7972 /* */
7973 /* Each encroached subsegment is repaired by splitting it - inserting a */
7974 /* vertex at or near its midpoint. Newly inserted vertices may encroach */
7975 /* upon other subsegments; these are also repaired. */
7976 /* */
7977 /* `triflaws' is a flag that specifies whether one should take note of new */
7978 /* bad triangles that result from inserting vertices to repair encroached */
7979 /* subsegments. */
7980 /* */
7981 /*****************************************************************************/
7982 
7983 void DelaunayTriangle::splitencsegs(struct mesh *m, struct behavior *b, int triflaws)
7984 {
7985  struct otri enctri;
7986  struct otri testtri;
7987  struct osub testsh;
7988  struct osub currentenc;
7989  struct badsubseg *encloop;
7990  vertex eorg, edest, eapex;
7991  vertex newvertex;
7992  enum insertvertexresult success;
7993  double segmentlength, nearestpoweroftwo;
7994  double split;
7995  double multiplier, divisor;
7996  int acuteorg, acuteorg2, acutedest, acutedest2;
7997  int i;
7998  triangle ptr; /* Temporary variable used by stpivot(). */
7999  subseg sptr; /* Temporary variable used by snext(). */
8000 
8001  /* Note that steinerleft == -1 if an unlimited number */
8002  /* of Steiner points is allowed. */
8003  while ((m->badsubsegs.items > 0) && (m->steinerleft != 0))
8004  {
8006  encloop = badsubsegtraverse(m);
8007  while ((encloop != (struct badsubseg *)NULL) && (m->steinerleft != 0))
8008  {
8009  sdecode(encloop->encsubseg, currentenc);
8010  sorg(currentenc, eorg);
8011  sdest(currentenc, edest);
8012  /* Make sure that this segment is still the same segment it was */
8013  /* when it was determined to be encroached. If the segment was */
8014  /* enqueued multiple times (because several newly inserted */
8015  /* vertices encroached it), it may have already been split. */
8016  if (!deadsubseg(currentenc.ss) && (eorg == encloop->subsegorg) &&
8017  (edest == encloop->subsegdest))
8018  {
8019  /* To decide where to split a segment, we need to know if the */
8020  /* segment shares an endpoint with an adjacent segment. */
8021  /* The concern is that, if we simply split every encroached */
8022  /* segment in its center, two adjacent segments with a small
8023  */
8024  /* angle between them might lead to an infinite loop; each */
8025  /* vertex added to split one segment will encroach upon the */
8026  /* other segment, which must then be split with a vertex that
8027  */
8028  /* will encroach upon the first segment, and so on forever. */
8029  /* To avoid this, imagine a set of concentric circles, whose */
8030  /* radii are powers of two, about each segment endpoint. */
8031  /* These concentric circles determine where the segment is */
8032  /* split. (If both endpoints are shared with adjacent */
8033  /* segments, split the segment in the middle, and apply the */
8034  /* concentric circles for later splittings.) */
8035 
8036  /* Is the origin shared with another segment? */
8037  stpivot(currentenc, enctri);
8038  lnext(enctri, testtri);
8039  tspivot(testtri, testsh);
8040  acuteorg = testsh.ss != m->dummysub;
8041  /* Is the destination shared with another segment? */
8042  lnextself(testtri);
8043  tspivot(testtri, testsh);
8044  acutedest = testsh.ss != m->dummysub;
8045 
8046  /* If we're using Chew's algorithm (rather than Ruppert's) */
8047  /* to define encroachment, delete free vertices from the */
8048  /* subsegment's diametral circle. */
8049  if (!acuteorg && !acutedest)
8050  {
8051  apex(enctri, eapex);
8052  while ((vertextype(eapex) == FREEVERTEX) &&
8053  ((eorg[0] - eapex[0]) * (edest[0] - eapex[0]) +
8054  (eorg[1] - eapex[1]) * (edest[1] - eapex[1]) <
8055  0.0))
8056  {
8057  deletevertex(m, b, &testtri);
8058  stpivot(currentenc, enctri);
8059  apex(enctri, eapex);
8060  lprev(enctri, testtri);
8061  }
8062  }
8063 
8064  /* Now, check the other side of the segment, if there's a
8065  * triangle */
8066  /* there. */
8067  sym(enctri, testtri);
8068  if (testtri.tri != m->dummytri)
8069  {
8070  /* Is the destination shared with another segment? */
8071  lnextself(testtri);
8072  tspivot(testtri, testsh);
8073  acutedest2 = testsh.ss != m->dummysub;
8074  acutedest = acutedest || acutedest2;
8075  /* Is the origin shared with another segment? */
8076  lnextself(testtri);
8077  tspivot(testtri, testsh);
8078  acuteorg2 = testsh.ss != m->dummysub;
8079  acuteorg = acuteorg || acuteorg2;
8080 
8081  /* Delete free vertices from the subsegment's diametral
8082  * circle. */
8083  if (!acuteorg2 && !acutedest2)
8084  {
8085  org(testtri, eapex);
8086  while (
8087  (vertextype(eapex) == FREEVERTEX) &&
8088  ((eorg[0] - eapex[0]) * (edest[0] - eapex[0]) +
8089  (eorg[1] - eapex[1]) * (edest[1] - eapex[1]) <
8090  0.0))
8091  {
8092  deletevertex(m, b, &testtri);
8093  sym(enctri, testtri);
8094  apex(testtri, eapex);
8095  lprevself(testtri);
8096  }
8097  }
8098  }
8099 
8100  /* Use the concentric circles if exactly one endpoint is shared
8101  */
8102  /* with another adjacent segment. */
8103  if (acuteorg || acutedest)
8104  {
8105  segmentlength =
8106  sqrt((edest[0] - eorg[0]) * (edest[0] - eorg[0]) +
8107  (edest[1] - eorg[1]) * (edest[1] - eorg[1]));
8108  /* Find the power of two that most evenly splits the
8109  * segment. */
8110  /* The worst case is a 2:1 ratio between subsegment
8111  * lengths. */
8112  nearestpoweroftwo = 1.0;
8113  while (segmentlength > 3.0 * nearestpoweroftwo)
8114  {
8115  nearestpoweroftwo *= 2.0;
8116  }
8117  while (segmentlength < 1.5 * nearestpoweroftwo)
8118  {
8119  nearestpoweroftwo *= 0.5;
8120  }
8121  /* Where do we split the segment? */
8122  split = nearestpoweroftwo / segmentlength;
8123  if (acutedest)
8124  {
8125  split = 1.0 - split;
8126  }
8127  }
8128  else
8129  {
8130  /* If we're not worried about adjacent segments, split */
8131  /* this segment in the middle. */
8132  split = 0.5;
8133  }
8134 
8135  /* Create the new vertex. */
8136  newvertex = (vertex)poolalloc(&m->vertices);
8137  /* Interpolate its coordinate and attributes. */
8138  for (i = 0; i < 2 + m->nextras; i++)
8139  {
8140  newvertex[i] = eorg[i] + split * (edest[i] - eorg[i]);
8141  }
8142 
8143  /* Roundoff in the above calculation may yield a `newvertex'
8144  */
8145  /* that is not precisely collinear with `eorg' and
8146  * `edest'. */
8147  /* Improve collinearity by one step of iterative
8148  * refinement. */
8149  multiplier = counterclockwise(m, b, eorg, edest, newvertex);
8150  divisor = ((eorg[0] - edest[0]) * (eorg[0] - edest[0]) +
8151  (eorg[1] - edest[1]) * (eorg[1] - edest[1]));
8152  if ((multiplier != 0.0) && (divisor != 0.0))
8153  {
8154  multiplier = multiplier / divisor;
8155  /* Watch out for NANs. */
8156  if (multiplier == multiplier)
8157  {
8158  newvertex[0] += multiplier * (edest[1] - eorg[1]);
8159  newvertex[1] += multiplier * (eorg[0] - edest[0]);
8160  }
8161  }
8162 
8163  setvertexmark(newvertex, mark(currentenc));
8164  setvertextype(newvertex, SEGMENTVERTEX);
8165 
8166  /* Check whether the new vertex lies on an endpoint. */
8167  if (((newvertex[0] == eorg[0]) && (newvertex[1] == eorg[1])) ||
8168  ((newvertex[0] == edest[0]) && (newvertex[1] == edest[1])))
8169  {
8170  printf("Error: Ran out of precision at (%.12g, %.12g).\n",
8171  newvertex[0],
8172  newvertex[1]);
8173  printf("I attempted to split a segment to a smaller size "
8174  "than\n");
8175  printf(
8176  " can be accommodated by the finite precision of\n");
8177  printf(" floating point arithmetic.\n");
8178  precisionerror();
8179  triexit(1);
8180  }
8181  /* Insert the splitting vertex. This should always succeed. */
8182  success = insertvertex(
8183  m, b, newvertex, &enctri, &currentenc, 1, triflaws);
8184  if ((success != SUCCESSFULVERTEX) &&
8185  (success != ENCROACHINGVERTEX))
8186  {
8187  printf("Internal error in splitencsegs():\n");
8188  printf(" Failure to split a segment.\n");
8189  internalerror();
8190  }
8191  if (m->steinerleft > 0)
8192  {
8193  m->steinerleft--;
8194  }
8195  /* Check the two new subsegments to see if they're encroached.
8196  */
8197  checkseg4encroach(m, b, &currentenc);
8198  snextself(currentenc);
8199  checkseg4encroach(m, b, &currentenc);
8200  }
8201 
8202  badsubsegdealloc(m, encloop);
8203  encloop = badsubsegtraverse(m);
8204  }
8205  }
8206 }
8207 
8208 /*****************************************************************************/
8209 /* */
8210 /* tallyfaces() Test every triangle in the mesh for quality measures. */
8211 /* */
8212 /*****************************************************************************/
8213 
8214 void DelaunayTriangle::tallyfaces(struct mesh *m, struct behavior *b)
8215 {
8216  struct otri triangleloop;
8217 
8218 
8219  traversalinit(&m->triangles);
8220  triangleloop.orient = 0;
8221  triangleloop.tri = triangletraverse(m);
8222  while (triangleloop.tri != (triangle *)NULL)
8223  {
8224  /* If the triangle is bad, enqueue it. */
8225  testtriangle(m, b, &triangleloop);
8226  triangleloop.tri = triangletraverse(m);
8227  }
8228 }
8229 
8230 /*****************************************************************************/
8231 /* */
8232 /* splittriangle() Inserts a vertex at the circumcenter of a triangle. */
8233 /* Deletes the newly inserted vertex if it encroaches */
8234 /* upon a segment. */
8235 /* */
8236 /*****************************************************************************/
8237 
8238 void DelaunayTriangle::splittriangle(struct mesh *m, struct behavior *b, struct badtriang *badtri)
8239 {
8240  struct otri badotri;
8241  vertex borg, bdest, bapex;
8242  vertex newvertex;
8243  double xi, eta;
8244  enum insertvertexresult success;
8245  int errorflag;
8246  int i;
8247 
8248  decode(badtri->poortri, badotri);
8249  org(badotri, borg);
8250  dest(badotri, bdest);
8251  apex(badotri, bapex);
8252  /* Make sure that this triangle is still the same triangle it was */
8253  /* when it was tested and determined to be of bad quality. */
8254  /* Subsequent transformations may have made it a different triangle. */
8255  if (!deadtri(badotri.tri) && (borg == badtri->triangorg) &&
8256  (bdest == badtri->triangdest) && (bapex == badtri->triangapex))
8257  {
8258 
8259 
8260  errorflag = 0;
8261  /* Create a new vertex at the triangle's circumcenter. */
8262  newvertex = (vertex)poolalloc(&m->vertices);
8263  findcircumcenter(m, b, borg, bdest, bapex, newvertex, &xi, &eta, 1);
8264 
8265  /* Check whether the new vertex lies on a triangle vertex. */
8266  if (((newvertex[0] == borg[0]) && (newvertex[1] == borg[1])) ||
8267  ((newvertex[0] == bdest[0]) && (newvertex[1] == bdest[1])) ||
8268  ((newvertex[0] == bapex[0]) && (newvertex[1] == bapex[1])))
8269  {
8270  vertexdealloc(m, newvertex);
8271  }
8272  else
8273  {
8274  for (i = 2; i < 2 + m->nextras; i++)
8275  {
8276  /* Interpolate the vertex attributes at the circumcenter. */
8277  newvertex[i] = borg[i] + xi * (bdest[i] - borg[i]) +
8278  eta * (bapex[i] - borg[i]);
8279  }
8280  /* The new vertex must be in the interior, and therefore is a */
8281  /* free vertex with a marker of zero. */
8282  setvertexmark(newvertex, 0);
8283  setvertextype(newvertex, FREEVERTEX);
8284 
8285  /* Ensure that the handle `badotri' does not represent the longest
8286  */
8287  /* edge of the triangle. This ensures that the circumcenter must
8288  */
8289  /* fall to the left of this edge, so point location will work. */
8290  /* (If the angle org-apex-dest exceeds 90 degrees, then the */
8291  /* circumcenter lies outside the org-dest edge, and eta is */
8292  /* negative. Roundoff error might prevent eta from being */
8293  /* negative when it should be, so I test eta against xi.) */
8294  if (eta < xi)
8295  {
8296  lprevself(badotri);
8297  }
8298 
8299  /* Insert the circumcenter, searching from the edge of the triangle,
8300  */
8301  /* and maintain the Delaunay property of the triangulation. */
8302  success = insertvertex(
8303  m, b, newvertex, &badotri, (struct osub *)NULL, 1, 1);
8304  if (success == SUCCESSFULVERTEX)
8305  {
8306  if (m->steinerleft > 0)
8307  {
8308  m->steinerleft--;
8309  }
8310  }
8311  else if (success == ENCROACHINGVERTEX)
8312  {
8313  /* If the newly inserted vertex encroaches upon a subsegment, */
8314  /* delete the new vertex. */
8315  undovertex(m, b);
8316 
8317  vertexdealloc(m, newvertex);
8318  }
8319  else if (success == VIOLATINGVERTEX)
8320  {
8321  /* Failed to insert the new vertex, but some subsegment was */
8322  /* marked as being encroached. */
8323  vertexdealloc(m, newvertex);
8324  }
8325  else
8326  { /* success == DUPLICATEVERTEX */
8327  /* Couldn't insert the new vertex because a vertex is already
8328  * there. */
8329 
8330  vertexdealloc(m, newvertex);
8331  }
8332  }
8333  if (errorflag)
8334  {
8335 
8336  printf(
8337  "This probably means that I am trying to refine triangles\n");
8338  printf(
8339  " to a smaller size than can be accommodated by the finite\n");
8340  printf(" precision of floating point arithmetic. (You can be\n");
8341  printf(" sure of this if I fail to terminate.)\n");
8342  precisionerror();
8343  }
8344  }
8345 }
8346 
8347 /*****************************************************************************/
8348 /* */
8349 /* enforcequality() Remove all the encroached subsegments and bad */
8350 /* triangles from the triangulation. */
8351 /* */
8352 /*****************************************************************************/
8353 
8355 {
8356  struct badtriang *badtri;
8357  int i;
8358 
8359  /* Initialize the pool of encroached subsegments. */
8360  poolinit(&m->badsubsegs,
8361  sizeof(struct badsubseg),
8364  0);
8365 
8366  /* Test all segments to see if they're encroached. */
8367  tallyencs(m, b);
8368 
8369  /* Fix encroached subsegments without noting bad triangles. */
8370  splitencsegs(m, b, 0);
8371  /* At this point, if we haven't run out of Steiner points, the */
8372  /* triangulation should be (conforming) Delaunay. */
8373 
8374  /* Next, we worry about enforcing triangle quality. */
8375  if ((b->minangle > 0.0) || b->usertest)
8376  {
8377  /* Initialize the pool of bad triangles. */
8378  poolinit(&m->badtriangles,
8379  sizeof(struct badtriang),
8382  0);
8383  /* Initialize the queues of bad triangles. */
8384  for (i = 0; i < 4096; i++)
8385  {
8386  m->queuefront[i] = (struct badtriang *)NULL;
8387  }
8388  m->firstnonemptyq = -1;
8389  /* Test all triangles to see if they're bad. */
8390  tallyfaces(m, b);
8391  /* Initialize the pool of recently flipped triangles. */
8392  poolinit(&m->flipstackers,
8393  sizeof(struct flipstacker),
8396  0);
8397  m->checkquality = 1;
8398 
8399  while ((m->badtriangles.items > 0) && (m->steinerleft != 0))
8400  {
8401  /* Fix one bad triangle by inserting a vertex at its circumcenter.
8402  */
8403  badtri = dequeuebadtriang(m);
8404  splittriangle(m, b, badtri);
8405  if (m->badsubsegs.items > 0)
8406  {
8407  /* Put bad triangle back in queue for another try later. */
8408  enqueuebadtriang(m, b, badtri);
8409  /* Fix any encroached subsegments that resulted. */
8410  /* Record any new bad triangles that result. */
8411  splitencsegs(m, b, 1);
8412  }
8413  else
8414  {
8415  /* Return the bad triangle to the pool. */
8416  pooldealloc(&m->badtriangles, (void *)badtri);
8417  }
8418  }
8419  }
8420  /* At this point, if the "-D" switch was selected and we haven't run out */
8421  /* of Steiner points, the triangulation should be (conforming) Delaunay */
8422  /* and have no low-quality triangles. */
8423 
8424 }
8425 
8426 /** **/
8427 /** **/
8428 /********* Mesh quality maintenance ends here *********/
8429 
8430 
8431 /********* File I/O routines begin here *********/
8432 /** **/
8433 /** **/
8434 
8435 /*****************************************************************************/
8436 /* */
8437 /* transfernodes() Read the vertices from memory. */
8438 /* */
8439 /*****************************************************************************/
8440 
8442  struct behavior *b,
8443  double *pointlist,
8444  double *pointattriblist,
8445  int *pointmarkerlist,
8446  int numberofpoints,
8447  int numberofpointattribs)
8448 {
8449  vertex vertexloop;
8450  double x, y;
8451  int i, j;
8452  int coordindex;
8453  int attribindex;
8454 
8455  m->invertices = numberofpoints;
8456  m->mesh_dim = 2;
8457  m->nextras = numberofpointattribs;
8458  m->readnodefile = 0;
8459  if (m->invertices < 3)
8460  {
8461  printf("Error: Input must have at least three input vertices.\n");
8462  triexit(1);
8463  }
8464  if (m->nextras == 0)
8465  {
8466  b->weighted = 0;
8467  }
8468 
8469  initializevertexpool(m, b);
8470 
8471  /* Read the vertices. */
8472  coordindex = 0;
8473  attribindex = 0;
8474  for (i = 0; i < m->invertices; i++)
8475  {
8476  vertexloop = (vertex)poolalloc(&m->vertices);
8477  /* Read the vertex coordinates. */
8478  x = vertexloop[0] = pointlist[coordindex++];
8479  y = vertexloop[1] = pointlist[coordindex++];
8480  /* Read the vertex attributes. */
8481  for (j = 0; j < numberofpointattribs; j++)
8482  {
8483  vertexloop[2 + j] = pointattriblist[attribindex++];
8484  }
8485  if (pointmarkerlist != (int *)NULL)
8486  {
8487  /* Read a vertex marker. */
8488  setvertexmark(vertexloop, pointmarkerlist[i]);
8489  }
8490  else
8491  {
8492  /* If no markers are specified, they default to zero. */
8493  setvertexmark(vertexloop, 0);
8494  }
8495  setvertextype(vertexloop, INPUTVERTEX);
8496  /* Determine the smallest and largest x and y coordinates. */
8497  if (i == 0)
8498  {
8499  m->xmin = m->xmax = x;
8500  m->ymin = m->ymax = y;
8501  }
8502  else
8503  {
8504  m->xmin = (x < m->xmin) ? x : m->xmin;
8505  m->xmax = (x > m->xmax) ? x : m->xmax;
8506  m->ymin = (y < m->ymin) ? y : m->ymin;
8507  m->ymax = (y > m->ymax) ? y : m->ymax;
8508  }
8509  }
8510 
8511  /* Nonexistent x value used as a flag to mark circle events in sweepline */
8512  /* Delaunay algorithm. */
8513  m->xminextreme = 10 * m->xmin - 9 * m->xmax;
8514 }
8515 
8516 /*****************************************************************************/
8517 /* */
8518 /* writenodes() Number the vertices and write them to a .node file. */
8519 /* */
8520 /* To save memory, the vertex numbers are written over the boundary markers */
8521 /* after the vertices are written to a file. */
8522 /* */
8523 /*****************************************************************************/
8524 
8526  struct behavior *b,
8527  double **pointlist,
8528  double **pointattriblist,
8529  int **pointmarkerlist)
8530 {
8531  double *plist;
8532  double *palist;
8533  int *pmlist;
8534  int coordindex;
8535  int attribindex;
8536  vertex vertexloop;
8537  long outvertices;
8538  int vertexnumber;
8539  int i;
8540 
8541  if (b->jettison)
8542  {
8543  outvertices = m->vertices.items - m->undeads;
8544  }
8545  else
8546  {
8547  outvertices = m->vertices.items;
8548  }
8549 
8550  /* Allocate memory for output vertices if necessary. */
8551  if (*pointlist == (double *)NULL)
8552  {
8553  *pointlist =
8554  (double *)trimalloc((int)(outvertices * 2 * sizeof(double)));
8555  }
8556  /* Allocate memory for output vertex attributes if necessary. */
8557  if ((m->nextras > 0) && (*pointattriblist == (double *)NULL))
8558  {
8559  *pointattriblist = (double *)trimalloc(
8560  (int)(outvertices * m->nextras * sizeof(double)));
8561  }
8562  /* Allocate memory for output vertex markers if necessary. */
8563  if (*pointmarkerlist == (int *)NULL)
8564  {
8565  *pointmarkerlist = (int *)trimalloc((int)(outvertices * sizeof(int)));
8566  }
8567  plist = *pointlist;
8568  palist = *pointattriblist;
8569  pmlist = *pointmarkerlist;
8570  coordindex = 0;
8571  attribindex = 0;
8572 
8573  traversalinit(&m->vertices);
8574  vertexnumber = 0;
8575  vertexloop = vertextraverse(m);
8576  while (vertexloop != (vertex)NULL)
8577  {
8578  if (!b->jettison || (vertextype(vertexloop) != UNDEADVERTEX))
8579  {
8580  /* X and y coordinates. */
8581  plist[coordindex++] = vertexloop[0];
8582  plist[coordindex++] = vertexloop[1];
8583  /* Vertex attributes. */
8584  for (i = 0; i < m->nextras; i++)
8585  {
8586  palist[attribindex++] = vertexloop[2 + i];
8587  }
8588 
8589  /* Copy the boundary marker. */
8590  pmlist[vertexnumber] = vertexmark(vertexloop);
8591 
8592  setvertexmark(vertexloop, vertexnumber);
8593  vertexnumber++;
8594  }
8595  vertexloop = vertextraverse(m);
8596  }
8597 }
8598 
8599 /*****************************************************************************/
8600 /* */
8601 /* numbernodes() Number the vertices. */
8602 /* */
8603 /* Each vertex is assigned a marker equal to its number. */
8604 /* */
8605 /* Used when writenodes() is not called because no .node file is written. */
8606 /* */
8607 /*****************************************************************************/
8608 
8609 void DelaunayTriangle::numbernodes(struct mesh *m, struct behavior *b)
8610 {
8611  vertex vertexloop;
8612  int vertexnumber;
8613 
8614  traversalinit(&m->vertices);
8615  vertexnumber = 0;
8616  vertexloop = vertextraverse(m);
8617  while (vertexloop != (vertex)NULL)
8618  {
8619  setvertexmark(vertexloop, vertexnumber);
8620  if (!b->jettison || (vertextype(vertexloop) != UNDEADVERTEX))
8621  {
8622  vertexnumber++;
8623  }
8624  vertexloop = vertextraverse(m);
8625  }
8626 }
8627 
8628 /*****************************************************************************/
8629 /* */
8630 /* writeelements() Write the triangles to an .ele file. */
8631 /* */
8632 /*****************************************************************************/
8633 
8635  struct behavior *b,
8636  int **trianglelist,
8637  double **triangleattriblist)
8638 {
8639  int *tlist;
8640  double *talist;
8641  int vertexindex;
8642  int attribindex;
8643  struct otri triangleloop;
8644  vertex p1, p2, p3;
8645  long elementnumber;
8646  int i;
8647 
8648  /* Allocate memory for output triangles if necessary. */
8649  if (*trianglelist == (int *)NULL)
8650  {
8651  *trianglelist = (int *)trimalloc(
8652  (int)(m->triangles.items * 3 *
8653  sizeof(int)));
8654  }
8655  /* Allocate memory for output triangle attributes if necessary. */
8656  if ((m->eextras > 0) && (*triangleattriblist == (double *)NULL))
8657  {
8658  *triangleattriblist = (double *)trimalloc(
8659  (int)(m->triangles.items * m->eextras * sizeof(double)));
8660  }
8661  tlist = *trianglelist;
8662  talist = *triangleattriblist;
8663  vertexindex = 0;
8664  attribindex = 0;
8665 
8666  traversalinit(&m->triangles);
8667  triangleloop.tri = triangletraverse(m);
8668  triangleloop.orient = 0;
8669  elementnumber = 0;
8670  while (triangleloop.tri != (triangle *)NULL)
8671  {
8672  org(triangleloop, p1);
8673  dest(triangleloop, p2);
8674  apex(triangleloop, p3);
8675 
8676  tlist[vertexindex++] = vertexmark(p1);
8677  tlist[vertexindex++] = vertexmark(p2);
8678  tlist[vertexindex++] = vertexmark(p3);
8679 
8680 
8681 
8682  for (i = 0; i < m->eextras; i++)
8683  {
8684  talist[attribindex++] = elemattribute(triangleloop, i);
8685  }
8686 
8687  triangleloop.tri = triangletraverse(m);
8688  elementnumber++;
8689  }
8690 }
8691 
8692 /*****************************************************************************/
8693 /* */
8694 /* writepoly() Write the segments and holes to a .poly file. */
8695 /* */
8696 /*****************************************************************************/
8697 
8699  struct behavior *b,
8700  int **segmentlist,
8701  int **segmentmarkerlist)
8702 {
8703  int *slist;
8704  int *smlist;
8705  int index;
8706  struct osub subsegloop;
8707  vertex endpoint1, endpoint2;
8708  long subsegnumber;
8709 
8710  /* Allocate memory for output segments if necessary. */
8711  if (*segmentlist == (int *)NULL)
8712  {
8713  *segmentlist =
8714  (int *)trimalloc((int)(m->subsegs.items * 2 * sizeof(int)));
8715  }
8716  /* Allocate memory for output segment markers if necessary. */
8717  if (*segmentmarkerlist == (int *)NULL)
8718  {
8719  *segmentmarkerlist =
8720  (int *)trimalloc((int)(m->subsegs.items * sizeof(int)));
8721  }
8722  slist = *segmentlist;
8723  smlist = *segmentmarkerlist;
8724  index = 0;
8725 
8726  traversalinit(&m->subsegs);
8727  subsegloop.ss = subsegtraverse(m);
8728  subsegloop.ssorient = 0;
8729  subsegnumber = 0;
8730  while (subsegloop.ss != (subseg *)NULL)
8731  {
8732  sorg(subsegloop, endpoint1);
8733  sdest(subsegloop, endpoint2);
8734  /* Copy indices of the segment's two endpoints. */
8735  slist[index++] = vertexmark(endpoint1);
8736  slist[index++] = vertexmark(endpoint2);
8737 
8738  /* Copy the boundary marker. */
8739  smlist[subsegnumber] = mark(subsegloop);
8740 
8741  subsegloop.ss = subsegtraverse(m);
8742  subsegnumber++;
8743  }
8744 }
8745 
8746 /** **/
8747 /** **/
8748 /********* File I/O routines end here *********/
8749 
8750 
8751 
8752 /*****************************************************************************/
8753 /* */
8754 /* main() or triangulate() Gosh, do everything. */
8755 /* */
8756 /* The sequence is roughly as follows. Many of these steps can be skipped, */
8757 /* depending on the command line switches. */
8758 /* */
8759 /* - Initialize constants and parse the command line. */
8760 /* - Read the vertices from a file and either */
8761 /* - triangulate them (no -r), or */
8762 /* - read an old mesh from files and reconstruct it (-r). */
8763 /* - Insert the PSLG segments (-p), and possibly segments on the convex */
8764 /* hull (-c). */
8765 /* - Read the holes (-p), regional attributes (-pA), and regional area */
8766 /* constraints (-pa). Carve the holes and concavities, and spread the */
8767 /* regional attributes and area constraints. */
8768 /* - Enforce the constraints on minimum angle (-q) and maximum area (-a). */
8769 /* Also enforce the conforming Delaunay property (-q and -a). */
8770 /* - Compute the number of edges in the resulting mesh. */
8771 /* - Promote the mesh's linear triangles to higher order elements (-o). */
8772 /* - Write the output files and print the statistics. */
8773 /* - Check the consistency and Delaunay property of the mesh (-C). */
8774 /* */
8775 /*****************************************************************************/
8776 
8777 void DelaunayTriangle::triangulate(char *triswitches)
8778 {
8779  struct mesh m;
8780  struct behavior b;
8781  double *holearray; /* Array of holes. */
8782  double
8783  *regionarray; /* Array of regional attributes and area constraints. */
8784 
8785  plus1mod3[0]= 1;
8786  plus1mod3[1]= 2;
8787  plus1mod3[2]= 0;
8788  minus1mod3[0] = 2;
8789  minus1mod3[1] = 0;
8790  minus1mod3[2] = 1;
8791 
8792  triangleinit(&m);
8793 
8794  parsecommandline(1, &triswitches, &b);
8795 
8796  m.steinerleft = -1;
8797 
8798  transfernodes(&m,
8799  &b,
8800  in.pointlist,
8801  in.pointattributelist,
8802  in.pointmarkerlist,
8803  in.numberofpoints,
8804  in.numberofpointattributes);
8805 
8806 
8807  m.hullsize = delaunay(&m, &b); /* Triangulate the vertices. */
8808 
8809  /* Ensure that no vertex can be mistaken for a triangular bounding */
8810  /* box vertex in insertvertex(). */
8811  m.infvertex1 = (vertex)NULL;
8812  m.infvertex2 = (vertex)NULL;
8813  m.infvertex3 = (vertex)NULL;
8814 
8815  if (b.usesegments)
8816  {
8817  m.checksegments = 1; /* Segments will be introduced next. */
8818 
8819  formskeleton(&m,
8820  &b,
8821  in.segmentlist,
8822  in.segmentmarkerlist,
8823  in.numberofsegments);
8824  }
8825 
8826  if (b.poly && (m.triangles.items > 0))
8827  {
8828  holearray = in.holelist;
8829  m.holes = in.numberofholes;
8830  regionarray = in.regionlist;
8831  m.regions = in.numberofregions;
8832 
8833  /* Carve out holes and concavities. */
8834  carveholes(&m, &b, holearray, m.holes, regionarray, m.regions);
8835  }
8836  else
8837  {
8838  /* Without a PSLG, there can be no holes or regional attributes */
8839  /* or area constraints. The following are set to zero to avoid */
8840  /* an accidental free() later. */
8841  m.holes = 0;
8842  m.regions = 0;
8843  }
8844 
8845  if (b.quality && (m.triangles.items > 0))
8846  {
8847  enforcequality(&m, &b); /* Enforce angle and area constraints. */
8848  }
8849 
8850  /* Calculate the number of edges. */
8851  m.edges = (3l * m.triangles.items + m.hullsize) / 2l;
8852 
8853  if (b.jettison)
8854  {
8856  }
8857  else
8858  {
8860  }
8863  out.numberofcorners = 3;
8865  out.numberofedges = m.edges;
8866  if (b.usesegments)
8867  {
8869  }
8870  else
8871  {
8873  }
8874 
8875  /* writenodes() numbers the vertices too. */
8876  writenodes(&m,
8877  &b,
8878  &out.pointlist,
8880  &out.pointmarkerlist);
8881 
8883 
8884  /* The -c switch (convex switch) causes a PSLG to be written */
8885  /* even if none was read. */
8886  if (b.poly)
8887  {
8888 
8890  out.numberofholes = m.holes;
8892  if (b.poly)
8893  {
8894  out.holelist = in.holelist;
8895  out.regionlist = in.regionlist;
8896  }
8897  else
8898  {
8899  out.holelist = (double *)NULL;
8900  out.regionlist = (double *)NULL;
8901  }
8902  }
8903 
8904  triangledeinit(&m, &b);
8905 }
8906 
8907 }
8908 }
#define setdest(otri, vertexptr)
void triangledeinit(struct mesh *m, struct behavior *b)
void badsubsegdealloc(struct mesh *m, struct badsubseg *dyingseg)
#define vertexmark(vx)
struct badtriang * dequeuebadtriang(struct mesh *m)
#define onextself(otri)
struct flipstacker * lastflip
void alternateaxes(vertex *sortarray, int arraysize, int axis)
void vertexmedian(vertex *sortarray, int arraysize, int median, int axis)
#define segdest(osub, vertexptr)
#define SEGMENTVERTEX
void writepoly(struct mesh *m, struct behavior *b, int **segmentlist, int **segmentmarkerlist)
void writenodes(struct mesh *m, struct behavior *b, double **pointlist, double **pointattriblist, int **pointmarkerlist)
void tallyencs(struct mesh *m, struct behavior *b)
void formskeleton(struct mesh *m, struct behavior *b, int *segmentlist, int *segmentmarkerlist, int numberofsegments)
#define setmark(osub, value)
#define bond(otri1, otri2)
void vertexsort(vertex *sortarray, unsigned int arraysize)
void writeelements(struct mesh *m, struct behavior *b, int **trianglelist, double **triangleattriblist)
#define setsegdest(osub, vertexptr)
void subsegdealloc(struct mesh *m, subseg *dyingsubseg)
double incircle(struct mesh *m, struct behavior *b, vertex pa, vertex pb, vertex pc, vertex pd)
#define Absolute(a)
#define setapex(otri, vertexptr)
void pooldeinit(struct memorypool *pool)
unsigned long randomnation(unsigned int choices)
void * traverse(struct memorypool *pool)
#define VIRUSPERBLOCK
#define sbond(osub1, osub2)
int triunsuitable(vertex triorg, vertex tridest, vertex triapex, double area)
#define stpivot(osub, otri)
struct badsubseg * badsubsegtraverse(struct mesh *m)
void * poolalloc(struct memorypool *pool)
#define Two_One_Product(a1, a0, b, x3, x2, x1, x0)
#define Two_Product_Presplit(a, b, bhi, blo, x, y)
#define Fast_Two_Sum(a, b, x, y)
#define tsdissolve(otri)
struct badtriang * queuetail[4096]
void maketriangle(struct mesh *m, struct behavior *b, struct otri *newotri)
void makevertexmap(struct mesh *m, struct behavior *b)
#define setsegorg(osub, vertexptr)
void poolinit(struct memorypool *pool, int bytecount, int itemcount, int firstitemcount, int alignment)
void poolzero(struct memorypool *pool)
#define UNDEADVERTEX
#define uninfect(otri)
#define decode(ptr, otri)
void carveholes(struct mesh *m, struct behavior *b, double *holelist, int holes, double *regionlist, int regions)
void triangulatepolygon(struct mesh *m, struct behavior *b, struct otri *firstedge, struct otri *lastedge, int edgecount, int doflip, int triflaws)
enum insertvertexresult insertvertex(struct mesh *m, struct behavior *b, vertex newvertex, struct otri *searchtri, struct osub *splitseg, int segmentflaws, int triflaws)
#define Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0)
#define segorg(osub, vertexptr)
#define setvertextype(vx, value)
void enqueuebadtriang(struct mesh *m, struct behavior *b, struct badtriang *badtri)
#define Two_Diff_Tail(a, b, x, y)
double orient3dadapt(vertex pa, vertex pb, vertex pc, vertex pd, double aheight, double bheight, double cheight, double dheight, double permanent)
#define SQUAREROOTTWO
void traversalinit(struct memorypool *pool)
#define otriequal(otri1, otri2)
void triangledealloc(struct mesh *m, triangle *dyingtriangle)
void initializevertexpool(struct mesh *m, struct behavior *b)
void insertsegment(struct mesh *m, struct behavior *b, vertex endpoint1, vertex endpoint2, int newmark)
long delaunay(struct mesh *m, struct behavior *b)
#define mark(osub)
#define setorg(otri, vertexptr)
#define sym(otri1, otri2)
#define INPUTVERTEX
void testtriangle(struct mesh *m, struct behavior *b, struct otri *testtri)
struct badtriang * queuefront[4096]
vertex getvertex(struct mesh *m, struct behavior *b, int number)
#define stdissolve(osub)
void vertexdealloc(struct mesh *m, vertex dyingvertex)
#define tsbond(otri, osub)
void enqueuebadtri(struct mesh *m, struct behavior *b, struct otri *enqtri, double minedge, vertex enqapex, vertex enqorg, vertex enqdest)
#define lprev(otri1, otri2)
#define snextself(osub)
void unflip(struct mesh *m, struct behavior *b, struct otri *flipedge)
void segmentintersection(struct mesh *m, struct behavior *b, struct otri *splittri, struct osub *splitsubseg, vertex endpoint2)
#define lnextself(otri)
#define setsdest(osub, vertexptr)
void mergehulls(struct mesh *m, struct behavior *b, struct otri *farleft, struct otri *innerleft, struct otri *innerright, struct otri *farright, int axis)
#define killtri(tria)
#define infected(otri)
#define vertextype(vx)
void numbernodes(struct mesh *m, struct behavior *b)
#define setvertex2tri(vx, value)
void flip(struct mesh *m, struct behavior *b, struct otri *flipedge)
#define dnext(otri1, otri2)
long removeghosts(struct mesh *m, struct behavior *b, struct otri *startghost)
void markhull(struct mesh *m, struct behavior *b)
void insertsubseg(struct mesh *m, struct behavior *b, struct otri *tri, int subsegmark)
void divconqrecurse(struct mesh *m, struct behavior *b, vertex *sortarray, int vertices, int axis, struct otri *farleft, struct otri *farright)
double counterclockwiseadapt(vertex pa, vertex pb, vertex pc, double detsum)
#define sdissolve(osub)
void delaunayfixup(struct mesh *m, struct behavior *b, struct otri *fixuptri, int leftside)
#define FREEVERTEX
void negate(NekPoint< DataType > &rhs)
Definition: NekPoint.hpp:373
enum locateresult preciselocate(struct mesh *m, struct behavior *b, vertex searchpoint, struct otri *searchtri, int stopatsubsegment)
#define symself(otri)
#define sdest(osub, vertexptr)
#define BADTRIPERBLOCK
long divconqdelaunay(struct mesh *m, struct behavior *b)
double counterclockwise(struct mesh *m, struct behavior *b, vertex pa, vertex pb, vertex pc)
#define vertex2tri(vx)
#define setelemattribute(otri, attnum, value)
int fast_expansion_sum_zeroelimTRI(int elen, double *e, int flen, double *f, double *h)
#define lprevself(otri)
#define FLIPSTACKERPERBLOCK
#define onext(otri1, otri2)
double orient3d(struct mesh *m, struct behavior *b, vertex pa, vertex pb, vertex pc, vertex pd, double aheight, double bheight, double cheight, double dheight)
#define apex(otri, vertexptr)
void plague(struct mesh *m, struct behavior *b)
#define VERTEXPERBLOCK
void poolrestart(struct memorypool *pool)
#define dnextself(otri)
#define infect(otri)
#define sorg(osub, vertexptr)
int scale_expansion_zeroelimTRI(int elen, double *e, double b, double *h)
void transfernodes(struct mesh *m, struct behavior *b, double *pointlist, double *pointattriblist, int *pointmarkerlist, int numberofpoints, int numberofpointattribs)
double nonregular(struct mesh *m, struct behavior *b, vertex pa, vertex pb, vertex pc, vertex pd)
void splittriangle(struct mesh *m, struct behavior *b, struct badtriang *badtri)
void undovertex(struct mesh *m, struct behavior *b)
#define PI
#define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0)
triangle * triangletraverse(struct mesh *m)
void deletevertex(struct mesh *m, struct behavior *b, struct otri *deltri)
enum finddirectionresult finddirection(struct mesh *m, struct behavior *b, struct otri *searchtri, vertex searchpoint)
#define setvertexmark(vx, value)
#define elemattribute(otri, attnum)
#define oprev(otri1, otri2)
#define SUBSEGPERBLOCK
void splitencsegs(struct mesh *m, struct behavior *b, int triflaws)
void constrainededge(struct mesh *m, struct behavior *b, struct otri *starttri, vertex endpoint2, int newmark)
void infecthull(struct mesh *m, struct behavior *b)
void enforcequality(struct mesh *m, struct behavior *b)
void dummyinit(struct mesh *m, struct behavior *b, int trianglebytes, int subsegbytes)
#define oprevself(otri)
#define TRIPERBLOCK
#define otricopy(otri1, otri2)
#define tspivot(otri, osub)
#define lnext(otri1, otri2)
#define SAMPLEFACTOR
#define dest(otri, vertexptr)
#define Split(a, ahi, alo)
struct memorypool flipstackers
#define deadsubseg(sub)
#define Two_Product(a, b, x, y)
void makesubseg(struct mesh *m, struct osub *newsubseg)
int checkseg4encroach(struct mesh *m, struct behavior *b, struct osub *testsubseg)
#define deadtri(tria)
void initializetrisubpools(struct mesh *m, struct behavior *b)
struct memorypool badtriangles
void tallyfaces(struct mesh *m, struct behavior *b)
#define Square(a, x, y)
#define BADSUBSEGPERBLOCK
#define dissolve(otri)
#define spivot(osub1, osub2)
#define setsorg(osub, vertexptr)
double incircleadaptTRI(vertex pa, vertex pb, vertex pc, vertex pd, double permanent)
void findcircumcenter(struct mesh *m, struct behavior *b, vertex torg, vertex tdest, vertex tapex, vertex circumcenter, double *xi, double *eta, int offcenter)
enum locateresult locate(struct mesh *m, struct behavior *b, vertex searchpoint, struct otri *searchtri)
int scoutsegment(struct mesh *m, struct behavior *b, struct otri *searchtri, vertex endpoint2, int newmark)
void pooldealloc(struct memorypool *pool, void *dyingitem)
#define org(otri, vertexptr)
void conformingedge(struct mesh *m, struct behavior *b, vertex endpoint1, vertex endpoint2, int newmark)
#define encode(otri)
#define Two_Sum(a, b, x, y)
#define sencode(osub)
#define ssym(osub1, osub2)
#define dprev(otri1, otri2)
#define ssymself(osub)
#define sdecode(sptr, osub)
void regionplague(struct mesh *m, struct behavior *b, double attribute, double area)
#define killsubseg(sub)
#define DEADVERTEX
void parsecommandline(int argc, char **argv, struct behavior *b)