1 /*****************************************************************************/
2 /*                                                                           */
3 /*      888888888        ,o,                          / 888                  */
4 /*         888    88o88o  "    o8888o  88o8888o o88888o 888  o88888o         */
5 /*         888    888    888       88b 888  888 888 888 888 d888  88b        */
6 /*         888    888    888  o88^o888 888  888 "88888" 888 8888oo888        */
7 /*         888    888    888 C888  888 888  888  /      888 q888             */
8 /*         888    888    888  "88o^888 888  888 Cb      888  "88oooo"        */
9 /*                                              "8oo8D                       */
10 /*                                                                           */
11 /*  A Two-Dimensional Quality Mesh Generator and Delaunay Triangulator.      */
12 /*  (triangle.c)                                                             */
13 /*                                                                           */
14 /*  Version 1.6                                                              */
15 /*  July 28, 2005                                                            */
16 /*                                                                           */
17 /*  Copyright 1993, 1995, 1997, 1998, 2002, 2005                             */
18 /*  Jonathan Richard Shewchuk                                                */
19 /*  2360 Woolsey #H                                                          */
20 /*  Berkeley, California  94705-1927                                         */
21 /*  jrs@cs.berkeley.edu                                                      */
22 /*                                                                           */
23 /*  This program may be freely redistributed under the condition that the    */
24 /*    copyright notices (including this entire header and the copyright      */
25 /*    notice printed when the `-h' switch is selected) are not removed, and  */
26 /*    no compensation is received.  Private, research, and institutional     */
27 /*    use is free.  You may distribute modified versions of this code UNDER  */
28 /*    THE CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE TO IT IN THE   */
29 /*    SAME FILE REMAIN UNDER COPYRIGHT OF THE ORIGINAL AUTHOR, BOTH SOURCE   */
30 /*    AND OBJECT CODE ARE MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR    */
31 /*    NOTICE IS GIVEN OF THE MODIFICATIONS.  Distribution of this code as    */
32 /*    part of a commercial system is permissible ONLY BY DIRECT ARRANGEMENT  */
33 /*    WITH THE AUTHOR.  (If you are not directly supplying this code to a    */
34 /*    customer, and you are instead telling them how they can obtain it for  */
35 /*    free, then you are not required to make any arrangement with me.)      */
36 /*                                                                           */
37 /*  Hypertext instructions for Triangle are available on the Web at          */
38 /*                                                                           */
39 /*      http://www.cs.cmu.edu/~quake/triangle.html                           */
40 /*                                                                           */
41 /*  Disclaimer:  Neither I nor Carnegie Mellon warrant this code in any way  */
42 /*    whatsoever.  This code is provided "as-is".  Use at your own risk.     */
43 /*                                                                           */
44 /*  Some of the references listed below are marked with an asterisk.  [*]    */
45 /*    These references are available for downloading from the Web page       */
46 /*                                                                           */
47 /*      http://www.cs.cmu.edu/~quake/triangle.research.html                  */
48 /*                                                                           */
49 /*  Three papers discussing aspects of Triangle are available.  A short      */
50 /*    overview appears in "Triangle:  Engineering a 2D Quality Mesh          */
51 /*    Generator and Delaunay Triangulator," in Applied Computational         */
52 /*    Geometry:  Towards Geometric Engineering, Ming C. Lin and Dinesh       */
53 /*    Manocha, editors, Lecture Notes in Computer Science volume 1148,       */
54 /*    pages 203-222, Springer-Verlag, Berlin, May 1996 (from the First ACM   */
55 /*    Workshop on Applied Computational Geometry).  [*]                      */
56 /*                                                                           */
57 /*    The algorithms are discussed in the greatest detail in "Delaunay       */
58 /*    Refinement Algorithms for Triangular Mesh Generation," Computational   */
59 /*    Geometry:  Theory and Applications 22(1-3):21-74, May 2002.  [*]       */
60 /*                                                                           */
61 /*    More detail about the data structures may be found in my dissertation: */
62 /*    "Delaunay Refinement Mesh Generation," Ph.D. thesis, Technical Report  */
63 /*    CMU-CS-97-137, School of Computer Science, Carnegie Mellon University, */
64 /*    Pittsburgh, Pennsylvania, 18 May 1997.  [*]                            */
65 /*                                                                           */
66 /*  Triangle was created as part of the Quake Project in the School of       */
67 /*    Computer Science at Carnegie Mellon University.  For further           */
68 /*    information, see Hesheng Bao, Jacobo Bielak, Omar Ghattas, Loukas F.   */
69 /*    Kallivokas, David R. O'Hallaron, Jonathan R. Shewchuk, and Jifeng Xu,  */
70 /*    "Large-scale Simulation of Elastic Wave Propagation in Heterogeneous   */
71 /*    Media on Parallel Computers," Computer Methods in Applied Mechanics    */
72 /*    and Engineering 152(1-2):85-102, 22 January 1998.                      */
73 /*                                                                           */
74 /*  Triangle's Delaunay refinement algorithm for quality mesh generation is  */
75 /*    a hybrid of one due to Jim Ruppert, "A Delaunay Refinement Algorithm   */
76 /*    for Quality 2-Dimensional Mesh Generation," Journal of Algorithms      */
77 /*    18(3):548-585, May 1995 [*], and one due to L. Paul Chew, "Guaranteed- */
78 /*    Quality Mesh Generation for Curved Surfaces," Proceedings of the Ninth */
79 /*    Annual Symposium on Computational Geometry (San Diego, California),    */
80 /*    pages 274-280, Association for Computing Machinery, May 1993,          */
81 /*    http://portal.acm.org/citation.cfm?id=161150 .                         */
82 /*                                                                           */
83 /*  The Delaunay refinement algorithm has been modified so that it meshes    */
84 /*    domains with small input angles well, as described in Gary L. Miller,  */
85 /*    Steven E. Pav, and Noel J. Walkington, "When and Why Ruppert's         */
86 /*    Algorithm Works," Twelfth International Meshing Roundtable, pages      */
87 /*    91-102, Sandia National Laboratories, September 2003.  [*]             */
88 /*                                                                           */
89 /*  My implementation of the divide-and-conquer and incremental Delaunay     */
90 /*    triangulation algorithms follows closely the presentation of Guibas    */
91 /*    and Stolfi, even though I use a triangle-based data structure instead  */
92 /*    of their quad-edge data structure.  (In fact, I originally implemented */
93 /*    Triangle using the quad-edge data structure, but the switch to a       */
94 /*    triangle-based data structure sped Triangle by a factor of two.)  The  */
95 /*    mesh manipulation primitives and the two aforementioned Delaunay       */
96 /*    triangulation algorithms are described by Leonidas J. Guibas and Jorge */
97 /*    Stolfi, "Primitives for the Manipulation of General Subdivisions and   */
98 /*    the Computation of Voronoi Diagrams," ACM Transactions on Graphics     */
99 /*    4(2):74-123, April 1985, http://portal.acm.org/citation.cfm?id=282923 .*/
100 /*                                                                           */
101 /*  Their O(n log n) divide-and-conquer algorithm is adapted from Der-Tsai   */
102 /*    Lee and Bruce J. Schachter, "Two Algorithms for Constructing the       */
103 /*    Delaunay Triangulation," International Journal of Computer and         */
104 /*    Information Science 9(3):219-242, 1980.  Triangle's improvement of the */
105 /*    divide-and-conquer algorithm by alternating between vertical and       */
106 /*    horizontal cuts was introduced by Rex A. Dwyer, "A Faster Divide-and-  */
107 /*    Conquer Algorithm for Constructing Delaunay Triangulations,"           */
108 /*    Algorithmica 2(2):137-151, 1987.                                       */
109 /*                                                                           */
110 /*  The incremental insertion algorithm was first proposed by C. L. Lawson,  */
111 /*    "Software for C1 Surface Interpolation," in Mathematical Software III, */
112 /*    John R. Rice, editor, Academic Press, New York, pp. 161-194, 1977.     */
113 /*    For point location, I use the algorithm of Ernst P. Mucke, Isaac       */
114 /*    Saias, and Binhai Zhu, "Fast Randomized Point Location Without         */
115 /*    Preprocessing in Two- and Three-Dimensional Delaunay Triangulations,"  */
116 /*    Proceedings of the Twelfth Annual Symposium on Computational Geometry, */
117 /*    ACM, May 1996.  [*]  If I were to randomize the order of vertex        */
118 /*    insertion (I currently don't bother), their result combined with the   */
119 /*    result of Kenneth L. Clarkson and Peter W. Shor, "Applications of      */
120 /*    Random Sampling in Computational Geometry II," Discrete &              */
121 /*    Computational Geometry 4(1):387-421, 1989, would yield an expected     */
122 /*    O(n^{4/3}) bound on running time.                                      */
123 /*                                                                           */
124 /*  The O(n log n) sweepline Delaunay triangulation algorithm is taken from  */
125 /*    Steven Fortune, "A Sweepline Algorithm for Voronoi Diagrams",          */
126 /*    Algorithmica 2(2):153-174, 1987.  A random sample of edges on the      */
127 /*    boundary of the triangulation are maintained in a splay tree for the   */
128 /*    purpose of point location.  Splay trees are described by Daniel        */
129 /*    Dominic Sleator and Robert Endre Tarjan, "Self-Adjusting Binary Search */
130 /*    Trees," Journal of the ACM 32(3):652-686, July 1985,                   */
131 /*    http://portal.acm.org/citation.cfm?id=3835 .                           */
132 /*                                                                           */
133 /*  The algorithms for exact computation of the signs of determinants are    */
134 /*    described in Jonathan Richard Shewchuk, "Adaptive Precision Floating-  */
135 /*    Point Arithmetic and Fast Robust Geometric Predicates," Discrete &     */
136 /*    Computational Geometry 18(3):305-363, October 1997.  (Also available   */
137 /*    as Technical Report CMU-CS-96-140, School of Computer Science,         */
138 /*    Carnegie Mellon University, Pittsburgh, Pennsylvania, May 1996.)  [*]  */
139 /*    An abbreviated version appears as Jonathan Richard Shewchuk, "Robust   */
140 /*    Adaptive Floating-Point Geometric Predicates," Proceedings of the      */
141 /*    Twelfth Annual Symposium on Computational Geometry, ACM, May 1996. [*] */
142 /*    Many of the ideas for my exact arithmetic routines originate with      */
143 /*    Douglas M. Priest, "Algorithms for Arbitrary Precision Floating Point  */
144 /*    Arithmetic," Tenth Symposium on Computer Arithmetic, pp. 132-143, IEEE */
145 /*    Computer Society Press, 1991.  [*]  Many of the ideas for the correct  */
146 /*    evaluation of the signs of determinants are taken from Steven Fortune  */
147 /*    and Christopher J. Van Wyk, "Efficient Exact Arithmetic for Computa-   */
148 /*    tional Geometry," Proceedings of the Ninth Annual Symposium on         */
149 /*    Computational Geometry, ACM, pp. 163-172, May 1993, and from Steven    */
150 /*    Fortune, "Numerical Stability of Algorithms for 2D Delaunay Triangu-   */
151 /*    lations," International Journal of Computational Geometry & Applica-   */
152 /*    tions 5(1-2):193-213, March-June 1995.                                 */
153 /*                                                                           */
154 /*  The method of inserting new vertices off-center (not precisely at the    */
155 /*    circumcenter of every poor-quality triangle) is from Alper Ungor,      */
156 /*    "Off-centers:  A New Type of Steiner Points for Computing Size-Optimal */
157 /*    Quality-Guaranteed Delaunay Triangulations," Proceedings of LATIN      */
158 /*    2004 (Buenos Aires, Argentina), April 2004.                            */
159 /*                                                                           */
160 /*  For definitions of and results involving Delaunay triangulations,        */
161 /*    constrained and conforming versions thereof, and other aspects of      */
162 /*    triangular mesh generation, see the excellent survey by Marshall Bern  */
163 /*    and David Eppstein, "Mesh Generation and Optimal Triangulation," in    */
164 /*    Computing and Euclidean Geometry, Ding-Zhu Du and Frank Hwang,         */
165 /*    editors, World Scientific, Singapore, pp. 23-90, 1992.  [*]            */
166 /*                                                                           */
167 /*  The time for incrementally adding PSLG (planar straight line graph)      */
168 /*    segments to create a constrained Delaunay triangulation is probably    */
169 /*    O(t^2) per segment in the worst case and O(t) per segment in the       */
170 /*    common case, where t is the number of triangles that intersect the     */
171 /*    segment before it is inserted.  This doesn't count point location,     */
172 /*    which can be much more expensive.  I could improve this to O(d log d)  */
173 /*    time, but d is usually quite small, so it's not worth the bother.      */
174 /*    (This note does not apply when the -s switch is used, invoking a       */
175 /*    different method is used to insert segments.)                          */
176 /*                                                                           */
177 /*  The time for deleting a vertex from a Delaunay triangulation is O(d^2)   */
178 /*    in the worst case and O(d) in the common case, where d is the degree   */
179 /*    of the vertex being deleted.  I could improve this to O(d log d) time, */
180 /*    but d is usually quite small, so it's not worth the bother.            */
181 /*                                                                           */
182 /*  Ruppert's Delaunay refinement algorithm typically generates triangles    */
183 /*    at a linear rate (constant time per triangle) after the initial        */
184 /*    triangulation is formed.  There may be pathological cases where        */
185 /*    quadratic time is required, but these never arise in practice.         */
186 /*                                                                           */
187 /*  The geometric predicates (circumcenter calculations, segment             */
188 /*    intersection formulae, etc.) appear in my "Lecture Notes on Geometric  */
189 /*    Robustness" at http://www.cs.berkeley.edu/~jrs/mesh .                  */
190 /*                                                                           */
191 /*  If you make any improvements to this code, please please please let me   */
192 /*    know, so that I may obtain the improvements.  Even if you don't change */
193 /*    the code, I'd still love to hear what it's being used for.             */
194 /*                                                                           */
195 /*****************************************************************************/
196 
197 
198 
199 /* For single precision (which will save some memory and reduce paging),     */
200 /*   define the symbol SINGLE by using the -DSINGLE compiler switch or by    */
201 /*   writing "#define SINGLE" below.                                         */
202 /*                                                                           */
203 /* For double precision (which will allow you to refine meshes to a smaller  */
204 /*   edge length), leave SINGLE undefined.                                   */
205 /*                                                                           */
206 /* Double precision uses more memory, but improves the resolution of the     */
207 /*   meshes you can generate with Triangle.  It also reduces the likelihood  */
208 /*   of a floating exception due to overflow.  Finally, it is much faster    */
209 /*   than single precision on 64-bit architectures like the DEC Alpha.  I    */
210 /*   recommend double precision unless you want to generate a mesh for which */
211 /*   you do not have enough memory.                                          */
212 
213 /* #define SINGLE */
214 
215 #ifdef _MSC_VER
216 #pragma warning ( disable: 4311 4312 )
217 #endif
218 
219 /* [Bruno] disable some warnings for ICC and MINGW */
220 
221 #ifdef __ICC
222 #pragma warning disable 869 180 593
223 #endif
224 
225 #if defined(__MINGW32__) || defined(__MINGW64)
226 #pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
227 #pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
228 #endif
229 
230 
231 #ifdef SINGLE
232 #define REAL float
233 #else /* not SINGLE */
234 #define REAL double
235 #endif /* not SINGLE */
236 
237 /* If yours is not a Unix system, define the NO_TIMER compiler switch to     */
238 /*   remove the Unix-specific timing code.                                   */
239 
240 #define NO_TIMER
241 
242 /* To insert lots of self-checks for internal errors, define the SELF_CHECK  */
243 /*   symbol.  This will slow down the program significantly.  It is best to  */
244 /*   define the symbol using the -DSELF_CHECK compiler switch, but you could */
245 /*   write "#define SELF_CHECK" below.  If you are modifying this code, I    */
246 /*   recommend you turn self-checks on until your work is debugged.          */
247 
248 /* #define SELF_CHECK */
249 
250 /* To compile Triangle as a callable object library (triangle.o), define the */
251 /*   TRILIBRARY symbol.  Read the file triangle.h for details on how to call */
252 /*   the procedure triangulate() that results.                               */
253 
254 #define TRILIBRARY
255 
256 /* It is possible to generate a smaller version of Triangle using one or     */
257 /*   both of the following symbols.  Define the REDUCED symbol to eliminate  */
258 /*   all features that are primarily of research interest; specifically, the */
259 /*   -i, -F, -s, and -C switches.  Define the CDT_ONLY symbol to eliminate   */
260 /*   all meshing algorithms above and beyond constrained Delaunay            */
261 /*   triangulation; specifically, the -r, -q, -a, -u, -D, -S, and -s         */
262 /*   switches.  These reductions are most likely to be useful when           */
263 /*   generating an object library (triangle.o) by defining the TRILIBRARY    */
264 /*   symbol.                                                                 */
265 
266 /* #define REDUCED */
267 /* #define CDT_ONLY */
268 
269 /* On some machines, my exact arithmetic routines might be defeated by the   */
270 /*   use of internal extended precision floating-point registers.  The best  */
271 /*   way to solve this problem is to set the floating-point registers to use */
272 /*   single or double precision internally.  On 80x86 processors, this may   */
273 /*   be accomplished by setting the CPU86 symbol for the Microsoft C         */
274 /*   compiler, or the LINUX symbol for the gcc compiler running on Linux.    */
275 /*                                                                           */
276 /* An inferior solution is to declare certain values as `volatile', thus     */
277 /*   forcing them to be stored to memory and rounded off.  Unfortunately,    */
278 /*   this solution might slow Triangle down quite a bit.  To use volatile    */
279 /*   values, write "#define INEXACT volatile" below.  Normally, however,     */
280 /*   INEXACT should be defined to be nothing.  ("#define INEXACT".)          */
281 /*                                                                           */
282 /* For more discussion, see http://www.cs.cmu.edu/~quake/robust.pc.html .    */
283 /*   For yet more discussion, see Section 5 of my paper, "Adaptive Precision */
284 /*   Floating-Point Arithmetic and Fast Robust Geometric Predicates" (also   */
285 /*   available as Section 6.6 of my dissertation).                           */
286 
287 /* #define CPU86 */
288 /* #define LINUX */
289 
290 #define INEXACT /* Nothing */
291 /* #define INEXACT volatile */
292 
293 /* Maximum number of characters in a file name (including the null).         */
294 
295 #define FILENAMESIZE 2048
296 
297 /* Maximum number of characters in a line read from a file (including the    */
298 /*   null).                                                                  */
299 
300 #define INPUTLINESIZE 1024
301 
302 /* For efficiency, a variety of data structures are allocated in bulk.  The  */
303 /*   following constants determine how many of each structure is allocated   */
304 /*   at once.                                                                */
305 
306 #define TRIPERBLOCK 4092           /* Number of triangles allocated at once. */
307 #define SUBSEGPERBLOCK 508       /* Number of subsegments allocated at once. */
308 #define VERTEXPERBLOCK 4092         /* Number of vertices allocated at once. */
309 #define VIRUSPERBLOCK 1020   /* Number of virus triangles allocated at once. */
310 /* Number of encroached subsegments allocated at once. */
311 #define BADSUBSEGPERBLOCK 252
312 /* Number of skinny triangles allocated at once. */
313 #define BADTRIPERBLOCK 4092
314 /* Number of flipped triangles allocated at once. */
315 #define FLIPSTACKERPERBLOCK 252
316 /* Number of splay tree nodes allocated at once. */
317 #define SPLAYNODEPERBLOCK 508
318 
319 /* The vertex types.   A DEADVERTEX has been deleted entirely.  An           */
320 /*   UNDEADVERTEX is not part of the mesh, but is written to the output      */
321 /*   .node file and affects the node indexing in the other output files.     */
322 
323 #define INPUTVERTEX 0
324 #define SEGMENTVERTEX 1
325 #define FREEVERTEX 2
326 #define DEADVERTEX -32768
327 #define UNDEADVERTEX -32767
328 
329 /* The next line is used to outsmart some very stupid compilers.  If your    */
330 /*   compiler is smarter, feel free to replace the "int" with "void".        */
331 /*   Not that it matters.                                                    */
332 
333 #define VOID int
334 
335 /* Two constants for algorithms based on random sampling.  Both constants    */
336 /*   have been chosen empirically to optimize their respective algorithms.   */
337 
338 /* Used for the point location scheme of Mucke, Saias, and Zhu, to decide    */
339 /*   how large a random sample of triangles to inspect.                      */
340 
341 #define SAMPLEFACTOR 11
342 
343 /* Used in Fortune's sweepline Delaunay algorithm to determine what fraction */
344 /*   of boundary edges should be maintained in the splay tree for point      */
345 /*   location on the front.                                                  */
346 
347 #define SAMPLERATE 10
348 
349 /* A number that speaks for itself, every kissable digit.                    */
350 
351 #define PI 3.141592653589793238462643383279502884197169399375105820974944592308
352 
353 /* Another fave.                                                             */
354 
355 #define SQUAREROOTTWO 1.4142135623730950488016887242096980785696718753769480732
356 
357 /* And here's one for those of you who are intimidated by math.              */
358 
359 #define ONETHIRD 0.333333333333333333333333333333333333333333333333333333333333
360 
361 
362 /* Define the size large enough to store and operate on a pointer.           */
363 /* (fix from LIBIGL). Replaced 'unsigned long' with 'INT_PTR' where needed.  */
364 #define INT_PTR unsigned long long
365 
366 
367 #include <stdio.h>
368 #include <stdlib.h>
369 #include <string.h>
370 #include <math.h>
371 #ifndef NO_TIMER
372 #include <sys/time.h>
373 #endif /* not NO_TIMER */
374 #ifdef CPU86
375 #include <float.h>
376 #endif /* CPU86 */
377 #ifdef LINUX
378 #include <fpu_control.h>
379 #endif /* LINUX */
380 #ifdef TRILIBRARY
381 #include <geogram/third_party/triangle/triangle.h>
382 #endif /* TRILIBRARY */
383 
384 /* A few forward declarations.                                               */
385 
386 #ifndef TRILIBRARY
387 char *readline();
388 char *findfield();
389 #endif /* not TRILIBRARY */
390 
391 /* Labels that signify the result of point location.  The result of a        */
392 /*   search indicates that the point falls in the interior of a triangle, on */
393 /*   an edge, on a vertex, or outside the mesh.                              */
394 
395 enum locateresult {INTRIANGLE, ONEDGE, ONVERTEX, OUTSIDE};
396 
397 /* Labels that signify the result of vertex insertion.  The result indicates */
398 /*   that the vertex was inserted with complete success, was inserted but    */
399 /*   encroaches upon a subsegment, was not inserted because it lies on a     */
400 /*   segment, or was not inserted because another vertex occupies the same   */
401 /*   location.                                                               */
402 
403 enum insertvertexresult {SUCCESSFULVERTEX, ENCROACHINGVERTEX, VIOLATINGVERTEX,
404                          DUPLICATEVERTEX};
405 
406 /* Labels that signify the result of direction finding.  The result          */
407 /*   indicates that a segment connecting the two query points falls within   */
408 /*   the direction triangle, along the left edge of the direction triangle,  */
409 /*   or along the right edge of the direction triangle.                      */
410 
411 enum finddirectionresult {WITHIN, LEFTCOLLINEAR, RIGHTCOLLINEAR};
412 
413 /*****************************************************************************/
414 /*                                                                           */
415 /*  The basic mesh data structures                                           */
416 /*                                                                           */
417 /*  There are three:  vertices, triangles, and subsegments (abbreviated      */
418 /*  `subseg').  These three data structures, linked by pointers, comprise    */
419 /*  the mesh.  A vertex simply represents a mesh vertex and its properties.  */
420 /*  A triangle is a triangle.  A subsegment is a special data structure used */
421 /*  to represent an impenetrable edge of the mesh (perhaps on the outer      */
422 /*  boundary, on the boundary of a hole, or part of an internal boundary     */
423 /*  separating two triangulated regions).  Subsegments represent boundaries, */
424 /*  defined by the user, that triangles may not lie across.                  */
425 /*                                                                           */
426 /*  A triangle consists of a list of three vertices, a list of three         */
427 /*  adjoining triangles, a list of three adjoining subsegments (when         */
428 /*  segments exist), an arbitrary number of optional user-defined            */
429 /*  floating-point attributes, and an optional area constraint.  The latter  */
430 /*  is an upper bound on the permissible area of each triangle in a region,  */
431 /*  used for mesh refinement.                                                */
432 /*                                                                           */
433 /*  For a triangle on a boundary of the mesh, some or all of the neighboring */
434 /*  triangles may not be present.  For a triangle in the interior of the     */
435 /*  mesh, often no neighboring subsegments are present.  Such absent         */
436 /*  triangles and subsegments are never represented by NULL pointers; they   */
437 /*  are represented by two special records:  `dummytri', the triangle that   */
438 /*  fills "outer space", and `dummysub', the omnipresent subsegment.         */
439 /*  `dummytri' and `dummysub' are used for several reasons; for instance,    */
440 /*  they can be dereferenced and their contents examined without violating   */
441 /*  protected memory.                                                        */
442 /*                                                                           */
443 /*  However, it is important to understand that a triangle includes other    */
444 /*  information as well.  The pointers to adjoining vertices, triangles, and */
445 /*  subsegments are ordered in a way that indicates their geometric relation */
446 /*  to each other.  Furthermore, each of these pointers contains orientation */
447 /*  information.  Each pointer to an adjoining triangle indicates which face */
448 /*  of that triangle is contacted.  Similarly, each pointer to an adjoining  */
449 /*  subsegment indicates which side of that subsegment is contacted, and how */
450 /*  the subsegment is oriented relative to the triangle.                     */
451 /*                                                                           */
452 /*  The data structure representing a subsegment may be thought to be        */
453 /*  abutting the edge of one or two triangle data structures:  either        */
454 /*  sandwiched between two triangles, or resting against one triangle on an  */
455 /*  exterior boundary or hole boundary.                                      */
456 /*                                                                           */
457 /*  A subsegment consists of a list of four vertices--the vertices of the    */
458 /*  subsegment, and the vertices of the segment it is a part of--a list of   */
459 /*  two adjoining subsegments, and a list of two adjoining triangles.  One   */
460 /*  of the two adjoining triangles may not be present (though there should   */
461 /*  always be one), and neighboring subsegments might not be present.        */
462 /*  Subsegments also store a user-defined integer "boundary marker".         */
463 /*  Typically, this integer is used to indicate what boundary conditions are */
464 /*  to be applied at that location in a finite element simulation.           */
465 /*                                                                           */
466 /*  Like triangles, subsegments maintain information about the relative      */
467 /*  orientation of neighboring objects.                                      */
468 /*                                                                           */
469 /*  Vertices are relatively simple.  A vertex is a list of floating-point    */
470 /*  numbers, starting with the x, and y coordinates, followed by an          */
471 /*  arbitrary number of optional user-defined floating-point attributes,     */
472 /*  followed by an integer boundary marker.  During the segment insertion    */
473 /*  phase, there is also a pointer from each vertex to a triangle that may   */
474 /*  contain it.  Each pointer is not always correct, but when one is, it     */
475 /*  speeds up segment insertion.  These pointers are assigned values once    */
476 /*  at the beginning of the segment insertion phase, and are not used or     */
477 /*  updated except during this phase.  Edge flipping during segment          */
478 /*  insertion will render some of them incorrect.  Hence, don't rely upon    */
479 /*  them for anything.                                                       */
480 /*                                                                           */
481 /*  Other than the exception mentioned above, vertices have no information   */
482 /*  about what triangles, subfacets, or subsegments they are linked to.      */
483 /*                                                                           */
484 /*****************************************************************************/
485 
486 /*****************************************************************************/
487 /*                                                                           */
488 /*  Handles                                                                  */
489 /*                                                                           */
490 /*  The oriented triangle (`otri') and oriented subsegment (`osub') data     */
491 /*  structures defined below do not themselves store any part of the mesh.   */
492 /*  The mesh itself is made of `triangle's, `subseg's, and `vertex's.        */
493 /*                                                                           */
494 /*  Oriented triangles and oriented subsegments will usually be referred to  */
495 /*  as "handles."  A handle is essentially a pointer into the mesh; it       */
496 /*  allows you to "hold" one particular part of the mesh.  Handles are used  */
497 /*  to specify the regions in which one is traversing and modifying the mesh.*/
498 /*  A single `triangle' may be held by many handles, or none at all.  (The   */
499 /*  latter case is not a memory leak, because the triangle is still          */
500 /*  connected to other triangles in the mesh.)                               */
501 /*                                                                           */
502 /*  An `otri' is a handle that holds a triangle.  It holds a specific edge   */
503 /*  of the triangle.  An `osub' is a handle that holds a subsegment.  It     */
504 /*  holds either the left or right side of the subsegment.                   */
505 /*                                                                           */
506 /*  Navigation about the mesh is accomplished through a set of mesh          */
507 /*  manipulation primitives, further below.  Many of these primitives take   */
508 /*  a handle and produce a new handle that holds the mesh near the first     */
509 /*  handle.  Other primitives take two handles and glue the corresponding    */
510 /*  parts of the mesh together.  The orientation of the handles is           */
511 /*  important.  For instance, when two triangles are glued together by the   */
512 /*  bond() primitive, they are glued at the edges on which the handles lie.  */
513 /*                                                                           */
514 /*  Because vertices have no information about which triangles they are      */
515 /*  attached to, I commonly represent a vertex by use of a handle whose      */
516 /*  origin is the vertex.  A single handle can simultaneously represent a    */
517 /*  triangle, an edge, and a vertex.                                         */
518 /*                                                                           */
519 /*****************************************************************************/
520 
521 /* The triangle data structure.  Each triangle contains three pointers to    */
522 /*   adjoining triangles, plus three pointers to vertices, plus three        */
523 /*   pointers to subsegments (declared below; these pointers are usually     */
524 /*   `dummysub').  It may or may not also contain user-defined attributes    */
525 /*   and/or a floating-point "area constraint."  It may also contain extra   */
526 /*   pointers for nodes, when the user asks for high-order elements.         */
527 /*   Because the size and structure of a `triangle' is not decided until     */
528 /*   runtime, I haven't simply declared the type `triangle' as a struct.     */
529 
530 typedef REAL **triangle;            /* Really:  typedef triangle *triangle   */
531 
532 /* An oriented triangle:  includes a pointer to a triangle and orientation.  */
533 /*   The orientation denotes an edge of the triangle.  Hence, there are      */
534 /*   three possible orientations.  By convention, each edge always points    */
535 /*   counterclockwise about the corresponding triangle.                      */
536 
537 struct otri {
538   triangle *tri;
539   int orient;                                         /* Ranges from 0 to 2. */
540 };
541 
542 /* The subsegment data structure.  Each subsegment contains two pointers to  */
543 /*   adjoining subsegments, plus four pointers to vertices, plus two         */
544 /*   pointers to adjoining triangles, plus one boundary marker, plus one     */
545 /*   segment number.                                                         */
546 
547 typedef REAL **subseg;                  /* Really:  typedef subseg *subseg   */
548 
549 /* An oriented subsegment:  includes a pointer to a subsegment and an        */
550 /*   orientation.  The orientation denotes a side of the edge.  Hence, there */
551 /*   are two possible orientations.  By convention, the edge is always       */
552 /*   directed so that the "side" denoted is the right side of the edge.      */
553 
554 struct osub {
555   subseg *ss;
556   int ssorient;                                       /* Ranges from 0 to 1. */
557 };
558 
559 /* The vertex data structure.  Each vertex is actually an array of REALs.    */
560 /*   The number of REALs is unknown until runtime.  An integer boundary      */
561 /*   marker, and sometimes a pointer to a triangle, is appended after the    */
562 /*   REALs.                                                                  */
563 
564 typedef REAL *vertex;
565 
566 /* A queue used to store encroached subsegments.  Each subsegment's vertices */
567 /*   are stored so that we can check whether a subsegment is still the same. */
568 
569 struct badsubseg {
570   subseg encsubseg;                             /* An encroached subsegment. */
571   vertex subsegorg, subsegdest;                         /* Its two vertices. */
572 };
573 
574 /* A queue used to store bad triangles.  The key is the square of the cosine */
575 /*   of the smallest angle of the triangle.  Each triangle's vertices are    */
576 /*   stored so that one can check whether a triangle is still the same.      */
577 
578 struct badtriang {
579   triangle poortri;                       /* A skinny or too-large triangle. */
580   REAL key;                             /* cos^2 of smallest (apical) angle. */
581   vertex triangorg, triangdest, triangapex;           /* Its three vertices. */
582   struct badtriang *nexttriang;             /* Pointer to next bad triangle. */
583 };
584 
585 /* A stack of triangles flipped during the most recent vertex insertion.     */
586 /*   The stack is used to undo the vertex insertion if the vertex encroaches */
587 /*   upon a subsegment.                                                      */
588 
589 struct flipstacker {
590   triangle flippedtri;                       /* A recently flipped triangle. */
591   struct flipstacker *prevflip;               /* Previous flip in the stack. */
592 };
593 
594 /* A node in a heap used to store events for the sweepline Delaunay          */
595 /*   algorithm.  Nodes do not point directly to their parents or children in */
596 /*   the heap.  Instead, each node knows its position in the heap, and can   */
597 /*   look up its parent and children in a separate array.  The `eventptr'    */
598 /*   points either to a `vertex' or to a triangle (in encoded format, so     */
599 /*   that an orientation is included).  In the latter case, the origin of    */
600 /*   the oriented triangle is the apex of a "circle event" of the sweepline  */
601 /*   algorithm.  To distinguish site events from circle events, all circle   */
602 /*   events are given an invalid (smaller than `xmin') x-coordinate `xkey'.  */
603 
604 struct event {
605   REAL xkey, ykey;                              /* Coordinates of the event. */
606   VOID *eventptr;      /* Can be a vertex or the location of a circle event. */
607   int heapposition;              /* Marks this event's position in the heap. */
608 };
609 
610 /* A node in the splay tree.  Each node holds an oriented ghost triangle     */
611 /*   that represents a boundary edge of the growing triangulation.  When a   */
612 /*   circle event covers two boundary edges with a triangle, so that they    */
613 /*   are no longer boundary edges, those edges are not immediately deleted   */
614 /*   from the tree; rather, they are lazily deleted when they are next       */
615 /*   encountered.  (Since only a random sample of boundary edges are kept    */
616 /*   in the tree, lazy deletion is faster.)  `keydest' is used to verify     */
617 /*   that a triangle is still the same as when it entered the splay tree; if */
618 /*   it has been rotated (due to a circle event), it no longer represents a  */
619 /*   boundary edge and should be deleted.                                    */
620 
621 struct splaynode {
622   struct otri keyedge;                     /* Lprev of an edge on the front. */
623   vertex keydest;           /* Used to verify that splay node is still live. */
624   struct splaynode *lchild, *rchild;              /* Children in splay tree. */
625 };
626 
627 /* A type used to allocate memory.  firstblock is the first block of items.  */
628 /*   nowblock is the block from which items are currently being allocated.   */
629 /*   nextitem points to the next slab of free memory for an item.            */
630 /*   deaditemstack is the head of a linked list (stack) of deallocated items */
631 /*   that can be recycled.  unallocateditems is the number of items that     */
632 /*   remain to be allocated from nowblock.                                   */
633 /*                                                                           */
634 /* Traversal is the process of walking through the entire list of items, and */
635 /*   is separate from allocation.  Note that a traversal will visit items on */
636 /*   the "deaditemstack" stack as well as live items.  pathblock points to   */
637 /*   the block currently being traversed.  pathitem points to the next item  */
638 /*   to be traversed.  pathitemsleft is the number of items that remain to   */
639 /*   be traversed in pathblock.                                              */
640 /*                                                                           */
641 /* alignbytes determines how new records should be aligned in memory.        */
642 /*   itembytes is the length of a record in bytes (after rounding up).       */
643 /*   itemsperblock is the number of items allocated at once in a single      */
644 /*   block.  itemsfirstblock is the number of items in the first block,      */
645 /*   which can vary from the others.  items is the number of currently       */
646 /*   allocated items.  maxitems is the maximum number of items that have     */
647 /*   been allocated at once; it is the current number of items plus the      */
648 /*   number of records kept on deaditemstack.                                */
649 
650 struct memorypool {
651   VOID **firstblock, **nowblock;
652   VOID *nextitem;
653   VOID *deaditemstack;
654   VOID **pathblock;
655   VOID *pathitem;
656   int alignbytes;
657   int itembytes;
658   int itemsperblock;
659   int itemsfirstblock;
660   long items, maxitems;
661   int unallocateditems;
662   int pathitemsleft;
663 };
664 
665 
666 /* Global constants.                                                         */
667 
668 REAL splitter;       /* Used to split REAL factors for exact multiplication. */
669 REAL epsilon;                             /* Floating-point machine epsilon. */
670 REAL resulterrbound;
671 REAL ccwerrboundA, ccwerrboundB, ccwerrboundC;
672 REAL iccerrboundA, iccerrboundB, iccerrboundC;
673 REAL o3derrboundA, o3derrboundB, o3derrboundC;
674 
675 /* Random number seed is not constant, but I've made it global anyway.       */
676 
677 unsigned long randomseed;                     /* Current random number seed. */
678 
679 
680 /* Mesh data structure.  Triangle operates on only one mesh, but the mesh    */
681 /*   structure is used (instead of global variables) to allow reentrancy.    */
682 
683 struct mesh {
684 
685 /* Variables used to allocate memory for triangles, subsegments, vertices,   */
686 /*   viri (triangles being eaten), encroached segments, bad (skinny or too   */
687 /*   large) triangles, and splay tree nodes.                                 */
688 
689   struct memorypool triangles;
690   struct memorypool subsegs;
691   struct memorypool vertices;
692   struct memorypool viri;
693   struct memorypool badsubsegs;
694   struct memorypool badtriangles;
695   struct memorypool flipstackers;
696   struct memorypool splaynodes;
697 
698 /* Variables that maintain the bad triangle queues.  The queues are          */
699 /*   ordered from 4095 (highest priority) to 0 (lowest priority).            */
700 
701   struct badtriang *queuefront[4096];
702   struct badtriang *queuetail[4096];
703   int nextnonemptyq[4096];
704   int firstnonemptyq;
705 
706 /* Variable that maintains the stack of recently flipped triangles.          */
707 
708   struct flipstacker *lastflip;
709 
710 /* Other variables. */
711 
712   REAL xmin, xmax, ymin, ymax;                            /* x and y bounds. */
713   REAL xminextreme;      /* Nonexistent x value used as a flag in sweepline. */
714   int invertices;                               /* Number of input vertices. */
715   int inelements;                              /* Number of input triangles. */
716   int insegments;                               /* Number of input segments. */
717   int holes;                                       /* Number of input holes. */
718   int regions;                                   /* Number of input regions. */
719   int undeads;    /* Number of input vertices that don't appear in the mesh. */
720   long edges;                                     /* Number of output edges. */
721   int mesh_dim;                                /* Dimension (ought to be 2). */
722   int nextras;                           /* Number of attributes per vertex. */
723   int eextras;                         /* Number of attributes per triangle. */
724   long hullsize;                          /* Number of edges in convex hull. */
725   int steinerleft;                 /* Number of Steiner points not yet used. */
726   int vertexmarkindex;         /* Index to find boundary marker of a vertex. */
727   int vertex2triindex;     /* Index to find a triangle adjacent to a vertex. */
728   int highorderindex;  /* Index to find extra nodes for high-order elements. */
729   int elemattribindex;            /* Index to find attributes of a triangle. */
730   int areaboundindex;             /* Index to find area bound of a triangle. */
731   int checksegments;         /* Are there segments in the triangulation yet? */
732   int checkquality;                  /* Has quality triangulation begun yet? */
733   int readnodefile;                           /* Has a .node file been read? */
734   long samples;              /* Number of random samples for point location. */
735 
736   long incirclecount;                 /* Number of incircle tests performed. */
737   long counterclockcount;     /* Number of counterclockwise tests performed. */
738   long orient3dcount;           /* Number of 3D orientation tests performed. */
739   long hyperbolacount;      /* Number of right-of-hyperbola tests performed. */
740   long circumcentercount;  /* Number of circumcenter calculations performed. */
741   long circletopcount;       /* Number of circle top calculations performed. */
742 
743 /* Triangular bounding box vertices.                                         */
744 
745   vertex infvertex1, infvertex2, infvertex3;
746 
747 /* Pointer to the `triangle' that occupies all of "outer space."             */
748 
749   triangle *dummytri;
750   triangle *dummytribase;    /* Keep base address so we can free() it later. */
751 
752 /* Pointer to the omnipresent subsegment.  Referenced by any triangle or     */
753 /*   subsegment that isn't really connected to a subsegment at that          */
754 /*   location.                                                               */
755 
756   subseg *dummysub;
757   subseg *dummysubbase;      /* Keep base address so we can free() it later. */
758 
759 /* Pointer to a recently visited triangle.  Improves point location if       */
760 /*   proximate vertices are inserted sequentially.                           */
761 
762   struct otri recenttri;
763 
764 };                                                  /* End of `struct mesh'. */
765 
766 
767 /* Data structure for command line switches and file names.  This structure  */
768 /*   is used (instead of global variables) to allow reentrancy.              */
769 
770 struct behavior {
771 
772 /* Switches for the triangulator.                                            */
773 /*   poly: -p switch.  refine: -r switch.                                    */
774 /*   quality: -q switch.                                                     */
775 /*     minangle: minimum angle bound, specified after -q switch.             */
776 /*     goodangle: cosine squared of minangle.                                */
777 /*     offconstant: constant used to place off-center Steiner points.        */
778 /*   vararea: -a switch without number.                                      */
779 /*   fixedarea: -a switch with number.                                       */
780 /*     maxarea: maximum area bound, specified after -a switch.               */
781 /*   usertest: -u switch.                                                    */
782 /*   regionattrib: -A switch.  convex: -c switch.                            */
783 /*   weighted: 1 for -w switch, 2 for -W switch.  jettison: -j switch        */
784 /*   firstnumber: inverse of -z switch.  All items are numbered starting     */
785 /*     from `firstnumber'.                                                   */
786 /*   edgesout: -e switch.  voronoi: -v switch.                               */
787 /*   neighbors: -n switch.  geomview: -g switch.                             */
788 /*   nobound: -B switch.  nopolywritten: -P switch.                          */
789 /*   nonodewritten: -N switch.  noelewritten: -E switch.                     */
790 /*   noiterationnum: -I switch.  noholes: -O switch.                         */
791 /*   noexact: -X switch.                                                     */
792 /*   order: element order, specified after -o switch.                        */
793 /*   nobisect: count of how often -Y switch is selected.                     */
794 /*   steiner: maximum number of Steiner points, specified after -S switch.   */
795 /*   incremental: -i switch.  sweepline: -F switch.                          */
796 /*   dwyer: inverse of -l switch.                                            */
797 /*   splitseg: -s switch.                                                    */
798 /*   conformdel: -D switch.  docheck: -C switch.                             */
799 /*   quiet: -Q switch.  verbose: count of how often -V switch is selected.   */
800 /*   usesegments: -p, -r, -q, or -c switch; determines whether segments are  */
801 /*     used at all.                                                          */
802 /*                                                                           */
803 /* Read the instructions to find out the meaning of these switches.          */
804 
805   int poly, refine, quality, vararea, fixedarea, usertest;
806   int regionattrib, convex, weighted, jettison;
807   int firstnumber;
808   int edgesout, voronoi, neighbors, geomview;
809   int nobound, nopolywritten, nonodewritten, noelewritten, noiterationnum;
810   int noholes, noexact, conformdel;
811   int incremental, sweepline, dwyer;
812   int splitseg;
813   int docheck;
814   int quiet, verbose;
815   int usesegments;
816   int order;
817   int nobisect;
818   int steiner;
819   REAL minangle, goodangle, offconstant;
820   REAL maxarea;
821 
822 /* Variables for file names.                                                 */
823 
824 #ifndef TRILIBRARY
825   char innodefilename[FILENAMESIZE];
826   char inelefilename[FILENAMESIZE];
827   char inpolyfilename[FILENAMESIZE];
828   char areafilename[FILENAMESIZE];
829   char outnodefilename[FILENAMESIZE];
830   char outelefilename[FILENAMESIZE];
831   char outpolyfilename[FILENAMESIZE];
832   char edgefilename[FILENAMESIZE];
833   char vnodefilename[FILENAMESIZE];
834   char vedgefilename[FILENAMESIZE];
835   char neighborfilename[FILENAMESIZE];
836   char offfilename[FILENAMESIZE];
837 #endif /* not TRILIBRARY */
838 
839 };                                              /* End of `struct behavior'. */
840 
841 
842 /*****************************************************************************/
843 /*                                                                           */
844 /*  Mesh manipulation primitives.  Each triangle contains three pointers to  */
845 /*  other triangles, with orientations.  Each pointer points not to the      */
846 /*  first byte of a triangle, but to one of the first three bytes of a       */
847 /*  triangle.  It is necessary to extract both the triangle itself and the   */
848 /*  orientation.  To save memory, I keep both pieces of information in one   */
849 /*  pointer.  To make this possible, I assume that all triangles are aligned */
850 /*  to four-byte boundaries.  The decode() routine below decodes a pointer,  */
851 /*  extracting an orientation (in the range 0 to 2) and a pointer to the     */
852 /*  beginning of a triangle.  The encode() routine compresses a pointer to a */
853 /*  triangle and an orientation into a single pointer.  My assumptions that  */
854 /*  triangles are four-byte-aligned and that the `unsigned long' type is     */
855 /*  long enough to hold a pointer are two of the few kludges in this program.*/
856 /*                                                                           */
857 /*  Subsegments are manipulated similarly.  A pointer to a subsegment        */
858 /*  carries both an address and an orientation in the range 0 to 1.          */
859 /*                                                                           */
860 /*  The other primitives take an oriented triangle or oriented subsegment,   */
861 /*  and return an oriented triangle or oriented subsegment or vertex; or     */
862 /*  they change the connections in the data structure.                       */
863 /*                                                                           */
864 /*  Below, triangles and subsegments are denoted by their vertices.  The     */
865 /*  triangle abc has origin (org) a, destination (dest) b, and apex (apex)   */
866 /*  c.  These vertices occur in counterclockwise order about the triangle.   */
867 /*  The handle abc may simultaneously denote vertex a, edge ab, and triangle */
868 /*  abc.                                                                     */
869 /*                                                                           */
870 /*  Similarly, the subsegment ab has origin (sorg) a and destination (sdest) */
871 /*  b.  If ab is thought to be directed upward (with b directly above a),    */
872 /*  then the handle ab is thought to grasp the right side of ab, and may     */
873 /*  simultaneously denote vertex a and edge ab.                              */
874 /*                                                                           */
875 /*  An asterisk (*) denotes a vertex whose identity is unknown.              */
876 /*                                                                           */
877 /*  Given this notation, a partial list of mesh manipulation primitives      */
878 /*  follows.                                                                 */
879 /*                                                                           */
880 /*                                                                           */
881 /*  For triangles:                                                           */
882 /*                                                                           */
883 /*  sym:  Find the abutting triangle; same edge.                             */
884 /*  sym(abc) -> ba*                                                          */
885 /*                                                                           */
886 /*  lnext:  Find the next edge (counterclockwise) of a triangle.             */
887 /*  lnext(abc) -> bca                                                        */
888 /*                                                                           */
889 /*  lprev:  Find the previous edge (clockwise) of a triangle.                */
890 /*  lprev(abc) -> cab                                                        */
891 /*                                                                           */
892 /*  onext:  Find the next edge counterclockwise with the same origin.        */
893 /*  onext(abc) -> ac*                                                        */
894 /*                                                                           */
895 /*  oprev:  Find the next edge clockwise with the same origin.               */
896 /*  oprev(abc) -> a*b                                                        */
897 /*                                                                           */
898 /*  dnext:  Find the next edge counterclockwise with the same destination.   */
899 /*  dnext(abc) -> *ba                                                        */
900 /*                                                                           */
901 /*  dprev:  Find the next edge clockwise with the same destination.          */
902 /*  dprev(abc) -> cb*                                                        */
903 /*                                                                           */
904 /*  rnext:  Find the next edge (counterclockwise) of the adjacent triangle.  */
905 /*  rnext(abc) -> *a*                                                        */
906 /*                                                                           */
907 /*  rprev:  Find the previous edge (clockwise) of the adjacent triangle.     */
908 /*  rprev(abc) -> b**                                                        */
909 /*                                                                           */
910 /*  org:  Origin          dest:  Destination          apex:  Apex            */
911 /*  org(abc) -> a         dest(abc) -> b              apex(abc) -> c         */
912 /*                                                                           */
913 /*  bond:  Bond two triangles together at the resepective handles.           */
914 /*  bond(abc, bad)                                                           */
915 /*                                                                           */
916 /*                                                                           */
917 /*  For subsegments:                                                         */
918 /*                                                                           */
919 /*  ssym:  Reverse the orientation of a subsegment.                          */
920 /*  ssym(ab) -> ba                                                           */
921 /*                                                                           */
922 /*  spivot:  Find adjoining subsegment with the same origin.                 */
923 /*  spivot(ab) -> a*                                                         */
924 /*                                                                           */
925 /*  snext:  Find next subsegment in sequence.                                */
926 /*  snext(ab) -> b*                                                          */
927 /*                                                                           */
928 /*  sorg:  Origin                      sdest:  Destination                   */
929 /*  sorg(ab) -> a                      sdest(ab) -> b                        */
930 /*                                                                           */
931 /*  sbond:  Bond two subsegments together at the respective origins.         */
932 /*  sbond(ab, ac)                                                            */
933 /*                                                                           */
934 /*                                                                           */
935 /*  For interacting tetrahedra and subfacets:                                */
936 /*                                                                           */
937 /*  tspivot:  Find a subsegment abutting a triangle.                         */
938 /*  tspivot(abc) -> ba                                                       */
939 /*                                                                           */
940 /*  stpivot:  Find a triangle abutting a subsegment.                         */
941 /*  stpivot(ab) -> ba*                                                       */
942 /*                                                                           */
943 /*  tsbond:  Bond a triangle to a subsegment.                                */
944 /*  tsbond(abc, ba)                                                          */
945 /*                                                                           */
946 /*****************************************************************************/
947 
948 /********* Mesh manipulation primitives begin here                   *********/
949 /**                                                                         **/
950 /**                                                                         **/
951 
952 /* Fast lookup arrays to speed some of the mesh manipulation primitives.     */
953 
954 int plus1mod3[3] = {1, 2, 0};
955 int minus1mod3[3] = {2, 0, 1};
956 
957 /********* Primitives for triangles                                  *********/
958 /*                                                                           */
959 /*                                                                           */
960 
961 /* decode() converts a pointer to an oriented triangle.  The orientation is  */
962 /*   extracted from the two least significant bits of the pointer.           */
963 
964 #define decode(ptr, otri)                                                     \
965   (otri).orient = (int) ((INT_PTR) (ptr) & (INT_PTR) 3l);                     \
966   (otri).tri = (triangle *)                                                   \
967                   ((INT_PTR) (ptr) ^ (INT_PTR) (otri).orient)
968 
969 /* encode() compresses an oriented triangle into a single pointer.  It       */
970 /*   relies on the assumption that all triangles are aligned to four-byte    */
971 /*   boundaries, so the two least significant bits of (otri).tri are zero.   */
972 
973 #define encode(otri)                                                          \
974   (triangle) ((INT_PTR) (otri).tri | (INT_PTR) (otri).orient)
975 
976 /* The following handle manipulation primitives are all described by Guibas  */
977 /*   and Stolfi.  However, Guibas and Stolfi use an edge-based data          */
978 /*   structure, whereas I use a triangle-based data structure.               */
979 
980 /* sym() finds the abutting triangle, on the same edge.  Note that the edge  */
981 /*   direction is necessarily reversed, because the handle specified by an   */
982 /*   oriented triangle is directed counterclockwise around the triangle.     */
983 
984 #define sym(otri1, otri2)                                                     \
985   ptr = (otri1).tri[(otri1).orient];                                          \
986   decode(ptr, otri2);
987 
988 #define symself(otri)                                                         \
989   ptr = (otri).tri[(otri).orient];                                            \
990   decode(ptr, otri);
991 
992 /* lnext() finds the next edge (counterclockwise) of a triangle.             */
993 
994 #define lnext(otri1, otri2)                                                   \
995   (otri2).tri = (otri1).tri;                                                  \
996   (otri2).orient = plus1mod3[(otri1).orient]
997 
998 #define lnextself(otri)                                                       \
999   (otri).orient = plus1mod3[(otri).orient]
1000 
1001 /* lprev() finds the previous edge (clockwise) of a triangle.                */
1002 
1003 #define lprev(otri1, otri2)                                                   \
1004   (otri2).tri = (otri1).tri;                                                  \
1005   (otri2).orient = minus1mod3[(otri1).orient]
1006 
1007 #define lprevself(otri)                                                       \
1008   (otri).orient = minus1mod3[(otri).orient]
1009 
1010 /* onext() spins counterclockwise around a vertex; that is, it finds the     */
1011 /*   next edge with the same origin in the counterclockwise direction.  This */
1012 /*   edge is part of a different triangle.                                   */
1013 
1014 #define onext(otri1, otri2)                                                   \
1015   lprev(otri1, otri2);                                                        \
1016   symself(otri2);
1017 
1018 #define onextself(otri)                                                       \
1019   lprevself(otri);                                                            \
1020   symself(otri);
1021 
1022 /* oprev() spins clockwise around a vertex; that is, it finds the next edge  */
1023 /*   with the same origin in the clockwise direction.  This edge is part of  */
1024 /*   a different triangle.                                                   */
1025 
1026 #define oprev(otri1, otri2)                                                   \
1027   sym(otri1, otri2);                                                          \
1028   lnextself(otri2);
1029 
1030 #define oprevself(otri)                                                       \
1031   symself(otri);                                                              \
1032   lnextself(otri);
1033 
1034 /* dnext() spins counterclockwise around a vertex; that is, it finds the     */
1035 /*   next edge with the same destination in the counterclockwise direction.  */
1036 /*   This edge is part of a different triangle.                              */
1037 
1038 #define dnext(otri1, otri2)                                                   \
1039   sym(otri1, otri2);                                                          \
1040   lprevself(otri2);
1041 
1042 #define dnextself(otri)                                                       \
1043   symself(otri);                                                              \
1044   lprevself(otri);
1045 
1046 /* dprev() spins clockwise around a vertex; that is, it finds the next edge  */
1047 /*   with the same destination in the clockwise direction.  This edge is     */
1048 /*   part of a different triangle.                                           */
1049 
1050 #define dprev(otri1, otri2)                                                   \
1051   lnext(otri1, otri2);                                                        \
1052   symself(otri2);
1053 
1054 #define dprevself(otri)                                                       \
1055   lnextself(otri);                                                            \
1056   symself(otri);
1057 
1058 /* rnext() moves one edge counterclockwise about the adjacent triangle.      */
1059 /*   (It's best understood by reading Guibas and Stolfi.  It involves        */
1060 /*   changing triangles twice.)                                              */
1061 
1062 #define rnext(otri1, otri2)                                                   \
1063   sym(otri1, otri2);                                                          \
1064   lnextself(otri2);                                                           \
1065   symself(otri2);
1066 
1067 #define rnextself(otri)                                                       \
1068   symself(otri);                                                              \
1069   lnextself(otri);                                                            \
1070   symself(otri);
1071 
1072 /* rprev() moves one edge clockwise about the adjacent triangle.             */
1073 /*   (It's best understood by reading Guibas and Stolfi.  It involves        */
1074 /*   changing triangles twice.)                                              */
1075 
1076 #define rprev(otri1, otri2)                                                   \
1077   sym(otri1, otri2);                                                          \
1078   lprevself(otri2);                                                           \
1079   symself(otri2);
1080 
1081 #define rprevself(otri)                                                       \
1082   symself(otri);                                                              \
1083   lprevself(otri);                                                            \
1084   symself(otri);
1085 
1086 /* These primitives determine or set the origin, destination, or apex of a   */
1087 /* triangle.                                                                 */
1088 
1089 #define org(otri, vertexptr)                                                  \
1090   vertexptr = (vertex) (otri).tri[plus1mod3[(otri).orient] + 3]
1091 
1092 #define dest(otri, vertexptr)                                                 \
1093   vertexptr = (vertex) (otri).tri[minus1mod3[(otri).orient] + 3]
1094 
1095 #define apex(otri, vertexptr)                                                 \
1096   vertexptr = (vertex) (otri).tri[(otri).orient + 3]
1097 
1098 #define setorg(otri, vertexptr)                                               \
1099   (otri).tri[plus1mod3[(otri).orient] + 3] = (triangle) vertexptr
1100 
1101 #define setdest(otri, vertexptr)                                              \
1102   (otri).tri[minus1mod3[(otri).orient] + 3] = (triangle) vertexptr
1103 
1104 #define setapex(otri, vertexptr)                                              \
1105   (otri).tri[(otri).orient + 3] = (triangle) vertexptr
1106 
1107 /* Bond two triangles together.                                              */
1108 
1109 #define bond(otri1, otri2)                                                    \
1110   (otri1).tri[(otri1).orient] = encode(otri2);                                \
1111   (otri2).tri[(otri2).orient] = encode(otri1)
1112 
1113 /* Dissolve a bond (from one side).  Note that the other triangle will still */
1114 /*   think it's connected to this triangle.  Usually, however, the other     */
1115 /*   triangle is being deleted entirely, or bonded to another triangle, so   */
1116 /*   it doesn't matter.                                                      */
1117 
1118 #define dissolve(otri)                                                        \
1119   (otri).tri[(otri).orient] = (triangle) m->dummytri
1120 
1121 /* Copy an oriented triangle.                                                */
1122 
1123 #define otricopy(otri1, otri2)                                                \
1124   (otri2).tri = (otri1).tri;                                                  \
1125   (otri2).orient = (otri1).orient
1126 
1127 /* Test for equality of oriented triangles.                                  */
1128 
1129 #define otriequal(otri1, otri2)                                               \
1130   (((otri1).tri == (otri2).tri) &&                                            \
1131    ((otri1).orient == (otri2).orient))
1132 
1133 /* Primitives to infect or cure a triangle with the virus.  These rely on    */
1134 /*   the assumption that all subsegments are aligned to four-byte boundaries.*/
1135 
1136 #define infect(otri)                                                          \
1137   (otri).tri[6] = (triangle)                                                  \
1138                     ((INT_PTR) (otri).tri[6] | (INT_PTR) 2l)
1139 
1140 #define uninfect(otri)                                                        \
1141   (otri).tri[6] = (triangle)                                                  \
1142                     ((INT_PTR) (otri).tri[6] & ~ (INT_PTR) 2l)
1143 
1144 /* Test a triangle for viral infection.                                      */
1145 
1146 #define infected(otri)                                                        \
1147   (((INT_PTR) (otri).tri[6] & (INT_PTR) 2l) != 0l)
1148 
1149 /* Check or set a triangle's attributes.                                     */
1150 
1151 #define elemattribute(otri, attnum)                                           \
1152   ((REAL *) (otri).tri)[m->elemattribindex + (attnum)]
1153 
1154 #define setelemattribute(otri, attnum, value)                                 \
1155   ((REAL *) (otri).tri)[m->elemattribindex + (attnum)] = value
1156 
1157 /* Check or set a triangle's maximum area bound.                             */
1158 
1159 #define areabound(otri)  ((REAL *) (otri).tri)[m->areaboundindex]
1160 
1161 #define setareabound(otri, value)                                             \
1162   ((REAL *) (otri).tri)[m->areaboundindex] = value
1163 
1164 /* Check or set a triangle's deallocation.  Its second pointer is set to     */
1165 /*   NULL to indicate that it is not allocated.  (Its first pointer is used  */
1166 /*   for the stack of dead items.)  Its fourth pointer (its first vertex)    */
1167 /*   is set to NULL in case a `badtriang' structure points to it.            */
1168 
1169 #define deadtri(tria)  ((tria)[1] == (triangle) NULL)
1170 
1171 #define killtri(tria)                                                         \
1172   (tria)[1] = (triangle) NULL;                                                \
1173   (tria)[3] = (triangle) NULL
1174 
1175 /********* Primitives for subsegments                                *********/
1176 /*                                                                           */
1177 /*                                                                           */
1178 
1179 /* sdecode() converts a pointer to an oriented subsegment.  The orientation  */
1180 /*   is extracted from the least significant bit of the pointer.  The two    */
1181 /*   least significant bits (one for orientation, one for viral infection)   */
1182 /*   are masked out to produce the real pointer.                             */
1183 
1184 #define sdecode(sptr, osub)                                                   \
1185   (osub).ssorient = (int) ((INT_PTR) (sptr) & (INT_PTR) 1l);                  \
1186   (osub).ss = (subseg *)                                                      \
1187               ((INT_PTR) (sptr) & ~ (INT_PTR) 3l)
1188 
1189 /* sencode() compresses an oriented subsegment into a single pointer.  It    */
1190 /*   relies on the assumption that all subsegments are aligned to two-byte   */
1191 /*   boundaries, so the least significant bit of (osub).ss is zero.          */
1192 
1193 #define sencode(osub)                                                         \
1194   (subseg) ((INT_PTR) (osub).ss | (INT_PTR) (osub).ssorient)
1195 
1196 /* ssym() toggles the orientation of a subsegment.                           */
1197 
1198 #define ssym(osub1, osub2)                                                    \
1199   (osub2).ss = (osub1).ss;                                                    \
1200   (osub2).ssorient = 1 - (osub1).ssorient
1201 
1202 #define ssymself(osub)                                                        \
1203   (osub).ssorient = 1 - (osub).ssorient
1204 
1205 /* spivot() finds the other subsegment (from the same segment) that shares   */
1206 /*   the same origin.                                                        */
1207 
1208 #define spivot(osub1, osub2)                                                  \
1209   sptr = (osub1).ss[(osub1).ssorient];                                        \
1210   sdecode(sptr, osub2)
1211 
1212 #define spivotself(osub)                                                      \
1213   sptr = (osub).ss[(osub).ssorient];                                          \
1214   sdecode(sptr, osub)
1215 
1216 /* snext() finds the next subsegment (from the same segment) in sequence;    */
1217 /*   one whose origin is the input subsegment's destination.                 */
1218 
1219 #define snext(osub1, osub2)                                                   \
1220   sptr = (osub1).ss[1 - (osub1).ssorient];                                    \
1221   sdecode(sptr, osub2)
1222 
1223 #define snextself(osub)                                                       \
1224   sptr = (osub).ss[1 - (osub).ssorient];                                      \
1225   sdecode(sptr, osub)
1226 
1227 /* These primitives determine or set the origin or destination of a          */
1228 /*   subsegment or the segment that includes it.                             */
1229 
1230 #define sorg(osub, vertexptr)                                                 \
1231   vertexptr = (vertex) (osub).ss[2 + (osub).ssorient]
1232 
1233 #define sdest(osub, vertexptr)                                                \
1234   vertexptr = (vertex) (osub).ss[3 - (osub).ssorient]
1235 
1236 #define setsorg(osub, vertexptr)                                              \
1237   (osub).ss[2 + (osub).ssorient] = (subseg) vertexptr
1238 
1239 #define setsdest(osub, vertexptr)                                             \
1240   (osub).ss[3 - (osub).ssorient] = (subseg) vertexptr
1241 
1242 #define segorg(osub, vertexptr)                                               \
1243   vertexptr = (vertex) (osub).ss[4 + (osub).ssorient]
1244 
1245 #define segdest(osub, vertexptr)                                              \
1246   vertexptr = (vertex) (osub).ss[5 - (osub).ssorient]
1247 
1248 #define setsegorg(osub, vertexptr)                                            \
1249   (osub).ss[4 + (osub).ssorient] = (subseg) vertexptr
1250 
1251 #define setsegdest(osub, vertexptr)                                           \
1252   (osub).ss[5 - (osub).ssorient] = (subseg) vertexptr
1253 
1254 /* These primitives read or set a boundary marker.  Boundary markers are     */
1255 /*   used to hold user-defined tags for setting boundary conditions in       */
1256 /*   finite element solvers.                                                 */
1257 
1258 #define mark(osub)  (* (int *) ((osub).ss + 8))
1259 
1260 #define setmark(osub, value)                                                  \
1261   * (int *) ((osub).ss + 8) = value
1262 
1263 /* Bond two subsegments together.                                            */
1264 
1265 #define sbond(osub1, osub2)                                                   \
1266   (osub1).ss[(osub1).ssorient] = sencode(osub2);                              \
1267   (osub2).ss[(osub2).ssorient] = sencode(osub1)
1268 
1269 /* Dissolve a subsegment bond (from one side).  Note that the other          */
1270 /*   subsegment will still think it's connected to this subsegment.          */
1271 
1272 #define sdissolve(osub)                                                       \
1273   (osub).ss[(osub).ssorient] = (subseg) m->dummysub
1274 
1275 /* Copy a subsegment.                                                        */
1276 
1277 #define subsegcopy(osub1, osub2)                                              \
1278   (osub2).ss = (osub1).ss;                                                    \
1279   (osub2).ssorient = (osub1).ssorient
1280 
1281 /* Test for equality of subsegments.                                         */
1282 
1283 #define subsegequal(osub1, osub2)                                             \
1284   (((osub1).ss == (osub2).ss) &&                                              \
1285    ((osub1).ssorient == (osub2).ssorient))
1286 
1287 /* Check or set a subsegment's deallocation.  Its second pointer is set to   */
1288 /*   NULL to indicate that it is not allocated.  (Its first pointer is used  */
1289 /*   for the stack of dead items.)  Its third pointer (its first vertex)     */
1290 /*   is set to NULL in case a `badsubseg' structure points to it.            */
1291 
1292 #define deadsubseg(sub)  ((sub)[1] == (subseg) NULL)
1293 
1294 #define killsubseg(sub)                                                       \
1295   (sub)[1] = (subseg) NULL;                                                   \
1296   (sub)[2] = (subseg) NULL
1297 
1298 /********* Primitives for interacting triangles and subsegments      *********/
1299 /*                                                                           */
1300 /*                                                                           */
1301 
1302 /* tspivot() finds a subsegment abutting a triangle.                         */
1303 
1304 #define tspivot(otri, osub)                                                   \
1305   sptr = (subseg) (otri).tri[6 + (otri).orient];                              \
1306   sdecode(sptr, osub)
1307 
1308 /* stpivot() finds a triangle abutting a subsegment.  It requires that the   */
1309 /*   variable `ptr' of type `triangle' be defined.                           */
1310 
1311 #define stpivot(osub, otri)                                                   \
1312   ptr = (triangle) (osub).ss[6 + (osub).ssorient];                            \
1313   decode(ptr, otri)
1314 
1315 /* Bond a triangle to a subsegment.                                          */
1316 
1317 #define tsbond(otri, osub)                                                    \
1318   (otri).tri[6 + (otri).orient] = (triangle) sencode(osub);                   \
1319   (osub).ss[6 + (osub).ssorient] = (subseg) encode(otri)
1320 
1321 /* Dissolve a bond (from the triangle side).                                 */
1322 
1323 #define tsdissolve(otri)                                                      \
1324   (otri).tri[6 + (otri).orient] = (triangle) m->dummysub
1325 
1326 /* Dissolve a bond (from the subsegment side).                               */
1327 
1328 #define stdissolve(osub)                                                      \
1329   (osub).ss[6 + (osub).ssorient] = (subseg) m->dummytri
1330 
1331 /********* Primitives for vertices                                   *********/
1332 /*                                                                           */
1333 /*                                                                           */
1334 
1335 #define vertexmark(vx)  ((int *) (vx))[m->vertexmarkindex]
1336 
1337 #define setvertexmark(vx, value)                                              \
1338   ((int *) (vx))[m->vertexmarkindex] = value
1339 
1340 #define vertextype(vx)  ((int *) (vx))[m->vertexmarkindex + 1]
1341 
1342 #define setvertextype(vx, value)                                              \
1343   ((int *) (vx))[m->vertexmarkindex + 1] = value
1344 
1345 #define vertex2tri(vx)  ((triangle *) (vx))[m->vertex2triindex]
1346 
1347 #define setvertex2tri(vx, value)                                              \
1348   ((triangle *) (vx))[m->vertex2triindex] = value
1349 
1350 /**                                                                         **/
1351 /**                                                                         **/
1352 /********* Mesh manipulation primitives end here                     *********/
1353 
1354 /********* User-defined triangle evaluation routine begins here      *********/
1355 /**                                                                         **/
1356 /**                                                                         **/
1357 
1358 /*****************************************************************************/
1359 /*                                                                           */
1360 /*  triunsuitable()   Determine if a triangle is unsuitable, and thus must   */
1361 /*                    be further refined.                                    */
1362 /*                                                                           */
1363 /*  You may write your own procedure that decides whether or not a selected  */
1364 /*  triangle is too big (and needs to be refined).  There are two ways to do */
1365 /*  this.                                                                    */
1366 /*                                                                           */
1367 /*  (1)  Modify the procedure `triunsuitable' below, then recompile          */
1368 /*  Triangle.                                                                */
1369 /*                                                                           */
1370 /*  (2)  Define the symbol EXTERNAL_TEST (either by adding the definition    */
1371 /*  to this file, or by using the appropriate compiler switch).  This way,   */
1372 /*  you can compile triangle.c separately from your test.  Write your own    */
1373 /*  `triunsuitable' procedure in a separate C file (using the same prototype */
1374 /*  as below).  Compile it and link the object code with triangle.o.         */
1375 /*                                                                           */
1376 /*  This procedure returns 1 if the triangle is too large and should be      */
1377 /*  refined; 0 otherwise.                                                    */
1378 /*                                                                           */
1379 /*****************************************************************************/
1380 
1381 #ifdef EXTERNAL_TEST
1382 
1383 int triunsuitable();
1384 
1385 #else /* not EXTERNAL_TEST */
1386 
1387 #ifdef ANSI_DECLARATORS
1388 int triunsuitable(vertex triorg, vertex tridest, vertex triapex, REAL area)
1389 #else /* not ANSI_DECLARATORS */
1390 int triunsuitable(triorg, tridest, triapex, area)
1391 vertex triorg;                              /* The triangle's origin vertex. */
1392 vertex tridest;                        /* The triangle's destination vertex. */
1393 vertex triapex;                               /* The triangle's apex vertex. */
1394 REAL area;                                      /* The area of the triangle. */
1395 #endif /* not ANSI_DECLARATORS */
1396 
1397 {
1398   REAL dxoa, dxda, dxod;
1399   REAL dyoa, dyda, dyod;
1400   REAL oalen, dalen, odlen;
1401   REAL maxlen;
1402 
1403   dxoa = triorg[0] - triapex[0];
1404   dyoa = triorg[1] - triapex[1];
1405   dxda = tridest[0] - triapex[0];
1406   dyda = tridest[1] - triapex[1];
1407   dxod = triorg[0] - tridest[0];
1408   dyod = triorg[1] - tridest[1];
1409   /* Find the squares of the lengths of the triangle's three edges. */
1410   oalen = dxoa * dxoa + dyoa * dyoa;
1411   dalen = dxda * dxda + dyda * dyda;
1412   odlen = dxod * dxod + dyod * dyod;
1413   /* Find the square of the length of the longest edge. */
1414   maxlen = (dalen > oalen) ? dalen : oalen;
1415   maxlen = (odlen > maxlen) ? odlen : maxlen;
1416 
1417   if (maxlen > 0.05 * (triorg[0] * triorg[0] + triorg[1] * triorg[1]) + 0.02) {
1418     return 1;
1419   } else {
1420     return 0;
1421   }
1422 }
1423 
1424 #endif /* not EXTERNAL_TEST */
1425 
1426 /**                                                                         **/
1427 /**                                                                         **/
1428 /********* User-defined triangle evaluation routine ends here        *********/
1429 
1430 /********* Memory allocation and program exit wrappers begin here    *********/
1431 /**                                                                         **/
1432 /**                                                                         **/
1433 
1434 #ifdef ANSI_DECLARATORS
1435 void triexit(int status)
1436 #else /* not ANSI_DECLARATORS */
1437 void triexit(status)
1438 int status;
1439 #endif /* not ANSI_DECLARATORS */
1440 
1441 {
1442   exit(status);
1443 }
1444 
1445 #ifdef ANSI_DECLARATORS
1446 VOID *trimalloc(int size)
1447 #else /* not ANSI_DECLARATORS */
1448 VOID *trimalloc(size)
1449 int size;
1450 #endif /* not ANSI_DECLARATORS */
1451 
1452 {
1453   VOID *memptr;
1454 
1455   memptr = (VOID *) malloc((unsigned int) size);
1456   if (memptr == (VOID *) NULL) {
1457     printf("Error:  Out of memory.\n");
1458     triexit(1);
1459   }
1460   return(memptr);
1461 }
1462 
1463 #ifdef ANSI_DECLARATORS
1464 void trifree(VOID *memptr)
1465 #else /* not ANSI_DECLARATORS */
1466 void trifree(memptr)
1467 VOID *memptr;
1468 #endif /* not ANSI_DECLARATORS */
1469 
1470 {
1471   free(memptr);
1472 }
1473 
1474 /**                                                                         **/
1475 /**                                                                         **/
1476 /********* Memory allocation and program exit wrappers end here      *********/
1477 
1478 /********* User interaction routines begin here                      *********/
1479 /**                                                                         **/
1480 /**                                                                         **/
1481 
1482 /*****************************************************************************/
1483 /*                                                                           */
1484 /*  syntax()   Print list of command line switches.                          */
1485 /*                                                                           */
1486 /*****************************************************************************/
1487 
1488 #ifndef TRILIBRARY
1489 
syntax()1490 void syntax()
1491 {
1492 #ifdef CDT_ONLY
1493 #ifdef REDUCED
1494   printf("triangle [-pAcjevngBPNEIOXzo_lQVh] input_file\n");
1495 #else /* not REDUCED */
1496   printf("triangle [-pAcjevngBPNEIOXzo_iFlCQVh] input_file\n");
1497 #endif /* not REDUCED */
1498 #else /* not CDT_ONLY */
1499 #ifdef REDUCED
1500   printf("triangle [-prq__a__uAcDjevngBPNEIOXzo_YS__lQVh] input_file\n");
1501 #else /* not REDUCED */
1502   printf("triangle [-prq__a__uAcDjevngBPNEIOXzo_YS__iFlsCQVh] input_file\n");
1503 #endif /* not REDUCED */
1504 #endif /* not CDT_ONLY */
1505 
1506   printf("    -p  Triangulates a Planar Straight Line Graph (.poly file).\n");
1507 #ifndef CDT_ONLY
1508   printf("    -r  Refines a previously generated mesh.\n");
1509   printf(
1510     "    -q  Quality mesh generation.  A minimum angle may be specified.\n");
1511   printf("    -a  Applies a maximum triangle area constraint.\n");
1512   printf("    -u  Applies a user-defined triangle constraint.\n");
1513 #endif /* not CDT_ONLY */
1514   printf(
1515     "    -A  Applies attributes to identify triangles in certain regions.\n");
1516   printf("    -c  Encloses the convex hull with segments.\n");
1517 #ifndef CDT_ONLY
1518   printf("    -D  Conforming Delaunay:  all triangles are truly Delaunay.\n");
1519 #endif /* not CDT_ONLY */
1520 /*
1521   printf("    -w  Weighted Delaunay triangulation.\n");
1522   printf("    -W  Regular triangulation (lower hull of a height field).\n");
1523 */
1524   printf("    -j  Jettison unused vertices from output .node file.\n");
1525   printf("    -e  Generates an edge list.\n");
1526   printf("    -v  Generates a Voronoi diagram.\n");
1527   printf("    -n  Generates a list of triangle neighbors.\n");
1528   printf("    -g  Generates an .off file for Geomview.\n");
1529   printf("    -B  Suppresses output of boundary information.\n");
1530   printf("    -P  Suppresses output of .poly file.\n");
1531   printf("    -N  Suppresses output of .node file.\n");
1532   printf("    -E  Suppresses output of .ele file.\n");
1533   printf("    -I  Suppresses mesh iteration numbers.\n");
1534   printf("    -O  Ignores holes in .poly file.\n");
1535   printf("    -X  Suppresses use of exact arithmetic.\n");
1536   printf("    -z  Numbers all items starting from zero (rather than one).\n");
1537   printf("    -o2 Generates second-order subparametric elements.\n");
1538 #ifndef CDT_ONLY
1539   printf("    -Y  Suppresses boundary segment splitting.\n");
1540   printf("    -S  Specifies maximum number of added Steiner points.\n");
1541 #endif /* not CDT_ONLY */
1542 #ifndef REDUCED
1543   printf("    -i  Uses incremental method, rather than divide-and-conquer.\n");
1544   printf("    -F  Uses Fortune's sweepline algorithm, rather than d-and-c.\n");
1545 #endif /* not REDUCED */
1546   printf("    -l  Uses vertical cuts only, rather than alternating cuts.\n");
1547 #ifndef REDUCED
1548 #ifndef CDT_ONLY
1549   printf(
1550     "    -s  Force segments into mesh by splitting (instead of using CDT).\n");
1551 #endif /* not CDT_ONLY */
1552   printf("    -C  Check consistency of final mesh.\n");
1553 #endif /* not REDUCED */
1554   printf("    -Q  Quiet:  No terminal output except errors.\n");
1555   printf("    -V  Verbose:  Detailed information on what I'm doing.\n");
1556   printf("    -h  Help:  Detailed instructions for Triangle.\n");
1557   triexit(0);
1558 }
1559 
1560 #endif /* not TRILIBRARY */
1561 
1562 /*****************************************************************************/
1563 /*                                                                           */
1564 /*  info()   Print out complete instructions.                                */
1565 /*                                                                           */
1566 /*****************************************************************************/
1567 
1568 #ifndef TRILIBRARY
1569 
info()1570 void info()
1571 {
1572   printf("Triangle\n");
1573   printf(
1574 "A Two-Dimensional Quality Mesh Generator and Delaunay Triangulator.\n");
1575   printf("Version 1.6\n\n");
1576   printf(
1577 "Copyright 1993, 1995, 1997, 1998, 2002, 2005 Jonathan Richard Shewchuk\n");
1578   printf("2360 Woolsey #H / Berkeley, California 94705-1927\n");
1579   printf("Bugs/comments to jrs@cs.berkeley.edu\n");
1580   printf(
1581 "Created as part of the Quake project (tools for earthquake simulation).\n");
1582   printf(
1583 "Supported in part by NSF Grant CMS-9318163 and an NSERC 1967 Scholarship.\n");
1584   printf("There is no warranty whatsoever.  Use at your own risk.\n");
1585 #ifdef SINGLE
1586   printf("This executable is compiled for single precision arithmetic.\n\n\n");
1587 #else /* not SINGLE */
1588   printf("This executable is compiled for double precision arithmetic.\n\n\n");
1589 #endif /* not SINGLE */
1590   printf(
1591 "Triangle generates exact Delaunay triangulations, constrained Delaunay\n");
1592   printf(
1593 "triangulations, conforming Delaunay triangulations, Voronoi diagrams, and\n");
1594   printf(
1595 "high-quality triangular meshes.  The latter can be generated with no small\n"
1596 );
1597   printf(
1598 "or large angles, and are thus suitable for finite element analysis.  If no\n"
1599 );
1600   printf(
1601 "command line switch is specified, your .node input file is read, and the\n");
1602   printf(
1603 "Delaunay triangulation is returned in .node and .ele output files.  The\n");
1604   printf("command syntax is:\n\n");
1605   printf("triangle [-prq__a__uAcDjevngBPNEIOXzo_YS__iFlsCQVh] input_file\n\n");
1606   printf(
1607 "Underscores indicate that numbers may optionally follow certain switches.\n");
1608   printf(
1609 "Do not leave any space between a switch and its numeric parameter.\n");
1610   printf(
1611 "input_file must be a file with extension .node, or extension .poly if the\n");
1612   printf(
1613 "-p switch is used.  If -r is used, you must supply .node and .ele files,\n");
1614   printf(
1615 "and possibly a .poly file and an .area file as well.  The formats of these\n"
1616 );
1617   printf("files are described below.\n\n");
1618   printf("Command Line Switches:\n\n");
1619   printf(
1620 "    -p  Reads a Planar Straight Line Graph (.poly file), which can specify\n"
1621 );
1622   printf(
1623 "        vertices, segments, holes, regional attributes, and regional area\n");
1624   printf(
1625 "        constraints.  Generates a constrained Delaunay triangulation (CDT)\n"
1626 );
1627   printf(
1628 "        fitting the input; or, if -s, -q, -a, or -u is used, a conforming\n");
1629   printf(
1630 "        constrained Delaunay triangulation (CCDT).  If you want a truly\n");
1631   printf(
1632 "        Delaunay (not just constrained Delaunay) triangulation, use -D as\n");
1633   printf(
1634 "        well.  When -p is not used, Triangle reads a .node file by default.\n"
1635 );
1636   printf(
1637 "    -r  Refines a previously generated mesh.  The mesh is read from a .node\n"
1638 );
1639   printf(
1640 "        file and an .ele file.  If -p is also used, a .poly file is read\n");
1641   printf(
1642 "        and used to constrain segments in the mesh.  If -a is also used\n");
1643   printf(
1644 "        (with no number following), an .area file is read and used to\n");
1645   printf(
1646 "        impose area constraints on the mesh.  Further details on refinement\n"
1647 );
1648   printf("        appear below.\n");
1649   printf(
1650 "    -q  Quality mesh generation by Delaunay refinement (a hybrid of Paul\n");
1651   printf(
1652 "        Chew's and Jim Ruppert's algorithms).  Adds vertices to the mesh to\n"
1653 );
1654   printf(
1655 "        ensure that all angles are between 20 and 140 degrees.  An\n");
1656   printf(
1657 "        alternative bound on the minimum angle, replacing 20 degrees, may\n");
1658   printf(
1659 "        be specified after the `q'.  The specified angle may include a\n");
1660   printf(
1661 "        decimal point, but not exponential notation.  Note that a bound of\n"
1662 );
1663   printf(
1664 "        theta degrees on the smallest angle also implies a bound of\n");
1665   printf(
1666 "        (180 - 2 theta) on the largest angle.  If the minimum angle is 28.6\n"
1667 );
1668   printf(
1669 "        degrees or smaller, Triangle is mathematically guaranteed to\n");
1670   printf(
1671 "        terminate (assuming infinite precision arithmetic--Triangle may\n");
1672   printf(
1673 "        fail to terminate if you run out of precision).  In practice,\n");
1674   printf(
1675 "        Triangle often succeeds for minimum angles up to 34 degrees.  For\n");
1676   printf(
1677 "        some meshes, however, you might need to reduce the minimum angle to\n"
1678 );
1679   printf(
1680 "        avoid problems associated with insufficient floating-point\n");
1681   printf("        precision.\n");
1682   printf(
1683 "    -a  Imposes a maximum triangle area.  If a number follows the `a', no\n");
1684   printf(
1685 "        triangle is generated whose area is larger than that number.  If no\n"
1686 );
1687   printf(
1688 "        number is specified, an .area file (if -r is used) or .poly file\n");
1689   printf(
1690 "        (if -r is not used) specifies a set of maximum area constraints.\n");
1691   printf(
1692 "        An .area file contains a separate area constraint for each\n");
1693   printf(
1694 "        triangle, and is useful for refining a finite element mesh based on\n"
1695 );
1696   printf(
1697 "        a posteriori error estimates.  A .poly file can optionally contain\n"
1698 );
1699   printf(
1700 "        an area constraint for each segment-bounded region, thereby\n");
1701   printf(
1702 "        controlling triangle densities in a first triangulation of a PSLG.\n"
1703 );
1704   printf(
1705 "        You can impose both a fixed area constraint and a varying area\n");
1706   printf(
1707 "        constraint by invoking the -a switch twice, once with and once\n");
1708   printf(
1709 "        without a number following.  Each area specified may include a\n");
1710   printf("        decimal point.\n");
1711   printf(
1712 "    -u  Imposes a user-defined constraint on triangle size.  There are two\n"
1713 );
1714   printf(
1715 "        ways to use this feature.  One is to edit the triunsuitable()\n");
1716   printf(
1717 "        procedure in triangle.c to encode any constraint you like, then\n");
1718   printf(
1719 "        recompile Triangle.  The other is to compile triangle.c with the\n");
1720   printf(
1721 "        EXTERNAL_TEST symbol set (compiler switch -DEXTERNAL_TEST), then\n");
1722   printf(
1723 "        link Triangle with a separate object file that implements\n");
1724   printf(
1725 "        triunsuitable().  In either case, the -u switch causes the user-\n");
1726   printf("        defined test to be applied to every triangle.\n");
1727   printf(
1728 "    -A  Assigns an additional floating-point attribute to each triangle\n");
1729   printf(
1730 "        that identifies what segment-bounded region each triangle belongs\n");
1731   printf(
1732 "        to.  Attributes are assigned to regions by the .poly file.  If a\n");
1733   printf(
1734 "        region is not explicitly marked by the .poly file, triangles in\n");
1735   printf(
1736 "        that region are assigned an attribute of zero.  The -A switch has\n");
1737   printf(
1738 "        an effect only when the -p switch is used and the -r switch is not.\n"
1739 );
1740   printf(
1741 "    -c  Creates segments on the convex hull of the triangulation.  If you\n");
1742   printf(
1743 "        are triangulating a vertex set, this switch causes a .poly file to\n"
1744 );
1745   printf(
1746 "        be written, containing all edges of the convex hull.  If you are\n");
1747   printf(
1748 "        triangulating a PSLG, this switch specifies that the whole convex\n");
1749   printf(
1750 "        hull of the PSLG should be triangulated, regardless of what\n");
1751   printf(
1752 "        segments the PSLG has.  If you do not use this switch when\n");
1753   printf(
1754 "        triangulating a PSLG, Triangle assumes that you have identified the\n"
1755 );
1756   printf(
1757 "        region to be triangulated by surrounding it with segments of the\n");
1758   printf(
1759 "        input PSLG.  Beware:  if you are not careful, this switch can cause\n"
1760 );
1761   printf(
1762 "        the introduction of an extremely thin angle between a PSLG segment\n"
1763 );
1764   printf(
1765 "        and a convex hull segment, which can cause overrefinement (and\n");
1766   printf(
1767 "        possibly failure if Triangle runs out of precision).  If you are\n");
1768   printf(
1769 "        refining a mesh, the -c switch works differently:  it causes a\n");
1770   printf(
1771 "        .poly file to be written containing the boundary edges of the mesh\n"
1772 );
1773   printf("        (useful if no .poly file was read).\n");
1774   printf(
1775 "    -D  Conforming Delaunay triangulation:  use this switch if you want to\n"
1776 );
1777   printf(
1778 "        ensure that all the triangles in the mesh are Delaunay, and not\n");
1779   printf(
1780 "        merely constrained Delaunay; or if you want to ensure that all the\n"
1781 );
1782   printf(
1783 "        Voronoi vertices lie within the triangulation.  (Some finite volume\n"
1784 );
1785   printf(
1786 "        methods have this requirement.)  This switch invokes Ruppert's\n");
1787   printf(
1788 "        original algorithm, which splits every subsegment whose diametral\n");
1789   printf(
1790 "        circle is encroached.  It usually increases the number of vertices\n"
1791 );
1792   printf("        and triangles.\n");
1793   printf(
1794 "    -j  Jettisons vertices that are not part of the final triangulation\n");
1795   printf(
1796 "        from the output .node file.  By default, Triangle copies all\n");
1797   printf(
1798 "        vertices in the input .node file to the output .node file, in the\n");
1799   printf(
1800 "        same order, so their indices do not change.  The -j switch prevents\n"
1801 );
1802   printf(
1803 "        duplicated input vertices, or vertices `eaten' by holes, from\n");
1804   printf(
1805 "        appearing in the output .node file.  Thus, if two input vertices\n");
1806   printf(
1807 "        have exactly the same coordinates, only the first appears in the\n");
1808   printf(
1809 "        output.  If any vertices are jettisoned, the vertex numbering in\n");
1810   printf(
1811 "        the output .node file differs from that of the input .node file.\n");
1812   printf(
1813 "    -e  Outputs (to an .edge file) a list of edges of the triangulation.\n");
1814   printf(
1815 "    -v  Outputs the Voronoi diagram associated with the triangulation.\n");
1816   printf(
1817 "        Does not attempt to detect degeneracies, so some Voronoi vertices\n");
1818   printf(
1819 "        may be duplicated.  See the discussion of Voronoi diagrams below.\n");
1820   printf(
1821 "    -n  Outputs (to a .neigh file) a list of triangles neighboring each\n");
1822   printf("        triangle.\n");
1823   printf(
1824 "    -g  Outputs the mesh to an Object File Format (.off) file, suitable for\n"
1825 );
1826   printf("        viewing with the Geometry Center's Geomview package.\n");
1827   printf(
1828 "    -B  No boundary markers in the output .node, .poly, and .edge output\n");
1829   printf(
1830 "        files.  See the detailed discussion of boundary markers below.\n");
1831   printf(
1832 "    -P  No output .poly file.  Saves disk space, but you lose the ability\n");
1833   printf(
1834 "        to maintain constraining segments on later refinements of the mesh.\n"
1835 );
1836   printf("    -N  No output .node file.\n");
1837   printf("    -E  No output .ele file.\n");
1838   printf(
1839 "    -I  No iteration numbers.  Suppresses the output of .node and .poly\n");
1840   printf(
1841 "        files, so your input files won't be overwritten.  (If your input is\n"
1842 );
1843   printf(
1844 "        a .poly file only, a .node file is written.)  Cannot be used with\n");
1845   printf(
1846 "        the -r switch, because that would overwrite your input .ele file.\n");
1847   printf(
1848 "        Shouldn't be used with the -q, -a, -u, or -s switch if you are\n");
1849   printf(
1850 "        using a .node file for input, because no .node file is written, so\n"
1851 );
1852   printf("        there is no record of any added Steiner points.\n");
1853   printf("    -O  No holes.  Ignores the holes in the .poly file.\n");
1854   printf(
1855 "    -X  No exact arithmetic.  Normally, Triangle uses exact floating-point\n"
1856 );
1857   printf(
1858 "        arithmetic for certain tests if it thinks the inexact tests are not\n"
1859 );
1860   printf(
1861 "        accurate enough.  Exact arithmetic ensures the robustness of the\n");
1862   printf(
1863 "        triangulation algorithms, despite floating-point roundoff error.\n");
1864   printf(
1865 "        Disabling exact arithmetic with the -X switch causes a small\n");
1866   printf(
1867 "        improvement in speed and creates the possibility that Triangle will\n"
1868 );
1869   printf("        fail to produce a valid mesh.  Not recommended.\n");
1870   printf(
1871 "    -z  Numbers all items starting from zero (rather than one).  Note that\n"
1872 );
1873   printf(
1874 "        this switch is normally overridden by the value used to number the\n"
1875 );
1876   printf(
1877 "        first vertex of the input .node or .poly file.  However, this\n");
1878   printf(
1879 "        switch is useful when calling Triangle from another program.\n");
1880   printf(
1881 "    -o2 Generates second-order subparametric elements with six nodes each.\n"
1882 );
1883   printf(
1884 "    -Y  No new vertices on the boundary.  This switch is useful when the\n");
1885   printf(
1886 "        mesh boundary must be preserved so that it conforms to some\n");
1887   printf(
1888 "        adjacent mesh.  Be forewarned that you will probably sacrifice much\n"
1889 );
1890   printf(
1891 "        of the quality of the mesh; Triangle will try, but the resulting\n");
1892   printf(
1893 "        mesh may contain poorly shaped triangles.  Works well if all the\n");
1894   printf(
1895 "        boundary vertices are closely spaced.  Specify this switch twice\n");
1896   printf(
1897 "        (`-YY') to prevent all segment splitting, including internal\n");
1898   printf("        boundaries.\n");
1899   printf(
1900 "    -S  Specifies the maximum number of Steiner points (vertices that are\n");
1901   printf(
1902 "        not in the input, but are added to meet the constraints on minimum\n"
1903 );
1904   printf(
1905 "        angle and maximum area).  The default is to allow an unlimited\n");
1906   printf(
1907 "        number.  If you specify this switch with no number after it,\n");
1908   printf(
1909 "        the limit is set to zero.  Triangle always adds vertices at segment\n"
1910 );
1911   printf(
1912 "        intersections, even if it needs to use more vertices than the limit\n"
1913 );
1914   printf(
1915 "        you set.  When Triangle inserts segments by splitting (-s), it\n");
1916   printf(
1917 "        always adds enough vertices to ensure that all the segments of the\n"
1918 );
1919   printf("        PLSG are recovered, ignoring the limit if necessary.\n");
1920   printf(
1921 "    -i  Uses an incremental rather than a divide-and-conquer algorithm to\n");
1922   printf(
1923 "        construct a Delaunay triangulation.  Try it if the divide-and-\n");
1924   printf("        conquer algorithm fails.\n");
1925   printf(
1926 "    -F  Uses Steven Fortune's sweepline algorithm to construct a Delaunay\n");
1927   printf(
1928 "        triangulation.  Warning:  does not use exact arithmetic for all\n");
1929   printf("        calculations.  An exact result is not guaranteed.\n");
1930   printf(
1931 "    -l  Uses only vertical cuts in the divide-and-conquer algorithm.  By\n");
1932   printf(
1933 "        default, Triangle alternates between vertical and horizontal cuts,\n"
1934 );
1935   printf(
1936 "        which usually improve the speed except with vertex sets that are\n");
1937   printf(
1938 "        small or short and wide.  This switch is primarily of theoretical\n");
1939   printf("        interest.\n");
1940   printf(
1941 "    -s  Specifies that segments should be forced into the triangulation by\n"
1942 );
1943   printf(
1944 "        recursively splitting them at their midpoints, rather than by\n");
1945   printf(
1946 "        generating a constrained Delaunay triangulation.  Segment splitting\n"
1947 );
1948   printf(
1949 "        is true to Ruppert's original algorithm, but can create needlessly\n"
1950 );
1951   printf(
1952 "        small triangles.  This switch is primarily of theoretical interest.\n"
1953 );
1954   printf(
1955 "    -C  Check the consistency of the final mesh.  Uses exact arithmetic for\n"
1956 );
1957   printf(
1958 "        checking, even if the -X switch is used.  Useful if you suspect\n");
1959   printf("        Triangle is buggy.\n");
1960   printf(
1961 "    -Q  Quiet:  Suppresses all explanation of what Triangle is doing,\n");
1962   printf("        unless an error occurs.\n");
1963   printf(
1964 "    -V  Verbose:  Gives detailed information about what Triangle is doing.\n"
1965 );
1966   printf(
1967 "        Add more `V's for increasing amount of detail.  `-V' is most\n");
1968   printf(
1969 "        useful; itgives information on algorithmic progress and much more\n");
1970   printf(
1971 "        detailed statistics.  `-VV' gives vertex-by-vertex details, and\n");
1972   printf(
1973 "        prints so much that Triangle runs much more slowly.  `-VVVV' gives\n"
1974 );
1975   printf("        information only a debugger could love.\n");
1976   printf("    -h  Help:  Displays these instructions.\n");
1977   printf("\n");
1978   printf("Definitions:\n");
1979   printf("\n");
1980   printf(
1981 "  A Delaunay triangulation of a vertex set is a triangulation whose\n");
1982   printf(
1983 "  vertices are the vertex set, that covers the convex hull of the vertex\n");
1984   printf(
1985 "  set.  A Delaunay triangulation has the property that no vertex lies\n");
1986   printf(
1987 "  inside the circumscribing circle (circle that passes through all three\n");
1988   printf("  vertices) of any triangle in the triangulation.\n\n");
1989   printf(
1990 "  A Voronoi diagram of a vertex set is a subdivision of the plane into\n");
1991   printf(
1992 "  polygonal cells (some of which may be unbounded, meaning infinitely\n");
1993   printf(
1994 "  large), where each cell is the set of points in the plane that are closer\n"
1995 );
1996   printf(
1997 "  to some input vertex than to any other input vertex.  The Voronoi diagram\n"
1998 );
1999   printf("  is a geometric dual of the Delaunay triangulation.\n\n");
2000   printf(
2001 "  A Planar Straight Line Graph (PSLG) is a set of vertices and segments.\n");
2002   printf(
2003 "  Segments are simply edges, whose endpoints are all vertices in the PSLG.\n"
2004 );
2005   printf(
2006 "  Segments may intersect each other only at their endpoints.  The file\n");
2007   printf("  format for PSLGs (.poly files) is described below.\n\n");
2008   printf(
2009 "  A constrained Delaunay triangulation (CDT) of a PSLG is similar to a\n");
2010   printf(
2011 "  Delaunay triangulation, but each PSLG segment is present as a single edge\n"
2012 );
2013   printf(
2014 "  of the CDT.  (A constrained Delaunay triangulation is not truly a\n");
2015   printf(
2016 "  Delaunay triangulation, because some of its triangles might not be\n");
2017   printf(
2018 "  Delaunay.)  By definition, a CDT does not have any vertices other than\n");
2019   printf(
2020 "  those specified in the input PSLG.  Depending on context, a CDT might\n");
2021   printf(
2022 "  cover the convex hull of the PSLG, or it might cover only a segment-\n");
2023   printf("  bounded region (e.g. a polygon).\n\n");
2024   printf(
2025 "  A conforming Delaunay triangulation of a PSLG is a triangulation in which\n"
2026 );
2027   printf(
2028 "  each triangle is truly Delaunay, and each PSLG segment is represented by\n"
2029 );
2030   printf(
2031 "  a linear contiguous sequence of edges of the triangulation.  New vertices\n"
2032 );
2033   printf(
2034 "  (not part of the PSLG) may appear, and each input segment may have been\n");
2035   printf(
2036 "  subdivided into shorter edges (subsegments) by these additional vertices.\n"
2037 );
2038   printf(
2039 "  The new vertices are frequently necessary to maintain the Delaunay\n");
2040   printf("  property while ensuring that every segment is represented.\n\n");
2041   printf(
2042 "  A conforming constrained Delaunay triangulation (CCDT) of a PSLG is a\n");
2043   printf(
2044 "  triangulation of a PSLG whose triangles are constrained Delaunay.  New\n");
2045   printf("  vertices may appear, and input segments may be subdivided into\n");
2046   printf(
2047 "  subsegments, but not to guarantee that segments are respected; rather, to\n"
2048 );
2049   printf(
2050 "  improve the quality of the triangles.  The high-quality meshes produced\n");
2051   printf(
2052 "  by the -q switch are usually CCDTs, but can be made conforming Delaunay\n");
2053   printf("  with the -D switch.\n\n");
2054   printf("File Formats:\n\n");
2055   printf(
2056 "  All files may contain comments prefixed by the character '#'.  Vertices,\n"
2057 );
2058   printf(
2059 "  triangles, edges, holes, and maximum area constraints must be numbered\n");
2060   printf(
2061 "  consecutively, starting from either 1 or 0.  Whichever you choose, all\n");
2062   printf(
2063 "  input files must be consistent; if the vertices are numbered from 1, so\n");
2064   printf(
2065 "  must be all other objects.  Triangle automatically detects your choice\n");
2066   printf(
2067 "  while reading the .node (or .poly) file.  (When calling Triangle from\n");
2068   printf(
2069 "  another program, use the -z switch if you wish to number objects from\n");
2070   printf("  zero.)  Examples of these file formats are given below.\n\n");
2071   printf("  .node files:\n");
2072   printf(
2073 "    First line:  <# of vertices> <dimension (must be 2)> <# of attributes>\n"
2074 );
2075   printf(
2076 "                                           <# of boundary markers (0 or 1)>\n"
2077 );
2078   printf(
2079 "    Remaining lines:  <vertex #> <x> <y> [attributes] [boundary marker]\n");
2080   printf("\n");
2081   printf(
2082 "    The attributes, which are typically floating-point values of physical\n");
2083   printf(
2084 "    quantities (such as mass or conductivity) associated with the nodes of\n"
2085 );
2086   printf(
2087 "    a finite element mesh, are copied unchanged to the output mesh.  If -q,\n"
2088 );
2089   printf(
2090 "    -a, -u, -D, or -s is selected, each new Steiner point added to the mesh\n"
2091 );
2092   printf("    has attributes assigned to it by linear interpolation.\n\n");
2093   printf(
2094 "    If the fourth entry of the first line is `1', the last column of the\n");
2095   printf(
2096 "    remainder of the file is assumed to contain boundary markers.  Boundary\n"
2097 );
2098   printf(
2099 "    markers are used to identify boundary vertices and vertices resting on\n"
2100 );
2101   printf(
2102 "    PSLG segments; a complete description appears in a section below.  The\n"
2103 );
2104   printf(
2105 "    .node file produced by Triangle contains boundary markers in the last\n");
2106   printf("    column unless they are suppressed by the -B switch.\n\n");
2107   printf("  .ele files:\n");
2108   printf(
2109 "    First line:  <# of triangles> <nodes per triangle> <# of attributes>\n");
2110   printf(
2111 "    Remaining lines:  <triangle #> <node> <node> <node> ... [attributes]\n");
2112   printf("\n");
2113   printf(
2114 "    Nodes are indices into the corresponding .node file.  The first three\n");
2115   printf(
2116 "    nodes are the corner vertices, and are listed in counterclockwise order\n"
2117 );
2118   printf(
2119 "    around each triangle.  (The remaining nodes, if any, depend on the type\n"
2120 );
2121   printf("    of finite element used.)\n\n");
2122   printf(
2123 "    The attributes are just like those of .node files.  Because there is no\n"
2124 );
2125   printf(
2126 "    simple mapping from input to output triangles, Triangle attempts to\n");
2127   printf(
2128 "    interpolate attributes, and may cause a lot of diffusion of attributes\n"
2129 );
2130   printf(
2131 "    among nearby triangles as the triangulation is refined.  Attributes do\n"
2132 );
2133   printf("    not diffuse across segments, so attributes used to identify\n");
2134   printf("    segment-bounded regions remain intact.\n\n");
2135   printf(
2136 "    In .ele files produced by Triangle, each triangular element has three\n");
2137   printf(
2138 "    nodes (vertices) unless the -o2 switch is used, in which case\n");
2139   printf(
2140 "    subparametric quadratic elements with six nodes each are generated.\n");
2141   printf(
2142 "    The first three nodes are the corners in counterclockwise order, and\n");
2143   printf(
2144 "    the fourth, fifth, and sixth nodes lie on the midpoints of the edges\n");
2145   printf(
2146 "    opposite the first, second, and third vertices, respectively.\n");
2147   printf("\n");
2148   printf("  .poly files:\n");
2149   printf(
2150 "    First line:  <# of vertices> <dimension (must be 2)> <# of attributes>\n"
2151 );
2152   printf(
2153 "                                           <# of boundary markers (0 or 1)>\n"
2154 );
2155   printf(
2156 "    Following lines:  <vertex #> <x> <y> [attributes] [boundary marker]\n");
2157   printf("    One line:  <# of segments> <# of boundary markers (0 or 1)>\n");
2158   printf(
2159 "    Following lines:  <segment #> <endpoint> <endpoint> [boundary marker]\n");
2160   printf("    One line:  <# of holes>\n");
2161   printf("    Following lines:  <hole #> <x> <y>\n");
2162   printf(
2163 "    Optional line:  <# of regional attributes and/or area constraints>\n");
2164   printf(
2165 "    Optional following lines:  <region #> <x> <y> <attribute> <max area>\n");
2166   printf("\n");
2167   printf(
2168 "    A .poly file represents a PSLG, as well as some additional information.\n"
2169 );
2170   printf(
2171 "    The first section lists all the vertices, and is identical to the\n");
2172   printf(
2173 "    format of .node files.  <# of vertices> may be set to zero to indicate\n"
2174 );
2175   printf(
2176 "    that the vertices are listed in a separate .node file; .poly files\n");
2177   printf(
2178 "    produced by Triangle always have this format.  A vertex set represented\n"
2179 );
2180   printf(
2181 "    this way has the advantage that it may easily be triangulated with or\n");
2182   printf(
2183 "    without segments (depending on whether the -p switch is invoked).\n");
2184   printf("\n");
2185   printf(
2186 "    The second section lists the segments.  Segments are edges whose\n");
2187   printf(
2188 "    presence in the triangulation is enforced.  (Depending on the choice of\n"
2189 );
2190   printf(
2191 "    switches, segment might be subdivided into smaller edges).  Each\n");
2192   printf(
2193 "    segment is specified by listing the indices of its two endpoints.  This\n"
2194 );
2195   printf(
2196 "    means that you must include its endpoints in the vertex list.  Each\n");
2197   printf("    segment, like each point, may have a boundary marker.\n\n");
2198   printf(
2199 "    If -q, -a, -u, and -s are not selected, Triangle produces a constrained\n"
2200 );
2201   printf(
2202 "    Delaunay triangulation (CDT), in which each segment appears as a single\n"
2203 );
2204   printf(
2205 "    edge in the triangulation.  If -q, -a, -u, or -s is selected, Triangle\n"
2206 );
2207   printf(
2208 "    produces a conforming constrained Delaunay triangulation (CCDT), in\n");
2209   printf(
2210 "    which segments may be subdivided into smaller edges.  If -D is\n");
2211   printf(
2212 "    selected, Triangle produces a conforming Delaunay triangulation, so\n");
2213   printf(
2214 "    that every triangle is Delaunay, and not just constrained Delaunay.\n");
2215   printf("\n");
2216   printf(
2217 "    The third section lists holes (and concavities, if -c is selected) in\n");
2218   printf(
2219 "    the triangulation.  Holes are specified by identifying a point inside\n");
2220   printf(
2221 "    each hole.  After the triangulation is formed, Triangle creates holes\n");
2222   printf(
2223 "    by eating triangles, spreading out from each hole point until its\n");
2224   printf(
2225 "    progress is blocked by segments in the PSLG.  You must be careful to\n");
2226   printf(
2227 "    enclose each hole in segments, or your whole triangulation might be\n");
2228   printf(
2229 "    eaten away.  If the two triangles abutting a segment are eaten, the\n");
2230   printf(
2231 "    segment itself is also eaten.  Do not place a hole directly on a\n");
2232   printf("    segment; if you do, Triangle chooses one side of the segment\n");
2233   printf("    arbitrarily.\n\n");
2234   printf(
2235 "    The optional fourth section lists regional attributes (to be assigned\n");
2236   printf(
2237 "    to all triangles in a region) and regional constraints on the maximum\n");
2238   printf(
2239 "    triangle area.  Triangle reads this section only if the -A switch is\n");
2240   printf(
2241 "    used or the -a switch is used without a number following it, and the -r\n"
2242 );
2243   printf(
2244 "    switch is not used.  Regional attributes and area constraints are\n");
2245   printf(
2246 "    propagated in the same manner as holes:  you specify a point for each\n");
2247   printf(
2248 "    attribute and/or constraint, and the attribute and/or constraint\n");
2249   printf(
2250 "    affects the whole region (bounded by segments) containing the point.\n");
2251   printf(
2252 "    If two values are written on a line after the x and y coordinate, the\n");
2253   printf(
2254 "    first such value is assumed to be a regional attribute (but is only\n");
2255   printf(
2256 "    applied if the -A switch is selected), and the second value is assumed\n"
2257 );
2258   printf(
2259 "    to be a regional area constraint (but is only applied if the -a switch\n"
2260 );
2261   printf(
2262 "    is selected).  You may specify just one value after the coordinates,\n");
2263   printf(
2264 "    which can serve as both an attribute and an area constraint, depending\n"
2265 );
2266   printf(
2267 "    on the choice of switches.  If you are using the -A and -a switches\n");
2268   printf(
2269 "    simultaneously and wish to assign an attribute to some region without\n");
2270   printf("    imposing an area constraint, use a negative maximum area.\n\n");
2271   printf(
2272 "    When a triangulation is created from a .poly file, you must either\n");
2273   printf(
2274 "    enclose the entire region to be triangulated in PSLG segments, or\n");
2275   printf(
2276 "    use the -c switch, which automatically creates extra segments that\n");
2277   printf(
2278 "    enclose the convex hull of the PSLG.  If you do not use the -c switch,\n"
2279 );
2280   printf(
2281 "    Triangle eats all triangles that are not enclosed by segments; if you\n");
2282   printf(
2283 "    are not careful, your whole triangulation may be eaten away.  If you do\n"
2284 );
2285   printf(
2286 "    use the -c switch, you can still produce concavities by the appropriate\n"
2287 );
2288   printf(
2289 "    placement of holes just inside the boundary of the convex hull.\n");
2290   printf("\n");
2291   printf(
2292 "    An ideal PSLG has no intersecting segments, nor any vertices that lie\n");
2293   printf(
2294 "    upon segments (except, of course, the endpoints of each segment).  You\n"
2295 );
2296   printf(
2297 "    aren't required to make your .poly files ideal, but you should be aware\n"
2298 );
2299   printf(
2300 "    of what can go wrong.  Segment intersections are relatively safe--\n");
2301   printf(
2302 "    Triangle calculates the intersection points for you and adds them to\n");
2303   printf(
2304 "    the triangulation--as long as your machine's floating-point precision\n");
2305   printf(
2306 "    doesn't become a problem.  You are tempting the fates if you have three\n"
2307 );
2308   printf(
2309 "    segments that cross at the same location, and expect Triangle to figure\n"
2310 );
2311   printf(
2312 "    out where the intersection point is.  Thanks to floating-point roundoff\n"
2313 );
2314   printf(
2315 "    error, Triangle will probably decide that the three segments intersect\n"
2316 );
2317   printf(
2318 "    at three different points, and you will find a minuscule triangle in\n");
2319   printf(
2320 "    your output--unless Triangle tries to refine the tiny triangle, uses\n");
2321   printf(
2322 "    up the last bit of machine precision, and fails to terminate at all.\n");
2323   printf(
2324 "    You're better off putting the intersection point in the input files,\n");
2325   printf(
2326 "    and manually breaking up each segment into two.  Similarly, if you\n");
2327   printf(
2328 "    place a vertex at the middle of a segment, and hope that Triangle will\n"
2329 );
2330   printf(
2331 "    break up the segment at that vertex, you might get lucky.  On the other\n"
2332 );
2333   printf(
2334 "    hand, Triangle might decide that the vertex doesn't lie precisely on\n");
2335   printf(
2336 "    the segment, and you'll have a needle-sharp triangle in your output--or\n"
2337 );
2338   printf("    a lot of tiny triangles if you're generating a quality mesh.\n");
2339   printf("\n");
2340   printf(
2341 "    When Triangle reads a .poly file, it also writes a .poly file, which\n");
2342   printf(
2343 "    includes all the subsegments--the edges that are parts of input\n");
2344   printf(
2345 "    segments.  If the -c switch is used, the output .poly file also\n");
2346   printf(
2347 "    includes all of the edges on the convex hull.  Hence, the output .poly\n"
2348 );
2349   printf(
2350 "    file is useful for finding edges associated with input segments and for\n"
2351 );
2352   printf(
2353 "    setting boundary conditions in finite element simulations.  Moreover,\n");
2354   printf(
2355 "    you will need the output .poly file if you plan to refine the output\n");
2356   printf(
2357 "    mesh, and don't want segments to be missing in later triangulations.\n");
2358   printf("\n");
2359   printf("  .area files:\n");
2360   printf("    First line:  <# of triangles>\n");
2361   printf("    Following lines:  <triangle #> <maximum area>\n");
2362   printf("\n");
2363   printf(
2364 "    An .area file associates with each triangle a maximum area that is used\n"
2365 );
2366   printf(
2367 "    for mesh refinement.  As with other file formats, every triangle must\n");
2368   printf(
2369 "    be represented, and the triangles must be numbered consecutively.  A\n");
2370   printf(
2371 "    triangle may be left unconstrained by assigning it a negative maximum\n");
2372   printf("    area.\n\n");
2373   printf("  .edge files:\n");
2374   printf("    First line:  <# of edges> <# of boundary markers (0 or 1)>\n");
2375   printf(
2376 "    Following lines:  <edge #> <endpoint> <endpoint> [boundary marker]\n");
2377   printf("\n");
2378   printf(
2379 "    Endpoints are indices into the corresponding .node file.  Triangle can\n"
2380 );
2381   printf(
2382 "    produce .edge files (use the -e switch), but cannot read them.  The\n");
2383   printf(
2384 "    optional column of boundary markers is suppressed by the -B switch.\n");
2385   printf("\n");
2386   printf(
2387 "    In Voronoi diagrams, one also finds a special kind of edge that is an\n");
2388   printf(
2389 "    infinite ray with only one endpoint.  For these edges, a different\n");
2390   printf("    format is used:\n\n");
2391   printf("        <edge #> <endpoint> -1 <direction x> <direction y>\n\n");
2392   printf(
2393 "    The `direction' is a floating-point vector that indicates the direction\n"
2394 );
2395   printf("    of the infinite ray.\n\n");
2396   printf("  .neigh files:\n");
2397   printf(
2398 "    First line:  <# of triangles> <# of neighbors per triangle (always 3)>\n"
2399 );
2400   printf(
2401 "    Following lines:  <triangle #> <neighbor> <neighbor> <neighbor>\n");
2402   printf("\n");
2403   printf(
2404 "    Neighbors are indices into the corresponding .ele file.  An index of -1\n"
2405 );
2406   printf(
2407 "    indicates no neighbor (because the triangle is on an exterior\n");
2408   printf(
2409 "    boundary).  The first neighbor of triangle i is opposite the first\n");
2410   printf("    corner of triangle i, and so on.\n\n");
2411   printf(
2412 "    Triangle can produce .neigh files (use the -n switch), but cannot read\n"
2413 );
2414   printf("    them.\n\n");
2415   printf("Boundary Markers:\n\n");
2416   printf(
2417 "  Boundary markers are tags used mainly to identify which output vertices\n");
2418   printf(
2419 "  and edges are associated with which PSLG segment, and to identify which\n");
2420   printf(
2421 "  vertices and edges occur on a boundary of the triangulation.  A common\n");
2422   printf(
2423 "  use is to determine where boundary conditions should be applied to a\n");
2424   printf(
2425 "  finite element mesh.  You can prevent boundary markers from being written\n"
2426 );
2427   printf("  into files produced by Triangle by using the -B switch.\n\n");
2428   printf(
2429 "  The boundary marker associated with each segment in an output .poly file\n"
2430 );
2431   printf("  and each edge in an output .edge file is chosen as follows:\n");
2432   printf(
2433 "    - If an output edge is part or all of a PSLG segment with a nonzero\n");
2434   printf(
2435 "      boundary marker, then the edge is assigned the same marker.\n");
2436   printf(
2437 "    - Otherwise, if the edge lies on a boundary of the triangulation\n");
2438   printf(
2439 "      (even the boundary of a hole), then the edge is assigned the marker\n");
2440   printf("      one (1).\n");
2441   printf("    - Otherwise, the edge is assigned the marker zero (0).\n");
2442   printf(
2443 "  The boundary marker associated with each vertex in an output .node file\n");
2444   printf("  is chosen as follows:\n");
2445   printf(
2446 "    - If a vertex is assigned a nonzero boundary marker in the input file,\n"
2447 );
2448   printf(
2449 "      then it is assigned the same marker in the output .node file.\n");
2450   printf(
2451 "    - Otherwise, if the vertex lies on a PSLG segment (even if it is an\n");
2452   printf(
2453 "      endpoint of the segment) with a nonzero boundary marker, then the\n");
2454   printf(
2455 "      vertex is assigned the same marker.  If the vertex lies on several\n");
2456   printf("      such segments, one of the markers is chosen arbitrarily.\n");
2457   printf(
2458 "    - Otherwise, if the vertex occurs on a boundary of the triangulation,\n");
2459   printf("      then the vertex is assigned the marker one (1).\n");
2460   printf("    - Otherwise, the vertex is assigned the marker zero (0).\n");
2461   printf("\n");
2462   printf(
2463 "  If you want Triangle to determine for you which vertices and edges are on\n"
2464 );
2465   printf(
2466 "  the boundary, assign them the boundary marker zero (or use no markers at\n"
2467 );
2468   printf(
2469 "  all) in your input files.  In the output files, all boundary vertices,\n");
2470   printf("  edges, and segments will be assigned the value one.\n\n");
2471   printf("Triangulation Iteration Numbers:\n\n");
2472   printf(
2473 "  Because Triangle can read and refine its own triangulations, input\n");
2474   printf(
2475 "  and output files have iteration numbers.  For instance, Triangle might\n");
2476   printf(
2477 "  read the files mesh.3.node, mesh.3.ele, and mesh.3.poly, refine the\n");
2478   printf(
2479 "  triangulation, and output the files mesh.4.node, mesh.4.ele, and\n");
2480   printf("  mesh.4.poly.  Files with no iteration number are treated as if\n");
2481   printf(
2482 "  their iteration number is zero; hence, Triangle might read the file\n");
2483   printf(
2484 "  points.node, triangulate it, and produce the files points.1.node and\n");
2485   printf("  points.1.ele.\n\n");
2486   printf(
2487 "  Iteration numbers allow you to create a sequence of successively finer\n");
2488   printf(
2489 "  meshes suitable for multigrid methods.  They also allow you to produce a\n"
2490 );
2491   printf(
2492 "  sequence of meshes using error estimate-driven mesh refinement.\n");
2493   printf("\n");
2494   printf(
2495 "  If you're not using refinement or quality meshing, and you don't like\n");
2496   printf(
2497 "  iteration numbers, use the -I switch to disable them.  This switch also\n");
2498   printf(
2499 "  disables output of .node and .poly files to prevent your input files from\n"
2500 );
2501   printf(
2502 "  being overwritten.  (If the input is a .poly file that contains its own\n");
2503   printf(
2504 "  points, a .node file is written.  This can be quite convenient for\n");
2505   printf("  computing CDTs or quality meshes.)\n\n");
2506   printf("Examples of How to Use Triangle:\n\n");
2507   printf(
2508 "  `triangle dots' reads vertices from dots.node, and writes their Delaunay\n"
2509 );
2510   printf(
2511 "  triangulation to dots.1.node and dots.1.ele.  (dots.1.node is identical\n");
2512   printf(
2513 "  to dots.node.)  `triangle -I dots' writes the triangulation to dots.ele\n");
2514   printf(
2515 "  instead.  (No additional .node file is needed, so none is written.)\n");
2516   printf("\n");
2517   printf(
2518 "  `triangle -pe object.1' reads a PSLG from object.1.poly (and possibly\n");
2519   printf(
2520 "  object.1.node, if the vertices are omitted from object.1.poly) and writes\n"
2521 );
2522   printf(
2523 "  its constrained Delaunay triangulation to object.2.node and object.2.ele.\n"
2524 );
2525   printf(
2526 "  The segments are copied to object.2.poly, and all edges are written to\n");
2527   printf("  object.2.edge.\n\n");
2528   printf(
2529 "  `triangle -pq31.5a.1 object' reads a PSLG from object.poly (and possibly\n"
2530 );
2531   printf(
2532 "  object.node), generates a mesh whose angles are all between 31.5 and 117\n"
2533 );
2534   printf(
2535 "  degrees and whose triangles all have areas of 0.1 or less, and writes the\n"
2536 );
2537   printf(
2538 "  mesh to object.1.node and object.1.ele.  Each segment may be broken up\n");
2539   printf("  into multiple subsegments; these are written to object.1.poly.\n");
2540   printf("\n");
2541   printf(
2542 "  Here is a sample file `box.poly' describing a square with a square hole:\n"
2543 );
2544   printf("\n");
2545   printf(
2546 "    # A box with eight vertices in 2D, no attributes, one boundary marker.\n"
2547 );
2548   printf("    8 2 0 1\n");
2549   printf("     # Outer box has these vertices:\n");
2550   printf("     1   0 0   0\n");
2551   printf("     2   0 3   0\n");
2552   printf("     3   3 0   0\n");
2553   printf("     4   3 3   33     # A special marker for this vertex.\n");
2554   printf("     # Inner square has these vertices:\n");
2555   printf("     5   1 1   0\n");
2556   printf("     6   1 2   0\n");
2557   printf("     7   2 1   0\n");
2558   printf("     8   2 2   0\n");
2559   printf("    # Five segments with boundary markers.\n");
2560   printf("    5 1\n");
2561   printf("     1   1 2   5      # Left side of outer box.\n");
2562   printf("     # Square hole has these segments:\n");
2563   printf("     2   5 7   0\n");
2564   printf("     3   7 8   0\n");
2565   printf("     4   8 6   10\n");
2566   printf("     5   6 5   0\n");
2567   printf("    # One hole in the middle of the inner square.\n");
2568   printf("    1\n");
2569   printf("     1   1.5 1.5\n");
2570   printf("\n");
2571   printf(
2572 "  Note that some segments are missing from the outer square, so you must\n");
2573   printf(
2574 "  use the `-c' switch.  After `triangle -pqc box.poly', here is the output\n"
2575 );
2576   printf(
2577 "  file `box.1.node', with twelve vertices.  The last four vertices were\n");
2578   printf(
2579 "  added to meet the angle constraint.  Vertices 1, 2, and 9 have markers\n");
2580   printf(
2581 "  from segment 1.  Vertices 6 and 8 have markers from segment 4.  All the\n");
2582   printf(
2583 "  other vertices but 4 have been marked to indicate that they lie on a\n");
2584   printf("  boundary.\n\n");
2585   printf("    12  2  0  1\n");
2586   printf("       1    0   0      5\n");
2587   printf("       2    0   3      5\n");
2588   printf("       3    3   0      1\n");
2589   printf("       4    3   3     33\n");
2590   printf("       5    1   1      1\n");
2591   printf("       6    1   2     10\n");
2592   printf("       7    2   1      1\n");
2593   printf("       8    2   2     10\n");
2594   printf("       9    0   1.5    5\n");
2595   printf("      10    1.5   0    1\n");
2596   printf("      11    3   1.5    1\n");
2597   printf("      12    1.5   3    1\n");
2598   printf("    # Generated by triangle -pqc box.poly\n");
2599   printf("\n");
2600   printf("  Here is the output file `box.1.ele', with twelve triangles.\n");
2601   printf("\n");
2602   printf("    12  3  0\n");
2603   printf("       1     5   6   9\n");
2604   printf("       2    10   3   7\n");
2605   printf("       3     6   8  12\n");
2606   printf("       4     9   1   5\n");
2607   printf("       5     6   2   9\n");
2608   printf("       6     7   3  11\n");
2609   printf("       7    11   4   8\n");
2610   printf("       8     7   5  10\n");
2611   printf("       9    12   2   6\n");
2612   printf("      10     8   7  11\n");
2613   printf("      11     5   1  10\n");
2614   printf("      12     8   4  12\n");
2615   printf("    # Generated by triangle -pqc box.poly\n\n");
2616   printf(
2617 "  Here is the output file `box.1.poly'.  Note that segments have been added\n"
2618 );
2619   printf(
2620 "  to represent the convex hull, and some segments have been subdivided by\n");
2621   printf(
2622 "  newly added vertices.  Note also that <# of vertices> is set to zero to\n");
2623   printf("  indicate that the vertices should be read from the .node file.\n");
2624   printf("\n");
2625   printf("    0  2  0  1\n");
2626   printf("    12  1\n");
2627   printf("       1     1   9     5\n");
2628   printf("       2     5   7     1\n");
2629   printf("       3     8   7     1\n");
2630   printf("       4     6   8    10\n");
2631   printf("       5     5   6     1\n");
2632   printf("       6     3  10     1\n");
2633   printf("       7     4  11     1\n");
2634   printf("       8     2  12     1\n");
2635   printf("       9     9   2     5\n");
2636   printf("      10    10   1     1\n");
2637   printf("      11    11   3     1\n");
2638   printf("      12    12   4     1\n");
2639   printf("    1\n");
2640   printf("       1   1.5 1.5\n");
2641   printf("    # Generated by triangle -pqc box.poly\n");
2642   printf("\n");
2643   printf("Refinement and Area Constraints:\n");
2644   printf("\n");
2645   printf(
2646 "  The -r switch causes a mesh (.node and .ele files) to be read and\n");
2647   printf(
2648 "  refined.  If the -p switch is also used, a .poly file is read and used to\n"
2649 );
2650   printf(
2651 "  specify edges that are constrained and cannot be eliminated (although\n");
2652   printf(
2653 "  they can be subdivided into smaller edges) by the refinement process.\n");
2654   printf("\n");
2655   printf(
2656 "  When you refine a mesh, you generally want to impose tighter constraints.\n"
2657 );
2658   printf(
2659 "  One way to accomplish this is to use -q with a larger angle, or -a\n");
2660   printf(
2661 "  followed by a smaller area than you used to generate the mesh you are\n");
2662   printf(
2663 "  refining.  Another way to do this is to create an .area file, which\n");
2664   printf(
2665 "  specifies a maximum area for each triangle, and use the -a switch\n");
2666   printf(
2667 "  (without a number following).  Each triangle's area constraint is applied\n"
2668 );
2669   printf(
2670 "  to that triangle.  Area constraints tend to diffuse as the mesh is\n");
2671   printf(
2672 "  refined, so if there are large variations in area constraint between\n");
2673   printf(
2674 "  adjacent triangles, you may not get the results you want.  In that case,\n"
2675 );
2676   printf(
2677 "  consider instead using the -u switch and writing a C procedure that\n");
2678   printf("  determines which triangles are too large.\n\n");
2679   printf(
2680 "  If you are refining a mesh composed of linear (three-node) elements, the\n"
2681 );
2682   printf(
2683 "  output mesh contains all the nodes present in the input mesh, in the same\n"
2684 );
2685   printf(
2686 "  order, with new nodes added at the end of the .node file.  However, the\n");
2687   printf(
2688 "  refinement is not hierarchical: there is no guarantee that each output\n");
2689   printf(
2690 "  element is contained in a single input element.  Often, an output element\n"
2691 );
2692   printf(
2693 "  can overlap two or three input elements, and some input edges are not\n");
2694   printf(
2695 "  present in the output mesh.  Hence, a sequence of refined meshes forms a\n"
2696 );
2697   printf(
2698 "  hierarchy of nodes, but not a hierarchy of elements.  If you refine a\n");
2699   printf(
2700 "  mesh of higher-order elements, the hierarchical property applies only to\n"
2701 );
2702   printf(
2703 "  the nodes at the corners of an element; the midpoint nodes on each edge\n");
2704   printf("  are discarded before the mesh is refined.\n\n");
2705   printf(
2706 "  Maximum area constraints in .poly files operate differently from those in\n"
2707 );
2708   printf(
2709 "  .area files.  A maximum area in a .poly file applies to the whole\n");
2710   printf(
2711 "  (segment-bounded) region in which a point falls, whereas a maximum area\n");
2712   printf(
2713 "  in an .area file applies to only one triangle.  Area constraints in .poly\n"
2714 );
2715   printf(
2716 "  files are used only when a mesh is first generated, whereas area\n");
2717   printf(
2718 "  constraints in .area files are used only to refine an existing mesh, and\n"
2719 );
2720   printf(
2721 "  are typically based on a posteriori error estimates resulting from a\n");
2722   printf("  finite element simulation on that mesh.\n\n");
2723   printf(
2724 "  `triangle -rq25 object.1' reads object.1.node and object.1.ele, then\n");
2725   printf(
2726 "  refines the triangulation to enforce a 25 degree minimum angle, and then\n"
2727 );
2728   printf(
2729 "  writes the refined triangulation to object.2.node and object.2.ele.\n");
2730   printf("\n");
2731   printf(
2732 "  `triangle -rpaa6.2 z.3' reads z.3.node, z.3.ele, z.3.poly, and z.3.area.\n"
2733 );
2734   printf(
2735 "  After reconstructing the mesh and its subsegments, Triangle refines the\n");
2736   printf(
2737 "  mesh so that no triangle has area greater than 6.2, and furthermore the\n");
2738   printf(
2739 "  triangles satisfy the maximum area constraints in z.3.area.  No angle\n");
2740   printf(
2741 "  bound is imposed at all.  The output is written to z.4.node, z.4.ele, and\n"
2742 );
2743   printf("  z.4.poly.\n\n");
2744   printf(
2745 "  The sequence `triangle -qa1 x', `triangle -rqa.3 x.1', `triangle -rqa.1\n");
2746   printf(
2747 "  x.2' creates a sequence of successively finer meshes x.1, x.2, and x.3,\n");
2748   printf("  suitable for multigrid.\n\n");
2749   printf("Convex Hulls and Mesh Boundaries:\n\n");
2750   printf(
2751 "  If the input is a vertex set (not a PSLG), Triangle produces its convex\n");
2752   printf(
2753 "  hull as a by-product in the output .poly file if you use the -c switch.\n");
2754   printf(
2755 "  There are faster algorithms for finding a two-dimensional convex hull\n");
2756   printf("  than triangulation, of course, but this one comes for free.\n\n");
2757   printf(
2758 "  If the input is an unconstrained mesh (you are using the -r switch but\n");
2759   printf(
2760 "  not the -p switch), Triangle produces a list of its boundary edges\n");
2761   printf(
2762 "  (including hole boundaries) as a by-product when you use the -c switch.\n");
2763   printf(
2764 "  If you also use the -p switch, the output .poly file contains all the\n");
2765   printf("  segments from the input .poly file as well.\n\n");
2766   printf("Voronoi Diagrams:\n\n");
2767   printf(
2768 "  The -v switch produces a Voronoi diagram, in files suffixed .v.node and\n");
2769   printf(
2770 "  .v.edge.  For example, `triangle -v points' reads points.node, produces\n");
2771   printf(
2772 "  its Delaunay triangulation in points.1.node and points.1.ele, and\n");
2773   printf(
2774 "  produces its Voronoi diagram in points.1.v.node and points.1.v.edge.  The\n"
2775 );
2776   printf(
2777 "  .v.node file contains a list of all Voronoi vertices, and the .v.edge\n");
2778   printf(
2779 "  file contains a list of all Voronoi edges, some of which may be infinite\n"
2780 );
2781   printf(
2782 "  rays.  (The choice of filenames makes it easy to run the set of Voronoi\n");
2783   printf("  vertices through Triangle, if so desired.)\n\n");
2784   printf(
2785 "  This implementation does not use exact arithmetic to compute the Voronoi\n"
2786 );
2787   printf(
2788 "  vertices, and does not check whether neighboring vertices are identical.\n"
2789 );
2790   printf(
2791 "  Be forewarned that if the Delaunay triangulation is degenerate or\n");
2792   printf(
2793 "  near-degenerate, the Voronoi diagram may have duplicate vertices or\n");
2794   printf("  crossing edges.\n\n");
2795   printf(
2796 "  The result is a valid Voronoi diagram only if Triangle's output is a true\n"
2797 );
2798   printf(
2799 "  Delaunay triangulation.  The Voronoi output is usually meaningless (and\n");
2800   printf(
2801 "  may contain crossing edges and other pathology) if the output is a CDT or\n"
2802 );
2803   printf(
2804 "  CCDT, or if it has holes or concavities.  If the triangulated domain is\n");
2805   printf(
2806 "  convex and has no holes, you can use -D switch to force Triangle to\n");
2807   printf(
2808 "  construct a conforming Delaunay triangulation instead of a CCDT, so the\n");
2809   printf("  Voronoi diagram will be valid.\n\n");
2810   printf("Mesh Topology:\n\n");
2811   printf(
2812 "  You may wish to know which triangles are adjacent to a certain Delaunay\n");
2813   printf(
2814 "  edge in an .edge file, which Voronoi cells are adjacent to a certain\n");
2815   printf(
2816 "  Voronoi edge in a .v.edge file, or which Voronoi cells are adjacent to\n");
2817   printf(
2818 "  each other.  All of this information can be found by cross-referencing\n");
2819   printf(
2820 "  output files with the recollection that the Delaunay triangulation and\n");
2821   printf("  the Voronoi diagram are planar duals.\n\n");
2822   printf(
2823 "  Specifically, edge i of an .edge file is the dual of Voronoi edge i of\n");
2824   printf(
2825 "  the corresponding .v.edge file, and is rotated 90 degrees counterclock-\n");
2826   printf(
2827 "  wise from the Voronoi edge.  Triangle j of an .ele file is the dual of\n");
2828   printf(
2829 "  vertex j of the corresponding .v.node file.  Voronoi cell k is the dual\n");
2830   printf("  of vertex k of the corresponding .node file.\n\n");
2831   printf(
2832 "  Hence, to find the triangles adjacent to a Delaunay edge, look at the\n");
2833   printf(
2834 "  vertices of the corresponding Voronoi edge.  If the endpoints of a\n");
2835   printf(
2836 "  Voronoi edge are Voronoi vertices 2 and 6 respectively, then triangles 2\n"
2837 );
2838   printf(
2839 "  and 6 adjoin the left and right sides of the corresponding Delaunay edge,\n"
2840 );
2841   printf(
2842 "  respectively.  To find the Voronoi cells adjacent to a Voronoi edge, look\n"
2843 );
2844   printf(
2845 "  at the endpoints of the corresponding Delaunay edge.  If the endpoints of\n"
2846 );
2847   printf(
2848 "  a Delaunay edge are input vertices 7 and 12, then Voronoi cells 7 and 12\n"
2849 );
2850   printf(
2851 "  adjoin the right and left sides of the corresponding Voronoi edge,\n");
2852   printf(
2853 "  respectively.  To find which Voronoi cells are adjacent to each other,\n");
2854   printf("  just read the list of Delaunay edges.\n\n");
2855   printf(
2856 "  Triangle does not write a list of the edges adjoining each Voronoi cell,\n"
2857 );
2858   printf(
2859 "  but you can reconstructed it straightforwardly.  For instance, to find\n");
2860   printf(
2861 "  all the edges of Voronoi cell 1, search the output .edge file for every\n");
2862   printf(
2863 "  edge that has input vertex 1 as an endpoint.  The corresponding dual\n");
2864   printf(
2865 "  edges in the output .v.edge file form the boundary of Voronoi cell 1.\n");
2866   printf("\n");
2867   printf(
2868 "  For each Voronoi vertex, the .neigh file gives a list of the three\n");
2869   printf(
2870 "  Voronoi vertices attached to it.  You might find this more convenient\n");
2871   printf("  than the .v.edge file.\n\n");
2872   printf("Quadratic Elements:\n\n");
2873   printf(
2874 "  Triangle generates meshes with subparametric quadratic elements if the\n");
2875   printf(
2876 "  -o2 switch is specified.  Quadratic elements have six nodes per element,\n"
2877 );
2878   printf(
2879 "  rather than three.  `Subparametric' means that the edges of the triangles\n"
2880 );
2881   printf(
2882 "  are always straight, so that subparametric quadratic elements are\n");
2883   printf(
2884 "  geometrically identical to linear elements, even though they can be used\n"
2885 );
2886   printf(
2887 "  with quadratic interpolating functions.  The three extra nodes of an\n");
2888   printf(
2889 "  element fall at the midpoints of the three edges, with the fourth, fifth,\n"
2890 );
2891   printf(
2892 "  and sixth nodes appearing opposite the first, second, and third corners\n");
2893   printf("  respectively.\n\n");
2894   printf("Domains with Small Angles:\n\n");
2895   printf(
2896 "  If two input segments adjoin each other at a small angle, clearly the -q\n"
2897 );
2898   printf(
2899 "  switch cannot remove the small angle.  Moreover, Triangle may have no\n");
2900   printf(
2901 "  choice but to generate additional triangles whose smallest angles are\n");
2902   printf(
2903 "  smaller than the specified bound.  However, these triangles only appear\n");
2904   printf(
2905 "  between input segments separated by small angles.  Moreover, if you\n");
2906   printf(
2907 "  request a minimum angle of theta degrees, Triangle will generally produce\n"
2908 );
2909   printf(
2910 "  no angle larger than 180 - 2 theta, even if it is forced to compromise on\n"
2911 );
2912   printf("  the minimum angle.\n\n");
2913   printf("Statistics:\n\n");
2914   printf(
2915 "  After generating a mesh, Triangle prints a count of entities in the\n");
2916   printf(
2917 "  output mesh, including the number of vertices, triangles, edges, exterior\n"
2918 );
2919   printf(
2920 "  boundary edges (i.e. subsegments on the boundary of the triangulation,\n");
2921   printf(
2922 "  including hole boundaries), interior boundary edges (i.e. subsegments of\n"
2923 );
2924   printf(
2925 "  input segments not on the boundary), and total subsegments.  If you've\n");
2926   printf(
2927 "  forgotten the statistics for an existing mesh, run Triangle on that mesh\n"
2928 );
2929   printf(
2930 "  with the -rNEP switches to read the mesh and print the statistics without\n"
2931 );
2932   printf(
2933 "  writing any files.  Use -rpNEP if you've got a .poly file for the mesh.\n");
2934   printf("\n");
2935   printf(
2936 "  The -V switch produces extended statistics, including a rough estimate\n");
2937   printf(
2938 "  of memory use, the number of calls to geometric predicates, and\n");
2939   printf(
2940 "  histograms of the angles and the aspect ratios of the triangles in the\n");
2941   printf("  mesh.\n\n");
2942   printf("Exact Arithmetic:\n\n");
2943   printf(
2944 "  Triangle uses adaptive exact arithmetic to perform what computational\n");
2945   printf(
2946 "  geometers call the `orientation' and `incircle' tests.  If the floating-\n"
2947 );
2948   printf(
2949 "  point arithmetic of your machine conforms to the IEEE 754 standard (as\n");
2950   printf(
2951 "  most workstations do), and does not use extended precision internal\n");
2952   printf(
2953 "  floating-point registers, then your output is guaranteed to be an\n");
2954   printf(
2955 "  absolutely true Delaunay or constrained Delaunay triangulation, roundoff\n"
2956 );
2957   printf(
2958 "  error notwithstanding.  The word `adaptive' implies that these arithmetic\n"
2959 );
2960   printf(
2961 "  routines compute the result only to the precision necessary to guarantee\n"
2962 );
2963   printf(
2964 "  correctness, so they are usually nearly as fast as their approximate\n");
2965   printf("  counterparts.\n\n");
2966   printf(
2967 "  May CPUs, including Intel x86 processors, have extended precision\n");
2968   printf(
2969 "  floating-point registers.  These must be reconfigured so their precision\n"
2970 );
2971   printf(
2972 "  is reduced to memory precision.  Triangle does this if it is compiled\n");
2973   printf("  correctly.  See the makefile for details.\n\n");
2974   printf(
2975 "  The exact tests can be disabled with the -X switch.  On most inputs, this\n"
2976 );
2977   printf(
2978 "  switch reduces the computation time by about eight percent--it's not\n");
2979   printf(
2980 "  worth the risk.  There are rare difficult inputs (having many collinear\n");
2981   printf(
2982 "  and cocircular vertices), however, for which the difference in speed\n");
2983   printf(
2984 "  could be a factor of two.  Be forewarned that these are precisely the\n");
2985   printf(
2986 "  inputs most likely to cause errors if you use the -X switch.  Hence, the\n"
2987 );
2988   printf("  -X switch is not recommended.\n\n");
2989   printf(
2990 "  Unfortunately, the exact tests don't solve every numerical problem.\n");
2991   printf(
2992 "  Exact arithmetic is not used to compute the positions of new vertices,\n");
2993   printf(
2994 "  because the bit complexity of vertex coordinates would grow without\n");
2995   printf(
2996 "  bound.  Hence, segment intersections aren't computed exactly; in very\n");
2997   printf(
2998 "  unusual cases, roundoff error in computing an intersection point might\n");
2999   printf(
3000 "  actually lead to an inverted triangle and an invalid triangulation.\n");
3001   printf(
3002 "  (This is one reason to specify your own intersection points in your .poly\n"
3003 );
3004   printf(
3005 "  files.)  Similarly, exact arithmetic is not used to compute the vertices\n"
3006 );
3007   printf("  of the Voronoi diagram.\n\n");
3008   printf(
3009 "  Another pair of problems not solved by the exact arithmetic routines is\n");
3010   printf(
3011 "  underflow and overflow.  If Triangle is compiled for double precision\n");
3012   printf(
3013 "  arithmetic, I believe that Triangle's geometric predicates work correctly\n"
3014 );
3015   printf(
3016 "  if the exponent of every input coordinate falls in the range [-148, 201].\n"
3017 );
3018   printf(
3019 "  Underflow can silently prevent the orientation and incircle tests from\n");
3020   printf(
3021 "  being performed exactly, while overflow typically causes a floating\n");
3022   printf("  exception.\n\n");
3023   printf("Calling Triangle from Another Program:\n\n");
3024   printf("  Read the file triangle.h for details.\n\n");
3025   printf("Troubleshooting:\n\n");
3026   printf("  Please read this section before mailing me bugs.\n\n");
3027   printf("  `My output mesh has no triangles!'\n\n");
3028   printf(
3029 "    If you're using a PSLG, you've probably failed to specify a proper set\n"
3030 );
3031   printf(
3032 "    of bounding segments, or forgotten to use the -c switch.  Or you may\n");
3033   printf(
3034 "    have placed a hole badly, thereby eating all your triangles.  To test\n");
3035   printf("    these possibilities, try again with the -c and -O switches.\n");
3036   printf(
3037 "    Alternatively, all your input vertices may be collinear, in which case\n"
3038 );
3039   printf("    you can hardly expect to triangulate them.\n\n");
3040   printf("  `Triangle doesn't terminate, or just crashes.'\n\n");
3041   printf(
3042 "    Bad things can happen when triangles get so small that the distance\n");
3043   printf(
3044 "    between their vertices isn't much larger than the precision of your\n");
3045   printf(
3046 "    machine's arithmetic.  If you've compiled Triangle for single-precision\n"
3047 );
3048   printf(
3049 "    arithmetic, you might do better by recompiling it for double-precision.\n"
3050 );
3051   printf(
3052 "    Then again, you might just have to settle for more lenient constraints\n"
3053 );
3054   printf(
3055 "    on the minimum angle and the maximum area than you had planned.\n");
3056   printf("\n");
3057   printf(
3058 "    You can minimize precision problems by ensuring that the origin lies\n");
3059   printf(
3060 "    inside your vertex set, or even inside the densest part of your\n");
3061   printf(
3062 "    mesh.  If you're triangulating an object whose x-coordinates all fall\n");
3063   printf(
3064 "    between 6247133 and 6247134, you're not leaving much floating-point\n");
3065   printf("    precision for Triangle to work with.\n\n");
3066   printf(
3067 "    Precision problems can occur covertly if the input PSLG contains two\n");
3068   printf(
3069 "    segments that meet (or intersect) at an extremely small angle, or if\n");
3070   printf(
3071 "    such an angle is introduced by the -c switch.  If you don't realize\n");
3072   printf(
3073 "    that a tiny angle is being formed, you might never discover why\n");
3074   printf(
3075 "    Triangle is crashing.  To check for this possibility, use the -S switch\n"
3076 );
3077   printf(
3078 "    (with an appropriate limit on the number of Steiner points, found by\n");
3079   printf(
3080 "    trial-and-error) to stop Triangle early, and view the output .poly file\n"
3081 );
3082   printf(
3083 "    with Show Me (described below).  Look carefully for regions where dense\n"
3084 );
3085   printf(
3086 "    clusters of vertices are forming and for small angles between segments.\n"
3087 );
3088   printf(
3089 "    Zoom in closely, as such segments might look like a single segment from\n"
3090 );
3091   printf("    a distance.\n\n");
3092   printf(
3093 "    If some of the input values are too large, Triangle may suffer a\n");
3094   printf(
3095 "    floating exception due to overflow when attempting to perform an\n");
3096   printf(
3097 "    orientation or incircle test.  (Read the section on exact arithmetic\n");
3098   printf(
3099 "    above.)  Again, I recommend compiling Triangle for double (rather\n");
3100   printf("    than single) precision arithmetic.\n\n");
3101   printf(
3102 "    Unexpected problems can arise if you use quality meshing (-q, -a, or\n");
3103   printf(
3104 "    -u) with an input that is not segment-bounded--that is, if your input\n");
3105   printf(
3106 "    is a vertex set, or you're using the -c switch.  If the convex hull of\n"
3107 );
3108   printf(
3109 "    your input vertices has collinear vertices on its boundary, an input\n");
3110   printf(
3111 "    vertex that you think lies on the convex hull might actually lie just\n");
3112   printf(
3113 "    inside the convex hull.  If so, the vertex and the nearby convex hull\n");
3114   printf(
3115 "    edge form an extremely thin triangle.  When Triangle tries to refine\n");
3116   printf(
3117 "    the mesh to enforce angle and area constraints, Triangle might generate\n"
3118 );
3119   printf(
3120 "    extremely tiny triangles, or it might fail because of insufficient\n");
3121   printf("    floating-point precision.\n\n");
3122   printf(
3123 "  `The numbering of the output vertices doesn't match the input vertices.'\n"
3124 );
3125   printf("\n");
3126   printf(
3127 "    You may have had duplicate input vertices, or you may have eaten some\n");
3128   printf(
3129 "    of your input vertices with a hole, or by placing them outside the area\n"
3130 );
3131   printf(
3132 "    enclosed by segments.  In any case, you can solve the problem by not\n");
3133   printf("    using the -j switch.\n\n");
3134   printf(
3135 "  `Triangle executes without incident, but when I look at the resulting\n");
3136   printf(
3137 "  mesh, it has overlapping triangles or other geometric inconsistencies.'\n");
3138   printf("\n");
3139   printf(
3140 "    If you select the -X switch, Triangle occasionally makes mistakes due\n");
3141   printf(
3142 "    to floating-point roundoff error.  Although these errors are rare,\n");
3143   printf(
3144 "    don't use the -X switch.  If you still have problems, please report the\n"
3145 );
3146   printf("    bug.\n\n");
3147   printf(
3148 "  `Triangle executes without incident, but when I look at the resulting\n");
3149   printf("  Voronoi diagram, it has overlapping edges or other geometric\n");
3150   printf("  inconsistencies.'\n");
3151   printf("\n");
3152   printf(
3153 "    If your input is a PSLG (-p), you can only expect a meaningful Voronoi\n"
3154 );
3155   printf(
3156 "    diagram if the domain you are triangulating is convex and free of\n");
3157   printf(
3158 "    holes, and you use the -D switch to construct a conforming Delaunay\n");
3159   printf("    triangulation (instead of a CDT or CCDT).\n\n");
3160   printf(
3161 "  Strange things can happen if you've taken liberties with your PSLG.  Do\n");
3162   printf(
3163 "  you have a vertex lying in the middle of a segment?  Triangle sometimes\n");
3164   printf(
3165 "  copes poorly with that sort of thing.  Do you want to lay out a collinear\n"
3166 );
3167   printf(
3168 "  row of evenly spaced, segment-connected vertices?  Have you simply\n");
3169   printf(
3170 "  defined one long segment connecting the leftmost vertex to the rightmost\n"
3171 );
3172   printf(
3173 "  vertex, and a bunch of vertices lying along it?  This method occasionally\n"
3174 );
3175   printf(
3176 "  works, especially with horizontal and vertical lines, but often it\n");
3177   printf(
3178 "  doesn't, and you'll have to connect each adjacent pair of vertices with a\n"
3179 );
3180   printf("  separate segment.  If you don't like it, tough.\n\n");
3181   printf(
3182 "  Furthermore, if you have segments that intersect other than at their\n");
3183   printf(
3184 "  endpoints, try not to let the intersections fall extremely close to PSLG\n"
3185 );
3186   printf("  vertices or each other.\n\n");
3187   printf(
3188 "  If you have problems refining a triangulation not produced by Triangle:\n");
3189   printf(
3190 "  Are you sure the triangulation is geometrically valid?  Is it formatted\n");
3191   printf(
3192 "  correctly for Triangle?  Are the triangles all listed so the first three\n"
3193 );
3194   printf(
3195 "  vertices are their corners in counterclockwise order?  Are all of the\n");
3196   printf(
3197 "  triangles constrained Delaunay?  Triangle's Delaunay refinement algorithm\n"
3198 );
3199   printf("  assumes that it starts with a CDT.\n\n");
3200   printf("Show Me:\n\n");
3201   printf(
3202 "  Triangle comes with a separate program named `Show Me', whose primary\n");
3203   printf(
3204 "  purpose is to draw meshes on your screen or in PostScript.  Its secondary\n"
3205 );
3206   printf(
3207 "  purpose is to check the validity of your input files, and do so more\n");
3208   printf(
3209 "  thoroughly than Triangle does.  Unlike Triangle, Show Me requires that\n");
3210   printf(
3211 "  you have the X Windows system.  Sorry, Microsoft Windows users.\n");
3212   printf("\n");
3213   printf("Triangle on the Web:\n");
3214   printf("\n");
3215   printf("  To see an illustrated version of these instructions, check out\n");
3216   printf("\n");
3217   printf("    http://www.cs.cmu.edu/~quake/triangle.html\n");
3218   printf("\n");
3219   printf("A Brief Plea:\n");
3220   printf("\n");
3221   printf(
3222 "  If you use Triangle, and especially if you use it to accomplish real\n");
3223   printf(
3224 "  work, I would like very much to hear from you.  A short letter or email\n");
3225   printf(
3226 "  (to jrs@cs.berkeley.edu) describing how you use Triangle will mean a lot\n"
3227 );
3228   printf(
3229 "  to me.  The more people I know are using this program, the more easily I\n"
3230 );
3231   printf(
3232 "  can justify spending time on improvements, which in turn will benefit\n");
3233   printf(
3234 "  you.  Also, I can put you on a list to receive email whenever a new\n");
3235   printf("  version of Triangle is available.\n\n");
3236   printf(
3237 "  If you use a mesh generated by Triangle in a publication, please include\n"
3238 );
3239   printf(
3240 "  an acknowledgment as well.  And please spell Triangle with a capital `T'!\n"
3241 );
3242   printf(
3243 "  If you want to include a citation, use `Jonathan Richard Shewchuk,\n");
3244   printf(
3245 "  ``Triangle: Engineering a 2D Quality Mesh Generator and Delaunay\n");
3246   printf(
3247 "  Triangulator,'' in Applied Computational Geometry:  Towards Geometric\n");
3248   printf(
3249 "  Engineering (Ming C. Lin and Dinesh Manocha, editors), volume 1148 of\n");
3250   printf(
3251 "  Lecture Notes in Computer Science, pages 203-222, Springer-Verlag,\n");
3252   printf(
3253 "  Berlin, May 1996.  (From the First ACM Workshop on Applied Computational\n"
3254 );
3255   printf("  Geometry.)'\n\n");
3256   printf("Research credit:\n\n");
3257   printf(
3258 "  Of course, I can take credit for only a fraction of the ideas that made\n");
3259   printf(
3260 "  this mesh generator possible.  Triangle owes its existence to the efforts\n"
3261 );
3262   printf(
3263 "  of many fine computational geometers and other researchers, including\n");
3264   printf(
3265 "  Marshall Bern, L. Paul Chew, Kenneth L. Clarkson, Boris Delaunay, Rex A.\n"
3266 );
3267   printf(
3268 "  Dwyer, David Eppstein, Steven Fortune, Leonidas J. Guibas, Donald E.\n");
3269   printf(
3270 "  Knuth, Charles L. Lawson, Der-Tsai Lee, Gary L. Miller, Ernst P. Mucke,\n");
3271   printf(
3272 "  Steven E. Pav, Douglas M. Priest, Jim Ruppert, Isaac Saias, Bruce J.\n");
3273   printf(
3274 "  Schachter, Micha Sharir, Peter W. Shor, Daniel D. Sleator, Jorge Stolfi,\n"
3275 );
3276   printf("  Robert E. Tarjan, Alper Ungor, Christopher J. Van Wyk, Noel J.\n");
3277   printf(
3278 "  Walkington, and Binhai Zhu.  See the comments at the beginning of the\n");
3279   printf("  source code for references.\n\n");
3280   triexit(0);
3281 }
3282 
3283 #endif /* not TRILIBRARY */
3284 
3285 /*****************************************************************************/
3286 /*                                                                           */
3287 /*  internalerror()   Ask the user to send me the defective product.  Exit.  */
3288 /*                                                                           */
3289 /*****************************************************************************/
3290 
internalerror()3291 void internalerror()
3292 {
3293   printf("  Please report this bug to jrs@cs.berkeley.edu\n");
3294   printf("  Include the message above, your input data set, and the exact\n");
3295   printf("    command line you used to run Triangle.\n");
3296   triexit(1);
3297 }
3298 
3299 /*****************************************************************************/
3300 /*                                                                           */
3301 /*  parsecommandline()   Read the command line, identify switches, and set   */
3302 /*                       up options and file names.                          */
3303 /*                                                                           */
3304 /*****************************************************************************/
3305 
3306 #ifdef ANSI_DECLARATORS
3307 void parsecommandline(int argc, char **argv, struct behavior *b)
3308 #else /* not ANSI_DECLARATORS */
3309 void parsecommandline(argc, argv, b)
3310 int argc;
3311 char **argv;
3312 struct behavior *b;
3313 #endif /* not ANSI_DECLARATORS */
3314 
3315 {
3316 #ifdef TRILIBRARY
3317 #define STARTINDEX 0
3318 #else /* not TRILIBRARY */
3319 #define STARTINDEX 1
3320   int increment;
3321   int meshnumber;
3322 #endif /* not TRILIBRARY */
3323   int i, j, k;
3324   char workstring[FILENAMESIZE];
3325 
3326   b->poly = b->refine = b->quality = 0;
3327   b->vararea = b->fixedarea = b->usertest = 0;
3328   b->regionattrib = b->convex = b->weighted = b->jettison = 0;
3329   b->firstnumber = 1;
3330   b->edgesout = b->voronoi = b->neighbors = b->geomview = 0;
3331   b->nobound = b->nopolywritten = b->nonodewritten = b->noelewritten = 0;
3332   b->noiterationnum = 0;
3333   b->noholes = b->noexact = 0;
3334   b->incremental = b->sweepline = 0;
3335   b->dwyer = 1;
3336   b->splitseg = 0;
3337   b->docheck = 0;
3338   b->nobisect = 0;
3339   b->conformdel = 0;
3340   b->steiner = -1;
3341   b->order = 1;
3342   b->minangle = 0.0;
3343   b->maxarea = -1.0;
3344   b->quiet = b->verbose = 0;
3345 #ifndef TRILIBRARY
3346   b->innodefilename[0] = '\0';
3347 #endif /* not TRILIBRARY */
3348 
3349   for (i = STARTINDEX; i < argc; i++) {
3350 #ifndef TRILIBRARY
3351     if (argv[i][0] == '-') {
3352 #endif /* not TRILIBRARY */
3353       for (j = STARTINDEX; argv[i][j] != '\0'; j++) {
3354         if (argv[i][j] == 'p') {
3355           b->poly = 1;
3356         }
3357 #ifndef CDT_ONLY
3358         if (argv[i][j] == 'r') {
3359           b->refine = 1;
3360         }
3361         if (argv[i][j] == 'q') {
3362           b->quality = 1;
3363           if (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) ||
3364               (argv[i][j + 1] == '.')) {
3365             k = 0;
3366             while (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) ||
3367                    (argv[i][j + 1] == '.')) {
3368               j++;
3369               workstring[k] = argv[i][j];
3370               k++;
3371             }
3372             workstring[k] = '\0';
3373             b->minangle = (REAL) strtod(workstring, (char **) NULL);
3374           } else {
3375             b->minangle = 20.0;
3376           }
3377         }
3378         if (argv[i][j] == 'a') {
3379           b->quality = 1;
3380           if (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) ||
3381               (argv[i][j + 1] == '.')) {
3382             b->fixedarea = 1;
3383             k = 0;
3384             while (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) ||
3385                    (argv[i][j + 1] == '.')) {
3386               j++;
3387               workstring[k] = argv[i][j];
3388               k++;
3389             }
3390             workstring[k] = '\0';
3391             b->maxarea = (REAL) strtod(workstring, (char **) NULL);
3392             if (b->maxarea <= 0.0) {
3393               printf("Error:  Maximum area must be greater than zero.\n");
3394               triexit(1);
3395             }
3396           } else {
3397             b->vararea = 1;
3398           }
3399         }
3400         if (argv[i][j] == 'u') {
3401           b->quality = 1;
3402           b->usertest = 1;
3403         }
3404 #endif /* not CDT_ONLY */
3405         if (argv[i][j] == 'A') {
3406           b->regionattrib = 1;
3407         }
3408         if (argv[i][j] == 'c') {
3409           b->convex = 1;
3410         }
3411         if (argv[i][j] == 'w') {
3412           b->weighted = 1;
3413         }
3414         if (argv[i][j] == 'W') {
3415           b->weighted = 2;
3416         }
3417         if (argv[i][j] == 'j') {
3418           b->jettison = 1;
3419         }
3420         if (argv[i][j] == 'z') {
3421           b->firstnumber = 0;
3422         }
3423         if (argv[i][j] == 'e') {
3424           b->edgesout = 1;
3425         }
3426         if (argv[i][j] == 'v') {
3427           b->voronoi = 1;
3428         }
3429         if (argv[i][j] == 'n') {
3430           b->neighbors = 1;
3431         }
3432         if (argv[i][j] == 'g') {
3433           b->geomview = 1;
3434         }
3435         if (argv[i][j] == 'B') {
3436           b->nobound = 1;
3437         }
3438         if (argv[i][j] == 'P') {
3439           b->nopolywritten = 1;
3440         }
3441         if (argv[i][j] == 'N') {
3442           b->nonodewritten = 1;
3443         }
3444         if (argv[i][j] == 'E') {
3445           b->noelewritten = 1;
3446         }
3447 #ifndef TRILIBRARY
3448         if (argv[i][j] == 'I') {
3449           b->noiterationnum = 1;
3450         }
3451 #endif /* not TRILIBRARY */
3452         if (argv[i][j] == 'O') {
3453           b->noholes = 1;
3454         }
3455         if (argv[i][j] == 'X') {
3456           b->noexact = 1;
3457         }
3458         if (argv[i][j] == 'o') {
3459           if (argv[i][j + 1] == '2') {
3460             j++;
3461             b->order = 2;
3462           }
3463         }
3464 #ifndef CDT_ONLY
3465         if (argv[i][j] == 'Y') {
3466           b->nobisect++;
3467         }
3468         if (argv[i][j] == 'S') {
3469           b->steiner = 0;
3470           while ((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) {
3471             j++;
3472             b->steiner = b->steiner * 10 + (int) (argv[i][j] - '0');
3473           }
3474         }
3475 #endif /* not CDT_ONLY */
3476 #ifndef REDUCED
3477         if (argv[i][j] == 'i') {
3478           b->incremental = 1;
3479         }
3480         if (argv[i][j] == 'F') {
3481           b->sweepline = 1;
3482         }
3483 #endif /* not REDUCED */
3484         if (argv[i][j] == 'l') {
3485           b->dwyer = 0;
3486         }
3487 #ifndef REDUCED
3488 #ifndef CDT_ONLY
3489         if (argv[i][j] == 's') {
3490           b->splitseg = 1;
3491         }
3492         if ((argv[i][j] == 'D') || (argv[i][j] == 'L')) {
3493           b->quality = 1;
3494           b->conformdel = 1;
3495         }
3496 #endif /* not CDT_ONLY */
3497         if (argv[i][j] == 'C') {
3498           b->docheck = 1;
3499         }
3500 #endif /* not REDUCED */
3501         if (argv[i][j] == 'Q') {
3502           b->quiet = 1;
3503         }
3504         if (argv[i][j] == 'V') {
3505           b->verbose++;
3506         }
3507 #ifndef TRILIBRARY
3508         if ((argv[i][j] == 'h') || (argv[i][j] == 'H') ||
3509             (argv[i][j] == '?')) {
3510           info();
3511         }
3512 #endif /* not TRILIBRARY */
3513       }
3514 #ifndef TRILIBRARY
3515     } else {
3516       strncpy(b->innodefilename, argv[i], FILENAMESIZE - 1);
3517       b->innodefilename[FILENAMESIZE - 1] = '\0';
3518     }
3519 #endif /* not TRILIBRARY */
3520   }
3521 #ifndef TRILIBRARY
3522   if (b->innodefilename[0] == '\0') {
3523     syntax();
3524   }
3525   if (!strcmp(&b->innodefilename[strlen(b->innodefilename) - 5], ".node")) {
3526     b->innodefilename[strlen(b->innodefilename) - 5] = '\0';
3527   }
3528   if (!strcmp(&b->innodefilename[strlen(b->innodefilename) - 5], ".poly")) {
3529     b->innodefilename[strlen(b->innodefilename) - 5] = '\0';
3530     b->poly = 1;
3531   }
3532 #ifndef CDT_ONLY
3533   if (!strcmp(&b->innodefilename[strlen(b->innodefilename) - 4], ".ele")) {
3534     b->innodefilename[strlen(b->innodefilename) - 4] = '\0';
3535     b->refine = 1;
3536   }
3537   if (!strcmp(&b->innodefilename[strlen(b->innodefilename) - 5], ".area")) {
3538     b->innodefilename[strlen(b->innodefilename) - 5] = '\0';
3539     b->refine = 1;
3540     b->quality = 1;
3541     b->vararea = 1;
3542   }
3543 #endif /* not CDT_ONLY */
3544 #endif /* not TRILIBRARY */
3545   b->usesegments = b->poly || b->refine || b->quality || b->convex;
3546   b->goodangle = cos(b->minangle * PI / 180.0);
3547   if (b->goodangle == 1.0) {
3548     b->offconstant = 0.0;
3549   } else {
3550     b->offconstant = 0.475 * sqrt((1.0 + b->goodangle) / (1.0 - b->goodangle));
3551   }
3552   b->goodangle *= b->goodangle;
3553   if (b->refine && b->noiterationnum) {
3554     printf(
3555       "Error:  You cannot use the -I switch when refining a triangulation.\n");
3556     triexit(1);
3557   }
3558   /* Be careful not to allocate space for element area constraints that */
3559   /*   will never be assigned any value (other than the default -1.0).  */
3560   if (!b->refine && !b->poly) {
3561     b->vararea = 0;
3562   }
3563   /* Be careful not to add an extra attribute to each element unless the */
3564   /*   input supports it (PSLG in, but not refining a preexisting mesh). */
3565   if (b->refine || !b->poly) {
3566     b->regionattrib = 0;
3567   }
3568   /* Regular/weighted triangulations are incompatible with PSLGs */
3569   /*   and meshing.                                              */
3570   if (b->weighted && (b->poly || b->quality)) {
3571     b->weighted = 0;
3572     if (!b->quiet) {
3573       printf("Warning:  weighted triangulations (-w, -W) are incompatible\n");
3574       printf("  with PSLGs (-p) and meshing (-q, -a, -u).  Weights ignored.\n"
3575              );
3576     }
3577   }
3578   if (b->jettison && b->nonodewritten && !b->quiet) {
3579     printf("Warning:  -j and -N switches are somewhat incompatible.\n");
3580     printf("  If any vertices are jettisoned, you will need the output\n");
3581     printf("  .node file to reconstruct the new node indices.");
3582   }
3583 
3584 #ifndef TRILIBRARY
3585   strcpy(b->inpolyfilename, b->innodefilename);
3586   strcpy(b->inelefilename, b->innodefilename);
3587   strcpy(b->areafilename, b->innodefilename);
3588   increment = 0;
3589   strcpy(workstring, b->innodefilename);
3590   j = 1;
3591   while (workstring[j] != '\0') {
3592     if ((workstring[j] == '.') && (workstring[j + 1] != '\0')) {
3593       increment = j + 1;
3594     }
3595     j++;
3596   }
3597   meshnumber = 0;
3598   if (increment > 0) {
3599     j = increment;
3600     do {
3601       if ((workstring[j] >= '0') && (workstring[j] <= '9')) {
3602         meshnumber = meshnumber * 10 + (int) (workstring[j] - '0');
3603       } else {
3604         increment = 0;
3605       }
3606       j++;
3607     } while (workstring[j] != '\0');
3608   }
3609   if (b->noiterationnum) {
3610     strcpy(b->outnodefilename, b->innodefilename);
3611     strcpy(b->outelefilename, b->innodefilename);
3612     strcpy(b->edgefilename, b->innodefilename);
3613     strcpy(b->vnodefilename, b->innodefilename);
3614     strcpy(b->vedgefilename, b->innodefilename);
3615     strcpy(b->neighborfilename, b->innodefilename);
3616     strcpy(b->offfilename, b->innodefilename);
3617     strcat(b->outnodefilename, ".node");
3618     strcat(b->outelefilename, ".ele");
3619     strcat(b->edgefilename, ".edge");
3620     strcat(b->vnodefilename, ".v.node");
3621     strcat(b->vedgefilename, ".v.edge");
3622     strcat(b->neighborfilename, ".neigh");
3623     strcat(b->offfilename, ".off");
3624   } else if (increment == 0) {
3625     strcpy(b->outnodefilename, b->innodefilename);
3626     strcpy(b->outpolyfilename, b->innodefilename);
3627     strcpy(b->outelefilename, b->innodefilename);
3628     strcpy(b->edgefilename, b->innodefilename);
3629     strcpy(b->vnodefilename, b->innodefilename);
3630     strcpy(b->vedgefilename, b->innodefilename);
3631     strcpy(b->neighborfilename, b->innodefilename);
3632     strcpy(b->offfilename, b->innodefilename);
3633     strcat(b->outnodefilename, ".1.node");
3634     strcat(b->outpolyfilename, ".1.poly");
3635     strcat(b->outelefilename, ".1.ele");
3636     strcat(b->edgefilename, ".1.edge");
3637     strcat(b->vnodefilename, ".1.v.node");
3638     strcat(b->vedgefilename, ".1.v.edge");
3639     strcat(b->neighborfilename, ".1.neigh");
3640     strcat(b->offfilename, ".1.off");
3641   } else {
3642     workstring[increment] = '%';
3643     workstring[increment + 1] = 'd';
3644     workstring[increment + 2] = '\0';
3645     sprintf(b->outnodefilename, workstring, meshnumber + 1);
3646     strcpy(b->outpolyfilename, b->outnodefilename);
3647     strcpy(b->outelefilename, b->outnodefilename);
3648     strcpy(b->edgefilename, b->outnodefilename);
3649     strcpy(b->vnodefilename, b->outnodefilename);
3650     strcpy(b->vedgefilename, b->outnodefilename);
3651     strcpy(b->neighborfilename, b->outnodefilename);
3652     strcpy(b->offfilename, b->outnodefilename);
3653     strcat(b->outnodefilename, ".node");
3654     strcat(b->outpolyfilename, ".poly");
3655     strcat(b->outelefilename, ".ele");
3656     strcat(b->edgefilename, ".edge");
3657     strcat(b->vnodefilename, ".v.node");
3658     strcat(b->vedgefilename, ".v.edge");
3659     strcat(b->neighborfilename, ".neigh");
3660     strcat(b->offfilename, ".off");
3661   }
3662   strcat(b->innodefilename, ".node");
3663   strcat(b->inpolyfilename, ".poly");
3664   strcat(b->inelefilename, ".ele");
3665   strcat(b->areafilename, ".area");
3666 #endif /* not TRILIBRARY */
3667 }
3668 
3669 /**                                                                         **/
3670 /**                                                                         **/
3671 /********* User interaction routines begin here                      *********/
3672 
3673 /********* Debugging routines begin here                             *********/
3674 /**                                                                         **/
3675 /**                                                                         **/
3676 
3677 /*****************************************************************************/
3678 /*                                                                           */
3679 /*  printtriangle()   Print out the details of an oriented triangle.         */
3680 /*                                                                           */
3681 /*  I originally wrote this procedure to simplify debugging; it can be       */
3682 /*  called directly from the debugger, and presents information about an     */
3683 /*  oriented triangle in digestible form.  It's also used when the           */
3684 /*  highest level of verbosity (`-VVV') is specified.                        */
3685 /*                                                                           */
3686 /*****************************************************************************/
3687 
3688 #ifdef ANSI_DECLARATORS
3689 void printtriangle(struct mesh *m, struct behavior *b, struct otri *t)
3690 #else /* not ANSI_DECLARATORS */
3691 void printtriangle(m, b, t)
3692 struct mesh *m;
3693 struct behavior *b;
3694 struct otri *t;
3695 #endif /* not ANSI_DECLARATORS */
3696 
3697 {
3698   struct otri printtri;
3699   struct osub printsh;
3700   vertex printvertex;
3701 
3702   printf("triangle x%lx with orientation %d:\n", (unsigned long) t->tri,
3703          t->orient);
3704   decode(t->tri[0], printtri);
3705   if (printtri.tri == m->dummytri) {
3706     printf("    [0] = Outer space\n");
3707   } else {
3708     printf("    [0] = x%lx  %d\n", (unsigned long) printtri.tri,
3709            printtri.orient);
3710   }
3711   decode(t->tri[1], printtri);
3712   if (printtri.tri == m->dummytri) {
3713     printf("    [1] = Outer space\n");
3714   } else {
3715     printf("    [1] = x%lx  %d\n", (unsigned long) printtri.tri,
3716            printtri.orient);
3717   }
3718   decode(t->tri[2], printtri);
3719   if (printtri.tri == m->dummytri) {
3720     printf("    [2] = Outer space\n");
3721   } else {
3722     printf("    [2] = x%lx  %d\n", (unsigned long) printtri.tri,
3723            printtri.orient);
3724   }
3725 
3726   org(*t, printvertex);
3727   if (printvertex == (vertex) NULL)
3728     printf("    Origin[%d] = NULL\n", (t->orient + 1) % 3 + 3);
3729   else
3730     printf("    Origin[%d] = x%lx  (%.12g, %.12g)\n",
3731            (t->orient + 1) % 3 + 3, (unsigned long) printvertex,
3732            printvertex[0], printvertex[1]);
3733   dest(*t, printvertex);
3734   if (printvertex == (vertex) NULL)
3735     printf("    Dest  [%d] = NULL\n", (t->orient + 2) % 3 + 3);
3736   else
3737     printf("    Dest  [%d] = x%lx  (%.12g, %.12g)\n",
3738            (t->orient + 2) % 3 + 3, (unsigned long) printvertex,
3739            printvertex[0], printvertex[1]);
3740   apex(*t, printvertex);
3741   if (printvertex == (vertex) NULL)
3742     printf("    Apex  [%d] = NULL\n", t->orient + 3);
3743   else
3744     printf("    Apex  [%d] = x%lx  (%.12g, %.12g)\n",
3745            t->orient + 3, (unsigned long) printvertex,
3746            printvertex[0], printvertex[1]);
3747 
3748   if (b->usesegments) {
3749     sdecode(t->tri[6], printsh);
3750     if (printsh.ss != m->dummysub) {
3751       printf("    [6] = x%lx  %d\n", (unsigned long) printsh.ss,
3752              printsh.ssorient);
3753     }
3754     sdecode(t->tri[7], printsh);
3755     if (printsh.ss != m->dummysub) {
3756       printf("    [7] = x%lx  %d\n", (unsigned long) printsh.ss,
3757              printsh.ssorient);
3758     }
3759     sdecode(t->tri[8], printsh);
3760     if (printsh.ss != m->dummysub) {
3761       printf("    [8] = x%lx  %d\n", (unsigned long) printsh.ss,
3762              printsh.ssorient);
3763     }
3764   }
3765 
3766   if (b->vararea) {
3767     printf("    Area constraint:  %.4g\n", areabound(*t));
3768   }
3769 }
3770 
3771 /*****************************************************************************/
3772 /*                                                                           */
3773 /*  printsubseg()   Print out the details of an oriented subsegment.         */
3774 /*                                                                           */
3775 /*  I originally wrote this procedure to simplify debugging; it can be       */
3776 /*  called directly from the debugger, and presents information about an     */
3777 /*  oriented subsegment in digestible form.  It's also used when the highest */
3778 /*  level of verbosity (`-VVV') is specified.                                */
3779 /*                                                                           */
3780 /*****************************************************************************/
3781 
3782 #ifdef ANSI_DECLARATORS
3783 void printsubseg(struct mesh *m, struct behavior *b, struct osub *s)
3784 #else /* not ANSI_DECLARATORS */
3785 void printsubseg(m, b, s)
3786 struct mesh *m;
3787 struct behavior *b;
3788 struct osub *s;
3789 #endif /* not ANSI_DECLARATORS */
3790 
3791 {
3792   struct osub printsh;
3793   struct otri printtri;
3794   vertex printvertex;
3795 
3796   printf("subsegment x%lx with orientation %d and mark %d:\n",
3797          (unsigned long) s->ss, s->ssorient, mark(*s));
3798   sdecode(s->ss[0], printsh);
3799   if (printsh.ss == m->dummysub) {
3800     printf("    [0] = No subsegment\n");
3801   } else {
3802     printf("    [0] = x%lx  %d\n", (unsigned long) printsh.ss,
3803            printsh.ssorient);
3804   }
3805   sdecode(s->ss[1], printsh);
3806   if (printsh.ss == m->dummysub) {
3807     printf("    [1] = No subsegment\n");
3808   } else {
3809     printf("    [1] = x%lx  %d\n", (unsigned long) printsh.ss,
3810            printsh.ssorient);
3811   }
3812 
3813   sorg(*s, printvertex);
3814   if (printvertex == (vertex) NULL)
3815     printf("    Origin[%d] = NULL\n", 2 + s->ssorient);
3816   else
3817     printf("    Origin[%d] = x%lx  (%.12g, %.12g)\n",
3818            2 + s->ssorient, (unsigned long) printvertex,
3819            printvertex[0], printvertex[1]);
3820   sdest(*s, printvertex);
3821   if (printvertex == (vertex) NULL)
3822     printf("    Dest  [%d] = NULL\n", 3 - s->ssorient);
3823   else
3824     printf("    Dest  [%d] = x%lx  (%.12g, %.12g)\n",
3825            3 - s->ssorient, (unsigned long) printvertex,
3826            printvertex[0], printvertex[1]);
3827 
3828   decode(s->ss[6], printtri);
3829   if (printtri.tri == m->dummytri) {
3830     printf("    [6] = Outer space\n");
3831   } else {
3832     printf("    [6] = x%lx  %d\n", (unsigned long) printtri.tri,
3833            printtri.orient);
3834   }
3835   decode(s->ss[7], printtri);
3836   if (printtri.tri == m->dummytri) {
3837     printf("    [7] = Outer space\n");
3838   } else {
3839     printf("    [7] = x%lx  %d\n", (unsigned long) printtri.tri,
3840            printtri.orient);
3841   }
3842 
3843   segorg(*s, printvertex);
3844   if (printvertex == (vertex) NULL)
3845     printf("    Segment origin[%d] = NULL\n", 4 + s->ssorient);
3846   else
3847     printf("    Segment origin[%d] = x%lx  (%.12g, %.12g)\n",
3848            4 + s->ssorient, (unsigned long) printvertex,
3849            printvertex[0], printvertex[1]);
3850   segdest(*s, printvertex);
3851   if (printvertex == (vertex) NULL)
3852     printf("    Segment dest  [%d] = NULL\n", 5 - s->ssorient);
3853   else
3854     printf("    Segment dest  [%d] = x%lx  (%.12g, %.12g)\n",
3855            5 - s->ssorient, (unsigned long) printvertex,
3856            printvertex[0], printvertex[1]);
3857 }
3858 
3859 /**                                                                         **/
3860 /**                                                                         **/
3861 /********* Debugging routines end here                               *********/
3862 
3863 /********* Memory management routines begin here                     *********/
3864 /**                                                                         **/
3865 /**                                                                         **/
3866 
3867 /*****************************************************************************/
3868 /*                                                                           */
3869 /*  poolzero()   Set all of a pool's fields to zero.                         */
3870 /*                                                                           */
3871 /*  This procedure should never be called on a pool that has any memory      */
3872 /*  allocated to it, as that memory would leak.                              */
3873 /*                                                                           */
3874 /*****************************************************************************/
3875 
3876 #ifdef ANSI_DECLARATORS
3877 void poolzero(struct memorypool *pool)
3878 #else /* not ANSI_DECLARATORS */
3879 void poolzero(pool)
3880 struct memorypool *pool;
3881 #endif /* not ANSI_DECLARATORS */
3882 
3883 {
3884   pool->firstblock = (VOID **) NULL;
3885   pool->nowblock = (VOID **) NULL;
3886   pool->nextitem = (VOID *) NULL;
3887   pool->deaditemstack = (VOID *) NULL;
3888   pool->pathblock = (VOID **) NULL;
3889   pool->pathitem = (VOID *) NULL;
3890   pool->alignbytes = 0;
3891   pool->itembytes = 0;
3892   pool->itemsperblock = 0;
3893   pool->itemsfirstblock = 0;
3894   pool->items = 0;
3895   pool->maxitems = 0;
3896   pool->unallocateditems = 0;
3897   pool->pathitemsleft = 0;
3898 }
3899 
3900 /*****************************************************************************/
3901 /*                                                                           */
3902 /*  poolrestart()   Deallocate all items in a pool.                          */
3903 /*                                                                           */
3904 /*  The pool is returned to its starting state, except that no memory is     */
3905 /*  freed to the operating system.  Rather, the previously allocated blocks  */
3906 /*  are ready to be reused.                                                  */
3907 /*                                                                           */
3908 /*****************************************************************************/
3909 
3910 #ifdef ANSI_DECLARATORS
3911 void poolrestart(struct memorypool *pool)
3912 #else /* not ANSI_DECLARATORS */
3913 void poolrestart(pool)
3914 struct memorypool *pool;
3915 #endif /* not ANSI_DECLARATORS */
3916 
3917 {
3918   INT_PTR alignptr = 0;
3919 
3920   pool->items = 0;
3921   pool->maxitems = 0;
3922 
3923   /* Set the currently active block. */
3924   pool->nowblock = pool->firstblock;
3925   /* Find the first item in the pool.  Increment by the size of (VOID *). */
3926   alignptr = (INT_PTR) (pool->nowblock + 1);
3927   /* Align the item on an `alignbytes'-byte boundary. */
3928   pool->nextitem = (VOID *)
3929     (alignptr + (INT_PTR) pool->alignbytes -
3930      (alignptr % (INT_PTR) pool->alignbytes));
3931   /* There are lots of unallocated items left in this block. */
3932   pool->unallocateditems = pool->itemsfirstblock;
3933   /* The stack of deallocated items is empty. */
3934   pool->deaditemstack = (VOID *) NULL;
3935 }
3936 
3937 /*****************************************************************************/
3938 /*                                                                           */
3939 /*  poolinit()   Initialize a pool of memory for allocation of items.        */
3940 /*                                                                           */
3941 /*  This routine initializes the machinery for allocating items.  A `pool'   */
3942 /*  is created whose records have size at least `bytecount'.  Items will be  */
3943 /*  allocated in `itemcount'-item blocks.  Each item is assumed to be a      */
3944 /*  collection of words, and either pointers or floating-point values are    */
3945 /*  assumed to be the "primary" word type.  (The "primary" word type is used */
3946 /*  to determine alignment of items.)  If `alignment' isn't zero, all items  */
3947 /*  will be `alignment'-byte aligned in memory.  `alignment' must be either  */
3948 /*  a multiple or a factor of the primary word size; powers of two are safe. */
3949 /*  `alignment' is normally used to create a few unused bits at the bottom   */
3950 /*  of each item's pointer, in which information may be stored.              */
3951 /*                                                                           */
3952 /*  Don't change this routine unless you understand it.                      */
3953 /*                                                                           */
3954 /*****************************************************************************/
3955 
3956 #ifdef ANSI_DECLARATORS
3957 void poolinit(struct memorypool *pool, int bytecount, int itemcount,
3958               int firstitemcount, int alignment)
3959 #else /* not ANSI_DECLARATORS */
3960 void poolinit(pool, bytecount, itemcount, firstitemcount, alignment)
3961 struct memorypool *pool;
3962 int bytecount;
3963 int itemcount;
3964 int firstitemcount;
3965 int alignment;
3966 #endif /* not ANSI_DECLARATORS */
3967 
3968 {
3969   /* Find the proper alignment, which must be at least as large as:   */
3970   /*   - The parameter `alignment'.                                   */
3971   /*   - sizeof(VOID *), so the stack of dead items can be maintained */
3972   /*       without unaligned accesses.                                */
3973   if (alignment > sizeof(VOID *)) {
3974     pool->alignbytes = alignment;
3975   } else {
3976     pool->alignbytes = sizeof(VOID *);
3977   }
3978   pool->itembytes = ((bytecount - 1) / pool->alignbytes + 1) *
3979                     pool->alignbytes;
3980   pool->itemsperblock = itemcount;
3981   if (firstitemcount == 0) {
3982     pool->itemsfirstblock = itemcount;
3983   } else {
3984     pool->itemsfirstblock = firstitemcount;
3985   }
3986 
3987   /* Allocate a block of items.  Space for `itemsfirstblock' items and one  */
3988   /*   pointer (to point to the next block) are allocated, as well as space */
3989   /*   to ensure alignment of the items.                                    */
3990   pool->firstblock = (VOID **)
3991     trimalloc(pool->itemsfirstblock * pool->itembytes + (int) sizeof(VOID *) +
3992               pool->alignbytes);
3993   /* Set the next block pointer to NULL. */
3994   *(pool->firstblock) = (VOID *) NULL;
3995   poolrestart(pool);
3996 }
3997 
3998 /*****************************************************************************/
3999 /*                                                                           */
4000 /*  pooldeinit()   Free to the operating system all memory taken by a pool.  */
4001 /*                                                                           */
4002 /*****************************************************************************/
4003 
4004 #ifdef ANSI_DECLARATORS
4005 void pooldeinit(struct memorypool *pool)
4006 #else /* not ANSI_DECLARATORS */
4007 void pooldeinit(pool)
4008 struct memorypool *pool;
4009 #endif /* not ANSI_DECLARATORS */
4010 
4011 {
4012   while (pool->firstblock != (VOID **) NULL) {
4013     pool->nowblock = (VOID **) *(pool->firstblock);
4014     trifree((VOID *) pool->firstblock);
4015     pool->firstblock = pool->nowblock;
4016   }
4017 }
4018 
4019 /*****************************************************************************/
4020 /*                                                                           */
4021 /*  poolalloc()   Allocate space for an item.                                */
4022 /*                                                                           */
4023 /*****************************************************************************/
4024 
4025 #ifdef ANSI_DECLARATORS
4026 VOID *poolalloc(struct memorypool *pool)
4027 #else /* not ANSI_DECLARATORS */
4028 VOID *poolalloc(pool)
4029 struct memorypool *pool;
4030 #endif /* not ANSI_DECLARATORS */
4031 
4032 {
4033   VOID *newitem;
4034   VOID **newblock;
4035   INT_PTR alignptr = 0;
4036 
4037   /* First check the linked list of dead items.  If the list is not   */
4038   /*   empty, allocate an item from the list rather than a fresh one. */
4039   if (pool->deaditemstack != (VOID *) NULL) {
4040     newitem = pool->deaditemstack;               /* Take first item in list. */
4041     pool->deaditemstack = * (VOID **) pool->deaditemstack;
4042   } else {
4043     /* Check if there are any free items left in the current block. */
4044     if (pool->unallocateditems == 0) {
4045       /* Check if another block must be allocated. */
4046       if (*(pool->nowblock) == (VOID *) NULL) {
4047         /* Allocate a new block of items, pointed to by the previous block. */
4048         newblock = (VOID **) trimalloc(pool->itemsperblock * pool->itembytes +
4049                                        (int) sizeof(VOID *) +
4050                                        pool->alignbytes);
4051         *(pool->nowblock) = (VOID *) newblock;
4052         /* The next block pointer is NULL. */
4053         *newblock = (VOID *) NULL;
4054       }
4055 
4056       /* Move to the new block. */
4057       pool->nowblock = (VOID **) *(pool->nowblock);
4058       /* Find the first item in the block.    */
4059       /*   Increment by the size of (VOID *). */
4060       alignptr = (INT_PTR) (pool->nowblock + 1);
4061       /* Align the item on an `alignbytes'-byte boundary. */
4062       pool->nextitem = (VOID *)
4063         (alignptr + (INT_PTR) pool->alignbytes -
4064          (alignptr % (INT_PTR) pool->alignbytes));
4065       /* There are lots of unallocated items left in this block. */
4066       pool->unallocateditems = pool->itemsperblock;
4067     }
4068 
4069     /* Allocate a new item. */
4070     newitem = pool->nextitem;
4071     /* Advance `nextitem' pointer to next free item in block. */
4072     pool->nextitem = (VOID *) ((char *) pool->nextitem + pool->itembytes);
4073     pool->unallocateditems--;
4074     pool->maxitems++;
4075   }
4076   pool->items++;
4077   return newitem;
4078 }
4079 
4080 /*****************************************************************************/
4081 /*                                                                           */
4082 /*  pooldealloc()   Deallocate space for an item.                            */
4083 /*                                                                           */
4084 /*  The deallocated space is stored in a queue for later reuse.              */
4085 /*                                                                           */
4086 /*****************************************************************************/
4087 
4088 #ifdef ANSI_DECLARATORS
4089 void pooldealloc(struct memorypool *pool, VOID *dyingitem)
4090 #else /* not ANSI_DECLARATORS */
4091 void pooldealloc(pool, dyingitem)
4092 struct memorypool *pool;
4093 VOID *dyingitem;
4094 #endif /* not ANSI_DECLARATORS */
4095 
4096 {
4097   /* Push freshly killed item onto stack. */
4098   *((VOID **) dyingitem) = pool->deaditemstack;
4099   pool->deaditemstack = dyingitem;
4100   pool->items--;
4101 }
4102 
4103 /*****************************************************************************/
4104 /*                                                                           */
4105 /*  traversalinit()   Prepare to traverse the entire list of items.          */
4106 /*                                                                           */
4107 /*  This routine is used in conjunction with traverse().                     */
4108 /*                                                                           */
4109 /*****************************************************************************/
4110 
4111 #ifdef ANSI_DECLARATORS
4112 void traversalinit(struct memorypool *pool)
4113 #else /* not ANSI_DECLARATORS */
4114 void traversalinit(pool)
4115 struct memorypool *pool;
4116 #endif /* not ANSI_DECLARATORS */
4117 
4118 {
4119   INT_PTR alignptr = 0;
4120 
4121   /* Begin the traversal in the first block. */
4122   pool->pathblock = pool->firstblock;
4123   /* Find the first item in the block.  Increment by the size of (VOID *). */
4124   alignptr = (INT_PTR) (pool->pathblock + 1);
4125   /* Align with item on an `alignbytes'-byte boundary. */
4126   pool->pathitem = (VOID *)
4127     (alignptr + (INT_PTR) pool->alignbytes -
4128      (alignptr % (INT_PTR) pool->alignbytes));
4129   /* Set the number of items left in the current block. */
4130   pool->pathitemsleft = pool->itemsfirstblock;
4131 }
4132 
4133 /*****************************************************************************/
4134 /*                                                                           */
4135 /*  traverse()   Find the next item in the list.                             */
4136 /*                                                                           */
4137 /*  This routine is used in conjunction with traversalinit().  Be forewarned */
4138 /*  that this routine successively returns all items in the list, including  */
4139 /*  deallocated ones on the deaditemqueue.  It's up to you to figure out     */
4140 /*  which ones are actually dead.  Why?  I don't want to allocate extra      */
4141 /*  space just to demarcate dead items.  It can usually be done more         */
4142 /*  space-efficiently by a routine that knows something about the structure  */
4143 /*  of the item.                                                             */
4144 /*                                                                           */
4145 /*****************************************************************************/
4146 
4147 #ifdef ANSI_DECLARATORS
4148 VOID *traverse(struct memorypool *pool)
4149 #else /* not ANSI_DECLARATORS */
4150 VOID *traverse(pool)
4151 struct memorypool *pool;
4152 #endif /* not ANSI_DECLARATORS */
4153 
4154 {
4155   VOID *newitem;
4156   INT_PTR alignptr = 0;
4157 
4158   /* Stop upon exhausting the list of items. */
4159   if (pool->pathitem == pool->nextitem) {
4160     return (VOID *) NULL;
4161   }
4162 
4163   /* Check whether any untraversed items remain in the current block. */
4164   if (pool->pathitemsleft == 0) {
4165     /* Find the next block. */
4166     pool->pathblock = (VOID **) *(pool->pathblock);
4167     /* Find the first item in the block.  Increment by the size of (VOID *). */
4168     alignptr = (INT_PTR) (pool->pathblock + 1);
4169     /* Align with item on an `alignbytes'-byte boundary. */
4170     pool->pathitem = (VOID *)
4171       (alignptr + (INT_PTR) pool->alignbytes -
4172        (alignptr % (INT_PTR) pool->alignbytes));
4173     /* Set the number of items left in the current block. */
4174     pool->pathitemsleft = pool->itemsperblock;
4175   }
4176 
4177   newitem = pool->pathitem;
4178   /* Find the next item in the block. */
4179   pool->pathitem = (VOID *) ((char *) pool->pathitem + pool->itembytes);
4180   pool->pathitemsleft--;
4181   return newitem;
4182 }
4183 
4184 /*****************************************************************************/
4185 /*                                                                           */
4186 /*  dummyinit()   Initialize the triangle that fills "outer space" and the   */
4187 /*                omnipresent subsegment.                                    */
4188 /*                                                                           */
4189 /*  The triangle that fills "outer space," called `dummytri', is pointed to  */
4190 /*  by every triangle and subsegment on a boundary (be it outer or inner) of */
4191 /*  the triangulation.  Also, `dummytri' points to one of the triangles on   */
4192 /*  the convex hull (until the holes and concavities are carved), making it  */
4193 /*  possible to find a starting triangle for point location.                 */
4194 /*                                                                           */
4195 /*  The omnipresent subsegment, `dummysub', is pointed to by every triangle  */
4196 /*  or subsegment that doesn't have a full complement of real subsegments    */
4197 /*  to point to.                                                             */
4198 /*                                                                           */
4199 /*  `dummytri' and `dummysub' are generally required to fulfill only a few   */
4200 /*  invariants:  their vertices must remain NULL and `dummytri' must always  */
4201 /*  be bonded (at offset zero) to some triangle on the convex hull of the    */
4202 /*  mesh, via a boundary edge.  Otherwise, the connections of `dummytri' and */
4203 /*  `dummysub' may change willy-nilly.  This makes it possible to avoid      */
4204 /*  writing a good deal of special-case code (in the edge flip, for example) */
4205 /*  for dealing with the boundary of the mesh, places where no subsegment is */
4206 /*  present, and so forth.  Other entities are frequently bonded to          */
4207 /*  `dummytri' and `dummysub' as if they were real mesh entities, with no    */
4208 /*  harm done.                                                               */
4209 /*                                                                           */
4210 /*****************************************************************************/
4211 
4212 #ifdef ANSI_DECLARATORS
4213 void dummyinit(struct mesh *m, struct behavior *b, int trianglebytes,
4214                int subsegbytes)
4215 #else /* not ANSI_DECLARATORS */
4216 void dummyinit(m, b, trianglebytes, subsegbytes)
4217 struct mesh *m;
4218 struct behavior *b;
4219 int trianglebytes;
4220 int subsegbytes;
4221 #endif /* not ANSI_DECLARATORS */
4222 
4223 {
4224   INT_PTR alignptr = 0;
4225 
4226   /* Set up `dummytri', the `triangle' that occupies "outer space." */
4227   m->dummytribase = (triangle *) trimalloc(trianglebytes +
4228                                            m->triangles.alignbytes);
4229   /* Align `dummytri' on a `triangles.alignbytes'-byte boundary. */
4230   alignptr = (INT_PTR) m->dummytribase;
4231   m->dummytri = (triangle *)
4232     (alignptr + (INT_PTR) m->triangles.alignbytes -
4233      (alignptr % (INT_PTR) m->triangles.alignbytes));
4234   /* Initialize the three adjoining triangles to be "outer space."  These  */
4235   /*   will eventually be changed by various bonding operations, but their */
4236   /*   values don't really matter, as long as they can legally be          */
4237   /*   dereferenced.                                                       */
4238   m->dummytri[0] = (triangle) m->dummytri;
4239   m->dummytri[1] = (triangle) m->dummytri;
4240   m->dummytri[2] = (triangle) m->dummytri;
4241   /* Three NULL vertices. */
4242   m->dummytri[3] = (triangle) NULL;
4243   m->dummytri[4] = (triangle) NULL;
4244   m->dummytri[5] = (triangle) NULL;
4245 
4246   if (b->usesegments) {
4247     /* Set up `dummysub', the omnipresent subsegment pointed to by any */
4248     /*   triangle side or subsegment end that isn't attached to a real */
4249     /*   subsegment.                                                   */
4250     m->dummysubbase = (subseg *) trimalloc(subsegbytes +
4251                                            m->subsegs.alignbytes);
4252     /* Align `dummysub' on a `subsegs.alignbytes'-byte boundary. */
4253     alignptr = (INT_PTR) m->dummysubbase;
4254     m->dummysub = (subseg *)
4255       (alignptr + (INT_PTR) m->subsegs.alignbytes -
4256        (alignptr % (INT_PTR) m->subsegs.alignbytes));
4257     /* Initialize the two adjoining subsegments to be the omnipresent      */
4258     /*   subsegment.  These will eventually be changed by various bonding  */
4259     /*   operations, but their values don't really matter, as long as they */
4260     /*   can legally be dereferenced.                                      */
4261     m->dummysub[0] = (subseg) m->dummysub;
4262     m->dummysub[1] = (subseg) m->dummysub;
4263     /* Four NULL vertices. */
4264     m->dummysub[2] = (subseg) NULL;
4265     m->dummysub[3] = (subseg) NULL;
4266     m->dummysub[4] = (subseg) NULL;
4267     m->dummysub[5] = (subseg) NULL;
4268     /* Initialize the two adjoining triangles to be "outer space." */
4269     m->dummysub[6] = (subseg) m->dummytri;
4270     m->dummysub[7] = (subseg) m->dummytri;
4271     /* Set the boundary marker to zero. */
4272     * (int *) (m->dummysub + 8) = 0;
4273 
4274     /* Initialize the three adjoining subsegments of `dummytri' to be */
4275     /*   the omnipresent subsegment.                                  */
4276     m->dummytri[6] = (triangle) m->dummysub;
4277     m->dummytri[7] = (triangle) m->dummysub;
4278     m->dummytri[8] = (triangle) m->dummysub;
4279   }
4280 }
4281 
4282 /*****************************************************************************/
4283 /*                                                                           */
4284 /*  initializevertexpool()   Calculate the size of the vertex data structure */
4285 /*                           and initialize its memory pool.                 */
4286 /*                                                                           */
4287 /*  This routine also computes the `vertexmarkindex' and `vertex2triindex'   */
4288 /*  indices used to find values within each vertex.                          */
4289 /*                                                                           */
4290 /*****************************************************************************/
4291 
4292 #ifdef ANSI_DECLARATORS
4293 void initializevertexpool(struct mesh *m, struct behavior *b)
4294 #else /* not ANSI_DECLARATORS */
4295 void initializevertexpool(m, b)
4296 struct mesh *m;
4297 struct behavior *b;
4298 #endif /* not ANSI_DECLARATORS */
4299 
4300 {
4301   int vertexsize;
4302 
4303   /* The index within each vertex at which the boundary marker is found,    */
4304   /*   followed by the vertex type.  Ensure the vertex marker is aligned to */
4305   /*   a sizeof(int)-byte address.                                          */
4306   m->vertexmarkindex = ((m->mesh_dim + m->nextras) * sizeof(REAL) +
4307                         sizeof(int) - 1) /
4308                        sizeof(int);
4309   vertexsize = (m->vertexmarkindex + 2) * sizeof(int);
4310   if (b->poly) {
4311     /* The index within each vertex at which a triangle pointer is found.  */
4312     /*   Ensure the pointer is aligned to a sizeof(triangle)-byte address. */
4313     m->vertex2triindex = (vertexsize + sizeof(triangle) - 1) /
4314                          sizeof(triangle);
4315     vertexsize = (m->vertex2triindex + 1) * sizeof(triangle);
4316   }
4317 
4318   /* Initialize the pool of vertices. */
4319   poolinit(&m->vertices, vertexsize, VERTEXPERBLOCK,
4320            m->invertices > VERTEXPERBLOCK ? m->invertices : VERTEXPERBLOCK,
4321            sizeof(REAL));
4322 }
4323 
4324 /*****************************************************************************/
4325 /*                                                                           */
4326 /*  initializetrisubpools()   Calculate the sizes of the triangle and        */
4327 /*                            subsegment data structures and initialize      */
4328 /*                            their memory pools.                            */
4329 /*                                                                           */
4330 /*  This routine also computes the `highorderindex', `elemattribindex', and  */
4331 /*  `areaboundindex' indices used to find values within each triangle.       */
4332 /*                                                                           */
4333 /*****************************************************************************/
4334 
4335 #ifdef ANSI_DECLARATORS
4336 void initializetrisubpools(struct mesh *m, struct behavior *b)
4337 #else /* not ANSI_DECLARATORS */
4338 void initializetrisubpools(m, b)
4339 struct mesh *m;
4340 struct behavior *b;
4341 #endif /* not ANSI_DECLARATORS */
4342 
4343 {
4344   int trisize;
4345 
4346   /* The index within each triangle at which the extra nodes (above three)  */
4347   /*   associated with high order elements are found.  There are three      */
4348   /*   pointers to other triangles, three pointers to corners, and possibly */
4349   /*   three pointers to subsegments before the extra nodes.                */
4350   m->highorderindex = 6 + (b->usesegments * 3);
4351   /* The number of bytes occupied by a triangle. */
4352   trisize = ((b->order + 1) * (b->order + 2) / 2 + (m->highorderindex - 3)) *
4353             sizeof(triangle);
4354   /* The index within each triangle at which its attributes are found, */
4355   /*   where the index is measured in REALs.                           */
4356   m->elemattribindex = (trisize + sizeof(REAL) - 1) / sizeof(REAL);
4357   /* The index within each triangle at which the maximum area constraint  */
4358   /*   is found, where the index is measured in REALs.  Note that if the  */
4359   /*   `regionattrib' flag is set, an additional attribute will be added. */
4360   m->areaboundindex = m->elemattribindex + m->eextras + b->regionattrib;
4361   /* If triangle attributes or an area bound are needed, increase the number */
4362   /*   of bytes occupied by a triangle.                                      */
4363   if (b->vararea) {
4364     trisize = (m->areaboundindex + 1) * sizeof(REAL);
4365   } else if (m->eextras + b->regionattrib > 0) {
4366     trisize = m->areaboundindex * sizeof(REAL);
4367   }
4368   /* If a Voronoi diagram or triangle neighbor graph is requested, make    */
4369   /*   sure there's room to store an integer index in each triangle.  This */
4370   /*   integer index can occupy the same space as the subsegment pointers  */
4371   /*   or attributes or area constraint or extra nodes.                    */
4372   if ((b->voronoi || b->neighbors) &&
4373       (trisize < 6 * sizeof(triangle) + sizeof(int))) {
4374     trisize = 6 * sizeof(triangle) + sizeof(int);
4375   }
4376 
4377   /* Having determined the memory size of a triangle, initialize the pool. */
4378   poolinit(&m->triangles, trisize, TRIPERBLOCK,
4379            (2 * m->invertices - 2) > TRIPERBLOCK ? (2 * m->invertices - 2) :
4380            TRIPERBLOCK, 4);
4381 
4382   if (b->usesegments) {
4383     /* Initialize the pool of subsegments.  Take into account all eight */
4384     /*   pointers and one boundary marker.                              */
4385     poolinit(&m->subsegs, 8 * sizeof(triangle) + sizeof(int),
4386              SUBSEGPERBLOCK, SUBSEGPERBLOCK, 4);
4387 
4388     /* Initialize the "outer space" triangle and omnipresent subsegment. */
4389     dummyinit(m, b, m->triangles.itembytes, m->subsegs.itembytes);
4390   } else {
4391     /* Initialize the "outer space" triangle. */
4392     dummyinit(m, b, m->triangles.itembytes, 0);
4393   }
4394 }
4395 
4396 /*****************************************************************************/
4397 /*                                                                           */
4398 /*  triangledealloc()   Deallocate space for a triangle, marking it dead.    */
4399 /*                                                                           */
4400 /*****************************************************************************/
4401 
4402 #ifdef ANSI_DECLARATORS
4403 void triangledealloc(struct mesh *m, triangle *dyingtriangle)
4404 #else /* not ANSI_DECLARATORS */
4405 void triangledealloc(m, dyingtriangle)
4406 struct mesh *m;
4407 triangle *dyingtriangle;
4408 #endif /* not ANSI_DECLARATORS */
4409 
4410 {
4411   /* Mark the triangle as dead.  This makes it possible to detect dead */
4412   /*   triangles when traversing the list of all triangles.            */
4413   killtri(dyingtriangle);
4414   pooldealloc(&m->triangles, (VOID *) dyingtriangle);
4415 }
4416 
4417 /*****************************************************************************/
4418 /*                                                                           */
4419 /*  triangletraverse()   Traverse the triangles, skipping dead ones.         */
4420 /*                                                                           */
4421 /*****************************************************************************/
4422 
4423 #ifdef ANSI_DECLARATORS
4424 triangle *triangletraverse(struct mesh *m)
4425 #else /* not ANSI_DECLARATORS */
4426 triangle *triangletraverse(m)
4427 struct mesh *m;
4428 #endif /* not ANSI_DECLARATORS */
4429 
4430 {
4431   triangle *newtriangle;
4432 
4433   do {
4434     newtriangle = (triangle *) traverse(&m->triangles);
4435     if (newtriangle == (triangle *) NULL) {
4436       return (triangle *) NULL;
4437     }
4438   } while (deadtri(newtriangle));                         /* Skip dead ones. */
4439   return newtriangle;
4440 }
4441 
4442 /*****************************************************************************/
4443 /*                                                                           */
4444 /*  subsegdealloc()   Deallocate space for a subsegment, marking it dead.    */
4445 /*                                                                           */
4446 /*****************************************************************************/
4447 
4448 #ifdef ANSI_DECLARATORS
4449 void subsegdealloc(struct mesh *m, subseg *dyingsubseg)
4450 #else /* not ANSI_DECLARATORS */
4451 void subsegdealloc(m, dyingsubseg)
4452 struct mesh *m;
4453 subseg *dyingsubseg;
4454 #endif /* not ANSI_DECLARATORS */
4455 
4456 {
4457   /* Mark the subsegment as dead.  This makes it possible to detect dead */
4458   /*   subsegments when traversing the list of all subsegments.          */
4459   killsubseg(dyingsubseg);
4460   pooldealloc(&m->subsegs, (VOID *) dyingsubseg);
4461 }
4462 
4463 /*****************************************************************************/
4464 /*                                                                           */
4465 /*  subsegtraverse()   Traverse the subsegments, skipping dead ones.         */
4466 /*                                                                           */
4467 /*****************************************************************************/
4468 
4469 #ifdef ANSI_DECLARATORS
4470 subseg *subsegtraverse(struct mesh *m)
4471 #else /* not ANSI_DECLARATORS */
4472 subseg *subsegtraverse(m)
4473 struct mesh *m;
4474 #endif /* not ANSI_DECLARATORS */
4475 
4476 {
4477   subseg *newsubseg;
4478 
4479   do {
4480     newsubseg = (subseg *) traverse(&m->subsegs);
4481     if (newsubseg == (subseg *) NULL) {
4482       return (subseg *) NULL;
4483     }
4484   } while (deadsubseg(newsubseg));                        /* Skip dead ones. */
4485   return newsubseg;
4486 }
4487 
4488 /*****************************************************************************/
4489 /*                                                                           */
4490 /*  vertexdealloc()   Deallocate space for a vertex, marking it dead.        */
4491 /*                                                                           */
4492 /*****************************************************************************/
4493 
4494 #ifdef ANSI_DECLARATORS
4495 void vertexdealloc(struct mesh *m, vertex dyingvertex)
4496 #else /* not ANSI_DECLARATORS */
4497 void vertexdealloc(m, dyingvertex)
4498 struct mesh *m;
4499 vertex dyingvertex;
4500 #endif /* not ANSI_DECLARATORS */
4501 
4502 {
4503   /* Mark the vertex as dead.  This makes it possible to detect dead */
4504   /*   vertices when traversing the list of all vertices.            */
4505   setvertextype(dyingvertex, DEADVERTEX);
4506   pooldealloc(&m->vertices, (VOID *) dyingvertex);
4507 }
4508 
4509 /*****************************************************************************/
4510 /*                                                                           */
4511 /*  vertextraverse()   Traverse the vertices, skipping dead ones.            */
4512 /*                                                                           */
4513 /*****************************************************************************/
4514 
4515 #ifdef ANSI_DECLARATORS
4516 vertex vertextraverse(struct mesh *m)
4517 #else /* not ANSI_DECLARATORS */
4518 vertex vertextraverse(m)
4519 struct mesh *m;
4520 #endif /* not ANSI_DECLARATORS */
4521 
4522 {
4523   vertex newvertex;
4524 
4525   do {
4526     newvertex = (vertex) traverse(&m->vertices);
4527     if (newvertex == (vertex) NULL) {
4528       return (vertex) NULL;
4529     }
4530   } while (vertextype(newvertex) == DEADVERTEX);          /* Skip dead ones. */
4531   return newvertex;
4532 }
4533 
4534 /*****************************************************************************/
4535 /*                                                                           */
4536 /*  badsubsegdealloc()   Deallocate space for a bad subsegment, marking it   */
4537 /*                       dead.                                               */
4538 /*                                                                           */
4539 /*****************************************************************************/
4540 
4541 #ifndef CDT_ONLY
4542 
4543 #ifdef ANSI_DECLARATORS
4544 void badsubsegdealloc(struct mesh *m, struct badsubseg *dyingseg)
4545 #else /* not ANSI_DECLARATORS */
4546 void badsubsegdealloc(m, dyingseg)
4547 struct mesh *m;
4548 struct badsubseg *dyingseg;
4549 #endif /* not ANSI_DECLARATORS */
4550 
4551 {
4552   /* Set subsegment's origin to NULL.  This makes it possible to detect dead */
4553   /*   badsubsegs when traversing the list of all badsubsegs             .   */
4554   dyingseg->subsegorg = (vertex) NULL;
4555   pooldealloc(&m->badsubsegs, (VOID *) dyingseg);
4556 }
4557 
4558 #endif /* not CDT_ONLY */
4559 
4560 /*****************************************************************************/
4561 /*                                                                           */
4562 /*  badsubsegtraverse()   Traverse the bad subsegments, skipping dead ones.  */
4563 /*                                                                           */
4564 /*****************************************************************************/
4565 
4566 #ifndef CDT_ONLY
4567 
4568 #ifdef ANSI_DECLARATORS
4569 struct badsubseg *badsubsegtraverse(struct mesh *m)
4570 #else /* not ANSI_DECLARATORS */
4571 struct badsubseg *badsubsegtraverse(m)
4572 struct mesh *m;
4573 #endif /* not ANSI_DECLARATORS */
4574 
4575 {
4576   struct badsubseg *newseg;
4577 
4578   do {
4579     newseg = (struct badsubseg *) traverse(&m->badsubsegs);
4580     if (newseg == (struct badsubseg *) NULL) {
4581       return (struct badsubseg *) NULL;
4582     }
4583   } while (newseg->subsegorg == (vertex) NULL);           /* Skip dead ones. */
4584   return newseg;
4585 }
4586 
4587 #endif /* not CDT_ONLY */
4588 
4589 /*****************************************************************************/
4590 /*                                                                           */
4591 /*  getvertex()   Get a specific vertex, by number, from the list.           */
4592 /*                                                                           */
4593 /*  The first vertex is number 'firstnumber'.                                */
4594 /*                                                                           */
4595 /*  Note that this takes O(n) time (with a small constant, if VERTEXPERBLOCK */
4596 /*  is large).  I don't care to take the trouble to make it work in constant */
4597 /*  time.                                                                    */
4598 /*                                                                           */
4599 /*****************************************************************************/
4600 
4601 #ifdef ANSI_DECLARATORS
4602 vertex getvertex(struct mesh *m, struct behavior *b, int number)
4603 #else /* not ANSI_DECLARATORS */
4604 vertex getvertex(m, b, number)
4605 struct mesh *m;
4606 struct behavior *b;
4607 int number;
4608 #endif /* not ANSI_DECLARATORS */
4609 
4610 {
4611   VOID **getblock;
4612   char *foundvertex;
4613   INT_PTR alignptr = 0;
4614   int current;
4615 
4616   getblock = m->vertices.firstblock;
4617   current = b->firstnumber;
4618 
4619   /* Find the right block. */
4620   if (current + m->vertices.itemsfirstblock <= number) {
4621     getblock = (VOID **) *getblock;
4622     current += m->vertices.itemsfirstblock;
4623     while (current + m->vertices.itemsperblock <= number) {
4624       getblock = (VOID **) *getblock;
4625       current += m->vertices.itemsperblock;
4626     }
4627   }
4628 
4629   /* Now find the right vertex. */
4630   alignptr = (INT_PTR) (getblock + 1);
4631   foundvertex = (char *) (alignptr + (INT_PTR) m->vertices.alignbytes -
4632                           (alignptr % (INT_PTR) m->vertices.alignbytes));
4633   return (vertex) (foundvertex + m->vertices.itembytes * (number - current));
4634 }
4635 
4636 /*****************************************************************************/
4637 /*                                                                           */
4638 /*  triangledeinit()   Free all remaining allocated memory.                  */
4639 /*                                                                           */
4640 /*****************************************************************************/
4641 
4642 #ifdef ANSI_DECLARATORS
4643 void triangledeinit(struct mesh *m, struct behavior *b)
4644 #else /* not ANSI_DECLARATORS */
4645 void triangledeinit(m, b)
4646 struct mesh *m;
4647 struct behavior *b;
4648 #endif /* not ANSI_DECLARATORS */
4649 
4650 {
4651   pooldeinit(&m->triangles);
4652   trifree((VOID *) m->dummytribase);
4653   if (b->usesegments) {
4654     pooldeinit(&m->subsegs);
4655     trifree((VOID *) m->dummysubbase);
4656   }
4657   pooldeinit(&m->vertices);
4658 #ifndef CDT_ONLY
4659   if (b->quality) {
4660     pooldeinit(&m->badsubsegs);
4661     if ((b->minangle > 0.0) || b->vararea || b->fixedarea || b->usertest) {
4662       pooldeinit(&m->badtriangles);
4663       pooldeinit(&m->flipstackers);
4664     }
4665   }
4666 #endif /* not CDT_ONLY */
4667 }
4668 
4669 /**                                                                         **/
4670 /**                                                                         **/
4671 /********* Memory management routines end here                       *********/
4672 
4673 /********* Constructors begin here                                   *********/
4674 /**                                                                         **/
4675 /**                                                                         **/
4676 
4677 /*****************************************************************************/
4678 /*                                                                           */
4679 /*  maketriangle()   Create a new triangle with orientation zero.            */
4680 /*                                                                           */
4681 /*****************************************************************************/
4682 
4683 #ifdef ANSI_DECLARATORS
4684 void maketriangle(struct mesh *m, struct behavior *b, struct otri *newotri)
4685 #else /* not ANSI_DECLARATORS */
4686 void maketriangle(m, b, newotri)
4687 struct mesh *m;
4688 struct behavior *b;
4689 struct otri *newotri;
4690 #endif /* not ANSI_DECLARATORS */
4691 
4692 {
4693   int i;
4694 
4695   newotri->tri = (triangle *) poolalloc(&m->triangles);
4696   /* Initialize the three adjoining triangles to be "outer space". */
4697   newotri->tri[0] = (triangle) m->dummytri;
4698   newotri->tri[1] = (triangle) m->dummytri;
4699   newotri->tri[2] = (triangle) m->dummytri;
4700   /* Three NULL vertices. */
4701   newotri->tri[3] = (triangle) NULL;
4702   newotri->tri[4] = (triangle) NULL;
4703   newotri->tri[5] = (triangle) NULL;
4704   if (b->usesegments) {
4705     /* Initialize the three adjoining subsegments to be the omnipresent */
4706     /*   subsegment.                                                    */
4707     newotri->tri[6] = (triangle) m->dummysub;
4708     newotri->tri[7] = (triangle) m->dummysub;
4709     newotri->tri[8] = (triangle) m->dummysub;
4710   }
4711   for (i = 0; i < m->eextras; i++) {
4712     setelemattribute(*newotri, i, 0.0);
4713   }
4714   if (b->vararea) {
4715     setareabound(*newotri, -1.0);
4716   }
4717 
4718   newotri->orient = 0;
4719 }
4720 
4721 /*****************************************************************************/
4722 /*                                                                           */
4723 /*  makesubseg()   Create a new subsegment with orientation zero.            */
4724 /*                                                                           */
4725 /*****************************************************************************/
4726 
4727 #ifdef ANSI_DECLARATORS
4728 void makesubseg(struct mesh *m, struct osub *newsubseg)
4729 #else /* not ANSI_DECLARATORS */
4730 void makesubseg(m, newsubseg)
4731 struct mesh *m;
4732 struct osub *newsubseg;
4733 #endif /* not ANSI_DECLARATORS */
4734 
4735 {
4736   newsubseg->ss = (subseg *) poolalloc(&m->subsegs);
4737   /* Initialize the two adjoining subsegments to be the omnipresent */
4738   /*   subsegment.                                                  */
4739   newsubseg->ss[0] = (subseg) m->dummysub;
4740   newsubseg->ss[1] = (subseg) m->dummysub;
4741   /* Four NULL vertices. */
4742   newsubseg->ss[2] = (subseg) NULL;
4743   newsubseg->ss[3] = (subseg) NULL;
4744   newsubseg->ss[4] = (subseg) NULL;
4745   newsubseg->ss[5] = (subseg) NULL;
4746   /* Initialize the two adjoining triangles to be "outer space." */
4747   newsubseg->ss[6] = (subseg) m->dummytri;
4748   newsubseg->ss[7] = (subseg) m->dummytri;
4749   /* Set the boundary marker to zero. */
4750   setmark(*newsubseg, 0);
4751 
4752   newsubseg->ssorient = 0;
4753 }
4754 
4755 /**                                                                         **/
4756 /**                                                                         **/
4757 /********* Constructors end here                                     *********/
4758 
4759 /********* Geometric primitives begin here                           *********/
4760 /**                                                                         **/
4761 /**                                                                         **/
4762 
4763 /* The adaptive exact arithmetic geometric predicates implemented herein are */
4764 /*   described in detail in my paper, "Adaptive Precision Floating-Point     */
4765 /*   Arithmetic and Fast Robust Geometric Predicates."  See the header for a */
4766 /*   full citation.                                                          */
4767 
4768 /* Which of the following two methods of finding the absolute values is      */
4769 /*   fastest is compiler-dependent.  A few compilers can inline and optimize */
4770 /*   the fabs() call; but most will incur the overhead of a function call,   */
4771 /*   which is disastrously slow.  A faster way on IEEE machines might be to  */
4772 /*   mask the appropriate bit, but that's difficult to do in C without       */
4773 /*   forcing the value to be stored to memory (rather than be kept in the    */
4774 /*   register to which the optimizer assigned it).                           */
4775 
4776 #define Absolute(a)  ((a) >= 0.0 ? (a) : -(a))
4777 /* #define Absolute(a)  fabs(a) */
4778 
4779 /* Many of the operations are broken up into two pieces, a main part that    */
4780 /*   performs an approximate operation, and a "tail" that computes the       */
4781 /*   roundoff error of that operation.                                       */
4782 /*                                                                           */
4783 /* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(),    */
4784 /*   Split(), and Two_Product() are all implemented as described in the      */
4785 /*   reference.  Each of these macros requires certain variables to be       */
4786 /*   defined in the calling routine.  The variables `bvirt', `c', `abig',    */
4787 /*   `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because   */
4788 /*   they store the result of an operation that may incur roundoff error.    */
4789 /*   The input parameter `x' (or the highest numbered `x_' parameter) must   */
4790 /*   also be declared `INEXACT'.                                             */
4791 
4792 #define Fast_Two_Sum_Tail(a, b, x, y) \
4793   bvirt = x - a; \
4794   y = b - bvirt
4795 
4796 #define Fast_Two_Sum(a, b, x, y) \
4797   x = (REAL) (a + b); \
4798   Fast_Two_Sum_Tail(a, b, x, y)
4799 
4800 #define Two_Sum_Tail(a, b, x, y) \
4801   bvirt = (REAL) (x - a); \
4802   avirt = x - bvirt; \
4803   bround = b - bvirt; \
4804   around = a - avirt; \
4805   y = around + bround
4806 
4807 #define Two_Sum(a, b, x, y) \
4808   x = (REAL) (a + b); \
4809   Two_Sum_Tail(a, b, x, y)
4810 
4811 #define Two_Diff_Tail(a, b, x, y) \
4812   bvirt = (REAL) (a - x); \
4813   avirt = x + bvirt; \
4814   bround = bvirt - b; \
4815   around = a - avirt; \
4816   y = around + bround
4817 
4818 #define Two_Diff(a, b, x, y) \
4819   x = (REAL) (a - b); \
4820   Two_Diff_Tail(a, b, x, y)
4821 
4822 #define Split(a, ahi, alo) \
4823   c = (REAL) (splitter * a); \
4824   abig = (REAL) (c - a); \
4825   ahi = c - abig; \
4826   alo = a - ahi
4827 
4828 #define Two_Product_Tail(a, b, x, y) \
4829   Split(a, ahi, alo); \
4830   Split(b, bhi, blo); \
4831   err1 = x - (ahi * bhi); \
4832   err2 = err1 - (alo * bhi); \
4833   err3 = err2 - (ahi * blo); \
4834   y = (alo * blo) - err3
4835 
4836 #define Two_Product(a, b, x, y) \
4837   x = (REAL) (a * b); \
4838   Two_Product_Tail(a, b, x, y)
4839 
4840 /* Two_Product_Presplit() is Two_Product() where one of the inputs has       */
4841 /*   already been split.  Avoids redundant splitting.                        */
4842 
4843 #define Two_Product_Presplit(a, b, bhi, blo, x, y) \
4844   x = (REAL) (a * b); \
4845   Split(a, ahi, alo); \
4846   err1 = x - (ahi * bhi); \
4847   err2 = err1 - (alo * bhi); \
4848   err3 = err2 - (ahi * blo); \
4849   y = (alo * blo) - err3
4850 
4851 /* Square() can be done more quickly than Two_Product().                     */
4852 
4853 #define Square_Tail(a, x, y) \
4854   Split(a, ahi, alo); \
4855   err1 = x - (ahi * ahi); \
4856   err3 = err1 - ((ahi + ahi) * alo); \
4857   y = (alo * alo) - err3
4858 
4859 #define Square(a, x, y) \
4860   x = (REAL) (a * a); \
4861   Square_Tail(a, x, y)
4862 
4863 /* Macros for summing expansions of various fixed lengths.  These are all    */
4864 /*   unrolled versions of Expansion_Sum().                                   */
4865 
4866 #define Two_One_Sum(a1, a0, b, x2, x1, x0) \
4867   Two_Sum(a0, b , _i, x0); \
4868   Two_Sum(a1, _i, x2, x1)
4869 
4870 #define Two_One_Diff(a1, a0, b, x2, x1, x0) \
4871   Two_Diff(a0, b , _i, x0); \
4872   Two_Sum( a1, _i, x2, x1)
4873 
4874 #define Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0) \
4875   Two_One_Sum(a1, a0, b0, _j, _0, x0); \
4876   Two_One_Sum(_j, _0, b1, x3, x2, x1)
4877 
4878 #define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0) \
4879   Two_One_Diff(a1, a0, b0, _j, _0, x0); \
4880   Two_One_Diff(_j, _0, b1, x3, x2, x1)
4881 
4882 /* Macro for multiplying a two-component expansion by a single component.    */
4883 
4884 #define Two_One_Product(a1, a0, b, x3, x2, x1, x0) \
4885   Split(b, bhi, blo); \
4886   Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \
4887   Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \
4888   Two_Sum(_i, _0, _k, x1); \
4889   Fast_Two_Sum(_j, _k, x3, x2)
4890 
4891 /*****************************************************************************/
4892 /*                                                                           */
4893 /*  exactinit()   Initialize the variables used for exact arithmetic.        */
4894 /*                                                                           */
4895 /*  `epsilon' is the largest power of two such that 1.0 + epsilon = 1.0 in   */
4896 /*  floating-point arithmetic.  `epsilon' bounds the relative roundoff       */
4897 /*  error.  It is used for floating-point error analysis.                    */
4898 /*                                                                           */
4899 /*  `splitter' is used to split floating-point numbers into two half-        */
4900 /*  length significands for exact multiplication.                            */
4901 /*                                                                           */
4902 /*  I imagine that a highly optimizing compiler might be too smart for its   */
4903 /*  own good, and somehow cause this routine to fail, if it pretends that    */
4904 /*  floating-point arithmetic is too much like real arithmetic.              */
4905 /*                                                                           */
4906 /*  Don't change this routine unless you fully understand it.                */
4907 /*                                                                           */
4908 /*****************************************************************************/
4909 
4910 static
exactinit()4911 void exactinit()
4912 {
4913   REAL half;
4914   REAL check, lastcheck;
4915   int every_other;
4916 #ifdef LINUX
4917   int cword;
4918 #endif /* LINUX */
4919 
4920 #ifdef CPU86
4921 #ifdef SINGLE
4922   _control87(_PC_24, _MCW_PC); /* Set FPU control word for single precision. */
4923 #else /* not SINGLE */
4924   _control87(_PC_53, _MCW_PC); /* Set FPU control word for double precision. */
4925 #endif /* not SINGLE */
4926 #endif /* CPU86 */
4927 #ifdef LINUX
4928 #ifdef SINGLE
4929   /*  cword = 4223; */
4930   cword = 4210;                 /* set FPU control word for single precision */
4931 #else /* not SINGLE */
4932   /*  cword = 4735; */
4933   cword = 4722;                 /* set FPU control word for double precision */
4934 #endif /* not SINGLE */
4935   _FPU_SETCW(cword);
4936 #endif /* LINUX */
4937 
4938   every_other = 1;
4939   half = 0.5;
4940   epsilon = 1.0;
4941   splitter = 1.0;
4942   check = 1.0;
4943   /* Repeatedly divide `epsilon' by two until it is too small to add to      */
4944   /*   one without causing roundoff.  (Also check if the sum is equal to     */
4945   /*   the previous sum, for machines that round up instead of using exact   */
4946   /*   rounding.  Not that these routines will work on such machines.)       */
4947   do {
4948     lastcheck = check;
4949     epsilon *= half;
4950     if (every_other) {
4951       splitter *= 2.0;
4952     }
4953     every_other = !every_other;
4954     check = 1.0 + epsilon;
4955   } while ((check != 1.0) && (check != lastcheck));
4956   splitter += 1.0;
4957   /* Error bounds for orientation and incircle tests. */
4958   resulterrbound = (3.0 + 8.0 * epsilon) * epsilon;
4959   ccwerrboundA = (3.0 + 16.0 * epsilon) * epsilon;
4960   ccwerrboundB = (2.0 + 12.0 * epsilon) * epsilon;
4961   ccwerrboundC = (9.0 + 64.0 * epsilon) * epsilon * epsilon;
4962   iccerrboundA = (10.0 + 96.0 * epsilon) * epsilon;
4963   iccerrboundB = (4.0 + 48.0 * epsilon) * epsilon;
4964   iccerrboundC = (44.0 + 576.0 * epsilon) * epsilon * epsilon;
4965   o3derrboundA = (7.0 + 56.0 * epsilon) * epsilon;
4966   o3derrboundB = (3.0 + 28.0 * epsilon) * epsilon;
4967   o3derrboundC = (26.0 + 288.0 * epsilon) * epsilon * epsilon;
4968 }
4969 
4970 /*****************************************************************************/
4971 /*                                                                           */
4972 /*  fast_expansion_sum_zeroelim()   Sum two expansions, eliminating zero     */
4973 /*                                  components from the output expansion.    */
4974 /*                                                                           */
4975 /*  Sets h = e + f.  See my Robust Predicates paper for details.             */
4976 /*                                                                           */
4977 /*  If round-to-even is used (as with IEEE 754), maintains the strongly      */
4978 /*  nonoverlapping property.  (That is, if e is strongly nonoverlapping, h   */
4979 /*  will be also.)  Does NOT maintain the nonoverlapping or nonadjacent      */
4980 /*  properties.                                                              */
4981 /*                                                                           */
4982 /*****************************************************************************/
4983 
4984 static
4985 #ifdef ANSI_DECLARATORS
fast_expansion_sum_zeroelim(int elen,REAL * e,int flen,REAL * f,REAL * h)4986 int fast_expansion_sum_zeroelim(int elen, REAL *e, int flen, REAL *f, REAL *h)
4987 #else /* not ANSI_DECLARATORS */
4988 int fast_expansion_sum_zeroelim(elen, e, flen, f, h)  /* h cannot be e or f. */
4989 int elen;
4990 REAL *e;
4991 int flen;
4992 REAL *f;
4993 REAL *h;
4994 #endif /* not ANSI_DECLARATORS */
4995 
4996 {
4997   REAL Q;
4998   INEXACT REAL Qnew;
4999   INEXACT REAL hh;
5000   INEXACT REAL bvirt;
5001   REAL avirt, bround, around;
5002   int eindex, findex, hindex;
5003   REAL enow, fnow;
5004 
5005   enow = e[0];
5006   fnow = f[0];
5007   eindex = findex = 0;
5008   if ((fnow > enow) == (fnow > -enow)) {
5009     Q = enow;
5010     enow = e[++eindex];
5011   } else {
5012     Q = fnow;
5013     fnow = f[++findex];
5014   }
5015   hindex = 0;
5016   if ((eindex < elen) && (findex < flen)) {
5017     if ((fnow > enow) == (fnow > -enow)) {
5018       Fast_Two_Sum(enow, Q, Qnew, hh);
5019       enow = e[++eindex];
5020     } else {
5021       Fast_Two_Sum(fnow, Q, Qnew, hh);
5022       fnow = f[++findex];
5023     }
5024     Q = Qnew;
5025     if (hh != 0.0) {
5026       h[hindex++] = hh;
5027     }
5028     while ((eindex < elen) && (findex < flen)) {
5029       if ((fnow > enow) == (fnow > -enow)) {
5030         Two_Sum(Q, enow, Qnew, hh);
5031         enow = e[++eindex];
5032       } else {
5033         Two_Sum(Q, fnow, Qnew, hh);
5034         fnow = f[++findex];
5035       }
5036       Q = Qnew;
5037       if (hh != 0.0) {
5038         h[hindex++] = hh;
5039       }
5040     }
5041   }
5042   while (eindex < elen) {
5043     Two_Sum(Q, enow, Qnew, hh);
5044     enow = e[++eindex];
5045     Q = Qnew;
5046     if (hh != 0.0) {
5047       h[hindex++] = hh;
5048     }
5049   }
5050   while (findex < flen) {
5051     Two_Sum(Q, fnow, Qnew, hh);
5052     fnow = f[++findex];
5053     Q = Qnew;
5054     if (hh != 0.0) {
5055       h[hindex++] = hh;
5056     }
5057   }
5058   if ((Q != 0.0) || (hindex == 0)) {
5059     h[hindex++] = Q;
5060   }
5061   return hindex;
5062 }
5063 
5064 /*****************************************************************************/
5065 /*                                                                           */
5066 /*  scale_expansion_zeroelim()   Multiply an expansion by a scalar,          */
5067 /*                               eliminating zero components from the        */
5068 /*                               output expansion.                           */
5069 /*                                                                           */
5070 /*  Sets h = be.  See my Robust Predicates paper for details.                */
5071 /*                                                                           */
5072 /*  Maintains the nonoverlapping property.  If round-to-even is used (as     */
5073 /*  with IEEE 754), maintains the strongly nonoverlapping and nonadjacent    */
5074 /*  properties as well.  (That is, if e has one of these properties, so      */
5075 /*  will h.)                                                                 */
5076 /*                                                                           */
5077 /*****************************************************************************/
5078 
5079 static
5080 #ifdef ANSI_DECLARATORS
scale_expansion_zeroelim(int elen,REAL * e,REAL b,REAL * h)5081 int scale_expansion_zeroelim(int elen, REAL *e, REAL b, REAL *h)
5082 #else /* not ANSI_DECLARATORS */
5083 int scale_expansion_zeroelim(elen, e, b, h)   /* e and h cannot be the same. */
5084 int elen;
5085 REAL *e;
5086 REAL b;
5087 REAL *h;
5088 #endif /* not ANSI_DECLARATORS */
5089 
5090 {
5091   INEXACT REAL Q, sum;
5092   REAL hh;
5093   INEXACT REAL product1;
5094   REAL product0;
5095   int eindex, hindex;
5096   REAL enow;
5097   INEXACT REAL bvirt;
5098   REAL avirt, bround, around;
5099   INEXACT REAL c;
5100   INEXACT REAL abig;
5101   REAL ahi, alo, bhi, blo;
5102   REAL err1, err2, err3;
5103 
5104   Split(b, bhi, blo);
5105   Two_Product_Presplit(e[0], b, bhi, blo, Q, hh);
5106   hindex = 0;
5107   if (hh != 0) {
5108     h[hindex++] = hh;
5109   }
5110   for (eindex = 1; eindex < elen; eindex++) {
5111     enow = e[eindex];
5112     Two_Product_Presplit(enow, b, bhi, blo, product1, product0);
5113     Two_Sum(Q, product0, sum, hh);
5114     if (hh != 0) {
5115       h[hindex++] = hh;
5116     }
5117     Fast_Two_Sum(product1, sum, Q, hh);
5118     if (hh != 0) {
5119       h[hindex++] = hh;
5120     }
5121   }
5122   if ((Q != 0.0) || (hindex == 0)) {
5123     h[hindex++] = Q;
5124   }
5125   return hindex;
5126 }
5127 
5128 /*****************************************************************************/
5129 /*                                                                           */
5130 /*  estimate()   Produce a one-word estimate of an expansion's value.        */
5131 /*                                                                           */
5132 /*  See my Robust Predicates paper for details.                              */
5133 /*                                                                           */
5134 /*****************************************************************************/
5135 
5136 static
5137 #ifdef ANSI_DECLARATORS
estimate(int elen,REAL * e)5138 REAL estimate(int elen, REAL *e)
5139 #else /* not ANSI_DECLARATORS */
5140 REAL estimate(elen, e)
5141 int elen;
5142 REAL *e;
5143 #endif /* not ANSI_DECLARATORS */
5144 
5145 {
5146   REAL Q;
5147   int eindex;
5148 
5149   Q = e[0];
5150   for (eindex = 1; eindex < elen; eindex++) {
5151     Q += e[eindex];
5152   }
5153   return Q;
5154 }
5155 
5156 /*****************************************************************************/
5157 /*                                                                           */
5158 /*  counterclockwise()   Return a positive value if the points pa, pb, and   */
5159 /*                       pc occur in counterclockwise order; a negative      */
5160 /*                       value if they occur in clockwise order; and zero    */
5161 /*                       if they are collinear.  The result is also a rough  */
5162 /*                       approximation of twice the signed area of the       */
5163 /*                       triangle defined by the three points.               */
5164 /*                                                                           */
5165 /*  Uses exact arithmetic if necessary to ensure a correct answer.  The      */
5166 /*  result returned is the determinant of a matrix.  This determinant is     */
5167 /*  computed adaptively, in the sense that exact arithmetic is used only to  */
5168 /*  the degree it is needed to ensure that the returned value has the        */
5169 /*  correct sign.  Hence, this function is usually quite fast, but will run  */
5170 /*  more slowly when the input points are collinear or nearly so.            */
5171 /*                                                                           */
5172 /*  See my Robust Predicates paper for details.                              */
5173 /*                                                                           */
5174 /*****************************************************************************/
5175 
5176 #ifdef ANSI_DECLARATORS
5177 REAL counterclockwiseadapt(vertex pa, vertex pb, vertex pc, REAL detsum)
5178 #else /* not ANSI_DECLARATORS */
5179 REAL counterclockwiseadapt(pa, pb, pc, detsum)
5180 vertex pa;
5181 vertex pb;
5182 vertex pc;
5183 REAL detsum;
5184 #endif /* not ANSI_DECLARATORS */
5185 
5186 {
5187   INEXACT REAL acx, acy, bcx, bcy;
5188   REAL acxtail, acytail, bcxtail, bcytail;
5189   INEXACT REAL detleft, detright;
5190   REAL detlefttail, detrighttail;
5191   REAL det, errbound;
5192   REAL B[4], C1[8], C2[12], D[16];
5193   INEXACT REAL B3;
5194   int C1length, C2length, Dlength;
5195   REAL u[4];
5196   INEXACT REAL u3;
5197   INEXACT REAL s1, t1;
5198   REAL s0, t0;
5199 
5200   INEXACT REAL bvirt;
5201   REAL avirt, bround, around;
5202   INEXACT REAL c;
5203   INEXACT REAL abig;
5204   REAL ahi, alo, bhi, blo;
5205   REAL err1, err2, err3;
5206   INEXACT REAL _i, _j;
5207   REAL _0;
5208 
5209   acx = (REAL) (pa[0] - pc[0]);
5210   bcx = (REAL) (pb[0] - pc[0]);
5211   acy = (REAL) (pa[1] - pc[1]);
5212   bcy = (REAL) (pb[1] - pc[1]);
5213 
5214   Two_Product(acx, bcy, detleft, detlefttail);
5215   Two_Product(acy, bcx, detright, detrighttail);
5216 
5217   Two_Two_Diff(detleft, detlefttail, detright, detrighttail,
5218                B3, B[2], B[1], B[0]);
5219   B[3] = B3;
5220 
5221   det = estimate(4, B);
5222   errbound = ccwerrboundB * detsum;
5223   if ((det >= errbound) || (-det >= errbound)) {
5224     return det;
5225   }
5226 
5227   Two_Diff_Tail(pa[0], pc[0], acx, acxtail);
5228   Two_Diff_Tail(pb[0], pc[0], bcx, bcxtail);
5229   Two_Diff_Tail(pa[1], pc[1], acy, acytail);
5230   Two_Diff_Tail(pb[1], pc[1], bcy, bcytail);
5231 
5232   if ((acxtail == 0.0) && (acytail == 0.0)
5233       && (bcxtail == 0.0) && (bcytail == 0.0)) {
5234     return det;
5235   }
5236 
5237   errbound = ccwerrboundC * detsum + resulterrbound * Absolute(det);
5238   det += (acx * bcytail + bcy * acxtail)
5239        - (acy * bcxtail + bcx * acytail);
5240   if ((det >= errbound) || (-det >= errbound)) {
5241     return det;
5242   }
5243 
5244   Two_Product(acxtail, bcy, s1, s0);
5245   Two_Product(acytail, bcx, t1, t0);
5246   Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
5247   u[3] = u3;
5248   C1length = fast_expansion_sum_zeroelim(4, B, 4, u, C1);
5249 
5250   Two_Product(acx, bcytail, s1, s0);
5251   Two_Product(acy, bcxtail, t1, t0);
5252   Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
5253   u[3] = u3;
5254   C2length = fast_expansion_sum_zeroelim(C1length, C1, 4, u, C2);
5255 
5256   Two_Product(acxtail, bcytail, s1, s0);
5257   Two_Product(acytail, bcxtail, t1, t0);
5258   Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
5259   u[3] = u3;
5260   Dlength = fast_expansion_sum_zeroelim(C2length, C2, 4, u, D);
5261 
5262   return(D[Dlength - 1]);
5263 }
5264 
5265 #ifdef ANSI_DECLARATORS
5266 REAL counterclockwise(struct mesh *m, struct behavior *b,
5267                       vertex pa, vertex pb, vertex pc)
5268 #else /* not ANSI_DECLARATORS */
5269 REAL counterclockwise(m, b, pa, pb, pc)
5270 struct mesh *m;
5271 struct behavior *b;
5272 vertex pa;
5273 vertex pb;
5274 vertex pc;
5275 #endif /* not ANSI_DECLARATORS */
5276 
5277 {
5278   REAL detleft, detright, det;
5279   REAL detsum, errbound;
5280 
5281   m->counterclockcount++;
5282 
5283   detleft = (pa[0] - pc[0]) * (pb[1] - pc[1]);
5284   detright = (pa[1] - pc[1]) * (pb[0] - pc[0]);
5285   det = detleft - detright;
5286 
5287   if (b->noexact) {
5288     return det;
5289   }
5290 
5291   if (detleft > 0.0) {
5292     if (detright <= 0.0) {
5293       return det;
5294     } else {
5295       detsum = detleft + detright;
5296     }
5297   } else if (detleft < 0.0) {
5298     if (detright >= 0.0) {
5299       return det;
5300     } else {
5301       detsum = -detleft - detright;
5302     }
5303   } else {
5304     return det;
5305   }
5306 
5307   errbound = ccwerrboundA * detsum;
5308   if ((det >= errbound) || (-det >= errbound)) {
5309     return det;
5310   }
5311 
5312   return counterclockwiseadapt(pa, pb, pc, detsum);
5313 }
5314 
5315 /*****************************************************************************/
5316 /*                                                                           */
5317 /*  incircle()   Return a positive value if the point pd lies inside the     */
5318 /*               circle passing through pa, pb, and pc; a negative value if  */
5319 /*               it lies outside; and zero if the four points are cocircular.*/
5320 /*               The points pa, pb, and pc must be in counterclockwise       */
5321 /*               order, or the sign of the result will be reversed.          */
5322 /*                                                                           */
5323 /*  Uses exact arithmetic if necessary to ensure a correct answer.  The      */
5324 /*  result returned is the determinant of a matrix.  This determinant is     */
5325 /*  computed adaptively, in the sense that exact arithmetic is used only to  */
5326 /*  the degree it is needed to ensure that the returned value has the        */
5327 /*  correct sign.  Hence, this function is usually quite fast, but will run  */
5328 /*  more slowly when the input points are cocircular or nearly so.           */
5329 /*                                                                           */
5330 /*  See my Robust Predicates paper for details.                              */
5331 /*                                                                           */
5332 /*****************************************************************************/
5333 
5334 static
5335 #ifdef ANSI_DECLARATORS
incircleadapt(vertex pa,vertex pb,vertex pc,vertex pd,REAL permanent)5336 REAL incircleadapt(vertex pa, vertex pb, vertex pc, vertex pd, REAL permanent)
5337 #else /* not ANSI_DECLARATORS */
5338 REAL incircleadapt(pa, pb, pc, pd, permanent)
5339 vertex pa;
5340 vertex pb;
5341 vertex pc;
5342 vertex pd;
5343 REAL permanent;
5344 #endif /* not ANSI_DECLARATORS */
5345 
5346 {
5347   INEXACT REAL adx, bdx, cdx, ady, bdy, cdy;
5348   REAL det, errbound;
5349 
5350   INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1;
5351   REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0;
5352   REAL bc[4], ca[4], ab[4];
5353   INEXACT REAL bc3, ca3, ab3;
5354   REAL axbc[8], axxbc[16], aybc[8], ayybc[16], adet[32];
5355   int axbclen, axxbclen, aybclen, ayybclen, alen;
5356   REAL bxca[8], bxxca[16], byca[8], byyca[16], bdet[32];
5357   int bxcalen, bxxcalen, bycalen, byycalen, blen;
5358   REAL cxab[8], cxxab[16], cyab[8], cyyab[16], cdet[32];
5359   int cxablen, cxxablen, cyablen, cyyablen, clen;
5360   REAL abdet[64];
5361   int ablen;
5362   REAL fin1[1152], fin2[1152];
5363   REAL *finnow, *finother, *finswap;
5364   int finlength;
5365 
5366   REAL adxtail, bdxtail, cdxtail, adytail, bdytail, cdytail;
5367   INEXACT REAL adxadx1, adyady1, bdxbdx1, bdybdy1, cdxcdx1, cdycdy1;
5368   REAL adxadx0, adyady0, bdxbdx0, bdybdy0, cdxcdx0, cdycdy0;
5369   REAL aa[4], bb[4], cc[4];
5370   INEXACT REAL aa3, bb3, cc3;
5371   INEXACT REAL ti1, tj1;
5372   REAL ti0, tj0;
5373   REAL u[4], v[4];
5374   INEXACT REAL u3, v3;
5375   REAL temp8[8], temp16a[16], temp16b[16], temp16c[16];
5376   REAL temp32a[32], temp32b[32], temp48[48], temp64[64];
5377   int temp8len, temp16alen, temp16blen, temp16clen;
5378   int temp32alen, temp32blen, temp48len, temp64len;
5379   REAL axtbb[8], axtcc[8], aytbb[8], aytcc[8];
5380   int axtbblen, axtcclen, aytbblen, aytcclen;
5381   REAL bxtaa[8], bxtcc[8], bytaa[8], bytcc[8];
5382   int bxtaalen, bxtcclen, bytaalen, bytcclen;
5383   REAL cxtaa[8], cxtbb[8], cytaa[8], cytbb[8];
5384   int cxtaalen, cxtbblen, cytaalen, cytbblen;
5385   REAL axtbc[8], aytbc[8], bxtca[8], bytca[8], cxtab[8], cytab[8];
5386   int axtbclen, aytbclen, bxtcalen, bytcalen, cxtablen, cytablen;
5387   REAL axtbct[16], aytbct[16], bxtcat[16], bytcat[16], cxtabt[16], cytabt[16];
5388   int axtbctlen, aytbctlen, bxtcatlen, bytcatlen, cxtabtlen, cytabtlen;
5389   REAL axtbctt[8], aytbctt[8], bxtcatt[8];
5390   REAL bytcatt[8], cxtabtt[8], cytabtt[8];
5391   int axtbcttlen, aytbcttlen, bxtcattlen, bytcattlen, cxtabttlen, cytabttlen;
5392   REAL abt[8], bct[8], cat[8];
5393   int abtlen, bctlen, catlen;
5394   REAL abtt[4], bctt[4], catt[4];
5395   int abttlen, bcttlen, cattlen;
5396   INEXACT REAL abtt3, bctt3, catt3;
5397   REAL negate;
5398 
5399   INEXACT REAL bvirt;
5400   REAL avirt, bround, around;
5401   INEXACT REAL c;
5402   INEXACT REAL abig;
5403   REAL ahi, alo, bhi, blo;
5404   REAL err1, err2, err3;
5405   INEXACT REAL _i, _j;
5406   REAL _0;
5407 
5408   adx = (REAL) (pa[0] - pd[0]);
5409   bdx = (REAL) (pb[0] - pd[0]);
5410   cdx = (REAL) (pc[0] - pd[0]);
5411   ady = (REAL) (pa[1] - pd[1]);
5412   bdy = (REAL) (pb[1] - pd[1]);
5413   cdy = (REAL) (pc[1] - pd[1]);
5414 
5415   Two_Product(bdx, cdy, bdxcdy1, bdxcdy0);
5416   Two_Product(cdx, bdy, cdxbdy1, cdxbdy0);
5417   Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]);
5418   bc[3] = bc3;
5419   axbclen = scale_expansion_zeroelim(4, bc, adx, axbc);
5420   axxbclen = scale_expansion_zeroelim(axbclen, axbc, adx, axxbc);
5421   aybclen = scale_expansion_zeroelim(4, bc, ady, aybc);
5422   ayybclen = scale_expansion_zeroelim(aybclen, aybc, ady, ayybc);
5423   alen = fast_expansion_sum_zeroelim(axxbclen, axxbc, ayybclen, ayybc, adet);
5424 
5425   Two_Product(cdx, ady, cdxady1, cdxady0);
5426   Two_Product(adx, cdy, adxcdy1, adxcdy0);
5427   Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]);
5428   ca[3] = ca3;
5429   bxcalen = scale_expansion_zeroelim(4, ca, bdx, bxca);
5430   bxxcalen = scale_expansion_zeroelim(bxcalen, bxca, bdx, bxxca);
5431   bycalen = scale_expansion_zeroelim(4, ca, bdy, byca);
5432   byycalen = scale_expansion_zeroelim(bycalen, byca, bdy, byyca);
5433   blen = fast_expansion_sum_zeroelim(bxxcalen, bxxca, byycalen, byyca, bdet);
5434 
5435   Two_Product(adx, bdy, adxbdy1, adxbdy0);
5436   Two_Product(bdx, ady, bdxady1, bdxady0);
5437   Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]);
5438   ab[3] = ab3;
5439   cxablen = scale_expansion_zeroelim(4, ab, cdx, cxab);
5440   cxxablen = scale_expansion_zeroelim(cxablen, cxab, cdx, cxxab);
5441   cyablen = scale_expansion_zeroelim(4, ab, cdy, cyab);
5442   cyyablen = scale_expansion_zeroelim(cyablen, cyab, cdy, cyyab);
5443   clen = fast_expansion_sum_zeroelim(cxxablen, cxxab, cyyablen, cyyab, cdet);
5444 
5445   ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
5446   finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1);
5447 
5448   det = estimate(finlength, fin1);
5449   errbound = iccerrboundB * permanent;
5450   if ((det >= errbound) || (-det >= errbound)) {
5451     return det;
5452   }
5453 
5454   Two_Diff_Tail(pa[0], pd[0], adx, adxtail);
5455   Two_Diff_Tail(pa[1], pd[1], ady, adytail);
5456   Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail);
5457   Two_Diff_Tail(pb[1], pd[1], bdy, bdytail);
5458   Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail);
5459   Two_Diff_Tail(pc[1], pd[1], cdy, cdytail);
5460   if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0)
5461       && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0)) {
5462     return det;
5463   }
5464 
5465   errbound = iccerrboundC * permanent + resulterrbound * Absolute(det);
5466   det += ((adx * adx + ady * ady) * ((bdx * cdytail + cdy * bdxtail)
5467                                      - (bdy * cdxtail + cdx * bdytail))
5468           + 2.0 * (adx * adxtail + ady * adytail) * (bdx * cdy - bdy * cdx))
5469        + ((bdx * bdx + bdy * bdy) * ((cdx * adytail + ady * cdxtail)
5470                                      - (cdy * adxtail + adx * cdytail))
5471           + 2.0 * (bdx * bdxtail + bdy * bdytail) * (cdx * ady - cdy * adx))
5472        + ((cdx * cdx + cdy * cdy) * ((adx * bdytail + bdy * adxtail)
5473                                      - (ady * bdxtail + bdx * adytail))
5474           + 2.0 * (cdx * cdxtail + cdy * cdytail) * (adx * bdy - ady * bdx));
5475   if ((det >= errbound) || (-det >= errbound)) {
5476     return det;
5477   }
5478 
5479   finnow = fin1;
5480   finother = fin2;
5481 
5482   if ((bdxtail != 0.0) || (bdytail != 0.0)
5483       || (cdxtail != 0.0) || (cdytail != 0.0)) {
5484     Square(adx, adxadx1, adxadx0);
5485     Square(ady, adyady1, adyady0);
5486     Two_Two_Sum(adxadx1, adxadx0, adyady1, adyady0, aa3, aa[2], aa[1], aa[0]);
5487     aa[3] = aa3;
5488   }
5489   if ((cdxtail != 0.0) || (cdytail != 0.0)
5490       || (adxtail != 0.0) || (adytail != 0.0)) {
5491     Square(bdx, bdxbdx1, bdxbdx0);
5492     Square(bdy, bdybdy1, bdybdy0);
5493     Two_Two_Sum(bdxbdx1, bdxbdx0, bdybdy1, bdybdy0, bb3, bb[2], bb[1], bb[0]);
5494     bb[3] = bb3;
5495   }
5496   if ((adxtail != 0.0) || (adytail != 0.0)
5497       || (bdxtail != 0.0) || (bdytail != 0.0)) {
5498     Square(cdx, cdxcdx1, cdxcdx0);
5499     Square(cdy, cdycdy1, cdycdy0);
5500     Two_Two_Sum(cdxcdx1, cdxcdx0, cdycdy1, cdycdy0, cc3, cc[2], cc[1], cc[0]);
5501     cc[3] = cc3;
5502   }
5503 
5504   if (adxtail != 0.0) {
5505     axtbclen = scale_expansion_zeroelim(4, bc, adxtail, axtbc);
5506     temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, 2.0 * adx,
5507                                           temp16a);
5508 
5509     axtcclen = scale_expansion_zeroelim(4, cc, adxtail, axtcc);
5510     temp16blen = scale_expansion_zeroelim(axtcclen, axtcc, bdy, temp16b);
5511 
5512     axtbblen = scale_expansion_zeroelim(4, bb, adxtail, axtbb);
5513     temp16clen = scale_expansion_zeroelim(axtbblen, axtbb, -cdy, temp16c);
5514 
5515     temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5516                                             temp16blen, temp16b, temp32a);
5517     temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
5518                                             temp32alen, temp32a, temp48);
5519     finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5520                                             temp48, finother);
5521     finswap = finnow; finnow = finother; finother = finswap;
5522   }
5523   if (adytail != 0.0) {
5524     aytbclen = scale_expansion_zeroelim(4, bc, adytail, aytbc);
5525     temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, 2.0 * ady,
5526                                           temp16a);
5527 
5528     aytbblen = scale_expansion_zeroelim(4, bb, adytail, aytbb);
5529     temp16blen = scale_expansion_zeroelim(aytbblen, aytbb, cdx, temp16b);
5530 
5531     aytcclen = scale_expansion_zeroelim(4, cc, adytail, aytcc);
5532     temp16clen = scale_expansion_zeroelim(aytcclen, aytcc, -bdx, temp16c);
5533 
5534     temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5535                                             temp16blen, temp16b, temp32a);
5536     temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
5537                                             temp32alen, temp32a, temp48);
5538     finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5539                                             temp48, finother);
5540     finswap = finnow; finnow = finother; finother = finswap;
5541   }
5542   if (bdxtail != 0.0) {
5543     bxtcalen = scale_expansion_zeroelim(4, ca, bdxtail, bxtca);
5544     temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, 2.0 * bdx,
5545                                           temp16a);
5546 
5547     bxtaalen = scale_expansion_zeroelim(4, aa, bdxtail, bxtaa);
5548     temp16blen = scale_expansion_zeroelim(bxtaalen, bxtaa, cdy, temp16b);
5549 
5550     bxtcclen = scale_expansion_zeroelim(4, cc, bdxtail, bxtcc);
5551     temp16clen = scale_expansion_zeroelim(bxtcclen, bxtcc, -ady, temp16c);
5552 
5553     temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5554                                             temp16blen, temp16b, temp32a);
5555     temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
5556                                             temp32alen, temp32a, temp48);
5557     finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5558                                             temp48, finother);
5559     finswap = finnow; finnow = finother; finother = finswap;
5560   }
5561   if (bdytail != 0.0) {
5562     bytcalen = scale_expansion_zeroelim(4, ca, bdytail, bytca);
5563     temp16alen = scale_expansion_zeroelim(bytcalen, bytca, 2.0 * bdy,
5564                                           temp16a);
5565 
5566     bytcclen = scale_expansion_zeroelim(4, cc, bdytail, bytcc);
5567     temp16blen = scale_expansion_zeroelim(bytcclen, bytcc, adx, temp16b);
5568 
5569     bytaalen = scale_expansion_zeroelim(4, aa, bdytail, bytaa);
5570     temp16clen = scale_expansion_zeroelim(bytaalen, bytaa, -cdx, temp16c);
5571 
5572     temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5573                                             temp16blen, temp16b, temp32a);
5574     temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
5575                                             temp32alen, temp32a, temp48);
5576     finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5577                                             temp48, finother);
5578     finswap = finnow; finnow = finother; finother = finswap;
5579   }
5580   if (cdxtail != 0.0) {
5581     cxtablen = scale_expansion_zeroelim(4, ab, cdxtail, cxtab);
5582     temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, 2.0 * cdx,
5583                                           temp16a);
5584 
5585     cxtbblen = scale_expansion_zeroelim(4, bb, cdxtail, cxtbb);
5586     temp16blen = scale_expansion_zeroelim(cxtbblen, cxtbb, ady, temp16b);
5587 
5588     cxtaalen = scale_expansion_zeroelim(4, aa, cdxtail, cxtaa);
5589     temp16clen = scale_expansion_zeroelim(cxtaalen, cxtaa, -bdy, temp16c);
5590 
5591     temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5592                                             temp16blen, temp16b, temp32a);
5593     temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
5594                                             temp32alen, temp32a, temp48);
5595     finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5596                                             temp48, finother);
5597     finswap = finnow; finnow = finother; finother = finswap;
5598   }
5599   if (cdytail != 0.0) {
5600     cytablen = scale_expansion_zeroelim(4, ab, cdytail, cytab);
5601     temp16alen = scale_expansion_zeroelim(cytablen, cytab, 2.0 * cdy,
5602                                           temp16a);
5603 
5604     cytaalen = scale_expansion_zeroelim(4, aa, cdytail, cytaa);
5605     temp16blen = scale_expansion_zeroelim(cytaalen, cytaa, bdx, temp16b);
5606 
5607     cytbblen = scale_expansion_zeroelim(4, bb, cdytail, cytbb);
5608     temp16clen = scale_expansion_zeroelim(cytbblen, cytbb, -adx, temp16c);
5609 
5610     temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5611                                             temp16blen, temp16b, temp32a);
5612     temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
5613                                             temp32alen, temp32a, temp48);
5614     finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5615                                             temp48, finother);
5616     finswap = finnow; finnow = finother; finother = finswap;
5617   }
5618 
5619   if ((adxtail != 0.0) || (adytail != 0.0)) {
5620     if ((bdxtail != 0.0) || (bdytail != 0.0)
5621         || (cdxtail != 0.0) || (cdytail != 0.0)) {
5622       Two_Product(bdxtail, cdy, ti1, ti0);
5623       Two_Product(bdx, cdytail, tj1, tj0);
5624       Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
5625       u[3] = u3;
5626       negate = -bdy;
5627       Two_Product(cdxtail, negate, ti1, ti0);
5628       negate = -bdytail;
5629       Two_Product(cdx, negate, tj1, tj0);
5630       Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
5631       v[3] = v3;
5632       bctlen = fast_expansion_sum_zeroelim(4, u, 4, v, bct);
5633 
5634       Two_Product(bdxtail, cdytail, ti1, ti0);
5635       Two_Product(cdxtail, bdytail, tj1, tj0);
5636       Two_Two_Diff(ti1, ti0, tj1, tj0, bctt3, bctt[2], bctt[1], bctt[0]);
5637       bctt[3] = bctt3;
5638       bcttlen = 4;
5639     } else {
5640       bct[0] = 0.0;
5641       bctlen = 1;
5642       bctt[0] = 0.0;
5643       bcttlen = 1;
5644     }
5645 
5646     if (adxtail != 0.0) {
5647       temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, adxtail, temp16a);
5648       axtbctlen = scale_expansion_zeroelim(bctlen, bct, adxtail, axtbct);
5649       temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, 2.0 * adx,
5650                                             temp32a);
5651       temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5652                                               temp32alen, temp32a, temp48);
5653       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5654                                               temp48, finother);
5655       finswap = finnow; finnow = finother; finother = finswap;
5656       if (bdytail != 0.0) {
5657         temp8len = scale_expansion_zeroelim(4, cc, adxtail, temp8);
5658         temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail,
5659                                               temp16a);
5660         finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
5661                                                 temp16a, finother);
5662         finswap = finnow; finnow = finother; finother = finswap;
5663       }
5664       if (cdytail != 0.0) {
5665         temp8len = scale_expansion_zeroelim(4, bb, -adxtail, temp8);
5666         temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail,
5667                                               temp16a);
5668         finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
5669                                                 temp16a, finother);
5670         finswap = finnow; finnow = finother; finother = finswap;
5671       }
5672 
5673       temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, adxtail,
5674                                             temp32a);
5675       axtbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adxtail, axtbctt);
5676       temp16alen = scale_expansion_zeroelim(axtbcttlen, axtbctt, 2.0 * adx,
5677                                             temp16a);
5678       temp16blen = scale_expansion_zeroelim(axtbcttlen, axtbctt, adxtail,
5679                                             temp16b);
5680       temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5681                                               temp16blen, temp16b, temp32b);
5682       temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
5683                                               temp32blen, temp32b, temp64);
5684       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
5685                                               temp64, finother);
5686       finswap = finnow; finnow = finother; finother = finswap;
5687     }
5688     if (adytail != 0.0) {
5689       temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, adytail, temp16a);
5690       aytbctlen = scale_expansion_zeroelim(bctlen, bct, adytail, aytbct);
5691       temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, 2.0 * ady,
5692                                             temp32a);
5693       temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5694                                               temp32alen, temp32a, temp48);
5695       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5696                                               temp48, finother);
5697       finswap = finnow; finnow = finother; finother = finswap;
5698 
5699 
5700       temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, adytail,
5701                                             temp32a);
5702       aytbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adytail, aytbctt);
5703       temp16alen = scale_expansion_zeroelim(aytbcttlen, aytbctt, 2.0 * ady,
5704                                             temp16a);
5705       temp16blen = scale_expansion_zeroelim(aytbcttlen, aytbctt, adytail,
5706                                             temp16b);
5707       temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5708                                               temp16blen, temp16b, temp32b);
5709       temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
5710                                               temp32blen, temp32b, temp64);
5711       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
5712                                               temp64, finother);
5713       finswap = finnow; finnow = finother; finother = finswap;
5714     }
5715   }
5716   if ((bdxtail != 0.0) || (bdytail != 0.0)) {
5717     if ((cdxtail != 0.0) || (cdytail != 0.0)
5718         || (adxtail != 0.0) || (adytail != 0.0)) {
5719       Two_Product(cdxtail, ady, ti1, ti0);
5720       Two_Product(cdx, adytail, tj1, tj0);
5721       Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
5722       u[3] = u3;
5723       negate = -cdy;
5724       Two_Product(adxtail, negate, ti1, ti0);
5725       negate = -cdytail;
5726       Two_Product(adx, negate, tj1, tj0);
5727       Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
5728       v[3] = v3;
5729       catlen = fast_expansion_sum_zeroelim(4, u, 4, v, cat);
5730 
5731       Two_Product(cdxtail, adytail, ti1, ti0);
5732       Two_Product(adxtail, cdytail, tj1, tj0);
5733       Two_Two_Diff(ti1, ti0, tj1, tj0, catt3, catt[2], catt[1], catt[0]);
5734       catt[3] = catt3;
5735       cattlen = 4;
5736     } else {
5737       cat[0] = 0.0;
5738       catlen = 1;
5739       catt[0] = 0.0;
5740       cattlen = 1;
5741     }
5742 
5743     if (bdxtail != 0.0) {
5744       temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, bdxtail, temp16a);
5745       bxtcatlen = scale_expansion_zeroelim(catlen, cat, bdxtail, bxtcat);
5746       temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, 2.0 * bdx,
5747                                             temp32a);
5748       temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5749                                               temp32alen, temp32a, temp48);
5750       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5751                                               temp48, finother);
5752       finswap = finnow; finnow = finother; finother = finswap;
5753       if (cdytail != 0.0) {
5754         temp8len = scale_expansion_zeroelim(4, aa, bdxtail, temp8);
5755         temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail,
5756                                               temp16a);
5757         finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
5758                                                 temp16a, finother);
5759         finswap = finnow; finnow = finother; finother = finswap;
5760       }
5761       if (adytail != 0.0) {
5762         temp8len = scale_expansion_zeroelim(4, cc, -bdxtail, temp8);
5763         temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail,
5764                                               temp16a);
5765         finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
5766                                                 temp16a, finother);
5767         finswap = finnow; finnow = finother; finother = finswap;
5768       }
5769 
5770       temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, bdxtail,
5771                                             temp32a);
5772       bxtcattlen = scale_expansion_zeroelim(cattlen, catt, bdxtail, bxtcatt);
5773       temp16alen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, 2.0 * bdx,
5774                                             temp16a);
5775       temp16blen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, bdxtail,
5776                                             temp16b);
5777       temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5778                                               temp16blen, temp16b, temp32b);
5779       temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
5780                                               temp32blen, temp32b, temp64);
5781       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
5782                                               temp64, finother);
5783       finswap = finnow; finnow = finother; finother = finswap;
5784     }
5785     if (bdytail != 0.0) {
5786       temp16alen = scale_expansion_zeroelim(bytcalen, bytca, bdytail, temp16a);
5787       bytcatlen = scale_expansion_zeroelim(catlen, cat, bdytail, bytcat);
5788       temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, 2.0 * bdy,
5789                                             temp32a);
5790       temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5791                                               temp32alen, temp32a, temp48);
5792       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5793                                               temp48, finother);
5794       finswap = finnow; finnow = finother; finother = finswap;
5795 
5796 
5797       temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, bdytail,
5798                                             temp32a);
5799       bytcattlen = scale_expansion_zeroelim(cattlen, catt, bdytail, bytcatt);
5800       temp16alen = scale_expansion_zeroelim(bytcattlen, bytcatt, 2.0 * bdy,
5801                                             temp16a);
5802       temp16blen = scale_expansion_zeroelim(bytcattlen, bytcatt, bdytail,
5803                                             temp16b);
5804       temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5805                                               temp16blen, temp16b, temp32b);
5806       temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
5807                                               temp32blen, temp32b, temp64);
5808       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
5809                                               temp64, finother);
5810       finswap = finnow; finnow = finother; finother = finswap;
5811     }
5812   }
5813   if ((cdxtail != 0.0) || (cdytail != 0.0)) {
5814     if ((adxtail != 0.0) || (adytail != 0.0)
5815         || (bdxtail != 0.0) || (bdytail != 0.0)) {
5816       Two_Product(adxtail, bdy, ti1, ti0);
5817       Two_Product(adx, bdytail, tj1, tj0);
5818       Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
5819       u[3] = u3;
5820       negate = -ady;
5821       Two_Product(bdxtail, negate, ti1, ti0);
5822       negate = -adytail;
5823       Two_Product(bdx, negate, tj1, tj0);
5824       Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
5825       v[3] = v3;
5826       abtlen = fast_expansion_sum_zeroelim(4, u, 4, v, abt);
5827 
5828       Two_Product(adxtail, bdytail, ti1, ti0);
5829       Two_Product(bdxtail, adytail, tj1, tj0);
5830       Two_Two_Diff(ti1, ti0, tj1, tj0, abtt3, abtt[2], abtt[1], abtt[0]);
5831       abtt[3] = abtt3;
5832       abttlen = 4;
5833     } else {
5834       abt[0] = 0.0;
5835       abtlen = 1;
5836       abtt[0] = 0.0;
5837       abttlen = 1;
5838     }
5839 
5840     if (cdxtail != 0.0) {
5841       temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, cdxtail, temp16a);
5842       cxtabtlen = scale_expansion_zeroelim(abtlen, abt, cdxtail, cxtabt);
5843       temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, 2.0 * cdx,
5844                                             temp32a);
5845       temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5846                                               temp32alen, temp32a, temp48);
5847       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5848                                               temp48, finother);
5849       finswap = finnow; finnow = finother; finother = finswap;
5850       if (adytail != 0.0) {
5851         temp8len = scale_expansion_zeroelim(4, bb, cdxtail, temp8);
5852         temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail,
5853                                               temp16a);
5854         finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
5855                                                 temp16a, finother);
5856         finswap = finnow; finnow = finother; finother = finswap;
5857       }
5858       if (bdytail != 0.0) {
5859         temp8len = scale_expansion_zeroelim(4, aa, -cdxtail, temp8);
5860         temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail,
5861                                               temp16a);
5862         finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
5863                                                 temp16a, finother);
5864         finswap = finnow; finnow = finother; finother = finswap;
5865       }
5866 
5867       temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, cdxtail,
5868                                             temp32a);
5869       cxtabttlen = scale_expansion_zeroelim(abttlen, abtt, cdxtail, cxtabtt);
5870       temp16alen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, 2.0 * cdx,
5871                                             temp16a);
5872       temp16blen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, cdxtail,
5873                                             temp16b);
5874       temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5875                                               temp16blen, temp16b, temp32b);
5876       temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
5877                                               temp32blen, temp32b, temp64);
5878       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
5879                                               temp64, finother);
5880       finswap = finnow; finnow = finother; finother = finswap;
5881     }
5882     if (cdytail != 0.0) {
5883       temp16alen = scale_expansion_zeroelim(cytablen, cytab, cdytail, temp16a);
5884       cytabtlen = scale_expansion_zeroelim(abtlen, abt, cdytail, cytabt);
5885       temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, 2.0 * cdy,
5886                                             temp32a);
5887       temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5888                                               temp32alen, temp32a, temp48);
5889       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5890                                               temp48, finother);
5891       finswap = finnow; finnow = finother; finother = finswap;
5892 
5893 
5894       temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, cdytail,
5895                                             temp32a);
5896       cytabttlen = scale_expansion_zeroelim(abttlen, abtt, cdytail, cytabtt);
5897       temp16alen = scale_expansion_zeroelim(cytabttlen, cytabtt, 2.0 * cdy,
5898                                             temp16a);
5899       temp16blen = scale_expansion_zeroelim(cytabttlen, cytabtt, cdytail,
5900                                             temp16b);
5901       temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5902                                               temp16blen, temp16b, temp32b);
5903       temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
5904                                               temp32blen, temp32b, temp64);
5905       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
5906                                               temp64, finother);
5907       finswap = finnow; finnow = finother; finother = finswap;
5908     }
5909   }
5910 
5911   return finnow[finlength - 1];
5912 }
5913 
5914 static
5915 #ifdef ANSI_DECLARATORS
incircle(struct mesh * m,struct behavior * b,vertex pa,vertex pb,vertex pc,vertex pd)5916 REAL incircle(struct mesh *m, struct behavior *b,
5917               vertex pa, vertex pb, vertex pc, vertex pd)
5918 #else /* not ANSI_DECLARATORS */
5919 REAL incircle(m, b, pa, pb, pc, pd)
5920 struct mesh *m;
5921 struct behavior *b;
5922 vertex pa;
5923 vertex pb;
5924 vertex pc;
5925 vertex pd;
5926 #endif /* not ANSI_DECLARATORS */
5927 
5928 {
5929   REAL adx, bdx, cdx, ady, bdy, cdy;
5930   REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
5931   REAL alift, blift, clift;
5932   REAL det;
5933   REAL permanent, errbound;
5934 
5935   m->incirclecount++;
5936 
5937   adx = pa[0] - pd[0];
5938   bdx = pb[0] - pd[0];
5939   cdx = pc[0] - pd[0];
5940   ady = pa[1] - pd[1];
5941   bdy = pb[1] - pd[1];
5942   cdy = pc[1] - pd[1];
5943 
5944   bdxcdy = bdx * cdy;
5945   cdxbdy = cdx * bdy;
5946   alift = adx * adx + ady * ady;
5947 
5948   cdxady = cdx * ady;
5949   adxcdy = adx * cdy;
5950   blift = bdx * bdx + bdy * bdy;
5951 
5952   adxbdy = adx * bdy;
5953   bdxady = bdx * ady;
5954   clift = cdx * cdx + cdy * cdy;
5955 
5956   det = alift * (bdxcdy - cdxbdy)
5957       + blift * (cdxady - adxcdy)
5958       + clift * (adxbdy - bdxady);
5959 
5960   if (b->noexact) {
5961     return det;
5962   }
5963 
5964   permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * alift
5965             + (Absolute(cdxady) + Absolute(adxcdy)) * blift
5966             + (Absolute(adxbdy) + Absolute(bdxady)) * clift;
5967   errbound = iccerrboundA * permanent;
5968   if ((det > errbound) || (-det > errbound)) {
5969     return det;
5970   }
5971 
5972   return incircleadapt(pa, pb, pc, pd, permanent);
5973 }
5974 
5975 /*****************************************************************************/
5976 /*                                                                           */
5977 /*  orient3d()   Return a positive value if the point pd lies below the      */
5978 /*               plane passing through pa, pb, and pc; "below" is defined so */
5979 /*               that pa, pb, and pc appear in counterclockwise order when   */
5980 /*               viewed from above the plane.  Returns a negative value if   */
5981 /*               pd lies above the plane.  Returns zero if the points are    */
5982 /*               coplanar.  The result is also a rough approximation of six  */
5983 /*               times the signed volume of the tetrahedron defined by the   */
5984 /*               four points.                                                */
5985 /*                                                                           */
5986 /*  Uses exact arithmetic if necessary to ensure a correct answer.  The      */
5987 /*  result returned is the determinant of a matrix.  This determinant is     */
5988 /*  computed adaptively, in the sense that exact arithmetic is used only to  */
5989 /*  the degree it is needed to ensure that the returned value has the        */
5990 /*  correct sign.  Hence, this function is usually quite fast, but will run  */
5991 /*  more slowly when the input points are coplanar or nearly so.             */
5992 /*                                                                           */
5993 /*  See my Robust Predicates paper for details.                              */
5994 /*                                                                           */
5995 /*****************************************************************************/
5996 
5997 static
5998 #ifdef ANSI_DECLARATORS
orient3dadapt(vertex pa,vertex pb,vertex pc,vertex pd,REAL aheight,REAL bheight,REAL cheight,REAL dheight,REAL permanent)5999 REAL orient3dadapt(vertex pa, vertex pb, vertex pc, vertex pd,
6000                    REAL aheight, REAL bheight, REAL cheight, REAL dheight,
6001                    REAL permanent)
6002 #else /* not ANSI_DECLARATORS */
6003 REAL orient3dadapt(pa, pb, pc, pd,
6004                    aheight, bheight, cheight, dheight, permanent)
6005 vertex pa;
6006 vertex pb;
6007 vertex pc;
6008 vertex pd;
6009 REAL aheight;
6010 REAL bheight;
6011 REAL cheight;
6012 REAL dheight;
6013 REAL permanent;
6014 #endif /* not ANSI_DECLARATORS */
6015 
6016 {
6017   INEXACT REAL adx, bdx, cdx, ady, bdy, cdy, adheight, bdheight, cdheight;
6018   REAL det, errbound;
6019 
6020   INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1;
6021   REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0;
6022   REAL bc[4], ca[4], ab[4];
6023   INEXACT REAL bc3, ca3, ab3;
6024   REAL adet[8], bdet[8], cdet[8];
6025   int alen, blen, clen;
6026   REAL abdet[16];
6027   int ablen;
6028   REAL *finnow, *finother, *finswap;
6029   REAL fin1[192], fin2[192];
6030   int finlength;
6031 
6032   REAL adxtail, bdxtail, cdxtail;
6033   REAL adytail, bdytail, cdytail;
6034   REAL adheighttail, bdheighttail, cdheighttail;
6035   INEXACT REAL at_blarge, at_clarge;
6036   INEXACT REAL bt_clarge, bt_alarge;
6037   INEXACT REAL ct_alarge, ct_blarge;
6038   REAL at_b[4], at_c[4], bt_c[4], bt_a[4], ct_a[4], ct_b[4];
6039   int at_blen, at_clen, bt_clen, bt_alen, ct_alen, ct_blen;
6040   INEXACT REAL bdxt_cdy1, cdxt_bdy1, cdxt_ady1;
6041   INEXACT REAL adxt_cdy1, adxt_bdy1, bdxt_ady1;
6042   REAL bdxt_cdy0, cdxt_bdy0, cdxt_ady0;
6043   REAL adxt_cdy0, adxt_bdy0, bdxt_ady0;
6044   INEXACT REAL bdyt_cdx1, cdyt_bdx1, cdyt_adx1;
6045   INEXACT REAL adyt_cdx1, adyt_bdx1, bdyt_adx1;
6046   REAL bdyt_cdx0, cdyt_bdx0, cdyt_adx0;
6047   REAL adyt_cdx0, adyt_bdx0, bdyt_adx0;
6048   REAL bct[8], cat[8], abt[8];
6049   int bctlen, catlen, abtlen;
6050   INEXACT REAL bdxt_cdyt1, cdxt_bdyt1, cdxt_adyt1;
6051   INEXACT REAL adxt_cdyt1, adxt_bdyt1, bdxt_adyt1;
6052   REAL bdxt_cdyt0, cdxt_bdyt0, cdxt_adyt0;
6053   REAL adxt_cdyt0, adxt_bdyt0, bdxt_adyt0;
6054   REAL u[4], v[12], w[16];
6055   INEXACT REAL u3;
6056   int vlength, wlength;
6057   REAL negate;
6058 
6059   INEXACT REAL bvirt;
6060   REAL avirt, bround, around;
6061   INEXACT REAL c;
6062   INEXACT REAL abig;
6063   REAL ahi, alo, bhi, blo;
6064   REAL err1, err2, err3;
6065   INEXACT REAL _i, _j, _k;
6066   REAL _0;
6067 
6068   adx = (REAL) (pa[0] - pd[0]);
6069   bdx = (REAL) (pb[0] - pd[0]);
6070   cdx = (REAL) (pc[0] - pd[0]);
6071   ady = (REAL) (pa[1] - pd[1]);
6072   bdy = (REAL) (pb[1] - pd[1]);
6073   cdy = (REAL) (pc[1] - pd[1]);
6074   adheight = (REAL) (aheight - dheight);
6075   bdheight = (REAL) (bheight - dheight);
6076   cdheight = (REAL) (cheight - dheight);
6077 
6078   Two_Product(bdx, cdy, bdxcdy1, bdxcdy0);
6079   Two_Product(cdx, bdy, cdxbdy1, cdxbdy0);
6080   Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]);
6081   bc[3] = bc3;
6082   alen = scale_expansion_zeroelim(4, bc, adheight, adet);
6083 
6084   Two_Product(cdx, ady, cdxady1, cdxady0);
6085   Two_Product(adx, cdy, adxcdy1, adxcdy0);
6086   Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]);
6087   ca[3] = ca3;
6088   blen = scale_expansion_zeroelim(4, ca, bdheight, bdet);
6089 
6090   Two_Product(adx, bdy, adxbdy1, adxbdy0);
6091   Two_Product(bdx, ady, bdxady1, bdxady0);
6092   Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]);
6093   ab[3] = ab3;
6094   clen = scale_expansion_zeroelim(4, ab, cdheight, cdet);
6095 
6096   ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
6097   finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1);
6098 
6099   det = estimate(finlength, fin1);
6100   errbound = o3derrboundB * permanent;
6101   if ((det >= errbound) || (-det >= errbound)) {
6102     return det;
6103   }
6104 
6105   Two_Diff_Tail(pa[0], pd[0], adx, adxtail);
6106   Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail);
6107   Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail);
6108   Two_Diff_Tail(pa[1], pd[1], ady, adytail);
6109   Two_Diff_Tail(pb[1], pd[1], bdy, bdytail);
6110   Two_Diff_Tail(pc[1], pd[1], cdy, cdytail);
6111   Two_Diff_Tail(aheight, dheight, adheight, adheighttail);
6112   Two_Diff_Tail(bheight, dheight, bdheight, bdheighttail);
6113   Two_Diff_Tail(cheight, dheight, cdheight, cdheighttail);
6114 
6115   if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0) &&
6116       (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0) &&
6117       (adheighttail == 0.0) &&
6118       (bdheighttail == 0.0) &&
6119       (cdheighttail == 0.0)) {
6120     return det;
6121   }
6122 
6123   errbound = o3derrboundC * permanent + resulterrbound * Absolute(det);
6124   det += (adheight * ((bdx * cdytail + cdy * bdxtail) -
6125                       (bdy * cdxtail + cdx * bdytail)) +
6126           adheighttail * (bdx * cdy - bdy * cdx)) +
6127          (bdheight * ((cdx * adytail + ady * cdxtail) -
6128                       (cdy * adxtail + adx * cdytail)) +
6129           bdheighttail * (cdx * ady - cdy * adx)) +
6130          (cdheight * ((adx * bdytail + bdy * adxtail) -
6131                       (ady * bdxtail + bdx * adytail)) +
6132           cdheighttail * (adx * bdy - ady * bdx));
6133   if ((det >= errbound) || (-det >= errbound)) {
6134     return det;
6135   }
6136 
6137   finnow = fin1;
6138   finother = fin2;
6139 
6140   if (adxtail == 0.0) {
6141     if (adytail == 0.0) {
6142       at_b[0] = 0.0;
6143       at_blen = 1;
6144       at_c[0] = 0.0;
6145       at_clen = 1;
6146     } else {
6147       negate = -adytail;
6148       Two_Product(negate, bdx, at_blarge, at_b[0]);
6149       at_b[1] = at_blarge;
6150       at_blen = 2;
6151       Two_Product(adytail, cdx, at_clarge, at_c[0]);
6152       at_c[1] = at_clarge;
6153       at_clen = 2;
6154     }
6155   } else {
6156     if (adytail == 0.0) {
6157       Two_Product(adxtail, bdy, at_blarge, at_b[0]);
6158       at_b[1] = at_blarge;
6159       at_blen = 2;
6160       negate = -adxtail;
6161       Two_Product(negate, cdy, at_clarge, at_c[0]);
6162       at_c[1] = at_clarge;
6163       at_clen = 2;
6164     } else {
6165       Two_Product(adxtail, bdy, adxt_bdy1, adxt_bdy0);
6166       Two_Product(adytail, bdx, adyt_bdx1, adyt_bdx0);
6167       Two_Two_Diff(adxt_bdy1, adxt_bdy0, adyt_bdx1, adyt_bdx0,
6168                    at_blarge, at_b[2], at_b[1], at_b[0]);
6169       at_b[3] = at_blarge;
6170       at_blen = 4;
6171       Two_Product(adytail, cdx, adyt_cdx1, adyt_cdx0);
6172       Two_Product(adxtail, cdy, adxt_cdy1, adxt_cdy0);
6173       Two_Two_Diff(adyt_cdx1, adyt_cdx0, adxt_cdy1, adxt_cdy0,
6174                    at_clarge, at_c[2], at_c[1], at_c[0]);
6175       at_c[3] = at_clarge;
6176       at_clen = 4;
6177     }
6178   }
6179   if (bdxtail == 0.0) {
6180     if (bdytail == 0.0) {
6181       bt_c[0] = 0.0;
6182       bt_clen = 1;
6183       bt_a[0] = 0.0;
6184       bt_alen = 1;
6185     } else {
6186       negate = -bdytail;
6187       Two_Product(negate, cdx, bt_clarge, bt_c[0]);
6188       bt_c[1] = bt_clarge;
6189       bt_clen = 2;
6190       Two_Product(bdytail, adx, bt_alarge, bt_a[0]);
6191       bt_a[1] = bt_alarge;
6192       bt_alen = 2;
6193     }
6194   } else {
6195     if (bdytail == 0.0) {
6196       Two_Product(bdxtail, cdy, bt_clarge, bt_c[0]);
6197       bt_c[1] = bt_clarge;
6198       bt_clen = 2;
6199       negate = -bdxtail;
6200       Two_Product(negate, ady, bt_alarge, bt_a[0]);
6201       bt_a[1] = bt_alarge;
6202       bt_alen = 2;
6203     } else {
6204       Two_Product(bdxtail, cdy, bdxt_cdy1, bdxt_cdy0);
6205       Two_Product(bdytail, cdx, bdyt_cdx1, bdyt_cdx0);
6206       Two_Two_Diff(bdxt_cdy1, bdxt_cdy0, bdyt_cdx1, bdyt_cdx0,
6207                    bt_clarge, bt_c[2], bt_c[1], bt_c[0]);
6208       bt_c[3] = bt_clarge;
6209       bt_clen = 4;
6210       Two_Product(bdytail, adx, bdyt_adx1, bdyt_adx0);
6211       Two_Product(bdxtail, ady, bdxt_ady1, bdxt_ady0);
6212       Two_Two_Diff(bdyt_adx1, bdyt_adx0, bdxt_ady1, bdxt_ady0,
6213                   bt_alarge, bt_a[2], bt_a[1], bt_a[0]);
6214       bt_a[3] = bt_alarge;
6215       bt_alen = 4;
6216     }
6217   }
6218   if (cdxtail == 0.0) {
6219     if (cdytail == 0.0) {
6220       ct_a[0] = 0.0;
6221       ct_alen = 1;
6222       ct_b[0] = 0.0;
6223       ct_blen = 1;
6224     } else {
6225       negate = -cdytail;
6226       Two_Product(negate, adx, ct_alarge, ct_a[0]);
6227       ct_a[1] = ct_alarge;
6228       ct_alen = 2;
6229       Two_Product(cdytail, bdx, ct_blarge, ct_b[0]);
6230       ct_b[1] = ct_blarge;
6231       ct_blen = 2;
6232     }
6233   } else {
6234     if (cdytail == 0.0) {
6235       Two_Product(cdxtail, ady, ct_alarge, ct_a[0]);
6236       ct_a[1] = ct_alarge;
6237       ct_alen = 2;
6238       negate = -cdxtail;
6239       Two_Product(negate, bdy, ct_blarge, ct_b[0]);
6240       ct_b[1] = ct_blarge;
6241       ct_blen = 2;
6242     } else {
6243       Two_Product(cdxtail, ady, cdxt_ady1, cdxt_ady0);
6244       Two_Product(cdytail, adx, cdyt_adx1, cdyt_adx0);
6245       Two_Two_Diff(cdxt_ady1, cdxt_ady0, cdyt_adx1, cdyt_adx0,
6246                    ct_alarge, ct_a[2], ct_a[1], ct_a[0]);
6247       ct_a[3] = ct_alarge;
6248       ct_alen = 4;
6249       Two_Product(cdytail, bdx, cdyt_bdx1, cdyt_bdx0);
6250       Two_Product(cdxtail, bdy, cdxt_bdy1, cdxt_bdy0);
6251       Two_Two_Diff(cdyt_bdx1, cdyt_bdx0, cdxt_bdy1, cdxt_bdy0,
6252                    ct_blarge, ct_b[2], ct_b[1], ct_b[0]);
6253       ct_b[3] = ct_blarge;
6254       ct_blen = 4;
6255     }
6256   }
6257 
6258   bctlen = fast_expansion_sum_zeroelim(bt_clen, bt_c, ct_blen, ct_b, bct);
6259   wlength = scale_expansion_zeroelim(bctlen, bct, adheight, w);
6260   finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
6261                                           finother);
6262   finswap = finnow; finnow = finother; finother = finswap;
6263 
6264   catlen = fast_expansion_sum_zeroelim(ct_alen, ct_a, at_clen, at_c, cat);
6265   wlength = scale_expansion_zeroelim(catlen, cat, bdheight, w);
6266   finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
6267                                           finother);
6268   finswap = finnow; finnow = finother; finother = finswap;
6269 
6270   abtlen = fast_expansion_sum_zeroelim(at_blen, at_b, bt_alen, bt_a, abt);
6271   wlength = scale_expansion_zeroelim(abtlen, abt, cdheight, w);
6272   finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
6273                                           finother);
6274   finswap = finnow; finnow = finother; finother = finswap;
6275 
6276   if (adheighttail != 0.0) {
6277     vlength = scale_expansion_zeroelim(4, bc, adheighttail, v);
6278     finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
6279                                             finother);
6280     finswap = finnow; finnow = finother; finother = finswap;
6281   }
6282   if (bdheighttail != 0.0) {
6283     vlength = scale_expansion_zeroelim(4, ca, bdheighttail, v);
6284     finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
6285                                             finother);
6286     finswap = finnow; finnow = finother; finother = finswap;
6287   }
6288   if (cdheighttail != 0.0) {
6289     vlength = scale_expansion_zeroelim(4, ab, cdheighttail, v);
6290     finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
6291                                             finother);
6292     finswap = finnow; finnow = finother; finother = finswap;
6293   }
6294 
6295   if (adxtail != 0.0) {
6296     if (bdytail != 0.0) {
6297       Two_Product(adxtail, bdytail, adxt_bdyt1, adxt_bdyt0);
6298       Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdheight, u3, u[2], u[1], u[0]);
6299       u[3] = u3;
6300       finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6301                                               finother);
6302       finswap = finnow; finnow = finother; finother = finswap;
6303       if (cdheighttail != 0.0) {
6304         Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdheighttail,
6305                         u3, u[2], u[1], u[0]);
6306         u[3] = u3;
6307         finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6308                                                 finother);
6309         finswap = finnow; finnow = finother; finother = finswap;
6310       }
6311     }
6312     if (cdytail != 0.0) {
6313       negate = -adxtail;
6314       Two_Product(negate, cdytail, adxt_cdyt1, adxt_cdyt0);
6315       Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdheight, u3, u[2], u[1], u[0]);
6316       u[3] = u3;
6317       finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6318                                               finother);
6319       finswap = finnow; finnow = finother; finother = finswap;
6320       if (bdheighttail != 0.0) {
6321         Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdheighttail,
6322                         u3, u[2], u[1], u[0]);
6323         u[3] = u3;
6324         finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6325                                                 finother);
6326         finswap = finnow; finnow = finother; finother = finswap;
6327       }
6328     }
6329   }
6330   if (bdxtail != 0.0) {
6331     if (cdytail != 0.0) {
6332       Two_Product(bdxtail, cdytail, bdxt_cdyt1, bdxt_cdyt0);
6333       Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adheight, u3, u[2], u[1], u[0]);
6334       u[3] = u3;
6335       finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6336                                               finother);
6337       finswap = finnow; finnow = finother; finother = finswap;
6338       if (adheighttail != 0.0) {
6339         Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adheighttail,
6340                         u3, u[2], u[1], u[0]);
6341         u[3] = u3;
6342         finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6343                                                 finother);
6344         finswap = finnow; finnow = finother; finother = finswap;
6345       }
6346     }
6347     if (adytail != 0.0) {
6348       negate = -bdxtail;
6349       Two_Product(negate, adytail, bdxt_adyt1, bdxt_adyt0);
6350       Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdheight, u3, u[2], u[1], u[0]);
6351       u[3] = u3;
6352       finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6353                                               finother);
6354       finswap = finnow; finnow = finother; finother = finswap;
6355       if (cdheighttail != 0.0) {
6356         Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdheighttail,
6357                         u3, u[2], u[1], u[0]);
6358         u[3] = u3;
6359         finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6360                                                 finother);
6361         finswap = finnow; finnow = finother; finother = finswap;
6362       }
6363     }
6364   }
6365   if (cdxtail != 0.0) {
6366     if (adytail != 0.0) {
6367       Two_Product(cdxtail, adytail, cdxt_adyt1, cdxt_adyt0);
6368       Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdheight, u3, u[2], u[1], u[0]);
6369       u[3] = u3;
6370       finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6371                                               finother);
6372       finswap = finnow; finnow = finother; finother = finswap;
6373       if (bdheighttail != 0.0) {
6374         Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdheighttail,
6375                         u3, u[2], u[1], u[0]);
6376         u[3] = u3;
6377         finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6378                                                 finother);
6379         finswap = finnow; finnow = finother; finother = finswap;
6380       }
6381     }
6382     if (bdytail != 0.0) {
6383       negate = -cdxtail;
6384       Two_Product(negate, bdytail, cdxt_bdyt1, cdxt_bdyt0);
6385       Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adheight, u3, u[2], u[1], u[0]);
6386       u[3] = u3;
6387       finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6388                                               finother);
6389       finswap = finnow; finnow = finother; finother = finswap;
6390       if (adheighttail != 0.0) {
6391         Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adheighttail,
6392                         u3, u[2], u[1], u[0]);
6393         u[3] = u3;
6394         finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6395                                                 finother);
6396         finswap = finnow; finnow = finother; finother = finswap;
6397       }
6398     }
6399   }
6400 
6401   if (adheighttail != 0.0) {
6402     wlength = scale_expansion_zeroelim(bctlen, bct, adheighttail, w);
6403     finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
6404                                             finother);
6405     finswap = finnow; finnow = finother; finother = finswap;
6406   }
6407   if (bdheighttail != 0.0) {
6408     wlength = scale_expansion_zeroelim(catlen, cat, bdheighttail, w);
6409     finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
6410                                             finother);
6411     finswap = finnow; finnow = finother; finother = finswap;
6412   }
6413   if (cdheighttail != 0.0) {
6414     wlength = scale_expansion_zeroelim(abtlen, abt, cdheighttail, w);
6415     finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
6416                                             finother);
6417     finswap = finnow; finnow = finother; finother = finswap;
6418   }
6419 
6420   return finnow[finlength - 1];
6421 }
6422 
6423 static
6424 #ifdef ANSI_DECLARATORS
orient3d(struct mesh * m,struct behavior * b,vertex pa,vertex pb,vertex pc,vertex pd,REAL aheight,REAL bheight,REAL cheight,REAL dheight)6425 REAL orient3d(struct mesh *m, struct behavior *b,
6426               vertex pa, vertex pb, vertex pc, vertex pd,
6427               REAL aheight, REAL bheight, REAL cheight, REAL dheight)
6428 #else /* not ANSI_DECLARATORS */
6429 REAL orient3d(m, b, pa, pb, pc, pd, aheight, bheight, cheight, dheight)
6430 struct mesh *m;
6431 struct behavior *b;
6432 vertex pa;
6433 vertex pb;
6434 vertex pc;
6435 vertex pd;
6436 REAL aheight;
6437 REAL bheight;
6438 REAL cheight;
6439 REAL dheight;
6440 #endif /* not ANSI_DECLARATORS */
6441 
6442 {
6443   REAL adx, bdx, cdx, ady, bdy, cdy, adheight, bdheight, cdheight;
6444   REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
6445   REAL det;
6446   REAL permanent, errbound;
6447 
6448   m->orient3dcount++;
6449 
6450   adx = pa[0] - pd[0];
6451   bdx = pb[0] - pd[0];
6452   cdx = pc[0] - pd[0];
6453   ady = pa[1] - pd[1];
6454   bdy = pb[1] - pd[1];
6455   cdy = pc[1] - pd[1];
6456   adheight = aheight - dheight;
6457   bdheight = bheight - dheight;
6458   cdheight = cheight - dheight;
6459 
6460   bdxcdy = bdx * cdy;
6461   cdxbdy = cdx * bdy;
6462 
6463   cdxady = cdx * ady;
6464   adxcdy = adx * cdy;
6465 
6466   adxbdy = adx * bdy;
6467   bdxady = bdx * ady;
6468 
6469   det = adheight * (bdxcdy - cdxbdy)
6470       + bdheight * (cdxady - adxcdy)
6471       + cdheight * (adxbdy - bdxady);
6472 
6473   if (b->noexact) {
6474     return det;
6475   }
6476 
6477   permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * Absolute(adheight)
6478             + (Absolute(cdxady) + Absolute(adxcdy)) * Absolute(bdheight)
6479             + (Absolute(adxbdy) + Absolute(bdxady)) * Absolute(cdheight);
6480   errbound = o3derrboundA * permanent;
6481   if ((det > errbound) || (-det > errbound)) {
6482     return det;
6483   }
6484 
6485   return orient3dadapt(pa, pb, pc, pd, aheight, bheight, cheight, dheight,
6486                        permanent);
6487 }
6488 
6489 /*****************************************************************************/
6490 /*                                                                           */
6491 /*  nonregular()   Return a positive value if the point pd is incompatible   */
6492 /*                 with the circle or plane passing through pa, pb, and pc   */
6493 /*                 (meaning that pd is inside the circle or below the        */
6494 /*                 plane); a negative value if it is compatible; and zero if */
6495 /*                 the four points are cocircular/coplanar.  The points pa,  */
6496 /*                 pb, and pc must be in counterclockwise order, or the sign */
6497 /*                 of the result will be reversed.                           */
6498 /*                                                                           */
6499 /*  If the -w switch is used, the points are lifted onto the parabolic       */
6500 /*  lifting map, then they are dropped according to their weights, then the  */
6501 /*  3D orientation test is applied.  If the -W switch is used, the points'   */
6502 /*  heights are already provided, so the 3D orientation test is applied      */
6503 /*  directly.  If neither switch is used, the incircle test is applied.      */
6504 /*                                                                           */
6505 /*****************************************************************************/
6506 
6507 #ifdef ANSI_DECLARATORS
6508 REAL nonregular(struct mesh *m, struct behavior *b,
6509                 vertex pa, vertex pb, vertex pc, vertex pd)
6510 #else /* not ANSI_DECLARATORS */
6511 REAL nonregular(m, b, pa, pb, pc, pd)
6512 struct mesh *m;
6513 struct behavior *b;
6514 vertex pa;
6515 vertex pb;
6516 vertex pc;
6517 vertex pd;
6518 #endif /* not ANSI_DECLARATORS */
6519 
6520 {
6521   if (b->weighted == 0) {
6522     return incircle(m, b, pa, pb, pc, pd);
6523   } else if (b->weighted == 1) {
6524     return orient3d(m, b, pa, pb, pc, pd,
6525                     pa[0] * pa[0] + pa[1] * pa[1] - pa[2],
6526                     pb[0] * pb[0] + pb[1] * pb[1] - pb[2],
6527                     pc[0] * pc[0] + pc[1] * pc[1] - pc[2],
6528                     pd[0] * pd[0] + pd[1] * pd[1] - pd[2]);
6529   } else {
6530     return orient3d(m, b, pa, pb, pc, pd, pa[2], pb[2], pc[2], pd[2]);
6531   }
6532 }
6533 
6534 /*****************************************************************************/
6535 /*                                                                           */
6536 /*  findcircumcenter()   Find the circumcenter of a triangle.                */
6537 /*                                                                           */
6538 /*  The result is returned both in terms of x-y coordinates and xi-eta       */
6539 /*  (barycentric) coordinates.  The xi-eta coordinate system is defined in   */
6540 /*  terms of the triangle:  the origin of the triangle is the origin of the  */
6541 /*  coordinate system; the destination of the triangle is one unit along the */
6542 /*  xi axis; and the apex of the triangle is one unit along the eta axis.    */
6543 /*  This procedure also returns the square of the length of the triangle's   */
6544 /*  shortest edge.                                                           */
6545 /*                                                                           */
6546 /*****************************************************************************/
6547 
6548 #ifdef ANSI_DECLARATORS
6549 void findcircumcenter(struct mesh *m, struct behavior *b,
6550                       vertex torg, vertex tdest, vertex tapex,
6551                       vertex circumcenter, REAL *xi, REAL *eta, int offcenter)
6552 #else /* not ANSI_DECLARATORS */
6553 void findcircumcenter(m, b, torg, tdest, tapex, circumcenter, xi, eta,
6554                       offcenter)
6555 struct mesh *m;
6556 struct behavior *b;
6557 vertex torg;
6558 vertex tdest;
6559 vertex tapex;
6560 vertex circumcenter;
6561 REAL *xi;
6562 REAL *eta;
6563 int offcenter;
6564 #endif /* not ANSI_DECLARATORS */
6565 
6566 {
6567   REAL xdo, ydo, xao, yao;
6568   REAL dodist, aodist, dadist;
6569   REAL denominator;
6570   REAL dx, dy, dxoff, dyoff;
6571 
6572   m->circumcentercount++;
6573 
6574   /* Compute the circumcenter of the triangle. */
6575   xdo = tdest[0] - torg[0];
6576   ydo = tdest[1] - torg[1];
6577   xao = tapex[0] - torg[0];
6578   yao = tapex[1] - torg[1];
6579   dodist = xdo * xdo + ydo * ydo;
6580   aodist = xao * xao + yao * yao;
6581   dadist = (tdest[0] - tapex[0]) * (tdest[0] - tapex[0]) +
6582            (tdest[1] - tapex[1]) * (tdest[1] - tapex[1]);
6583   if (b->noexact) {
6584     denominator = 0.5 / (xdo * yao - xao * ydo);
6585   } else {
6586     /* Use the counterclockwise() routine to ensure a positive (and */
6587     /*   reasonably accurate) result, avoiding any possibility of   */
6588     /*   division by zero.                                          */
6589     denominator = 0.5 / counterclockwise(m, b, tdest, tapex, torg);
6590     /* Don't count the above as an orientation test. */
6591     m->counterclockcount--;
6592   }
6593   dx = (yao * dodist - ydo * aodist) * denominator;
6594   dy = (xdo * aodist - xao * dodist) * denominator;
6595 
6596   /* Find the (squared) length of the triangle's shortest edge.  This   */
6597   /*   serves as a conservative estimate of the insertion radius of the */
6598   /*   circumcenter's parent.  The estimate is used to ensure that      */
6599   /*   the algorithm terminates even if very small angles appear in     */
6600   /*   the input PSLG.                                                  */
6601   if ((dodist < aodist) && (dodist < dadist)) {
6602     if (offcenter && (b->offconstant > 0.0)) {
6603       /* Find the position of the off-center, as described by Alper Ungor. */
6604       dxoff = 0.5 * xdo - b->offconstant * ydo;
6605       dyoff = 0.5 * ydo + b->offconstant * xdo;
6606       /* If the off-center is closer to the origin than the */
6607       /*   circumcenter, use the off-center instead.        */
6608       if (dxoff * dxoff + dyoff * dyoff < dx * dx + dy * dy) {
6609         dx = dxoff;
6610         dy = dyoff;
6611       }
6612     }
6613   } else if (aodist < dadist) {
6614     if (offcenter && (b->offconstant > 0.0)) {
6615       dxoff = 0.5 * xao + b->offconstant * yao;
6616       dyoff = 0.5 * yao - b->offconstant * xao;
6617       /* If the off-center is closer to the origin than the */
6618       /*   circumcenter, use the off-center instead.        */
6619       if (dxoff * dxoff + dyoff * dyoff < dx * dx + dy * dy) {
6620         dx = dxoff;
6621         dy = dyoff;
6622       }
6623     }
6624   } else {
6625     if (offcenter && (b->offconstant > 0.0)) {
6626       dxoff = 0.5 * (tapex[0] - tdest[0]) -
6627               b->offconstant * (tapex[1] - tdest[1]);
6628       dyoff = 0.5 * (tapex[1] - tdest[1]) +
6629               b->offconstant * (tapex[0] - tdest[0]);
6630       /* If the off-center is closer to the destination than the */
6631       /*   circumcenter, use the off-center instead.             */
6632       if (dxoff * dxoff + dyoff * dyoff <
6633           (dx - xdo) * (dx - xdo) + (dy - ydo) * (dy - ydo)) {
6634         dx = xdo + dxoff;
6635         dy = ydo + dyoff;
6636       }
6637     }
6638   }
6639 
6640   circumcenter[0] = torg[0] + dx;
6641   circumcenter[1] = torg[1] + dy;
6642 
6643   /* To interpolate vertex attributes for the new vertex inserted at */
6644   /*   the circumcenter, define a coordinate system with a xi-axis,  */
6645   /*   directed from the triangle's origin to its destination, and   */
6646   /*   an eta-axis, directed from its origin to its apex.            */
6647   /*   Calculate the xi and eta coordinates of the circumcenter.     */
6648   *xi = (yao * dx - xao * dy) * (2.0 * denominator);
6649   *eta = (xdo * dy - ydo * dx) * (2.0 * denominator);
6650 }
6651 
6652 /**                                                                         **/
6653 /**                                                                         **/
6654 /********* Geometric primitives end here                             *********/
6655 
6656 /*****************************************************************************/
6657 /*                                                                           */
6658 /*  triangleinit()   Initialize some variables.                              */
6659 /*                                                                           */
6660 /*****************************************************************************/
6661 
6662 #ifdef ANSI_DECLARATORS
6663 void triangleinit(struct mesh *m)
6664 #else /* not ANSI_DECLARATORS */
6665 void triangleinit(m)
6666 struct mesh *m;
6667 #endif /* not ANSI_DECLARATORS */
6668 
6669 {
6670   poolzero(&m->vertices);
6671   poolzero(&m->triangles);
6672   poolzero(&m->subsegs);
6673   poolzero(&m->viri);
6674   poolzero(&m->badsubsegs);
6675   poolzero(&m->badtriangles);
6676   poolzero(&m->flipstackers);
6677   poolzero(&m->splaynodes);
6678 
6679   m->recenttri.tri = (triangle *) NULL; /* No triangle has been visited yet. */
6680   m->undeads = 0;                       /* No eliminated input vertices yet. */
6681   m->samples = 1;         /* Point location should take at least one sample. */
6682   m->checksegments = 0;   /* There are no segments in the triangulation yet. */
6683   m->checkquality = 0;     /* The quality triangulation stage has not begun. */
6684   m->incirclecount = m->counterclockcount = m->orient3dcount = 0;
6685   m->hyperbolacount = m->circletopcount = m->circumcentercount = 0;
6686   randomseed = 1;
6687 
6688   exactinit();                     /* Initialize exact arithmetic constants. */
6689 }
6690 
6691 /*****************************************************************************/
6692 /*                                                                           */
6693 /*  randomnation()   Generate a random number between 0 and `choices' - 1.   */
6694 /*                                                                           */
6695 /*  This is a simple linear congruential random number generator.  Hence, it */
6696 /*  is a bad random number generator, but good enough for most randomized    */
6697 /*  geometric algorithms.                                                    */
6698 /*                                                                           */
6699 /*****************************************************************************/
6700 
6701 #ifdef ANSI_DECLARATORS
6702 unsigned long randomnation(unsigned int choices)
6703 #else /* not ANSI_DECLARATORS */
6704 unsigned long randomnation(choices)
6705 unsigned int choices;
6706 #endif /* not ANSI_DECLARATORS */
6707 
6708 {
6709   randomseed = (randomseed * 1366l + 150889l) % 714025l;
6710   return randomseed / (714025l / choices + 1);
6711 }
6712 
6713 /********* Mesh quality testing routines begin here                  *********/
6714 /**                                                                         **/
6715 /**                                                                         **/
6716 
6717 /*****************************************************************************/
6718 /*                                                                           */
6719 /*  checkmesh()   Test the mesh for topological consistency.                 */
6720 /*                                                                           */
6721 /*****************************************************************************/
6722 
6723 #ifndef REDUCED
6724 
6725 #ifdef ANSI_DECLARATORS
6726 void checkmesh(struct mesh *m, struct behavior *b)
6727 #else /* not ANSI_DECLARATORS */
6728 void checkmesh(m, b)
6729 struct mesh *m;
6730 struct behavior *b;
6731 #endif /* not ANSI_DECLARATORS */
6732 
6733 {
6734   struct otri triangleloop;
6735   struct otri oppotri, oppooppotri;
6736   vertex triorg, tridest, triapex;
6737   vertex oppoorg, oppodest;
6738   int horrors;
6739   int saveexact;
6740   triangle ptr;                         /* Temporary variable used by sym(). */
6741 
6742   /* Temporarily turn on exact arithmetic if it's off. */
6743   saveexact = b->noexact;
6744   b->noexact = 0;
6745   if (!b->quiet) {
6746     printf("  Checking consistency of mesh...\n");
6747   }
6748   horrors = 0;
6749   /* Run through the list of triangles, checking each one. */
6750   traversalinit(&m->triangles);
6751   triangleloop.tri = triangletraverse(m);
6752   while (triangleloop.tri != (triangle *) NULL) {
6753     /* Check all three edges of the triangle. */
6754     for (triangleloop.orient = 0; triangleloop.orient < 3;
6755          triangleloop.orient++) {
6756       org(triangleloop, triorg);
6757       dest(triangleloop, tridest);
6758       if (triangleloop.orient == 0) {       /* Only test for inversion once. */
6759         /* Test if the triangle is flat or inverted. */
6760         apex(triangleloop, triapex);
6761         if (counterclockwise(m, b, triorg, tridest, triapex) <= 0.0) {
6762           printf("  !! !! Inverted ");
6763           printtriangle(m, b, &triangleloop);
6764           horrors++;
6765         }
6766       }
6767       /* Find the neighboring triangle on this edge. */
6768       sym(triangleloop, oppotri);
6769       if (oppotri.tri != m->dummytri) {
6770         /* Check that the triangle's neighbor knows it's a neighbor. */
6771         sym(oppotri, oppooppotri);
6772         if ((triangleloop.tri != oppooppotri.tri)
6773             || (triangleloop.orient != oppooppotri.orient)) {
6774           printf("  !! !! Asymmetric triangle-triangle bond:\n");
6775           if (triangleloop.tri == oppooppotri.tri) {
6776             printf("   (Right triangle, wrong orientation)\n");
6777           }
6778           printf("    First ");
6779           printtriangle(m, b, &triangleloop);
6780           printf("    Second (nonreciprocating) ");
6781           printtriangle(m, b, &oppotri);
6782           horrors++;
6783         }
6784         /* Check that both triangles agree on the identities */
6785         /*   of their shared vertices.                       */
6786         org(oppotri, oppoorg);
6787         dest(oppotri, oppodest);
6788         if ((triorg != oppodest) || (tridest != oppoorg)) {
6789           printf("  !! !! Mismatched edge coordinates between two triangles:\n"
6790                  );
6791           printf("    First mismatched ");
6792           printtriangle(m, b, &triangleloop);
6793           printf("    Second mismatched ");
6794           printtriangle(m, b, &oppotri);
6795           horrors++;
6796         }
6797       }
6798     }
6799     triangleloop.tri = triangletraverse(m);
6800   }
6801   if (horrors == 0) {
6802     if (!b->quiet) {
6803       printf("  In my studied opinion, the mesh appears to be consistent.\n");
6804     }
6805   } else if (horrors == 1) {
6806     printf("  !! !! !! !! Precisely one festering wound discovered.\n");
6807   } else {
6808     printf("  !! !! !! !! %d abominations witnessed.\n", horrors);
6809   }
6810   /* Restore the status of exact arithmetic. */
6811   b->noexact = saveexact;
6812 }
6813 
6814 #endif /* not REDUCED */
6815 
6816 /*****************************************************************************/
6817 /*                                                                           */
6818 /*  checkdelaunay()   Ensure that the mesh is (constrained) Delaunay.        */
6819 /*                                                                           */
6820 /*****************************************************************************/
6821 
6822 #ifndef REDUCED
6823 
6824 #ifdef ANSI_DECLARATORS
6825 void checkdelaunay(struct mesh *m, struct behavior *b)
6826 #else /* not ANSI_DECLARATORS */
6827 void checkdelaunay(m, b)
6828 struct mesh *m;
6829 struct behavior *b;
6830 #endif /* not ANSI_DECLARATORS */
6831 
6832 {
6833   struct otri triangleloop;
6834   struct otri oppotri;
6835   struct osub opposubseg;
6836   vertex triorg, tridest, triapex;
6837   vertex oppoapex;
6838   int shouldbedelaunay;
6839   int horrors;
6840   int saveexact;
6841   triangle ptr;                         /* Temporary variable used by sym(). */
6842   subseg sptr;                      /* Temporary variable used by tspivot(). */
6843 
6844   /* Temporarily turn on exact arithmetic if it's off. */
6845   saveexact = b->noexact;
6846   b->noexact = 0;
6847   if (!b->quiet) {
6848     printf("  Checking Delaunay property of mesh...\n");
6849   }
6850   horrors = 0;
6851   /* Run through the list of triangles, checking each one. */
6852   traversalinit(&m->triangles);
6853   triangleloop.tri = triangletraverse(m);
6854   while (triangleloop.tri != (triangle *) NULL) {
6855     /* Check all three edges of the triangle. */
6856     for (triangleloop.orient = 0; triangleloop.orient < 3;
6857          triangleloop.orient++) {
6858       org(triangleloop, triorg);
6859       dest(triangleloop, tridest);
6860       apex(triangleloop, triapex);
6861       sym(triangleloop, oppotri);
6862       apex(oppotri, oppoapex);
6863       /* Only test that the edge is locally Delaunay if there is an   */
6864       /*   adjoining triangle whose pointer is larger (to ensure that */
6865       /*   each pair isn't tested twice).                             */
6866       shouldbedelaunay = (oppotri.tri != m->dummytri) &&
6867             !deadtri(oppotri.tri) && (triangleloop.tri < oppotri.tri) &&
6868             (triorg != m->infvertex1) && (triorg != m->infvertex2) &&
6869             (triorg != m->infvertex3) &&
6870             (tridest != m->infvertex1) && (tridest != m->infvertex2) &&
6871             (tridest != m->infvertex3) &&
6872             (triapex != m->infvertex1) && (triapex != m->infvertex2) &&
6873             (triapex != m->infvertex3) &&
6874             (oppoapex != m->infvertex1) && (oppoapex != m->infvertex2) &&
6875             (oppoapex != m->infvertex3);
6876       if (m->checksegments && shouldbedelaunay) {
6877         /* If a subsegment separates the triangles, then the edge is */
6878         /*   constrained, so no local Delaunay test should be done.  */
6879         tspivot(triangleloop, opposubseg);
6880         if (opposubseg.ss != m->dummysub){
6881           shouldbedelaunay = 0;
6882         }
6883       }
6884       if (shouldbedelaunay) {
6885         if (nonregular(m, b, triorg, tridest, triapex, oppoapex) > 0.0) {
6886           if (!b->weighted) {
6887             printf("  !! !! Non-Delaunay pair of triangles:\n");
6888             printf("    First non-Delaunay ");
6889             printtriangle(m, b, &triangleloop);
6890             printf("    Second non-Delaunay ");
6891           } else {
6892             printf("  !! !! Non-regular pair of triangles:\n");
6893             printf("    First non-regular ");
6894             printtriangle(m, b, &triangleloop);
6895             printf("    Second non-regular ");
6896           }
6897           printtriangle(m, b, &oppotri);
6898           horrors++;
6899         }
6900       }
6901     }
6902     triangleloop.tri = triangletraverse(m);
6903   }
6904   if (horrors == 0) {
6905     if (!b->quiet) {
6906       printf(
6907   "  By virtue of my perceptive intelligence, I declare the mesh Delaunay.\n");
6908     }
6909   } else if (horrors == 1) {
6910     printf(
6911          "  !! !! !! !! Precisely one terrifying transgression identified.\n");
6912   } else {
6913     printf("  !! !! !! !! %d obscenities viewed with horror.\n", horrors);
6914   }
6915   /* Restore the status of exact arithmetic. */
6916   b->noexact = saveexact;
6917 }
6918 
6919 #endif /* not REDUCED */
6920 
6921 /*****************************************************************************/
6922 /*                                                                           */
6923 /*  enqueuebadtriang()   Add a bad triangle data structure to the end of a   */
6924 /*                       queue.                                              */
6925 /*                                                                           */
6926 /*  The queue is actually a set of 4096 queues.  I use multiple queues to    */
6927 /*  give priority to smaller angles.  I originally implemented a heap, but   */
6928 /*  the queues are faster by a larger margin than I'd suspected.             */
6929 /*                                                                           */
6930 /*****************************************************************************/
6931 
6932 #ifndef CDT_ONLY
6933 
6934 #ifdef ANSI_DECLARATORS
6935 void enqueuebadtriang(struct mesh *m, struct behavior *b,
6936                       struct badtriang *badtri)
6937 #else /* not ANSI_DECLARATORS */
6938 void enqueuebadtriang(m, b, badtri)
6939 struct mesh *m;
6940 struct behavior *b;
6941 struct badtriang *badtri;
6942 #endif /* not ANSI_DECLARATORS */
6943 
6944 {
6945   REAL length, multiplier;
6946   int exponent, expincrement;
6947   int queuenumber;
6948   int posexponent;
6949   int i;
6950 
6951   if (b->verbose > 2) {
6952     printf("  Queueing bad triangle:\n");
6953     printf("    (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
6954            badtri->triangorg[0], badtri->triangorg[1],
6955            badtri->triangdest[0], badtri->triangdest[1],
6956            badtri->triangapex[0], badtri->triangapex[1]);
6957   }
6958 
6959   /* Determine the appropriate queue to put the bad triangle into.    */
6960   /*   Recall that the key is the square of its shortest edge length. */
6961   if (badtri->key >= 1.0) {
6962     length = badtri->key;
6963     posexponent = 1;
6964   } else {
6965     /* `badtri->key' is 2.0 to a negative exponent, so we'll record that */
6966     /*   fact and use the reciprocal of `badtri->key', which is > 1.0.   */
6967     length = 1.0 / badtri->key;
6968     posexponent = 0;
6969   }
6970   /* `length' is approximately 2.0 to what exponent?  The following code */
6971   /*   determines the answer in time logarithmic in the exponent.        */
6972   exponent = 0;
6973   while (length > 2.0) {
6974     /* Find an approximation by repeated squaring of two. */
6975     expincrement = 1;
6976     multiplier = 0.5;
6977     while (length * multiplier * multiplier > 1.0) {
6978       expincrement *= 2;
6979       multiplier *= multiplier;
6980     }
6981     /* Reduce the value of `length', then iterate if necessary. */
6982     exponent += expincrement;
6983     length *= multiplier;
6984   }
6985   /* `length' is approximately squareroot(2.0) to what exponent? */
6986   exponent = (int)(2.0 * exponent + (length > SQUAREROOTTWO));
6987   /* `exponent' is now in the range 0...2047 for IEEE double precision.   */
6988   /*   Choose a queue in the range 0...4095.  The shortest edges have the */
6989   /*   highest priority (queue 4095).                                     */
6990   if (posexponent) {
6991     queuenumber = 2047 - exponent;
6992   } else {
6993     queuenumber = 2048 + exponent;
6994   }
6995 
6996   /* Are we inserting into an empty queue? */
6997   if (m->queuefront[queuenumber] == (struct badtriang *) NULL) {
6998     /* Yes, we are inserting into an empty queue.     */
6999     /*   Will this become the highest-priority queue? */
7000     if (queuenumber > m->firstnonemptyq) {
7001       /* Yes, this is the highest-priority queue. */
7002       m->nextnonemptyq[queuenumber] = m->firstnonemptyq;
7003       m->firstnonemptyq = queuenumber;
7004     } else {
7005       /* No, this is not the highest-priority queue. */
7006       /*   Find the queue with next higher priority. */
7007       i = queuenumber + 1;
7008       while (m->queuefront[i] == (struct badtriang *) NULL) {
7009         i++;
7010       }
7011       /* Mark the newly nonempty queue as following a higher-priority queue. */
7012       m->nextnonemptyq[queuenumber] = m->nextnonemptyq[i];
7013       m->nextnonemptyq[i] = queuenumber;
7014     }
7015     /* Put the bad triangle at the beginning of the (empty) queue. */
7016     m->queuefront[queuenumber] = badtri;
7017   } else {
7018     /* Add the bad triangle to the end of an already nonempty queue. */
7019     m->queuetail[queuenumber]->nexttriang = badtri;
7020   }
7021   /* Maintain a pointer to the last triangle of the queue. */
7022   m->queuetail[queuenumber] = badtri;
7023   /* Newly enqueued bad triangle has no successor in the queue. */
7024   badtri->nexttriang = (struct badtriang *) NULL;
7025 }
7026 
7027 #endif /* not CDT_ONLY */
7028 
7029 /*****************************************************************************/
7030 /*                                                                           */
7031 /*  enqueuebadtri()   Add a bad triangle to the end of a queue.              */
7032 /*                                                                           */
7033 /*  Allocates a badtriang data structure for the triangle, then passes it to */
7034 /*  enqueuebadtriang().                                                      */
7035 /*                                                                           */
7036 /*****************************************************************************/
7037 
7038 #ifndef CDT_ONLY
7039 
7040 #ifdef ANSI_DECLARATORS
7041 void enqueuebadtri(struct mesh *m, struct behavior *b, struct otri *enqtri,
7042                    REAL minedge, vertex enqapex, vertex enqorg, vertex enqdest)
7043 #else /* not ANSI_DECLARATORS */
7044 void enqueuebadtri(m, b, enqtri, minedge, enqapex, enqorg, enqdest)
7045 struct mesh *m;
7046 struct behavior *b;
7047 struct otri *enqtri;
7048 REAL minedge;
7049 vertex enqapex;
7050 vertex enqorg;
7051 vertex enqdest;
7052 #endif /* not ANSI_DECLARATORS */
7053 
7054 {
7055   struct badtriang *newbad;
7056 
7057   /* Allocate space for the bad triangle. */
7058   newbad = (struct badtriang *) poolalloc(&m->badtriangles);
7059   newbad->poortri = encode(*enqtri);
7060   newbad->key = minedge;
7061   newbad->triangapex = enqapex;
7062   newbad->triangorg = enqorg;
7063   newbad->triangdest = enqdest;
7064   enqueuebadtriang(m, b, newbad);
7065 }
7066 
7067 #endif /* not CDT_ONLY */
7068 
7069 /*****************************************************************************/
7070 /*                                                                           */
7071 /*  dequeuebadtriang()   Remove a triangle from the front of the queue.      */
7072 /*                                                                           */
7073 /*****************************************************************************/
7074 
7075 #ifndef CDT_ONLY
7076 
7077 #ifdef ANSI_DECLARATORS
7078 struct badtriang *dequeuebadtriang(struct mesh *m)
7079 #else /* not ANSI_DECLARATORS */
7080 struct badtriang *dequeuebadtriang(m)
7081 struct mesh *m;
7082 #endif /* not ANSI_DECLARATORS */
7083 
7084 {
7085   struct badtriang *result;
7086 
7087   /* If no queues are nonempty, return NULL. */
7088   if (m->firstnonemptyq < 0) {
7089     return (struct badtriang *) NULL;
7090   }
7091   /* Find the first triangle of the highest-priority queue. */
7092   result = m->queuefront[m->firstnonemptyq];
7093   /* Remove the triangle from the queue. */
7094   m->queuefront[m->firstnonemptyq] = result->nexttriang;
7095   /* If this queue is now empty, note the new highest-priority */
7096   /*   nonempty queue.                                         */
7097   if (result == m->queuetail[m->firstnonemptyq]) {
7098     m->firstnonemptyq = m->nextnonemptyq[m->firstnonemptyq];
7099   }
7100   return result;
7101 }
7102 
7103 #endif /* not CDT_ONLY */
7104 
7105 /*****************************************************************************/
7106 /*                                                                           */
7107 /*  checkseg4encroach()   Check a subsegment to see if it is encroached; add */
7108 /*                        it to the list if it is.                           */
7109 /*                                                                           */
7110 /*  A subsegment is encroached if there is a vertex in its diametral lens.   */
7111 /*  For Ruppert's algorithm (-D switch), the "diametral lens" is the         */
7112 /*  diametral circle.  For Chew's algorithm (default), the diametral lens is */
7113 /*  just big enough to enclose two isosceles triangles whose bases are the   */
7114 /*  subsegment.  Each of the two isosceles triangles has two angles equal    */
7115 /*  to `b->minangle'.                                                        */
7116 /*                                                                           */
7117 /*  Chew's algorithm does not require diametral lenses at all--but they save */
7118 /*  time.  Any vertex inside a subsegment's diametral lens implies that the  */
7119 /*  triangle adjoining the subsegment will be too skinny, so it's only a     */
7120 /*  matter of time before the encroaching vertex is deleted by Chew's        */
7121 /*  algorithm.  It's faster to simply not insert the doomed vertex in the    */
7122 /*  first place, which is why I use diametral lenses with Chew's algorithm.  */
7123 /*                                                                           */
7124 /*  Returns a nonzero value if the subsegment is encroached.                 */
7125 /*                                                                           */
7126 /*****************************************************************************/
7127 
7128 #ifndef CDT_ONLY
7129 
7130 #ifdef ANSI_DECLARATORS
7131 int checkseg4encroach(struct mesh *m, struct behavior *b,
7132                       struct osub *testsubseg)
7133 #else /* not ANSI_DECLARATORS */
7134 int checkseg4encroach(m, b, testsubseg)
7135 struct mesh *m;
7136 struct behavior *b;
7137 struct osub *testsubseg;
7138 #endif /* not ANSI_DECLARATORS */
7139 
7140 {
7141   struct otri neighbortri;
7142   struct osub testsym;
7143   struct badsubseg *encroachedseg;
7144   REAL dotproduct;
7145   int encroached;
7146   int sides;
7147   vertex eorg, edest, eapex;
7148   triangle ptr;                     /* Temporary variable used by stpivot(). */
7149 
7150   encroached = 0;
7151   sides = 0;
7152 
7153   sorg(*testsubseg, eorg);
7154   sdest(*testsubseg, edest);
7155   /* Check one neighbor of the subsegment. */
7156   stpivot(*testsubseg, neighbortri);
7157   /* Does the neighbor exist, or is this a boundary edge? */
7158   if (neighbortri.tri != m->dummytri) {
7159     sides++;
7160     /* Find a vertex opposite this subsegment. */
7161     apex(neighbortri, eapex);
7162     /* Check whether the apex is in the diametral lens of the subsegment */
7163     /*   (the diametral circle if `conformdel' is set).  A dot product   */
7164     /*   of two sides of the triangle is used to check whether the angle */
7165     /*   at the apex is greater than (180 - 2 `minangle') degrees (for   */
7166     /*   lenses; 90 degrees for diametral circles).                      */
7167     dotproduct = (eorg[0] - eapex[0]) * (edest[0] - eapex[0]) +
7168                  (eorg[1] - eapex[1]) * (edest[1] - eapex[1]);
7169     if (dotproduct < 0.0) {
7170       if (b->conformdel ||
7171           (dotproduct * dotproduct >=
7172            (2.0 * b->goodangle - 1.0) * (2.0 * b->goodangle - 1.0) *
7173            ((eorg[0] - eapex[0]) * (eorg[0] - eapex[0]) +
7174             (eorg[1] - eapex[1]) * (eorg[1] - eapex[1])) *
7175            ((edest[0] - eapex[0]) * (edest[0] - eapex[0]) +
7176             (edest[1] - eapex[1]) * (edest[1] - eapex[1])))) {
7177         encroached = 1;
7178       }
7179     }
7180   }
7181   /* Check the other neighbor of the subsegment. */
7182   ssym(*testsubseg, testsym);
7183   stpivot(testsym, neighbortri);
7184   /* Does the neighbor exist, or is this a boundary edge? */
7185   if (neighbortri.tri != m->dummytri) {
7186     sides++;
7187     /* Find the other vertex opposite this subsegment. */
7188     apex(neighbortri, eapex);
7189     /* Check whether the apex is in the diametral lens of the subsegment */
7190     /*   (or the diametral circle, if `conformdel' is set).              */
7191     dotproduct = (eorg[0] - eapex[0]) * (edest[0] - eapex[0]) +
7192                  (eorg[1] - eapex[1]) * (edest[1] - eapex[1]);
7193     if (dotproduct < 0.0) {
7194       if (b->conformdel ||
7195           (dotproduct * dotproduct >=
7196            (2.0 * b->goodangle - 1.0) * (2.0 * b->goodangle - 1.0) *
7197            ((eorg[0] - eapex[0]) * (eorg[0] - eapex[0]) +
7198             (eorg[1] - eapex[1]) * (eorg[1] - eapex[1])) *
7199            ((edest[0] - eapex[0]) * (edest[0] - eapex[0]) +
7200             (edest[1] - eapex[1]) * (edest[1] - eapex[1])))) {
7201         encroached += 2;
7202       }
7203     }
7204   }
7205 
7206   if (encroached && (!b->nobisect || ((b->nobisect == 1) && (sides == 2)))) {
7207     if (b->verbose > 2) {
7208       printf(
7209         "  Queueing encroached subsegment (%.12g, %.12g) (%.12g, %.12g).\n",
7210         eorg[0], eorg[1], edest[0], edest[1]);
7211     }
7212     /* Add the subsegment to the list of encroached subsegments. */
7213     /*   Be sure to get the orientation right.                   */
7214     encroachedseg = (struct badsubseg *) poolalloc(&m->badsubsegs);
7215     if (encroached == 1) {
7216       encroachedseg->encsubseg = sencode(*testsubseg);
7217       encroachedseg->subsegorg = eorg;
7218       encroachedseg->subsegdest = edest;
7219     } else {
7220       encroachedseg->encsubseg = sencode(testsym);
7221       encroachedseg->subsegorg = edest;
7222       encroachedseg->subsegdest = eorg;
7223     }
7224   }
7225 
7226   return encroached;
7227 }
7228 
7229 #endif /* not CDT_ONLY */
7230 
7231 /*****************************************************************************/
7232 /*                                                                           */
7233 /*  testtriangle()   Test a triangle for quality and size.                   */
7234 /*                                                                           */
7235 /*  Tests a triangle to see if it satisfies the minimum angle condition and  */
7236 /*  the maximum area condition.  Triangles that aren't up to spec are added  */
7237 /*  to the bad triangle queue.                                               */
7238 /*                                                                           */
7239 /*****************************************************************************/
7240 
7241 #ifndef CDT_ONLY
7242 
7243 #ifdef ANSI_DECLARATORS
7244 void testtriangle(struct mesh *m, struct behavior *b, struct otri *testtri)
7245 #else /* not ANSI_DECLARATORS */
7246 void testtriangle(m, b, testtri)
7247 struct mesh *m;
7248 struct behavior *b;
7249 struct otri *testtri;
7250 #endif /* not ANSI_DECLARATORS */
7251 
7252 {
7253   struct otri tri1, tri2;
7254   struct osub testsub;
7255   vertex torg, tdest, tapex;
7256   vertex base1, base2;
7257   vertex org1, dest1, org2, dest2;
7258   vertex joinvertex;
7259   REAL dxod, dyod, dxda, dyda, dxao, dyao;
7260   REAL dxod2, dyod2, dxda2, dyda2, dxao2, dyao2;
7261   REAL apexlen, orglen, destlen, minedge;
7262   REAL angle;
7263   REAL area;
7264   REAL dist1, dist2;
7265   subseg sptr;                      /* Temporary variable used by tspivot(). */
7266   triangle ptr;           /* Temporary variable used by oprev() and dnext(). */
7267 
7268   org(*testtri, torg);
7269   dest(*testtri, tdest);
7270   apex(*testtri, tapex);
7271   dxod = torg[0] - tdest[0];
7272   dyod = torg[1] - tdest[1];
7273   dxda = tdest[0] - tapex[0];
7274   dyda = tdest[1] - tapex[1];
7275   dxao = tapex[0] - torg[0];
7276   dyao = tapex[1] - torg[1];
7277   dxod2 = dxod * dxod;
7278   dyod2 = dyod * dyod;
7279   dxda2 = dxda * dxda;
7280   dyda2 = dyda * dyda;
7281   dxao2 = dxao * dxao;
7282   dyao2 = dyao * dyao;
7283   /* Find the lengths of the triangle's three edges. */
7284   apexlen = dxod2 + dyod2;
7285   orglen = dxda2 + dyda2;
7286   destlen = dxao2 + dyao2;
7287 
7288   if ((apexlen < orglen) && (apexlen < destlen)) {
7289     /* The edge opposite the apex is shortest. */
7290     minedge = apexlen;
7291     /* Find the square of the cosine of the angle at the apex. */
7292     angle = dxda * dxao + dyda * dyao;
7293     angle = angle * angle / (orglen * destlen);
7294     base1 = torg;
7295     base2 = tdest;
7296     otricopy(*testtri, tri1);
7297   } else if (orglen < destlen) {
7298     /* The edge opposite the origin is shortest. */
7299     minedge = orglen;
7300     /* Find the square of the cosine of the angle at the origin. */
7301     angle = dxod * dxao + dyod * dyao;
7302     angle = angle * angle / (apexlen * destlen);
7303     base1 = tdest;
7304     base2 = tapex;
7305     lnext(*testtri, tri1);
7306   } else {
7307     /* The edge opposite the destination is shortest. */
7308     minedge = destlen;
7309     /* Find the square of the cosine of the angle at the destination. */
7310     angle = dxod * dxda + dyod * dyda;
7311     angle = angle * angle / (apexlen * orglen);
7312     base1 = tapex;
7313     base2 = torg;
7314     lprev(*testtri, tri1);
7315   }
7316 
7317   if (b->vararea || b->fixedarea || b->usertest) {
7318     /* Check whether the area is larger than permitted. */
7319     area = 0.5 * (dxod * dyda - dyod * dxda);
7320     if (b->fixedarea && (area > b->maxarea)) {
7321       /* Add this triangle to the list of bad triangles. */
7322       enqueuebadtri(m, b, testtri, minedge, tapex, torg, tdest);
7323       return;
7324     }
7325 
7326     /* Nonpositive area constraints are treated as unconstrained. */
7327     if ((b->vararea) && (area > areabound(*testtri)) &&
7328         (areabound(*testtri) > 0.0)) {
7329       /* Add this triangle to the list of bad triangles. */
7330       enqueuebadtri(m, b, testtri, minedge, tapex, torg, tdest);
7331       return;
7332     }
7333 
7334     if (b->usertest) {
7335       /* Check whether the user thinks this triangle is too large. */
7336       if (triunsuitable(torg, tdest, tapex, area)) {
7337         enqueuebadtri(m, b, testtri, minedge, tapex, torg, tdest);
7338         return;
7339       }
7340     }
7341   }
7342 
7343   /* Check whether the angle is smaller than permitted. */
7344   if (angle > b->goodangle) {
7345     /* Use the rules of Miller, Pav, and Walkington to decide that certain */
7346     /*   triangles should not be split, even if they have bad angles.      */
7347     /*   A skinny triangle is not split if its shortest edge subtends a    */
7348     /*   small input angle, and both endpoints of the edge lie on a        */
7349     /*   concentric circular shell.  For convenience, I make a small       */
7350     /*   adjustment to that rule:  I check if the endpoints of the edge    */
7351     /*   both lie in segment interiors, equidistant from the apex where    */
7352     /*   the two segments meet.                                            */
7353     /* First, check if both points lie in segment interiors.               */
7354     if ((vertextype(base1) == SEGMENTVERTEX) &&
7355         (vertextype(base2) == SEGMENTVERTEX)) {
7356       /* Check if both points lie in a common segment.  If they do, the */
7357       /*   skinny triangle is enqueued to be split as usual.            */
7358       tspivot(tri1, testsub);
7359       if (testsub.ss == m->dummysub) {
7360         /* No common segment.  Find a subsegment that contains `torg'. */
7361         otricopy(tri1, tri2);
7362         do {
7363           oprevself(tri1);
7364           tspivot(tri1, testsub);
7365         } while (testsub.ss == m->dummysub);
7366         /* Find the endpoints of the containing segment. */
7367         segorg(testsub, org1);
7368         segdest(testsub, dest1);
7369         /* Find a subsegment that contains `tdest'. */
7370         do {
7371           dnextself(tri2);
7372           tspivot(tri2, testsub);
7373         } while (testsub.ss == m->dummysub);
7374         /* Find the endpoints of the containing segment. */
7375         segorg(testsub, org2);
7376         segdest(testsub, dest2);
7377         /* Check if the two containing segments have an endpoint in common. */
7378         joinvertex = (vertex) NULL;
7379         if ((dest1[0] == org2[0]) && (dest1[1] == org2[1])) {
7380           joinvertex = dest1;
7381         } else if ((org1[0] == dest2[0]) && (org1[1] == dest2[1])) {
7382           joinvertex = org1;
7383         }
7384         if (joinvertex != (vertex) NULL) {
7385           /* Compute the distance from the common endpoint (of the two  */
7386           /*   segments) to each of the endpoints of the shortest edge. */
7387           dist1 = ((base1[0] - joinvertex[0]) * (base1[0] - joinvertex[0]) +
7388                    (base1[1] - joinvertex[1]) * (base1[1] - joinvertex[1]));
7389           dist2 = ((base2[0] - joinvertex[0]) * (base2[0] - joinvertex[0]) +
7390                    (base2[1] - joinvertex[1]) * (base2[1] - joinvertex[1]));
7391           /* If the two distances are equal, don't split the triangle. */
7392           if ((dist1 < 1.001 * dist2) && (dist1 > 0.999 * dist2)) {
7393             /* Return now to avoid enqueueing the bad triangle. */
7394             return;
7395           }
7396         }
7397       }
7398     }
7399 
7400     /* Add this triangle to the list of bad triangles. */
7401     enqueuebadtri(m, b, testtri, minedge, tapex, torg, tdest);
7402   }
7403 }
7404 
7405 #endif /* not CDT_ONLY */
7406 
7407 /**                                                                         **/
7408 /**                                                                         **/
7409 /********* Mesh quality testing routines end here                    *********/
7410 
7411 /********* Point location routines begin here                        *********/
7412 /**                                                                         **/
7413 /**                                                                         **/
7414 
7415 /*****************************************************************************/
7416 /*                                                                           */
7417 /*  makevertexmap()   Construct a mapping from vertices to triangles to      */
7418 /*                    improve the speed of point location for segment        */
7419 /*                    insertion.                                             */
7420 /*                                                                           */
7421 /*  Traverses all the triangles, and provides each corner of each triangle   */
7422 /*  with a pointer to that triangle.  Of course, pointers will be            */
7423 /*  overwritten by other pointers because (almost) each vertex is a corner   */
7424 /*  of several triangles, but in the end every vertex will point to some     */
7425 /*  triangle that contains it.                                               */
7426 /*                                                                           */
7427 /*****************************************************************************/
7428 
7429 #ifdef ANSI_DECLARATORS
7430 void makevertexmap(struct mesh *m, struct behavior *b)
7431 #else /* not ANSI_DECLARATORS */
7432 void makevertexmap(m, b)
7433 struct mesh *m;
7434 struct behavior *b;
7435 #endif /* not ANSI_DECLARATORS */
7436 
7437 {
7438   struct otri triangleloop;
7439   vertex triorg;
7440 
7441   if (b->verbose) {
7442     printf("    Constructing mapping from vertices to triangles.\n");
7443   }
7444   traversalinit(&m->triangles);
7445   triangleloop.tri = triangletraverse(m);
7446   while (triangleloop.tri != (triangle *) NULL) {
7447     /* Check all three vertices of the triangle. */
7448     for (triangleloop.orient = 0; triangleloop.orient < 3;
7449          triangleloop.orient++) {
7450       org(triangleloop, triorg);
7451       setvertex2tri(triorg, encode(triangleloop));
7452     }
7453     triangleloop.tri = triangletraverse(m);
7454   }
7455 }
7456 
7457 /*****************************************************************************/
7458 /*                                                                           */
7459 /*  preciselocate()   Find a triangle or edge containing a given point.      */
7460 /*                                                                           */
7461 /*  Begins its search from `searchtri'.  It is important that `searchtri'    */
7462 /*  be a handle with the property that `searchpoint' is strictly to the left */
7463 /*  of the edge denoted by `searchtri', or is collinear with that edge and   */
7464 /*  does not intersect that edge.  (In particular, `searchpoint' should not  */
7465 /*  be the origin or destination of that edge.)                              */
7466 /*                                                                           */
7467 /*  These conditions are imposed because preciselocate() is normally used in */
7468 /*  one of two situations:                                                   */
7469 /*                                                                           */
7470 /*  (1)  To try to find the location to insert a new point.  Normally, we    */
7471 /*       know an edge that the point is strictly to the left of.  In the     */
7472 /*       incremental Delaunay algorithm, that edge is a bounding box edge.   */
7473 /*       In Ruppert's Delaunay refinement algorithm for quality meshing,     */
7474 /*       that edge is the shortest edge of the triangle whose circumcenter   */
7475 /*       is being inserted.                                                  */
7476 /*                                                                           */
7477 /*  (2)  To try to find an existing point.  In this case, any edge on the    */
7478 /*       convex hull is a good starting edge.  You must screen out the       */
7479 /*       possibility that the vertex sought is an endpoint of the starting   */
7480 /*       edge before you call preciselocate().                               */
7481 /*                                                                           */
7482 /*  On completion, `searchtri' is a triangle that contains `searchpoint'.    */
7483 /*                                                                           */
7484 /*  This implementation differs from that given by Guibas and Stolfi.  It    */
7485 /*  walks from triangle to triangle, crossing an edge only if `searchpoint'  */
7486 /*  is on the other side of the line containing that edge.  After entering   */
7487 /*  a triangle, there are two edges by which one can leave that triangle.    */
7488 /*  If both edges are valid (`searchpoint' is on the other side of both      */
7489 /*  edges), one of the two is chosen by drawing a line perpendicular to      */
7490 /*  the entry edge (whose endpoints are `forg' and `fdest') passing through  */
7491 /*  `fapex'.  Depending on which side of this perpendicular `searchpoint'    */
7492 /*  falls on, an exit edge is chosen.                                        */
7493 /*                                                                           */
7494 /*  This implementation is empirically faster than the Guibas and Stolfi     */
7495 /*  point location routine (which I originally used), which tends to spiral  */
7496 /*  in toward its target.                                                    */
7497 /*                                                                           */
7498 /*  Returns ONVERTEX if the point lies on an existing vertex.  `searchtri'   */
7499 /*  is a handle whose origin is the existing vertex.                         */
7500 /*                                                                           */
7501 /*  Returns ONEDGE if the point lies on a mesh edge.  `searchtri' is a       */
7502 /*  handle whose primary edge is the edge on which the point lies.           */
7503 /*                                                                           */
7504 /*  Returns INTRIANGLE if the point lies strictly within a triangle.         */
7505 /*  `searchtri' is a handle on the triangle that contains the point.         */
7506 /*                                                                           */
7507 /*  Returns OUTSIDE if the point lies outside the mesh.  `searchtri' is a    */
7508 /*  handle whose primary edge the point is to the right of.  This might      */
7509 /*  occur when the circumcenter of a triangle falls just slightly outside    */
7510 /*  the mesh due to floating-point roundoff error.  It also occurs when      */
7511 /*  seeking a hole or region point that a foolish user has placed outside    */
7512 /*  the mesh.                                                                */
7513 /*                                                                           */
7514 /*  If `stopatsubsegment' is nonzero, the search will stop if it tries to    */
7515 /*  walk through a subsegment, and will return OUTSIDE.                      */
7516 /*                                                                           */
7517 /*  WARNING:  This routine is designed for convex triangulations, and will   */
7518 /*  not generally work after the holes and concavities have been carved.     */
7519 /*  However, it can still be used to find the circumcenter of a triangle, as */
7520 /*  long as the search is begun from the triangle in question.               */
7521 /*                                                                           */
7522 /*****************************************************************************/
7523 
7524 #ifdef ANSI_DECLARATORS
7525 enum locateresult preciselocate(struct mesh *m, struct behavior *b,
7526                                 vertex searchpoint, struct otri *searchtri,
7527                                 int stopatsubsegment)
7528 #else /* not ANSI_DECLARATORS */
7529 enum locateresult preciselocate(m, b, searchpoint, searchtri, stopatsubsegment)
7530 struct mesh *m;
7531 struct behavior *b;
7532 vertex searchpoint;
7533 struct otri *searchtri;
7534 int stopatsubsegment;
7535 #endif /* not ANSI_DECLARATORS */
7536 
7537 {
7538   struct otri backtracktri;
7539   struct osub checkedge;
7540   vertex forg, fdest, fapex;
7541   REAL orgorient, destorient;
7542   int moveleft;
7543   triangle ptr;                         /* Temporary variable used by sym(). */
7544   subseg sptr;                      /* Temporary variable used by tspivot(). */
7545 
7546   if (b->verbose > 2) {
7547     printf("  Searching for point (%.12g, %.12g).\n",
7548            searchpoint[0], searchpoint[1]);
7549   }
7550   /* Where are we? */
7551   org(*searchtri, forg);
7552   dest(*searchtri, fdest);
7553   apex(*searchtri, fapex);
7554   while (1) {
7555     if (b->verbose > 2) {
7556       printf("    At (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
7557              forg[0], forg[1], fdest[0], fdest[1], fapex[0], fapex[1]);
7558     }
7559     /* Check whether the apex is the point we seek. */
7560     if ((fapex[0] == searchpoint[0]) && (fapex[1] == searchpoint[1])) {
7561       lprevself(*searchtri);
7562       return ONVERTEX;
7563     }
7564     /* Does the point lie on the other side of the line defined by the */
7565     /*   triangle edge opposite the triangle's destination?            */
7566     destorient = counterclockwise(m, b, forg, fapex, searchpoint);
7567     /* Does the point lie on the other side of the line defined by the */
7568     /*   triangle edge opposite the triangle's origin?                 */
7569     orgorient = counterclockwise(m, b, fapex, fdest, searchpoint);
7570     if (destorient > 0.0) {
7571       if (orgorient > 0.0) {
7572         /* Move left if the inner product of (fapex - searchpoint) and  */
7573         /*   (fdest - forg) is positive.  This is equivalent to drawing */
7574         /*   a line perpendicular to the line (forg, fdest) and passing */
7575         /*   through `fapex', and determining which side of this line   */
7576         /*   `searchpoint' falls on.                                    */
7577         moveleft = (fapex[0] - searchpoint[0]) * (fdest[0] - forg[0]) +
7578                    (fapex[1] - searchpoint[1]) * (fdest[1] - forg[1]) > 0.0;
7579       } else {
7580         moveleft = 1;
7581       }
7582     } else {
7583       if (orgorient > 0.0) {
7584         moveleft = 0;
7585       } else {
7586         /* The point we seek must be on the boundary of or inside this */
7587         /*   triangle.                                                 */
7588         if (destorient == 0.0) {
7589           lprevself(*searchtri);
7590           return ONEDGE;
7591         }
7592         if (orgorient == 0.0) {
7593           lnextself(*searchtri);
7594           return ONEDGE;
7595         }
7596         return INTRIANGLE;
7597       }
7598     }
7599 
7600     /* Move to another triangle.  Leave a trace `backtracktri' in case */
7601     /*   floating-point roundoff or some such bogey causes us to walk  */
7602     /*   off a boundary of the triangulation.                          */
7603     if (moveleft) {
7604       lprev(*searchtri, backtracktri);
7605       fdest = fapex;
7606     } else {
7607       lnext(*searchtri, backtracktri);
7608       forg = fapex;
7609     }
7610     sym(backtracktri, *searchtri);
7611 
7612     if (m->checksegments && stopatsubsegment) {
7613       /* Check for walking through a subsegment. */
7614       tspivot(backtracktri, checkedge);
7615       if (checkedge.ss != m->dummysub) {
7616         /* Go back to the last triangle. */
7617         otricopy(backtracktri, *searchtri);
7618         return OUTSIDE;
7619       }
7620     }
7621     /* Check for walking right out of the triangulation. */
7622     if (searchtri->tri == m->dummytri) {
7623       /* Go back to the last triangle. */
7624       otricopy(backtracktri, *searchtri);
7625       return OUTSIDE;
7626     }
7627 
7628     apex(*searchtri, fapex);
7629   }
7630 }
7631 
7632 /*****************************************************************************/
7633 /*                                                                           */
7634 /*  locate()   Find a triangle or edge containing a given point.             */
7635 /*                                                                           */
7636 /*  Searching begins from one of:  the input `searchtri', a recently         */
7637 /*  encountered triangle `recenttri', or from a triangle chosen from a       */
7638 /*  random sample.  The choice is made by determining which triangle's       */
7639 /*  origin is closest to the point we are searching for.  Normally,          */
7640 /*  `searchtri' should be a handle on the convex hull of the triangulation.  */
7641 /*                                                                           */
7642 /*  Details on the random sampling method can be found in the Mucke, Saias,  */
7643 /*  and Zhu paper cited in the header of this code.                          */
7644 /*                                                                           */
7645 /*  On completion, `searchtri' is a triangle that contains `searchpoint'.    */
7646 /*                                                                           */
7647 /*  Returns ONVERTEX if the point lies on an existing vertex.  `searchtri'   */
7648 /*  is a handle whose origin is the existing vertex.                         */
7649 /*                                                                           */
7650 /*  Returns ONEDGE if the point lies on a mesh edge.  `searchtri' is a       */
7651 /*  handle whose primary edge is the edge on which the point lies.           */
7652 /*                                                                           */
7653 /*  Returns INTRIANGLE if the point lies strictly within a triangle.         */
7654 /*  `searchtri' is a handle on the triangle that contains the point.         */
7655 /*                                                                           */
7656 /*  Returns OUTSIDE if the point lies outside the mesh.  `searchtri' is a    */
7657 /*  handle whose primary edge the point is to the right of.  This might      */
7658 /*  occur when the circumcenter of a triangle falls just slightly outside    */
7659 /*  the mesh due to floating-point roundoff error.  It also occurs when      */
7660 /*  seeking a hole or region point that a foolish user has placed outside    */
7661 /*  the mesh.                                                                */
7662 /*                                                                           */
7663 /*  WARNING:  This routine is designed for convex triangulations, and will   */
7664 /*  not generally work after the holes and concavities have been carved.     */
7665 /*                                                                           */
7666 /*****************************************************************************/
7667 
7668 #ifdef ANSI_DECLARATORS
7669 enum locateresult locate(struct mesh *m, struct behavior *b,
7670                          vertex searchpoint, struct otri *searchtri)
7671 #else /* not ANSI_DECLARATORS */
7672 enum locateresult locate(m, b, searchpoint, searchtri)
7673 struct mesh *m;
7674 struct behavior *b;
7675 vertex searchpoint;
7676 struct otri *searchtri;
7677 #endif /* not ANSI_DECLARATORS */
7678 
7679 {
7680   VOID **sampleblock;
7681   char *firsttri;
7682   struct otri sampletri;
7683   vertex torg, tdest;
7684   INT_PTR alignptr = 0;
7685   REAL searchdist, dist;
7686   REAL ahead;
7687   long samplesperblock, totalsamplesleft, samplesleft;
7688   long population, totalpopulation;
7689   triangle ptr;                         /* Temporary variable used by sym(). */
7690 
7691   if (b->verbose > 2) {
7692     printf("  Randomly sampling for a triangle near point (%.12g, %.12g).\n",
7693            searchpoint[0], searchpoint[1]);
7694   }
7695   /* Record the distance from the suggested starting triangle to the */
7696   /*   point we seek.                                                */
7697   org(*searchtri, torg);
7698   searchdist = (searchpoint[0] - torg[0]) * (searchpoint[0] - torg[0]) +
7699                (searchpoint[1] - torg[1]) * (searchpoint[1] - torg[1]);
7700   if (b->verbose > 2) {
7701     printf("    Boundary triangle has origin (%.12g, %.12g).\n",
7702            torg[0], torg[1]);
7703   }
7704 
7705   /* If a recently encountered triangle has been recorded and has not been */
7706   /*   deallocated, test it as a good starting point.                      */
7707   if (m->recenttri.tri != (triangle *) NULL) {
7708     if (!deadtri(m->recenttri.tri)) {
7709       org(m->recenttri, torg);
7710       if ((torg[0] == searchpoint[0]) && (torg[1] == searchpoint[1])) {
7711         otricopy(m->recenttri, *searchtri);
7712         return ONVERTEX;
7713       }
7714       dist = (searchpoint[0] - torg[0]) * (searchpoint[0] - torg[0]) +
7715              (searchpoint[1] - torg[1]) * (searchpoint[1] - torg[1]);
7716       if (dist < searchdist) {
7717         otricopy(m->recenttri, *searchtri);
7718         searchdist = dist;
7719         if (b->verbose > 2) {
7720           printf("    Choosing recent triangle with origin (%.12g, %.12g).\n",
7721                  torg[0], torg[1]);
7722         }
7723       }
7724     }
7725   }
7726 
7727   /* The number of random samples taken is proportional to the cube root of */
7728   /*   the number of triangles in the mesh.  The next bit of code assumes   */
7729   /*   that the number of triangles increases monotonically (or at least    */
7730   /*   doesn't decrease enough to matter).                                  */
7731   while (SAMPLEFACTOR * m->samples * m->samples * m->samples <
7732          m->triangles.items) {
7733     m->samples++;
7734   }
7735 
7736   /* We'll draw ceiling(samples * TRIPERBLOCK / maxitems) random samples  */
7737   /*   from each block of triangles (except the first)--until we meet the */
7738   /*   sample quota.  The ceiling means that blocks at the end might be   */
7739   /*   neglected, but I don't care.                                       */
7740   samplesperblock = (m->samples * TRIPERBLOCK - 1) / m->triangles.maxitems + 1;
7741   /* We'll draw ceiling(samples * itemsfirstblock / maxitems) random samples */
7742   /*   from the first block of triangles.                                    */
7743   samplesleft = (m->samples * m->triangles.itemsfirstblock - 1) /
7744                 m->triangles.maxitems + 1;
7745   totalsamplesleft = m->samples;
7746   population = m->triangles.itemsfirstblock;
7747   totalpopulation = m->triangles.maxitems;
7748   sampleblock = m->triangles.firstblock;
7749   sampletri.orient = 0;
7750   while (totalsamplesleft > 0) {
7751     /* If we're in the last block, `population' needs to be corrected. */
7752     if (population > totalpopulation) {
7753       population = totalpopulation;
7754     }
7755     /* Find a pointer to the first triangle in the block. */
7756     alignptr = (INT_PTR) (sampleblock + 1);
7757     firsttri = (char *) (alignptr +
7758                          (INT_PTR) m->triangles.alignbytes -
7759                          (alignptr %
7760                           (INT_PTR) m->triangles.alignbytes));
7761 
7762     /* Choose `samplesleft' randomly sampled triangles in this block. */
7763     do {
7764       sampletri.tri = (triangle *) (firsttri +
7765                                     (randomnation((unsigned int) population) *
7766                                      m->triangles.itembytes));
7767       if (!deadtri(sampletri.tri)) {
7768         org(sampletri, torg);
7769         dist = (searchpoint[0] - torg[0]) * (searchpoint[0] - torg[0]) +
7770                (searchpoint[1] - torg[1]) * (searchpoint[1] - torg[1]);
7771         if (dist < searchdist) {
7772           otricopy(sampletri, *searchtri);
7773           searchdist = dist;
7774           if (b->verbose > 2) {
7775             printf("    Choosing triangle with origin (%.12g, %.12g).\n",
7776                    torg[0], torg[1]);
7777           }
7778         }
7779       }
7780 
7781       samplesleft--;
7782       totalsamplesleft--;
7783     } while ((samplesleft > 0) && (totalsamplesleft > 0));
7784 
7785     if (totalsamplesleft > 0) {
7786       sampleblock = (VOID **) *sampleblock;
7787       samplesleft = samplesperblock;
7788       totalpopulation -= population;
7789       population = TRIPERBLOCK;
7790     }
7791   }
7792 
7793   /* Where are we? */
7794   org(*searchtri, torg);
7795   dest(*searchtri, tdest);
7796   /* Check the starting triangle's vertices. */
7797   if ((torg[0] == searchpoint[0]) && (torg[1] == searchpoint[1])) {
7798     return ONVERTEX;
7799   }
7800   if ((tdest[0] == searchpoint[0]) && (tdest[1] == searchpoint[1])) {
7801     lnextself(*searchtri);
7802     return ONVERTEX;
7803   }
7804   /* Orient `searchtri' to fit the preconditions of calling preciselocate(). */
7805   ahead = counterclockwise(m, b, torg, tdest, searchpoint);
7806   if (ahead < 0.0) {
7807     /* Turn around so that `searchpoint' is to the left of the */
7808     /*   edge specified by `searchtri'.                        */
7809     symself(*searchtri);
7810   } else if (ahead == 0.0) {
7811     /* Check if `searchpoint' is between `torg' and `tdest'. */
7812     if (((torg[0] < searchpoint[0]) == (searchpoint[0] < tdest[0])) &&
7813         ((torg[1] < searchpoint[1]) == (searchpoint[1] < tdest[1]))) {
7814       return ONEDGE;
7815     }
7816   }
7817   return preciselocate(m, b, searchpoint, searchtri, 0);
7818 }
7819 
7820 /**                                                                         **/
7821 /**                                                                         **/
7822 /********* Point location routines end here                          *********/
7823 
7824 /********* Mesh transformation routines begin here                   *********/
7825 /**                                                                         **/
7826 /**                                                                         **/
7827 
7828 /*****************************************************************************/
7829 /*                                                                           */
7830 /*  insertsubseg()   Create a new subsegment and insert it between two       */
7831 /*                   triangles.                                              */
7832 /*                                                                           */
7833 /*  The new subsegment is inserted at the edge described by the handle       */
7834 /*  `tri'.  Its vertices are properly initialized.  The marker `subsegmark'  */
7835 /*  is applied to the subsegment and, if appropriate, its vertices.          */
7836 /*                                                                           */
7837 /*****************************************************************************/
7838 
7839 #ifdef ANSI_DECLARATORS
7840 void insertsubseg(struct mesh *m, struct behavior *b, struct otri *tri,
7841                   int subsegmark)
7842 #else /* not ANSI_DECLARATORS */
7843 void insertsubseg(m, b, tri, subsegmark)
7844 struct mesh *m;
7845 struct behavior *b;
7846 struct otri *tri;             /* Edge at which to insert the new subsegment. */
7847 int subsegmark;                            /* Marker for the new subsegment. */
7848 #endif /* not ANSI_DECLARATORS */
7849 
7850 {
7851   struct otri oppotri;
7852   struct osub newsubseg;
7853   vertex triorg, tridest;
7854   triangle ptr;                         /* Temporary variable used by sym(). */
7855   subseg sptr;                      /* Temporary variable used by tspivot(). */
7856 
7857   org(*tri, triorg);
7858   dest(*tri, tridest);
7859   /* Mark vertices if possible. */
7860   if (vertexmark(triorg) == 0) {
7861     setvertexmark(triorg, subsegmark);
7862   }
7863   if (vertexmark(tridest) == 0) {
7864     setvertexmark(tridest, subsegmark);
7865   }
7866   /* Check if there's already a subsegment here. */
7867   tspivot(*tri, newsubseg);
7868   if (newsubseg.ss == m->dummysub) {
7869     /* Make new subsegment and initialize its vertices. */
7870     makesubseg(m, &newsubseg);
7871     setsorg(newsubseg, tridest);
7872     setsdest(newsubseg, triorg);
7873     setsegorg(newsubseg, tridest);
7874     setsegdest(newsubseg, triorg);
7875     /* Bond new subsegment to the two triangles it is sandwiched between. */
7876     /*   Note that the facing triangle `oppotri' might be equal to        */
7877     /*   `dummytri' (outer space), but the new subsegment is bonded to it */
7878     /*   all the same.                                                    */
7879     tsbond(*tri, newsubseg);
7880     sym(*tri, oppotri);
7881     ssymself(newsubseg);
7882     tsbond(oppotri, newsubseg);
7883     setmark(newsubseg, subsegmark);
7884     if (b->verbose > 2) {
7885       printf("  Inserting new ");
7886       printsubseg(m, b, &newsubseg);
7887     }
7888   } else {
7889     if (mark(newsubseg) == 0) {
7890       setmark(newsubseg, subsegmark);
7891     }
7892   }
7893 }
7894 
7895 /*****************************************************************************/
7896 /*                                                                           */
7897 /*  Terminology                                                              */
7898 /*                                                                           */
7899 /*  A "local transformation" replaces a small set of triangles with another  */
7900 /*  set of triangles.  This may or may not involve inserting or deleting a   */
7901 /*  vertex.                                                                  */
7902 /*                                                                           */
7903 /*  The term "casing" is used to describe the set of triangles that are      */
7904 /*  attached to the triangles being transformed, but are not transformed     */
7905 /*  themselves.  Think of the casing as a fixed hollow structure inside      */
7906 /*  which all the action happens.  A "casing" is only defined relative to    */
7907 /*  a single transformation; each occurrence of a transformation will        */
7908 /*  involve a different casing.                                              */
7909 /*                                                                           */
7910 /*****************************************************************************/
7911 
7912 /*****************************************************************************/
7913 /*                                                                           */
7914 /*  flip()   Transform two triangles to two different triangles by flipping  */
7915 /*           an edge counterclockwise within a quadrilateral.                */
7916 /*                                                                           */
7917 /*  Imagine the original triangles, abc and bad, oriented so that the        */
7918 /*  shared edge ab lies in a horizontal plane, with the vertex b on the left */
7919 /*  and the vertex a on the right.  The vertex c lies below the edge, and    */
7920 /*  the vertex d lies above the edge.  The `flipedge' handle holds the edge  */
7921 /*  ab of triangle abc, and is directed left, from vertex a to vertex b.     */
7922 /*                                                                           */
7923 /*  The triangles abc and bad are deleted and replaced by the triangles cdb  */
7924 /*  and dca.  The triangles that represent abc and bad are NOT deallocated;  */
7925 /*  they are reused for dca and cdb, respectively.  Hence, any handles that  */
7926 /*  may have held the original triangles are still valid, although not       */
7927 /*  directed as they were before.                                            */
7928 /*                                                                           */
7929 /*  Upon completion of this routine, the `flipedge' handle holds the edge    */
7930 /*  dc of triangle dca, and is directed down, from vertex d to vertex c.     */
7931 /*  (Hence, the two triangles have rotated counterclockwise.)                */
7932 /*                                                                           */
7933 /*  WARNING:  This transformation is geometrically valid only if the         */
7934 /*  quadrilateral adbc is convex.  Furthermore, this transformation is       */
7935 /*  valid only if there is not a subsegment between the triangles abc and    */
7936 /*  bad.  This routine does not check either of these preconditions, and     */
7937 /*  it is the responsibility of the calling routine to ensure that they are  */
7938 /*  met.  If they are not, the streets shall be filled with wailing and      */
7939 /*  gnashing of teeth.                                                       */
7940 /*                                                                           */
7941 /*****************************************************************************/
7942 
7943 #ifdef ANSI_DECLARATORS
7944 void flip(struct mesh *m, struct behavior *b, struct otri *flipedge)
7945 #else /* not ANSI_DECLARATORS */
7946 void flip(m, b, flipedge)
7947 struct mesh *m;
7948 struct behavior *b;
7949 struct otri *flipedge;                    /* Handle for the triangle abc. */
7950 #endif /* not ANSI_DECLARATORS */
7951 
7952 {
7953   struct otri botleft, botright;
7954   struct otri topleft, topright;
7955   struct otri top;
7956   struct otri botlcasing, botrcasing;
7957   struct otri toplcasing, toprcasing;
7958   struct osub botlsubseg, botrsubseg;
7959   struct osub toplsubseg, toprsubseg;
7960   vertex leftvertex, rightvertex, botvertex;
7961   vertex farvertex;
7962   triangle ptr;                         /* Temporary variable used by sym(). */
7963   subseg sptr;                      /* Temporary variable used by tspivot(). */
7964 
7965   /* Identify the vertices of the quadrilateral. */
7966   org(*flipedge, rightvertex);
7967   dest(*flipedge, leftvertex);
7968   apex(*flipedge, botvertex);
7969   sym(*flipedge, top);
7970 #ifdef SELF_CHECK
7971   if (top.tri == m->dummytri) {
7972     printf("Internal error in flip():  Attempt to flip on boundary.\n");
7973     lnextself(*flipedge);
7974     return;
7975   }
7976   if (m->checksegments) {
7977     tspivot(*flipedge, toplsubseg);
7978     if (toplsubseg.ss != m->dummysub) {
7979       printf("Internal error in flip():  Attempt to flip a segment.\n");
7980       lnextself(*flipedge);
7981       return;
7982     }
7983   }
7984 #endif /* SELF_CHECK */
7985   apex(top, farvertex);
7986 
7987   /* Identify the casing of the quadrilateral. */
7988   lprev(top, topleft);
7989   sym(topleft, toplcasing);
7990   lnext(top, topright);
7991   sym(topright, toprcasing);
7992   lnext(*flipedge, botleft);
7993   sym(botleft, botlcasing);
7994   lprev(*flipedge, botright);
7995   sym(botright, botrcasing);
7996   /* Rotate the quadrilateral one-quarter turn counterclockwise. */
7997   bond(topleft, botlcasing);
7998   bond(botleft, botrcasing);
7999   bond(botright, toprcasing);
8000   bond(topright, toplcasing);
8001 
8002   if (m->checksegments) {
8003     /* Check for subsegments and rebond them to the quadrilateral. */
8004     tspivot(topleft, toplsubseg);
8005     tspivot(botleft, botlsubseg);
8006     tspivot(botright, botrsubseg);
8007     tspivot(topright, toprsubseg);
8008     if (toplsubseg.ss == m->dummysub) {
8009       tsdissolve(topright);
8010     } else {
8011       tsbond(topright, toplsubseg);
8012     }
8013     if (botlsubseg.ss == m->dummysub) {
8014       tsdissolve(topleft);
8015     } else {
8016       tsbond(topleft, botlsubseg);
8017     }
8018     if (botrsubseg.ss == m->dummysub) {
8019       tsdissolve(botleft);
8020     } else {
8021       tsbond(botleft, botrsubseg);
8022     }
8023     if (toprsubseg.ss == m->dummysub) {
8024       tsdissolve(botright);
8025     } else {
8026       tsbond(botright, toprsubseg);
8027     }
8028   }
8029 
8030   /* New vertex assignments for the rotated quadrilateral. */
8031   setorg(*flipedge, farvertex);
8032   setdest(*flipedge, botvertex);
8033   setapex(*flipedge, rightvertex);
8034   setorg(top, botvertex);
8035   setdest(top, farvertex);
8036   setapex(top, leftvertex);
8037   if (b->verbose > 2) {
8038     printf("  Edge flip results in left ");
8039     printtriangle(m, b, &top);
8040     printf("  and right ");
8041     printtriangle(m, b, flipedge);
8042   }
8043 }
8044 
8045 /*****************************************************************************/
8046 /*                                                                           */
8047 /*  unflip()   Transform two triangles to two different triangles by         */
8048 /*             flipping an edge clockwise within a quadrilateral.  Reverses  */
8049 /*             the flip() operation so that the data structures representing */
8050 /*             the triangles are back where they were before the flip().     */
8051 /*                                                                           */
8052 /*  Imagine the original triangles, abc and bad, oriented so that the        */
8053 /*  shared edge ab lies in a horizontal plane, with the vertex b on the left */
8054 /*  and the vertex a on the right.  The vertex c lies below the edge, and    */
8055 /*  the vertex d lies above the edge.  The `flipedge' handle holds the edge  */
8056 /*  ab of triangle abc, and is directed left, from vertex a to vertex b.     */
8057 /*                                                                           */
8058 /*  The triangles abc and bad are deleted and replaced by the triangles cdb  */
8059 /*  and dca.  The triangles that represent abc and bad are NOT deallocated;  */
8060 /*  they are reused for cdb and dca, respectively.  Hence, any handles that  */
8061 /*  may have held the original triangles are still valid, although not       */
8062 /*  directed as they were before.                                            */
8063 /*                                                                           */
8064 /*  Upon completion of this routine, the `flipedge' handle holds the edge    */
8065 /*  cd of triangle cdb, and is directed up, from vertex c to vertex d.       */
8066 /*  (Hence, the two triangles have rotated clockwise.)                       */
8067 /*                                                                           */
8068 /*  WARNING:  This transformation is geometrically valid only if the         */
8069 /*  quadrilateral adbc is convex.  Furthermore, this transformation is       */
8070 /*  valid only if there is not a subsegment between the triangles abc and    */
8071 /*  bad.  This routine does not check either of these preconditions, and     */
8072 /*  it is the responsibility of the calling routine to ensure that they are  */
8073 /*  met.  If they are not, the streets shall be filled with wailing and      */
8074 /*  gnashing of teeth.                                                       */
8075 /*                                                                           */
8076 /*****************************************************************************/
8077 
8078 #ifdef ANSI_DECLARATORS
8079 void unflip(struct mesh *m, struct behavior *b, struct otri *flipedge)
8080 #else /* not ANSI_DECLARATORS */
8081 void unflip(m, b, flipedge)
8082 struct mesh *m;
8083 struct behavior *b;
8084 struct otri *flipedge;                    /* Handle for the triangle abc. */
8085 #endif /* not ANSI_DECLARATORS */
8086 
8087 {
8088   struct otri botleft, botright;
8089   struct otri topleft, topright;
8090   struct otri top;
8091   struct otri botlcasing, botrcasing;
8092   struct otri toplcasing, toprcasing;
8093   struct osub botlsubseg, botrsubseg;
8094   struct osub toplsubseg, toprsubseg;
8095   vertex leftvertex, rightvertex, botvertex;
8096   vertex farvertex;
8097   triangle ptr;                         /* Temporary variable used by sym(). */
8098   subseg sptr;                      /* Temporary variable used by tspivot(). */
8099 
8100   /* Identify the vertices of the quadrilateral. */
8101   org(*flipedge, rightvertex);
8102   dest(*flipedge, leftvertex);
8103   apex(*flipedge, botvertex);
8104   sym(*flipedge, top);
8105 #ifdef SELF_CHECK
8106   if (top.tri == m->dummytri) {
8107     printf("Internal error in unflip():  Attempt to flip on boundary.\n");
8108     lnextself(*flipedge);
8109     return;
8110   }
8111   if (m->checksegments) {
8112     tspivot(*flipedge, toplsubseg);
8113     if (toplsubseg.ss != m->dummysub) {
8114       printf("Internal error in unflip():  Attempt to flip a subsegment.\n");
8115       lnextself(*flipedge);
8116       return;
8117     }
8118   }
8119 #endif /* SELF_CHECK */
8120   apex(top, farvertex);
8121 
8122   /* Identify the casing of the quadrilateral. */
8123   lprev(top, topleft);
8124   sym(topleft, toplcasing);
8125   lnext(top, topright);
8126   sym(topright, toprcasing);
8127   lnext(*flipedge, botleft);
8128   sym(botleft, botlcasing);
8129   lprev(*flipedge, botright);
8130   sym(botright, botrcasing);
8131   /* Rotate the quadrilateral one-quarter turn clockwise. */
8132   bond(topleft, toprcasing);
8133   bond(botleft, toplcasing);
8134   bond(botright, botlcasing);
8135   bond(topright, botrcasing);
8136 
8137   if (m->checksegments) {
8138     /* Check for subsegments and rebond them to the quadrilateral. */
8139     tspivot(topleft, toplsubseg);
8140     tspivot(botleft, botlsubseg);
8141     tspivot(botright, botrsubseg);
8142     tspivot(topright, toprsubseg);
8143     if (toplsubseg.ss == m->dummysub) {
8144       tsdissolve(botleft);
8145     } else {
8146       tsbond(botleft, toplsubseg);
8147     }
8148     if (botlsubseg.ss == m->dummysub) {
8149       tsdissolve(botright);
8150     } else {
8151       tsbond(botright, botlsubseg);
8152     }
8153     if (botrsubseg.ss == m->dummysub) {
8154       tsdissolve(topright);
8155     } else {
8156       tsbond(topright, botrsubseg);
8157     }
8158     if (toprsubseg.ss == m->dummysub) {
8159       tsdissolve(topleft);
8160     } else {
8161       tsbond(topleft, toprsubseg);
8162     }
8163   }
8164 
8165   /* New vertex assignments for the rotated quadrilateral. */
8166   setorg(*flipedge, botvertex);
8167   setdest(*flipedge, farvertex);
8168   setapex(*flipedge, leftvertex);
8169   setorg(top, farvertex);
8170   setdest(top, botvertex);
8171   setapex(top, rightvertex);
8172   if (b->verbose > 2) {
8173     printf("  Edge unflip results in left ");
8174     printtriangle(m, b, flipedge);
8175     printf("  and right ");
8176     printtriangle(m, b, &top);
8177   }
8178 }
8179 
8180 /*****************************************************************************/
8181 /*                                                                           */
8182 /*  insertvertex()   Insert a vertex into a Delaunay triangulation,          */
8183 /*                   performing flips as necessary to maintain the Delaunay  */
8184 /*                   property.                                               */
8185 /*                                                                           */
8186 /*  The point `insertvertex' is located.  If `searchtri.tri' is not NULL,    */
8187 /*  the search for the containing triangle begins from `searchtri'.  If      */
8188 /*  `searchtri.tri' is NULL, a full point location procedure is called.      */
8189 /*  If `insertvertex' is found inside a triangle, the triangle is split into */
8190 /*  three; if `insertvertex' lies on an edge, the edge is split in two,      */
8191 /*  thereby splitting the two adjacent triangles into four.  Edge flips are  */
8192 /*  used to restore the Delaunay property.  If `insertvertex' lies on an     */
8193 /*  existing vertex, no action is taken, and the value DUPLICATEVERTEX is    */
8194 /*  returned.  On return, `searchtri' is set to a handle whose origin is the */
8195 /*  existing vertex.                                                         */
8196 /*                                                                           */
8197 /*  Normally, the parameter `splitseg' is set to NULL, implying that no      */
8198 /*  subsegment should be split.  In this case, if `insertvertex' is found to */
8199 /*  lie on a segment, no action is taken, and the value VIOLATINGVERTEX is   */
8200 /*  returned.  On return, `searchtri' is set to a handle whose primary edge  */
8201 /*  is the violated subsegment.                                              */
8202 /*                                                                           */
8203 /*  If the calling routine wishes to split a subsegment by inserting a       */
8204 /*  vertex in it, the parameter `splitseg' should be that subsegment.  In    */
8205 /*  this case, `searchtri' MUST be the triangle handle reached by pivoting   */
8206 /*  from that subsegment; no point location is done.                         */
8207 /*                                                                           */
8208 /*  `segmentflaws' and `triflaws' are flags that indicate whether or not     */
8209 /*  there should be checks for the creation of encroached subsegments or bad */
8210 /*  quality triangles.  If a newly inserted vertex encroaches upon           */
8211 /*  subsegments, these subsegments are added to the list of subsegments to   */
8212 /*  be split if `segmentflaws' is set.  If bad triangles are created, these  */
8213 /*  are added to the queue if `triflaws' is set.                             */
8214 /*                                                                           */
8215 /*  If a duplicate vertex or violated segment does not prevent the vertex    */
8216 /*  from being inserted, the return value will be ENCROACHINGVERTEX if the   */
8217 /*  vertex encroaches upon a subsegment (and checking is enabled), or        */
8218 /*  SUCCESSFULVERTEX otherwise.  In either case, `searchtri' is set to a     */
8219 /*  handle whose origin is the newly inserted vertex.                        */
8220 /*                                                                           */
8221 /*  insertvertex() does not use flip() for reasons of speed; some            */
8222 /*  information can be reused from edge flip to edge flip, like the          */
8223 /*  locations of subsegments.                                                */
8224 /*                                                                           */
8225 /*****************************************************************************/
8226 
8227 #ifdef ANSI_DECLARATORS
8228 enum insertvertexresult insertvertex(struct mesh *m, struct behavior *b,
8229                                      vertex newvertex, struct otri *searchtri,
8230                                      struct osub *splitseg,
8231                                      int segmentflaws, int triflaws)
8232 #else /* not ANSI_DECLARATORS */
8233 enum insertvertexresult insertvertex(m, b, newvertex, searchtri, splitseg,
8234                                      segmentflaws, triflaws)
8235 struct mesh *m;
8236 struct behavior *b;
8237 vertex newvertex;
8238 struct otri *searchtri;
8239 struct osub *splitseg;
8240 int segmentflaws;
8241 int triflaws;
8242 #endif /* not ANSI_DECLARATORS */
8243 
8244 {
8245   struct otri horiz;
8246   struct otri top;
8247   struct otri botleft, botright;
8248   struct otri topleft, topright;
8249   struct otri newbotleft, newbotright;
8250   struct otri newtopright;
8251   struct otri botlcasing, botrcasing;
8252   struct otri toplcasing, toprcasing;
8253   struct otri testtri;
8254   struct osub botlsubseg, botrsubseg;
8255   struct osub toplsubseg, toprsubseg;
8256   struct osub brokensubseg;
8257   struct osub checksubseg;
8258   struct osub rightsubseg;
8259   struct osub newsubseg;
8260   struct badsubseg *encroached;
8261   struct flipstacker *newflip;
8262   vertex first;
8263   vertex leftvertex, rightvertex, botvertex, topvertex, farvertex;
8264   vertex segmentorg, segmentdest;
8265   REAL attrib;
8266   REAL area;
8267   enum insertvertexresult success;
8268   enum locateresult intersect;
8269   int doflip;
8270   int mirrorflag;
8271   int enq;
8272   int i;
8273   triangle ptr;                         /* Temporary variable used by sym(). */
8274   subseg sptr;         /* Temporary variable used by spivot() and tspivot(). */
8275 
8276   if (b->verbose > 1) {
8277     printf("  Inserting (%.12g, %.12g).\n", newvertex[0], newvertex[1]);
8278   }
8279 
8280   if (splitseg == (struct osub *) NULL) {
8281     /* Find the location of the vertex to be inserted.  Check if a good */
8282     /*   starting triangle has already been provided by the caller.     */
8283     if (searchtri->tri == m->dummytri) {
8284       /* Find a boundary triangle. */
8285       horiz.tri = m->dummytri;
8286       horiz.orient = 0;
8287       symself(horiz);
8288       /* Search for a triangle containing `newvertex'. */
8289       intersect = locate(m, b, newvertex, &horiz);
8290     } else {
8291       /* Start searching from the triangle provided by the caller. */
8292       otricopy(*searchtri, horiz);
8293       intersect = preciselocate(m, b, newvertex, &horiz, 1);
8294     }
8295   } else {
8296     /* The calling routine provides the subsegment in which */
8297     /*   the vertex is inserted.                             */
8298     otricopy(*searchtri, horiz);
8299     intersect = ONEDGE;
8300   }
8301 
8302   if (intersect == ONVERTEX) {
8303     /* There's already a vertex there.  Return in `searchtri' a triangle */
8304     /*   whose origin is the existing vertex.                            */
8305     otricopy(horiz, *searchtri);
8306     otricopy(horiz, m->recenttri);
8307     return DUPLICATEVERTEX;
8308   }
8309   if ((intersect == ONEDGE) || (intersect == OUTSIDE)) {
8310     /* The vertex falls on an edge or boundary. */
8311     if (m->checksegments && (splitseg == (struct osub *) NULL)) {
8312       /* Check whether the vertex falls on a subsegment. */
8313       tspivot(horiz, brokensubseg);
8314       if (brokensubseg.ss != m->dummysub) {
8315         /* The vertex falls on a subsegment, and hence will not be inserted. */
8316         if (segmentflaws) {
8317           enq = b->nobisect != 2;
8318           if (enq && (b->nobisect == 1)) {
8319             /* This subsegment may be split only if it is an */
8320             /*   internal boundary.                          */
8321             sym(horiz, testtri);
8322             enq = testtri.tri != m->dummytri;
8323           }
8324           if (enq) {
8325             /* Add the subsegment to the list of encroached subsegments. */
8326             encroached = (struct badsubseg *) poolalloc(&m->badsubsegs);
8327             encroached->encsubseg = sencode(brokensubseg);
8328             sorg(brokensubseg, encroached->subsegorg);
8329             sdest(brokensubseg, encroached->subsegdest);
8330             if (b->verbose > 2) {
8331               printf(
8332           "  Queueing encroached subsegment (%.12g, %.12g) (%.12g, %.12g).\n",
8333                      encroached->subsegorg[0], encroached->subsegorg[1],
8334                      encroached->subsegdest[0], encroached->subsegdest[1]);
8335             }
8336           }
8337         }
8338         /* Return a handle whose primary edge contains the vertex, */
8339         /*   which has not been inserted.                          */
8340         otricopy(horiz, *searchtri);
8341         otricopy(horiz, m->recenttri);
8342         return VIOLATINGVERTEX;
8343       }
8344     }
8345 
8346     /* Insert the vertex on an edge, dividing one triangle into two (if */
8347     /*   the edge lies on a boundary) or two triangles into four.       */
8348     lprev(horiz, botright);
8349     sym(botright, botrcasing);
8350     sym(horiz, topright);
8351     /* Is there a second triangle?  (Or does this edge lie on a boundary?) */
8352     mirrorflag = topright.tri != m->dummytri;
8353     if (mirrorflag) {
8354       lnextself(topright);
8355       sym(topright, toprcasing);
8356       maketriangle(m, b, &newtopright);
8357     } else {
8358       /* Splitting a boundary edge increases the number of boundary edges. */
8359       m->hullsize++;
8360     }
8361     maketriangle(m, b, &newbotright);
8362 
8363     /* Set the vertices of changed and new triangles. */
8364     org(horiz, rightvertex);
8365     dest(horiz, leftvertex);
8366     apex(horiz, botvertex);
8367     setorg(newbotright, botvertex);
8368     setdest(newbotright, rightvertex);
8369     setapex(newbotright, newvertex);
8370     setorg(horiz, newvertex);
8371     for (i = 0; i < m->eextras; i++) {
8372       /* Set the element attributes of a new triangle. */
8373       setelemattribute(newbotright, i, elemattribute(botright, i));
8374     }
8375     if (b->vararea) {
8376       /* Set the area constraint of a new triangle. */
8377       setareabound(newbotright, areabound(botright));
8378     }
8379     if (mirrorflag) {
8380       dest(topright, topvertex);
8381       setorg(newtopright, rightvertex);
8382       setdest(newtopright, topvertex);
8383       setapex(newtopright, newvertex);
8384       setorg(topright, newvertex);
8385       for (i = 0; i < m->eextras; i++) {
8386         /* Set the element attributes of another new triangle. */
8387         setelemattribute(newtopright, i, elemattribute(topright, i));
8388       }
8389       if (b->vararea) {
8390         /* Set the area constraint of another new triangle. */
8391         setareabound(newtopright, areabound(topright));
8392       }
8393     }
8394 
8395     /* There may be subsegments that need to be bonded */
8396     /*   to the new triangle(s).                       */
8397     if (m->checksegments) {
8398       tspivot(botright, botrsubseg);
8399       if (botrsubseg.ss != m->dummysub) {
8400         tsdissolve(botright);
8401         tsbond(newbotright, botrsubseg);
8402       }
8403       if (mirrorflag) {
8404         tspivot(topright, toprsubseg);
8405         if (toprsubseg.ss != m->dummysub) {
8406           tsdissolve(topright);
8407           tsbond(newtopright, toprsubseg);
8408         }
8409       }
8410     }
8411 
8412     /* Bond the new triangle(s) to the surrounding triangles. */
8413     bond(newbotright, botrcasing);
8414     lprevself(newbotright);
8415     bond(newbotright, botright);
8416     lprevself(newbotright);
8417     if (mirrorflag) {
8418       bond(newtopright, toprcasing);
8419       lnextself(newtopright);
8420       bond(newtopright, topright);
8421       lnextself(newtopright);
8422       bond(newtopright, newbotright);
8423     }
8424 
8425     if (splitseg != (struct osub *) NULL) {
8426       /* Split the subsegment into two. */
8427       setsdest(*splitseg, newvertex);
8428       segorg(*splitseg, segmentorg);
8429       segdest(*splitseg, segmentdest);
8430       ssymself(*splitseg);
8431       spivot(*splitseg, rightsubseg);
8432       insertsubseg(m, b, &newbotright, mark(*splitseg));
8433       tspivot(newbotright, newsubseg);
8434       setsegorg(newsubseg, segmentorg);
8435       setsegdest(newsubseg, segmentdest);
8436       sbond(*splitseg, newsubseg);
8437       ssymself(newsubseg);
8438       sbond(newsubseg, rightsubseg);
8439       ssymself(*splitseg);
8440       /* Transfer the subsegment's boundary marker to the vertex */
8441       /*   if required.                                          */
8442       if (vertexmark(newvertex) == 0) {
8443         setvertexmark(newvertex, mark(*splitseg));
8444       }
8445     }
8446 
8447     if (m->checkquality) {
8448       poolrestart(&m->flipstackers);
8449       m->lastflip = (struct flipstacker *) poolalloc(&m->flipstackers);
8450       m->lastflip->flippedtri = encode(horiz);
8451       m->lastflip->prevflip = (struct flipstacker *) &insertvertex;
8452     }
8453 
8454 #ifdef SELF_CHECK
8455     if (counterclockwise(m, b, rightvertex, leftvertex, botvertex) < 0.0) {
8456       printf("Internal error in insertvertex():\n");
8457       printf(
8458             "  Clockwise triangle prior to edge vertex insertion (bottom).\n");
8459     }
8460     if (mirrorflag) {
8461       if (counterclockwise(m, b, leftvertex, rightvertex, topvertex) < 0.0) {
8462         printf("Internal error in insertvertex():\n");
8463         printf("  Clockwise triangle prior to edge vertex insertion (top).\n");
8464       }
8465       if (counterclockwise(m, b, rightvertex, topvertex, newvertex) < 0.0) {
8466         printf("Internal error in insertvertex():\n");
8467         printf(
8468             "  Clockwise triangle after edge vertex insertion (top right).\n");
8469       }
8470       if (counterclockwise(m, b, topvertex, leftvertex, newvertex) < 0.0) {
8471         printf("Internal error in insertvertex():\n");
8472         printf(
8473             "  Clockwise triangle after edge vertex insertion (top left).\n");
8474       }
8475     }
8476     if (counterclockwise(m, b, leftvertex, botvertex, newvertex) < 0.0) {
8477       printf("Internal error in insertvertex():\n");
8478       printf(
8479           "  Clockwise triangle after edge vertex insertion (bottom left).\n");
8480     }
8481     if (counterclockwise(m, b, botvertex, rightvertex, newvertex) < 0.0) {
8482       printf("Internal error in insertvertex():\n");
8483       printf(
8484         "  Clockwise triangle after edge vertex insertion (bottom right).\n");
8485     }
8486 #endif /* SELF_CHECK */
8487     if (b->verbose > 2) {
8488       printf("  Updating bottom left ");
8489       printtriangle(m, b, &botright);
8490       if (mirrorflag) {
8491         printf("  Updating top left ");
8492         printtriangle(m, b, &topright);
8493         printf("  Creating top right ");
8494         printtriangle(m, b, &newtopright);
8495       }
8496       printf("  Creating bottom right ");
8497       printtriangle(m, b, &newbotright);
8498     }
8499 
8500     /* Position `horiz' on the first edge to check for */
8501     /*   the Delaunay property.                        */
8502     lnextself(horiz);
8503   } else {
8504     /* Insert the vertex in a triangle, splitting it into three. */
8505     lnext(horiz, botleft);
8506     lprev(horiz, botright);
8507     sym(botleft, botlcasing);
8508     sym(botright, botrcasing);
8509     maketriangle(m, b, &newbotleft);
8510     maketriangle(m, b, &newbotright);
8511 
8512     /* Set the vertices of changed and new triangles. */
8513     org(horiz, rightvertex);
8514     dest(horiz, leftvertex);
8515     apex(horiz, botvertex);
8516     setorg(newbotleft, leftvertex);
8517     setdest(newbotleft, botvertex);
8518     setapex(newbotleft, newvertex);
8519     setorg(newbotright, botvertex);
8520     setdest(newbotright, rightvertex);
8521     setapex(newbotright, newvertex);
8522     setapex(horiz, newvertex);
8523     for (i = 0; i < m->eextras; i++) {
8524       /* Set the element attributes of the new triangles. */
8525       attrib = elemattribute(horiz, i);
8526       setelemattribute(newbotleft, i, attrib);
8527       setelemattribute(newbotright, i, attrib);
8528     }
8529     if (b->vararea) {
8530       /* Set the area constraint of the new triangles. */
8531       area = areabound(horiz);
8532       setareabound(newbotleft, area);
8533       setareabound(newbotright, area);
8534     }
8535 
8536     /* There may be subsegments that need to be bonded */
8537     /*   to the new triangles.                         */
8538     if (m->checksegments) {
8539       tspivot(botleft, botlsubseg);
8540       if (botlsubseg.ss != m->dummysub) {
8541         tsdissolve(botleft);
8542         tsbond(newbotleft, botlsubseg);
8543       }
8544       tspivot(botright, botrsubseg);
8545       if (botrsubseg.ss != m->dummysub) {
8546         tsdissolve(botright);
8547         tsbond(newbotright, botrsubseg);
8548       }
8549     }
8550 
8551     /* Bond the new triangles to the surrounding triangles. */
8552     bond(newbotleft, botlcasing);
8553     bond(newbotright, botrcasing);
8554     lnextself(newbotleft);
8555     lprevself(newbotright);
8556     bond(newbotleft, newbotright);
8557     lnextself(newbotleft);
8558     bond(botleft, newbotleft);
8559     lprevself(newbotright);
8560     bond(botright, newbotright);
8561 
8562     if (m->checkquality) {
8563       poolrestart(&m->flipstackers);
8564       m->lastflip = (struct flipstacker *) poolalloc(&m->flipstackers);
8565       m->lastflip->flippedtri = encode(horiz);
8566       m->lastflip->prevflip = (struct flipstacker *) NULL;
8567     }
8568 
8569 #ifdef SELF_CHECK
8570     if (counterclockwise(m, b, rightvertex, leftvertex, botvertex) < 0.0) {
8571       printf("Internal error in insertvertex():\n");
8572       printf("  Clockwise triangle prior to vertex insertion.\n");
8573     }
8574     if (counterclockwise(m, b, rightvertex, leftvertex, newvertex) < 0.0) {
8575       printf("Internal error in insertvertex():\n");
8576       printf("  Clockwise triangle after vertex insertion (top).\n");
8577     }
8578     if (counterclockwise(m, b, leftvertex, botvertex, newvertex) < 0.0) {
8579       printf("Internal error in insertvertex():\n");
8580       printf("  Clockwise triangle after vertex insertion (left).\n");
8581     }
8582     if (counterclockwise(m, b, botvertex, rightvertex, newvertex) < 0.0) {
8583       printf("Internal error in insertvertex():\n");
8584       printf("  Clockwise triangle after vertex insertion (right).\n");
8585     }
8586 #endif /* SELF_CHECK */
8587     if (b->verbose > 2) {
8588       printf("  Updating top ");
8589       printtriangle(m, b, &horiz);
8590       printf("  Creating left ");
8591       printtriangle(m, b, &newbotleft);
8592       printf("  Creating right ");
8593       printtriangle(m, b, &newbotright);
8594     }
8595   }
8596 
8597   /* The insertion is successful by default, unless an encroached */
8598   /*   subsegment is found.                                       */
8599   success = SUCCESSFULVERTEX;
8600   /* Circle around the newly inserted vertex, checking each edge opposite */
8601   /*   it for the Delaunay property.  Non-Delaunay edges are flipped.     */
8602   /*   `horiz' is always the edge being checked.  `first' marks where to  */
8603   /*   stop circling.                                                     */
8604   org(horiz, first);
8605   rightvertex = first;
8606   dest(horiz, leftvertex);
8607   /* Circle until finished. */
8608   while (1) {
8609     /* By default, the edge will be flipped. */
8610     doflip = 1;
8611 
8612     if (m->checksegments) {
8613       /* Check for a subsegment, which cannot be flipped. */
8614       tspivot(horiz, checksubseg);
8615       if (checksubseg.ss != m->dummysub) {
8616         /* The edge is a subsegment and cannot be flipped. */
8617         doflip = 0;
8618 #ifndef CDT_ONLY
8619         if (segmentflaws) {
8620           /* Does the new vertex encroach upon this subsegment? */
8621           if (checkseg4encroach(m, b, &checksubseg)) {
8622             success = ENCROACHINGVERTEX;
8623           }
8624         }
8625 #endif /* not CDT_ONLY */
8626       }
8627     }
8628 
8629     if (doflip) {
8630       /* Check if the edge is a boundary edge. */
8631       sym(horiz, top);
8632       if (top.tri == m->dummytri) {
8633         /* The edge is a boundary edge and cannot be flipped. */
8634         doflip = 0;
8635       } else {
8636         /* Find the vertex on the other side of the edge. */
8637         apex(top, farvertex);
8638         /* In the incremental Delaunay triangulation algorithm, any of      */
8639         /*   `leftvertex', `rightvertex', and `farvertex' could be vertices */
8640         /*   of the triangular bounding box.  These vertices must be        */
8641         /*   treated as if they are infinitely distant, even though their   */
8642         /*   "coordinates" are not.                                         */
8643         if ((leftvertex == m->infvertex1) || (leftvertex == m->infvertex2) ||
8644             (leftvertex == m->infvertex3)) {
8645           /* `leftvertex' is infinitely distant.  Check the convexity of  */
8646           /*   the boundary of the triangulation.  'farvertex' might be   */
8647           /*   infinite as well, but trust me, this same condition should */
8648           /*   be applied.                                                */
8649           doflip = counterclockwise(m, b, newvertex, rightvertex, farvertex)
8650                    > 0.0;
8651         } else if ((rightvertex == m->infvertex1) ||
8652                    (rightvertex == m->infvertex2) ||
8653                    (rightvertex == m->infvertex3)) {
8654           /* `rightvertex' is infinitely distant.  Check the convexity of */
8655           /*   the boundary of the triangulation.  'farvertex' might be   */
8656           /*   infinite as well, but trust me, this same condition should */
8657           /*   be applied.                                                */
8658           doflip = counterclockwise(m, b, farvertex, leftvertex, newvertex)
8659                    > 0.0;
8660         } else if ((farvertex == m->infvertex1) ||
8661                    (farvertex == m->infvertex2) ||
8662                    (farvertex == m->infvertex3)) {
8663           /* `farvertex' is infinitely distant and cannot be inside */
8664           /*   the circumcircle of the triangle `horiz'.            */
8665           doflip = 0;
8666         } else {
8667           /* Test whether the edge is locally Delaunay. */
8668           doflip = incircle(m, b, leftvertex, newvertex, rightvertex,
8669                             farvertex) > 0.0;
8670         }
8671         if (doflip) {
8672           /* We made it!  Flip the edge `horiz' by rotating its containing */
8673           /*   quadrilateral (the two triangles adjacent to `horiz').      */
8674           /* Identify the casing of the quadrilateral. */
8675           lprev(top, topleft);
8676           sym(topleft, toplcasing);
8677           lnext(top, topright);
8678           sym(topright, toprcasing);
8679           lnext(horiz, botleft);
8680           sym(botleft, botlcasing);
8681           lprev(horiz, botright);
8682           sym(botright, botrcasing);
8683           /* Rotate the quadrilateral one-quarter turn counterclockwise. */
8684           bond(topleft, botlcasing);
8685           bond(botleft, botrcasing);
8686           bond(botright, toprcasing);
8687           bond(topright, toplcasing);
8688           if (m->checksegments) {
8689             /* Check for subsegments and rebond them to the quadrilateral. */
8690             tspivot(topleft, toplsubseg);
8691             tspivot(botleft, botlsubseg);
8692             tspivot(botright, botrsubseg);
8693             tspivot(topright, toprsubseg);
8694             if (toplsubseg.ss == m->dummysub) {
8695               tsdissolve(topright);
8696             } else {
8697               tsbond(topright, toplsubseg);
8698             }
8699             if (botlsubseg.ss == m->dummysub) {
8700               tsdissolve(topleft);
8701             } else {
8702               tsbond(topleft, botlsubseg);
8703             }
8704             if (botrsubseg.ss == m->dummysub) {
8705               tsdissolve(botleft);
8706             } else {
8707               tsbond(botleft, botrsubseg);
8708             }
8709             if (toprsubseg.ss == m->dummysub) {
8710               tsdissolve(botright);
8711             } else {
8712               tsbond(botright, toprsubseg);
8713             }
8714           }
8715           /* New vertex assignments for the rotated quadrilateral. */
8716           setorg(horiz, farvertex);
8717           setdest(horiz, newvertex);
8718           setapex(horiz, rightvertex);
8719           setorg(top, newvertex);
8720           setdest(top, farvertex);
8721           setapex(top, leftvertex);
8722           for (i = 0; i < m->eextras; i++) {
8723             /* Take the average of the two triangles' attributes. */
8724             attrib = 0.5 * (elemattribute(top, i) + elemattribute(horiz, i));
8725             setelemattribute(top, i, attrib);
8726             setelemattribute(horiz, i, attrib);
8727           }
8728           if (b->vararea) {
8729             if ((areabound(top) <= 0.0) || (areabound(horiz) <= 0.0)) {
8730               area = -1.0;
8731             } else {
8732               /* Take the average of the two triangles' area constraints.    */
8733               /*   This prevents small area constraints from migrating a     */
8734               /*   long, long way from their original location due to flips. */
8735               area = 0.5 * (areabound(top) + areabound(horiz));
8736             }
8737             setareabound(top, area);
8738             setareabound(horiz, area);
8739           }
8740 
8741           if (m->checkquality) {
8742             newflip = (struct flipstacker *) poolalloc(&m->flipstackers);
8743             newflip->flippedtri = encode(horiz);
8744             newflip->prevflip = m->lastflip;
8745             m->lastflip = newflip;
8746           }
8747 
8748 #ifdef SELF_CHECK
8749           if (newvertex != (vertex) NULL) {
8750             if (counterclockwise(m, b, leftvertex, newvertex, rightvertex) <
8751                 0.0) {
8752               printf("Internal error in insertvertex():\n");
8753               printf("  Clockwise triangle prior to edge flip (bottom).\n");
8754             }
8755             /* The following test has been removed because constrainededge() */
8756             /*   sometimes generates inverted triangles that insertvertex()  */
8757             /*   removes.                                                    */
8758 /*
8759             if (counterclockwise(m, b, rightvertex, farvertex, leftvertex) <
8760                 0.0) {
8761               printf("Internal error in insertvertex():\n");
8762               printf("  Clockwise triangle prior to edge flip (top).\n");
8763             }
8764 */
8765             if (counterclockwise(m, b, farvertex, leftvertex, newvertex) <
8766                 0.0) {
8767               printf("Internal error in insertvertex():\n");
8768               printf("  Clockwise triangle after edge flip (left).\n");
8769             }
8770             if (counterclockwise(m, b, newvertex, rightvertex, farvertex) <
8771                 0.0) {
8772               printf("Internal error in insertvertex():\n");
8773               printf("  Clockwise triangle after edge flip (right).\n");
8774             }
8775           }
8776 #endif /* SELF_CHECK */
8777           if (b->verbose > 2) {
8778             printf("  Edge flip results in left ");
8779             lnextself(topleft);
8780             printtriangle(m, b, &topleft);
8781             printf("  and right ");
8782             printtriangle(m, b, &horiz);
8783           }
8784           /* On the next iterations, consider the two edges that were  */
8785           /*   exposed (this is, are now visible to the newly inserted */
8786           /*   vertex) by the edge flip.                               */
8787           lprevself(horiz);
8788           leftvertex = farvertex;
8789         }
8790       }
8791     }
8792     if (!doflip) {
8793       /* The handle `horiz' is accepted as locally Delaunay. */
8794 #ifndef CDT_ONLY
8795       if (triflaws) {
8796         /* Check the triangle `horiz' for quality. */
8797         testtriangle(m, b, &horiz);
8798       }
8799 #endif /* not CDT_ONLY */
8800       /* Look for the next edge around the newly inserted vertex. */
8801       lnextself(horiz);
8802       sym(horiz, testtri);
8803       /* Check for finishing a complete revolution about the new vertex, or */
8804       /*   falling outside  of the triangulation.  The latter will happen   */
8805       /*   when a vertex is inserted at a boundary.                         */
8806       if ((leftvertex == first) || (testtri.tri == m->dummytri)) {
8807         /* We're done.  Return a triangle whose origin is the new vertex. */
8808         lnext(horiz, *searchtri);
8809         lnext(horiz, m->recenttri);
8810         return success;
8811       }
8812       /* Finish finding the next edge around the newly inserted vertex. */
8813       lnext(testtri, horiz);
8814       rightvertex = leftvertex;
8815       dest(horiz, leftvertex);
8816     }
8817   }
8818 }
8819 
8820 /*****************************************************************************/
8821 /*                                                                           */
8822 /*  triangulatepolygon()   Find the Delaunay triangulation of a polygon that */
8823 /*                         has a certain "nice" shape.  This includes the    */
8824 /*                         polygons that result from deletion of a vertex or */
8825 /*                         insertion of a segment.                           */
8826 /*                                                                           */
8827 /*  This is a conceptually difficult routine.  The starting assumption is    */
8828 /*  that we have a polygon with n sides.  n - 1 of these sides are currently */
8829 /*  represented as edges in the mesh.  One side, called the "base", need not */
8830 /*  be.                                                                      */
8831 /*                                                                           */
8832 /*  Inside the polygon is a structure I call a "fan", consisting of n - 1    */
8833 /*  triangles that share a common origin.  For each of these triangles, the  */
8834 /*  edge opposite the origin is one of the sides of the polygon.  The        */
8835 /*  primary edge of each triangle is the edge directed from the origin to    */
8836 /*  the destination; note that this is not the same edge that is a side of   */
8837 /*  the polygon.  `firstedge' is the primary edge of the first triangle.     */
8838 /*  From there, the triangles follow in counterclockwise order about the     */
8839 /*  polygon, until `lastedge', the primary edge of the last triangle.        */
8840 /*  `firstedge' and `lastedge' are probably connected to other triangles     */
8841 /*  beyond the extremes of the fan, but their identity is not important, as  */
8842 /*  long as the fan remains connected to them.                               */
8843 /*                                                                           */
8844 /*  Imagine the polygon oriented so that its base is at the bottom.  This    */
8845 /*  puts `firstedge' on the far right, and `lastedge' on the far left.       */
8846 /*  The right vertex of the base is the destination of `firstedge', and the  */
8847 /*  left vertex of the base is the apex of `lastedge'.                       */
8848 /*                                                                           */
8849 /*  The challenge now is to find the right sequence of edge flips to         */
8850 /*  transform the fan into a Delaunay triangulation of the polygon.  Each    */
8851 /*  edge flip effectively removes one triangle from the fan, committing it   */
8852 /*  to the polygon.  The resulting polygon has one fewer edge.  If `doflip'  */
8853 /*  is set, the final flip will be performed, resulting in a fan of one      */
8854 /*  (useless?) triangle.  If `doflip' is not set, the final flip is not      */
8855 /*  performed, resulting in a fan of two triangles, and an unfinished        */
8856 /*  triangular polygon that is not yet filled out with a single triangle.    */
8857 /*  On completion of the routine, `lastedge' is the last remaining triangle, */
8858 /*  or the leftmost of the last two.                                         */
8859 /*                                                                           */
8860 /*  Although the flips are performed in the order described above, the       */
8861 /*  decisions about what flips to perform are made in precisely the reverse  */
8862 /*  order.  The recursive triangulatepolygon() procedure makes a decision,   */
8863 /*  uses up to two recursive calls to triangulate the "subproblems"          */
8864 /*  (polygons with fewer edges), and then performs an edge flip.             */
8865 /*                                                                           */
8866 /*  The "decision" it makes is which vertex of the polygon should be         */
8867 /*  connected to the base.  This decision is made by testing every possible  */
8868 /*  vertex.  Once the best vertex is found, the two edges that connect this  */
8869 /*  vertex to the base become the bases for two smaller polygons.  These     */
8870 /*  are triangulated recursively.  Unfortunately, this approach can take     */
8871 /*  O(n^2) time not only in the worst case, but in many common cases.  It's  */
8872 /*  rarely a big deal for vertex deletion, where n is rarely larger than     */
8873 /*  ten, but it could be a big deal for segment insertion, especially if     */
8874 /*  there's a lot of long segments that each cut many triangles.  I ought to */
8875 /*  code a faster algorithm some day.                                        */
8876 /*                                                                           */
8877 /*  The `edgecount' parameter is the number of sides of the polygon,         */
8878 /*  including its base.  `triflaws' is a flag that determines whether the    */
8879 /*  new triangles should be tested for quality, and enqueued if they are     */
8880 /*  bad.                                                                     */
8881 /*                                                                           */
8882 /*****************************************************************************/
8883 
8884 #ifdef ANSI_DECLARATORS
8885 void triangulatepolygon(struct mesh *m, struct behavior *b,
8886                         struct otri *firstedge, struct otri *lastedge,
8887                         int edgecount, int doflip, int triflaws)
8888 #else /* not ANSI_DECLARATORS */
8889 void triangulatepolygon(m, b, firstedge, lastedge, edgecount, doflip, triflaws)
8890 struct mesh *m;
8891 struct behavior *b;
8892 struct otri *firstedge;
8893 struct otri *lastedge;
8894 int edgecount;
8895 int doflip;
8896 int triflaws;
8897 #endif /* not ANSI_DECLARATORS */
8898 
8899 {
8900   struct otri testtri;
8901   struct otri besttri;
8902   struct otri tempedge;
8903   vertex leftbasevertex, rightbasevertex;
8904   vertex testvertex;
8905   vertex bestvertex;
8906   int bestnumber;
8907   int i;
8908   triangle ptr;   /* Temporary variable used by sym(), onext(), and oprev(). */
8909 
8910   /* Identify the base vertices. */
8911   apex(*lastedge, leftbasevertex);
8912   dest(*firstedge, rightbasevertex);
8913   if (b->verbose > 2) {
8914     printf("  Triangulating interior polygon at edge\n");
8915     printf("    (%.12g, %.12g) (%.12g, %.12g)\n", leftbasevertex[0],
8916            leftbasevertex[1], rightbasevertex[0], rightbasevertex[1]);
8917   }
8918   /* Find the best vertex to connect the base to. */
8919   onext(*firstedge, besttri);
8920   dest(besttri, bestvertex);
8921   otricopy(besttri, testtri);
8922   bestnumber = 1;
8923   for (i = 2; i <= edgecount - 2; i++) {
8924     onextself(testtri);
8925     dest(testtri, testvertex);
8926     /* Is this a better vertex? */
8927     if (incircle(m, b, leftbasevertex, rightbasevertex, bestvertex,
8928                  testvertex) > 0.0) {
8929       otricopy(testtri, besttri);
8930       bestvertex = testvertex;
8931       bestnumber = i;
8932     }
8933   }
8934   if (b->verbose > 2) {
8935     printf("    Connecting edge to (%.12g, %.12g)\n", bestvertex[0],
8936            bestvertex[1]);
8937   }
8938   if (bestnumber > 1) {
8939     /* Recursively triangulate the smaller polygon on the right. */
8940     oprev(besttri, tempedge);
8941     triangulatepolygon(m, b, firstedge, &tempedge, bestnumber + 1, 1,
8942                        triflaws);
8943   }
8944   if (bestnumber < edgecount - 2) {
8945     /* Recursively triangulate the smaller polygon on the left. */
8946     sym(besttri, tempedge);
8947     triangulatepolygon(m, b, &besttri, lastedge, edgecount - bestnumber, 1,
8948                        triflaws);
8949     /* Find `besttri' again; it may have been lost to edge flips. */
8950     sym(tempedge, besttri);
8951   }
8952   if (doflip) {
8953     /* Do one final edge flip. */
8954     flip(m, b, &besttri);
8955 #ifndef CDT_ONLY
8956     if (triflaws) {
8957       /* Check the quality of the newly committed triangle. */
8958       sym(besttri, testtri);
8959       testtriangle(m, b, &testtri);
8960     }
8961 #endif /* not CDT_ONLY */
8962   }
8963   /* Return the base triangle. */
8964   otricopy(besttri, *lastedge);
8965 }
8966 
8967 /*****************************************************************************/
8968 /*                                                                           */
8969 /*  deletevertex()   Delete a vertex from a Delaunay triangulation, ensuring */
8970 /*                   that the triangulation remains Delaunay.                */
8971 /*                                                                           */
8972 /*  The origin of `deltri' is deleted.  The union of the triangles adjacent  */
8973 /*  to this vertex is a polygon, for which the Delaunay triangulation is     */
8974 /*  found.  Two triangles are removed from the mesh.                         */
8975 /*                                                                           */
8976 /*  Only interior vertices that do not lie on segments or boundaries may be  */
8977 /*  deleted.                                                                 */
8978 /*                                                                           */
8979 /*****************************************************************************/
8980 
8981 #ifndef CDT_ONLY
8982 
8983 #ifdef ANSI_DECLARATORS
8984 void deletevertex(struct mesh *m, struct behavior *b, struct otri *deltri)
8985 #else /* not ANSI_DECLARATORS */
8986 void deletevertex(m, b, deltri)
8987 struct mesh *m;
8988 struct behavior *b;
8989 struct otri *deltri;
8990 #endif /* not ANSI_DECLARATORS */
8991 
8992 {
8993   struct otri countingtri;
8994   struct otri firstedge, lastedge;
8995   struct otri deltriright;
8996   struct otri lefttri, righttri;
8997   struct otri leftcasing, rightcasing;
8998   struct osub leftsubseg, rightsubseg;
8999   vertex delvertex;
9000   vertex neworg;
9001   int edgecount;
9002   triangle ptr;   /* Temporary variable used by sym(), onext(), and oprev(). */
9003   subseg sptr;                      /* Temporary variable used by tspivot(). */
9004 
9005   org(*deltri, delvertex);
9006   if (b->verbose > 1) {
9007     printf("  Deleting (%.12g, %.12g).\n", delvertex[0], delvertex[1]);
9008   }
9009   vertexdealloc(m, delvertex);
9010 
9011   /* Count the degree of the vertex being deleted. */
9012   onext(*deltri, countingtri);
9013   edgecount = 1;
9014   while (!otriequal(*deltri, countingtri)) {
9015 #ifdef SELF_CHECK
9016     if (countingtri.tri == m->dummytri) {
9017       printf("Internal error in deletevertex():\n");
9018       printf("  Attempt to delete boundary vertex.\n");
9019       internalerror();
9020     }
9021 #endif /* SELF_CHECK */
9022     edgecount++;
9023     onextself(countingtri);
9024   }
9025 
9026 #ifdef SELF_CHECK
9027   if (edgecount < 3) {
9028     printf("Internal error in deletevertex():\n  Vertex has degree %d.\n",
9029            edgecount);
9030     internalerror();
9031   }
9032 #endif /* SELF_CHECK */
9033   if (edgecount > 3) {
9034     /* Triangulate the polygon defined by the union of all triangles */
9035     /*   adjacent to the vertex being deleted.  Check the quality of */
9036     /*   the resulting triangles.                                    */
9037     onext(*deltri, firstedge);
9038     oprev(*deltri, lastedge);
9039     triangulatepolygon(m, b, &firstedge, &lastedge, edgecount, 0,
9040                        !b->nobisect);
9041   }
9042   /* Splice out two triangles. */
9043   lprev(*deltri, deltriright);
9044   dnext(*deltri, lefttri);
9045   sym(lefttri, leftcasing);
9046   oprev(deltriright, righttri);
9047   sym(righttri, rightcasing);
9048   bond(*deltri, leftcasing);
9049   bond(deltriright, rightcasing);
9050   tspivot(lefttri, leftsubseg);
9051   if (leftsubseg.ss != m->dummysub) {
9052     tsbond(*deltri, leftsubseg);
9053   }
9054   tspivot(righttri, rightsubseg);
9055   if (rightsubseg.ss != m->dummysub) {
9056     tsbond(deltriright, rightsubseg);
9057   }
9058 
9059   /* Set the new origin of `deltri' and check its quality. */
9060   org(lefttri, neworg);
9061   setorg(*deltri, neworg);
9062   if (!b->nobisect) {
9063     testtriangle(m, b, deltri);
9064   }
9065 
9066   /* Delete the two spliced-out triangles. */
9067   triangledealloc(m, lefttri.tri);
9068   triangledealloc(m, righttri.tri);
9069 }
9070 
9071 #endif /* not CDT_ONLY */
9072 
9073 /*****************************************************************************/
9074 /*                                                                           */
9075 /*  undovertex()   Undo the most recent vertex insertion.                    */
9076 /*                                                                           */
9077 /*  Walks through the list of transformations (flips and a vertex insertion) */
9078 /*  in the reverse of the order in which they were done, and undoes them.    */
9079 /*  The inserted vertex is removed from the triangulation and deallocated.   */
9080 /*  Two triangles (possibly just one) are also deallocated.                  */
9081 /*                                                                           */
9082 /*****************************************************************************/
9083 
9084 #ifndef CDT_ONLY
9085 
9086 #ifdef ANSI_DECLARATORS
9087 void undovertex(struct mesh *m, struct behavior *b)
9088 #else /* not ANSI_DECLARATORS */
9089 void undovertex(m, b)
9090 struct mesh *m;
9091 struct behavior *b;
9092 #endif /* not ANSI_DECLARATORS */
9093 
9094 {
9095   struct otri fliptri;
9096   struct otri botleft, botright, topright;
9097   struct otri botlcasing, botrcasing, toprcasing;
9098   struct otri gluetri;
9099   struct osub botlsubseg, botrsubseg, toprsubseg;
9100   vertex botvertex, rightvertex;
9101   triangle ptr;                         /* Temporary variable used by sym(). */
9102   subseg sptr;                      /* Temporary variable used by tspivot(). */
9103 
9104   /* Walk through the list of transformations (flips and a vertex insertion) */
9105   /*   in the reverse of the order in which they were done, and undo them.   */
9106   while (m->lastflip != (struct flipstacker *) NULL) {
9107     /* Find a triangle involved in the last unreversed transformation. */
9108     decode(m->lastflip->flippedtri, fliptri);
9109 
9110     /* We are reversing one of three transformations:  a trisection of one */
9111     /*   triangle into three (by inserting a vertex in the triangle), a    */
9112     /*   bisection of two triangles into four (by inserting a vertex in an */
9113     /*   edge), or an edge flip.                                           */
9114     if (m->lastflip->prevflip == (struct flipstacker *) NULL) {
9115       /* Restore a triangle that was split into three triangles, */
9116       /*   so it is again one triangle.                          */
9117       dprev(fliptri, botleft);
9118       lnextself(botleft);
9119       onext(fliptri, botright);
9120       lprevself(botright);
9121       sym(botleft, botlcasing);
9122       sym(botright, botrcasing);
9123       dest(botleft, botvertex);
9124 
9125       setapex(fliptri, botvertex);
9126       lnextself(fliptri);
9127       bond(fliptri, botlcasing);
9128       tspivot(botleft, botlsubseg);
9129       tsbond(fliptri, botlsubseg);
9130       lnextself(fliptri);
9131       bond(fliptri, botrcasing);
9132       tspivot(botright, botrsubseg);
9133       tsbond(fliptri, botrsubseg);
9134 
9135       /* Delete the two spliced-out triangles. */
9136       triangledealloc(m, botleft.tri);
9137       triangledealloc(m, botright.tri);
9138     } else if (m->lastflip->prevflip == (struct flipstacker *) &insertvertex) {
9139       /* Restore two triangles that were split into four triangles, */
9140       /*   so they are again two triangles.                         */
9141       lprev(fliptri, gluetri);
9142       sym(gluetri, botright);
9143       lnextself(botright);
9144       sym(botright, botrcasing);
9145       dest(botright, rightvertex);
9146 
9147       setorg(fliptri, rightvertex);
9148       bond(gluetri, botrcasing);
9149       tspivot(botright, botrsubseg);
9150       tsbond(gluetri, botrsubseg);
9151 
9152       /* Delete the spliced-out triangle. */
9153       triangledealloc(m, botright.tri);
9154 
9155       sym(fliptri, gluetri);
9156       if (gluetri.tri != m->dummytri) {
9157         lnextself(gluetri);
9158         dnext(gluetri, topright);
9159         sym(topright, toprcasing);
9160 
9161         setorg(gluetri, rightvertex);
9162         bond(gluetri, toprcasing);
9163         tspivot(topright, toprsubseg);
9164         tsbond(gluetri, toprsubseg);
9165 
9166         /* Delete the spliced-out triangle. */
9167         triangledealloc(m, topright.tri);
9168       }
9169 
9170       /* This is the end of the list, sneakily encoded. */
9171       m->lastflip->prevflip = (struct flipstacker *) NULL;
9172     } else {
9173       /* Undo an edge flip. */
9174       unflip(m, b, &fliptri);
9175     }
9176 
9177     /* Go on and process the next transformation. */
9178     m->lastflip = m->lastflip->prevflip;
9179   }
9180 }
9181 
9182 #endif /* not CDT_ONLY */
9183 
9184 /**                                                                         **/
9185 /**                                                                         **/
9186 /********* Mesh transformation routines end here                     *********/
9187 
9188 /********* Divide-and-conquer Delaunay triangulation begins here     *********/
9189 /**                                                                         **/
9190 /**                                                                         **/
9191 
9192 /*****************************************************************************/
9193 /*                                                                           */
9194 /*  The divide-and-conquer bounding box                                      */
9195 /*                                                                           */
9196 /*  I originally implemented the divide-and-conquer and incremental Delaunay */
9197 /*  triangulations using the edge-based data structure presented by Guibas   */
9198 /*  and Stolfi.  Switching to a triangle-based data structure doubled the    */
9199 /*  speed.  However, I had to think of a few extra tricks to maintain the    */
9200 /*  elegance of the original algorithms.                                     */
9201 /*                                                                           */
9202 /*  The "bounding box" used by my variant of the divide-and-conquer          */
9203 /*  algorithm uses one triangle for each edge of the convex hull of the      */
9204 /*  triangulation.  These bounding triangles all share a common apical       */
9205 /*  vertex, which is represented by NULL and which represents nothing.       */
9206 /*  The bounding triangles are linked in a circular fan about this NULL      */
9207 /*  vertex, and the edges on the convex hull of the triangulation appear     */
9208 /*  opposite the NULL vertex.  You might find it easiest to imagine that     */
9209 /*  the NULL vertex is a point in 3D space behind the center of the          */
9210 /*  triangulation, and that the bounding triangles form a sort of cone.      */
9211 /*                                                                           */
9212 /*  This bounding box makes it easy to represent degenerate cases.  For      */
9213 /*  instance, the triangulation of two vertices is a single edge.  This edge */
9214 /*  is represented by two bounding box triangles, one on each "side" of the  */
9215 /*  edge.  These triangles are also linked together in a fan about the NULL  */
9216 /*  vertex.                                                                  */
9217 /*                                                                           */
9218 /*  The bounding box also makes it easy to traverse the convex hull, as the  */
9219 /*  divide-and-conquer algorithm needs to do.                                */
9220 /*                                                                           */
9221 /*****************************************************************************/
9222 
9223 /*****************************************************************************/
9224 /*                                                                           */
9225 /*  vertexsort()   Sort an array of vertices by x-coordinate, using the      */
9226 /*                 y-coordinate as a secondary key.                          */
9227 /*                                                                           */
9228 /*  Uses quicksort.  Randomized O(n log n) time.  No, I did not make any of  */
9229 /*  the usual quicksort mistakes.                                            */
9230 /*                                                                           */
9231 /*****************************************************************************/
9232 
9233 #ifdef ANSI_DECLARATORS
9234 void vertexsort(vertex *sortarray, int arraysize)
9235 #else /* not ANSI_DECLARATORS */
9236 void vertexsort(sortarray, arraysize)
9237 vertex *sortarray;
9238 int arraysize;
9239 #endif /* not ANSI_DECLARATORS */
9240 
9241 {
9242   int left, right;
9243   int pivot;
9244   REAL pivotx, pivoty;
9245   vertex temp;
9246 
9247   if (arraysize == 2) {
9248     /* Recursive base case. */
9249     if ((sortarray[0][0] > sortarray[1][0]) ||
9250         ((sortarray[0][0] == sortarray[1][0]) &&
9251          (sortarray[0][1] > sortarray[1][1]))) {
9252       temp = sortarray[1];
9253       sortarray[1] = sortarray[0];
9254       sortarray[0] = temp;
9255     }
9256     return;
9257   }
9258   /* Choose a random pivot to split the array. */
9259   pivot = (int) randomnation((unsigned int) arraysize);
9260   pivotx = sortarray[pivot][0];
9261   pivoty = sortarray[pivot][1];
9262   /* Split the array. */
9263   left = -1;
9264   right = arraysize;
9265   while (left < right) {
9266     /* Search for a vertex whose x-coordinate is too large for the left. */
9267     do {
9268       left++;
9269     } while ((left <= right) && ((sortarray[left][0] < pivotx) ||
9270                                  ((sortarray[left][0] == pivotx) &&
9271                                   (sortarray[left][1] < pivoty))));
9272     /* Search for a vertex whose x-coordinate is too small for the right. */
9273     do {
9274       right--;
9275     } while ((left <= right) && ((sortarray[right][0] > pivotx) ||
9276                                  ((sortarray[right][0] == pivotx) &&
9277                                   (sortarray[right][1] > pivoty))));
9278     if (left < right) {
9279       /* Swap the left and right vertices. */
9280       temp = sortarray[left];
9281       sortarray[left] = sortarray[right];
9282       sortarray[right] = temp;
9283     }
9284   }
9285   if (left > 1) {
9286     /* Recursively sort the left subset. */
9287     vertexsort(sortarray, left);
9288   }
9289   if (right < arraysize - 2) {
9290     /* Recursively sort the right subset. */
9291     vertexsort(&sortarray[right + 1], arraysize - right - 1);
9292   }
9293 }
9294 
9295 /*****************************************************************************/
9296 /*                                                                           */
9297 /*  vertexmedian()   An order statistic algorithm, almost.  Shuffles an      */
9298 /*                   array of vertices so that the first `median' vertices   */
9299 /*                   occur lexicographically before the remaining vertices.  */
9300 /*                                                                           */
9301 /*  Uses the x-coordinate as the primary key if axis == 0; the y-coordinate  */
9302 /*  if axis == 1.  Very similar to the vertexsort() procedure, but runs in   */
9303 /*  randomized linear time.                                                  */
9304 /*                                                                           */
9305 /*****************************************************************************/
9306 
9307 #ifdef ANSI_DECLARATORS
9308 void vertexmedian(vertex *sortarray, int arraysize, int median, int axis)
9309 #else /* not ANSI_DECLARATORS */
9310 void vertexmedian(sortarray, arraysize, median, axis)
9311 vertex *sortarray;
9312 int arraysize;
9313 int median;
9314 int axis;
9315 #endif /* not ANSI_DECLARATORS */
9316 
9317 {
9318   int left, right;
9319   int pivot;
9320   REAL pivot1, pivot2;
9321   vertex temp;
9322 
9323   if (arraysize == 2) {
9324     /* Recursive base case. */
9325     if ((sortarray[0][axis] > sortarray[1][axis]) ||
9326         ((sortarray[0][axis] == sortarray[1][axis]) &&
9327          (sortarray[0][1 - axis] > sortarray[1][1 - axis]))) {
9328       temp = sortarray[1];
9329       sortarray[1] = sortarray[0];
9330       sortarray[0] = temp;
9331     }
9332     return;
9333   }
9334   /* Choose a random pivot to split the array. */
9335   pivot = (int) randomnation((unsigned int) arraysize);
9336   pivot1 = sortarray[pivot][axis];
9337   pivot2 = sortarray[pivot][1 - axis];
9338   /* Split the array. */
9339   left = -1;
9340   right = arraysize;
9341   while (left < right) {
9342     /* Search for a vertex whose x-coordinate is too large for the left. */
9343     do {
9344       left++;
9345     } while ((left <= right) && ((sortarray[left][axis] < pivot1) ||
9346                                  ((sortarray[left][axis] == pivot1) &&
9347                                   (sortarray[left][1 - axis] < pivot2))));
9348     /* Search for a vertex whose x-coordinate is too small for the right. */
9349     do {
9350       right--;
9351     } while ((left <= right) && ((sortarray[right][axis] > pivot1) ||
9352                                  ((sortarray[right][axis] == pivot1) &&
9353                                   (sortarray[right][1 - axis] > pivot2))));
9354     if (left < right) {
9355       /* Swap the left and right vertices. */
9356       temp = sortarray[left];
9357       sortarray[left] = sortarray[right];
9358       sortarray[right] = temp;
9359     }
9360   }
9361   /* Unlike in vertexsort(), at most one of the following */
9362   /*   conditionals is true.                             */
9363   if (left > median) {
9364     /* Recursively shuffle the left subset. */
9365     vertexmedian(sortarray, left, median, axis);
9366   }
9367   if (right < median - 1) {
9368     /* Recursively shuffle the right subset. */
9369     vertexmedian(&sortarray[right + 1], arraysize - right - 1,
9370                  median - right - 1, axis);
9371   }
9372 }
9373 
9374 /*****************************************************************************/
9375 /*                                                                           */
9376 /*  alternateaxes()   Sorts the vertices as appropriate for the divide-and-  */
9377 /*                    conquer algorithm with alternating cuts.               */
9378 /*                                                                           */
9379 /*  Partitions by x-coordinate if axis == 0; by y-coordinate if axis == 1.   */
9380 /*  For the base case, subsets containing only two or three vertices are     */
9381 /*  always sorted by x-coordinate.                                           */
9382 /*                                                                           */
9383 /*****************************************************************************/
9384 
9385 #ifdef ANSI_DECLARATORS
9386 void alternateaxes(vertex *sortarray, int arraysize, int axis)
9387 #else /* not ANSI_DECLARATORS */
9388 void alternateaxes(sortarray, arraysize, axis)
9389 vertex *sortarray;
9390 int arraysize;
9391 int axis;
9392 #endif /* not ANSI_DECLARATORS */
9393 
9394 {
9395   int divider;
9396 
9397   divider = arraysize >> 1;
9398   if (arraysize <= 3) {
9399     /* Recursive base case:  subsets of two or three vertices will be    */
9400     /*   handled specially, and should always be sorted by x-coordinate. */
9401     axis = 0;
9402   }
9403   /* Partition with a horizontal or vertical cut. */
9404   vertexmedian(sortarray, arraysize, divider, axis);
9405   /* Recursively partition the subsets with a cross cut. */
9406   if (arraysize - divider >= 2) {
9407     if (divider >= 2) {
9408       alternateaxes(sortarray, divider, 1 - axis);
9409     }
9410     alternateaxes(&sortarray[divider], arraysize - divider, 1 - axis);
9411   }
9412 }
9413 
9414 /*****************************************************************************/
9415 /*                                                                           */
9416 /*  mergehulls()   Merge two adjacent Delaunay triangulations into a         */
9417 /*                 single Delaunay triangulation.                            */
9418 /*                                                                           */
9419 /*  This is similar to the algorithm given by Guibas and Stolfi, but uses    */
9420 /*  a triangle-based, rather than edge-based, data structure.                */
9421 /*                                                                           */
9422 /*  The algorithm walks up the gap between the two triangulations, knitting  */
9423 /*  them together.  As they are merged, some of their bounding triangles     */
9424 /*  are converted into real triangles of the triangulation.  The procedure   */
9425 /*  pulls each hull's bounding triangles apart, then knits them together     */
9426 /*  like the teeth of two gears.  The Delaunay property determines, at each  */
9427 /*  step, whether the next "tooth" is a bounding triangle of the left hull   */
9428 /*  or the right.  When a bounding triangle becomes real, its apex is        */
9429 /*  changed from NULL to a real vertex.                                      */
9430 /*                                                                           */
9431 /*  Only two new triangles need to be allocated.  These become new bounding  */
9432 /*  triangles at the top and bottom of the seam.  They are used to connect   */
9433 /*  the remaining bounding triangles (those that have not been converted     */
9434 /*  into real triangles) into a single fan.                                  */
9435 /*                                                                           */
9436 /*  On entry, `farleft' and `innerleft' are bounding triangles of the left   */
9437 /*  triangulation.  The origin of `farleft' is the leftmost vertex, and      */
9438 /*  the destination of `innerleft' is the rightmost vertex of the            */
9439 /*  triangulation.  Similarly, `innerright' and `farright' are bounding      */
9440 /*  triangles of the right triangulation.  The origin of `innerright' and    */
9441 /*  destination of `farright' are the leftmost and rightmost vertices.       */
9442 /*                                                                           */
9443 /*  On completion, the origin of `farleft' is the leftmost vertex of the     */
9444 /*  merged triangulation, and the destination of `farright' is the rightmost */
9445 /*  vertex.                                                                  */
9446 /*                                                                           */
9447 /*****************************************************************************/
9448 
9449 #ifdef ANSI_DECLARATORS
9450 void mergehulls(struct mesh *m, struct behavior *b, struct otri *farleft,
9451                 struct otri *innerleft, struct otri *innerright,
9452                 struct otri *farright, int axis)
9453 #else /* not ANSI_DECLARATORS */
9454 void mergehulls(m, b, farleft, innerleft, innerright, farright, axis)
9455 struct mesh *m;
9456 struct behavior *b;
9457 struct otri *farleft;
9458 struct otri *innerleft;
9459 struct otri *innerright;
9460 struct otri *farright;
9461 int axis;
9462 #endif /* not ANSI_DECLARATORS */
9463 
9464 {
9465   struct otri leftcand, rightcand;
9466   struct otri baseedge;
9467   struct otri nextedge;
9468   struct otri sidecasing, topcasing, outercasing;
9469   struct otri checkedge;
9470   vertex innerleftdest;
9471   vertex innerrightorg;
9472   vertex innerleftapex, innerrightapex;
9473   vertex farleftpt, farrightpt;
9474   vertex farleftapex, farrightapex;
9475   vertex lowerleft, lowerright;
9476   vertex upperleft, upperright;
9477   vertex nextapex;
9478   vertex checkvertex;
9479   int changemade;
9480   int badedge;
9481   int leftfinished, rightfinished;
9482   triangle ptr;                         /* Temporary variable used by sym(). */
9483 
9484   dest(*innerleft, innerleftdest);
9485   apex(*innerleft, innerleftapex);
9486   org(*innerright, innerrightorg);
9487   apex(*innerright, innerrightapex);
9488   /* Special treatment for horizontal cuts. */
9489   if (b->dwyer && (axis == 1)) {
9490     org(*farleft, farleftpt);
9491     apex(*farleft, farleftapex);
9492     dest(*farright, farrightpt);
9493     apex(*farright, farrightapex);
9494     /* The pointers to the extremal vertices are shifted to point to the */
9495     /*   topmost and bottommost vertex of each hull, rather than the     */
9496     /*   leftmost and rightmost vertices.                                */
9497     while (farleftapex[1] < farleftpt[1]) {
9498       lnextself(*farleft);
9499       symself(*farleft);
9500       farleftpt = farleftapex;
9501       apex(*farleft, farleftapex);
9502     }
9503     sym(*innerleft, checkedge);
9504     apex(checkedge, checkvertex);
9505     while (checkvertex[1] > innerleftdest[1]) {
9506       lnext(checkedge, *innerleft);
9507       innerleftapex = innerleftdest;
9508       innerleftdest = checkvertex;
9509       sym(*innerleft, checkedge);
9510       apex(checkedge, checkvertex);
9511     }
9512     while (innerrightapex[1] < innerrightorg[1]) {
9513       lnextself(*innerright);
9514       symself(*innerright);
9515       innerrightorg = innerrightapex;
9516       apex(*innerright, innerrightapex);
9517     }
9518     sym(*farright, checkedge);
9519     apex(checkedge, checkvertex);
9520     while (checkvertex[1] > farrightpt[1]) {
9521       lnext(checkedge, *farright);
9522       farrightapex = farrightpt;
9523       farrightpt = checkvertex;
9524       sym(*farright, checkedge);
9525       apex(checkedge, checkvertex);
9526     }
9527   }
9528   /* Find a line tangent to and below both hulls. */
9529   do {
9530     changemade = 0;
9531     /* Make innerleftdest the "bottommost" vertex of the left hull. */
9532     if (counterclockwise(m, b, innerleftdest, innerleftapex, innerrightorg) >
9533         0.0) {
9534       lprevself(*innerleft);
9535       symself(*innerleft);
9536       innerleftdest = innerleftapex;
9537       apex(*innerleft, innerleftapex);
9538       changemade = 1;
9539     }
9540     /* Make innerrightorg the "bottommost" vertex of the right hull. */
9541     if (counterclockwise(m, b, innerrightapex, innerrightorg, innerleftdest) >
9542         0.0) {
9543       lnextself(*innerright);
9544       symself(*innerright);
9545       innerrightorg = innerrightapex;
9546       apex(*innerright, innerrightapex);
9547       changemade = 1;
9548     }
9549   } while (changemade);
9550   /* Find the two candidates to be the next "gear tooth." */
9551   sym(*innerleft, leftcand);
9552   sym(*innerright, rightcand);
9553   /* Create the bottom new bounding triangle. */
9554   maketriangle(m, b, &baseedge);
9555   /* Connect it to the bounding boxes of the left and right triangulations. */
9556   bond(baseedge, *innerleft);
9557   lnextself(baseedge);
9558   bond(baseedge, *innerright);
9559   lnextself(baseedge);
9560   setorg(baseedge, innerrightorg);
9561   setdest(baseedge, innerleftdest);
9562   /* Apex is intentionally left NULL. */
9563   if (b->verbose > 2) {
9564     printf("  Creating base bounding ");
9565     printtriangle(m, b, &baseedge);
9566   }
9567   /* Fix the extreme triangles if necessary. */
9568   org(*farleft, farleftpt);
9569   if (innerleftdest == farleftpt) {
9570     lnext(baseedge, *farleft);
9571   }
9572   dest(*farright, farrightpt);
9573   if (innerrightorg == farrightpt) {
9574     lprev(baseedge, *farright);
9575   }
9576   /* The vertices of the current knitting edge. */
9577   lowerleft = innerleftdest;
9578   lowerright = innerrightorg;
9579   /* The candidate vertices for knitting. */
9580   apex(leftcand, upperleft);
9581   apex(rightcand, upperright);
9582   /* Walk up the gap between the two triangulations, knitting them together. */
9583   while (1) {
9584     /* Have we reached the top?  (This isn't quite the right question,       */
9585     /*   because even though the left triangulation might seem finished now, */
9586     /*   moving up on the right triangulation might reveal a new vertex of   */
9587     /*   the left triangulation.  And vice-versa.)                           */
9588     leftfinished = counterclockwise(m, b, upperleft, lowerleft, lowerright) <=
9589                    0.0;
9590     rightfinished = counterclockwise(m, b, upperright, lowerleft, lowerright)
9591                  <= 0.0;
9592     if (leftfinished && rightfinished) {
9593       /* Create the top new bounding triangle. */
9594       maketriangle(m, b, &nextedge);
9595       setorg(nextedge, lowerleft);
9596       setdest(nextedge, lowerright);
9597       /* Apex is intentionally left NULL. */
9598       /* Connect it to the bounding boxes of the two triangulations. */
9599       bond(nextedge, baseedge);
9600       lnextself(nextedge);
9601       bond(nextedge, rightcand);
9602       lnextself(nextedge);
9603       bond(nextedge, leftcand);
9604       if (b->verbose > 2) {
9605         printf("  Creating top bounding ");
9606         printtriangle(m, b, &nextedge);
9607       }
9608       /* Special treatment for horizontal cuts. */
9609       if (b->dwyer && (axis == 1)) {
9610         org(*farleft, farleftpt);
9611         apex(*farleft, farleftapex);
9612         dest(*farright, farrightpt);
9613         apex(*farright, farrightapex);
9614         sym(*farleft, checkedge);
9615         apex(checkedge, checkvertex);
9616         /* The pointers to the extremal vertices are restored to the  */
9617         /*   leftmost and rightmost vertices (rather than topmost and */
9618         /*   bottommost).                                             */
9619         while (checkvertex[0] < farleftpt[0]) {
9620           lprev(checkedge, *farleft);
9621           farleftapex = farleftpt;
9622           farleftpt = checkvertex;
9623           sym(*farleft, checkedge);
9624           apex(checkedge, checkvertex);
9625         }
9626         while (farrightapex[0] > farrightpt[0]) {
9627           lprevself(*farright);
9628           symself(*farright);
9629           farrightpt = farrightapex;
9630           apex(*farright, farrightapex);
9631         }
9632       }
9633       return;
9634     }
9635     /* Consider eliminating edges from the left triangulation. */
9636     if (!leftfinished) {
9637       /* What vertex would be exposed if an edge were deleted? */
9638       lprev(leftcand, nextedge);
9639       symself(nextedge);
9640       apex(nextedge, nextapex);
9641       /* If nextapex is NULL, then no vertex would be exposed; the */
9642       /*   triangulation would have been eaten right through.      */
9643       if (nextapex != (vertex) NULL) {
9644         /* Check whether the edge is Delaunay. */
9645         badedge = incircle(m, b, lowerleft, lowerright, upperleft, nextapex) >
9646                   0.0;
9647         while (badedge) {
9648           /* Eliminate the edge with an edge flip.  As a result, the    */
9649           /*   left triangulation will have one more boundary triangle. */
9650           lnextself(nextedge);
9651           sym(nextedge, topcasing);
9652           lnextself(nextedge);
9653           sym(nextedge, sidecasing);
9654           bond(nextedge, topcasing);
9655           bond(leftcand, sidecasing);
9656           lnextself(leftcand);
9657           sym(leftcand, outercasing);
9658           lprevself(nextedge);
9659           bond(nextedge, outercasing);
9660           /* Correct the vertices to reflect the edge flip. */
9661           setorg(leftcand, lowerleft);
9662           setdest(leftcand, NULL);
9663           setapex(leftcand, nextapex);
9664           setorg(nextedge, NULL);
9665           setdest(nextedge, upperleft);
9666           setapex(nextedge, nextapex);
9667           /* Consider the newly exposed vertex. */
9668           upperleft = nextapex;
9669           /* What vertex would be exposed if another edge were deleted? */
9670           otricopy(sidecasing, nextedge);
9671           apex(nextedge, nextapex);
9672           if (nextapex != (vertex) NULL) {
9673             /* Check whether the edge is Delaunay. */
9674             badedge = incircle(m, b, lowerleft, lowerright, upperleft,
9675                                nextapex) > 0.0;
9676           } else {
9677             /* Avoid eating right through the triangulation. */
9678             badedge = 0;
9679           }
9680         }
9681       }
9682     }
9683     /* Consider eliminating edges from the right triangulation. */
9684     if (!rightfinished) {
9685       /* What vertex would be exposed if an edge were deleted? */
9686       lnext(rightcand, nextedge);
9687       symself(nextedge);
9688       apex(nextedge, nextapex);
9689       /* If nextapex is NULL, then no vertex would be exposed; the */
9690       /*   triangulation would have been eaten right through.      */
9691       if (nextapex != (vertex) NULL) {
9692         /* Check whether the edge is Delaunay. */
9693         badedge = incircle(m, b, lowerleft, lowerright, upperright, nextapex) >
9694                   0.0;
9695         while (badedge) {
9696           /* Eliminate the edge with an edge flip.  As a result, the     */
9697           /*   right triangulation will have one more boundary triangle. */
9698           lprevself(nextedge);
9699           sym(nextedge, topcasing);
9700           lprevself(nextedge);
9701           sym(nextedge, sidecasing);
9702           bond(nextedge, topcasing);
9703           bond(rightcand, sidecasing);
9704           lprevself(rightcand);
9705           sym(rightcand, outercasing);
9706           lnextself(nextedge);
9707           bond(nextedge, outercasing);
9708           /* Correct the vertices to reflect the edge flip. */
9709           setorg(rightcand, NULL);
9710           setdest(rightcand, lowerright);
9711           setapex(rightcand, nextapex);
9712           setorg(nextedge, upperright);
9713           setdest(nextedge, NULL);
9714           setapex(nextedge, nextapex);
9715           /* Consider the newly exposed vertex. */
9716           upperright = nextapex;
9717           /* What vertex would be exposed if another edge were deleted? */
9718           otricopy(sidecasing, nextedge);
9719           apex(nextedge, nextapex);
9720           if (nextapex != (vertex) NULL) {
9721             /* Check whether the edge is Delaunay. */
9722             badedge = incircle(m, b, lowerleft, lowerright, upperright,
9723                                nextapex) > 0.0;
9724           } else {
9725             /* Avoid eating right through the triangulation. */
9726             badedge = 0;
9727           }
9728         }
9729       }
9730     }
9731     if (leftfinished || (!rightfinished &&
9732            (incircle(m, b, upperleft, lowerleft, lowerright, upperright) >
9733             0.0))) {
9734       /* Knit the triangulations, adding an edge from `lowerleft' */
9735       /*   to `upperright'.                                       */
9736       bond(baseedge, rightcand);
9737       lprev(rightcand, baseedge);
9738       setdest(baseedge, lowerleft);
9739       lowerright = upperright;
9740       sym(baseedge, rightcand);
9741       apex(rightcand, upperright);
9742     } else {
9743       /* Knit the triangulations, adding an edge from `upperleft' */
9744       /*   to `lowerright'.                                       */
9745       bond(baseedge, leftcand);
9746       lnext(leftcand, baseedge);
9747       setorg(baseedge, lowerright);
9748       lowerleft = upperleft;
9749       sym(baseedge, leftcand);
9750       apex(leftcand, upperleft);
9751     }
9752     if (b->verbose > 2) {
9753       printf("  Connecting ");
9754       printtriangle(m, b, &baseedge);
9755     }
9756   }
9757 }
9758 
9759 /*****************************************************************************/
9760 /*                                                                           */
9761 /*  divconqrecurse()   Recursively form a Delaunay triangulation by the      */
9762 /*                     divide-and-conquer method.                            */
9763 /*                                                                           */
9764 /*  Recursively breaks down the problem into smaller pieces, which are       */
9765 /*  knitted together by mergehulls().  The base cases (problems of two or    */
9766 /*  three vertices) are handled specially here.                              */
9767 /*                                                                           */
9768 /*  On completion, `farleft' and `farright' are bounding triangles such that */
9769 /*  the origin of `farleft' is the leftmost vertex (breaking ties by         */
9770 /*  choosing the highest leftmost vertex), and the destination of            */
9771 /*  `farright' is the rightmost vertex (breaking ties by choosing the        */
9772 /*  lowest rightmost vertex).                                                */
9773 /*                                                                           */
9774 /*****************************************************************************/
9775 
9776 #ifdef ANSI_DECLARATORS
9777 void divconqrecurse(struct mesh *m, struct behavior *b, vertex *sortarray,
9778                     int vertices, int axis,
9779                     struct otri *farleft, struct otri *farright)
9780 #else /* not ANSI_DECLARATORS */
9781 void divconqrecurse(m, b, sortarray, vertices, axis, farleft, farright)
9782 struct mesh *m;
9783 struct behavior *b;
9784 vertex *sortarray;
9785 int vertices;
9786 int axis;
9787 struct otri *farleft;
9788 struct otri *farright;
9789 #endif /* not ANSI_DECLARATORS */
9790 
9791 {
9792   struct otri midtri, tri1, tri2, tri3;
9793   struct otri innerleft, innerright;
9794   REAL area;
9795   int divider;
9796 
9797   if (b->verbose > 2) {
9798     printf("  Triangulating %d vertices.\n", vertices);
9799   }
9800   if (vertices == 2) {
9801     /* The triangulation of two vertices is an edge.  An edge is */
9802     /*   represented by two bounding triangles.                  */
9803     maketriangle(m, b, farleft);
9804     setorg(*farleft, sortarray[0]);
9805     setdest(*farleft, sortarray[1]);
9806     /* The apex is intentionally left NULL. */
9807     maketriangle(m, b, farright);
9808     setorg(*farright, sortarray[1]);
9809     setdest(*farright, sortarray[0]);
9810     /* The apex is intentionally left NULL. */
9811     bond(*farleft, *farright);
9812     lprevself(*farleft);
9813     lnextself(*farright);
9814     bond(*farleft, *farright);
9815     lprevself(*farleft);
9816     lnextself(*farright);
9817     bond(*farleft, *farright);
9818     if (b->verbose > 2) {
9819       printf("  Creating ");
9820       printtriangle(m, b, farleft);
9821       printf("  Creating ");
9822       printtriangle(m, b, farright);
9823     }
9824     /* Ensure that the origin of `farleft' is sortarray[0]. */
9825     lprev(*farright, *farleft);
9826     return;
9827   } else if (vertices == 3) {
9828     /* The triangulation of three vertices is either a triangle (with */
9829     /*   three bounding triangles) or two edges (with four bounding   */
9830     /*   triangles).  In either case, four triangles are created.     */
9831     maketriangle(m, b, &midtri);
9832     maketriangle(m, b, &tri1);
9833     maketriangle(m, b, &tri2);
9834     maketriangle(m, b, &tri3);
9835     area = counterclockwise(m, b, sortarray[0], sortarray[1], sortarray[2]);
9836     if (area == 0.0) {
9837       /* Three collinear vertices; the triangulation is two edges. */
9838       setorg(midtri, sortarray[0]);
9839       setdest(midtri, sortarray[1]);
9840       setorg(tri1, sortarray[1]);
9841       setdest(tri1, sortarray[0]);
9842       setorg(tri2, sortarray[2]);
9843       setdest(tri2, sortarray[1]);
9844       setorg(tri3, sortarray[1]);
9845       setdest(tri3, sortarray[2]);
9846       /* All apices are intentionally left NULL. */
9847       bond(midtri, tri1);
9848       bond(tri2, tri3);
9849       lnextself(midtri);
9850       lprevself(tri1);
9851       lnextself(tri2);
9852       lprevself(tri3);
9853       bond(midtri, tri3);
9854       bond(tri1, tri2);
9855       lnextself(midtri);
9856       lprevself(tri1);
9857       lnextself(tri2);
9858       lprevself(tri3);
9859       bond(midtri, tri1);
9860       bond(tri2, tri3);
9861       /* Ensure that the origin of `farleft' is sortarray[0]. */
9862       otricopy(tri1, *farleft);
9863       /* Ensure that the destination of `farright' is sortarray[2]. */
9864       otricopy(tri2, *farright);
9865     } else {
9866       /* The three vertices are not collinear; the triangulation is one */
9867       /*   triangle, namely `midtri'.                                   */
9868       setorg(midtri, sortarray[0]);
9869       setdest(tri1, sortarray[0]);
9870       setorg(tri3, sortarray[0]);
9871       /* Apices of tri1, tri2, and tri3 are left NULL. */
9872       if (area > 0.0) {
9873         /* The vertices are in counterclockwise order. */
9874         setdest(midtri, sortarray[1]);
9875         setorg(tri1, sortarray[1]);
9876         setdest(tri2, sortarray[1]);
9877         setapex(midtri, sortarray[2]);
9878         setorg(tri2, sortarray[2]);
9879         setdest(tri3, sortarray[2]);
9880       } else {
9881         /* The vertices are in clockwise order. */
9882         setdest(midtri, sortarray[2]);
9883         setorg(tri1, sortarray[2]);
9884         setdest(tri2, sortarray[2]);
9885         setapex(midtri, sortarray[1]);
9886         setorg(tri2, sortarray[1]);
9887         setdest(tri3, sortarray[1]);
9888       }
9889       /* The topology does not depend on how the vertices are ordered. */
9890       bond(midtri, tri1);
9891       lnextself(midtri);
9892       bond(midtri, tri2);
9893       lnextself(midtri);
9894       bond(midtri, tri3);
9895       lprevself(tri1);
9896       lnextself(tri2);
9897       bond(tri1, tri2);
9898       lprevself(tri1);
9899       lprevself(tri3);
9900       bond(tri1, tri3);
9901       lnextself(tri2);
9902       lprevself(tri3);
9903       bond(tri2, tri3);
9904       /* Ensure that the origin of `farleft' is sortarray[0]. */
9905       otricopy(tri1, *farleft);
9906       /* Ensure that the destination of `farright' is sortarray[2]. */
9907       if (area > 0.0) {
9908         otricopy(tri2, *farright);
9909       } else {
9910         lnext(*farleft, *farright);
9911       }
9912     }
9913     if (b->verbose > 2) {
9914       printf("  Creating ");
9915       printtriangle(m, b, &midtri);
9916       printf("  Creating ");
9917       printtriangle(m, b, &tri1);
9918       printf("  Creating ");
9919       printtriangle(m, b, &tri2);
9920       printf("  Creating ");
9921       printtriangle(m, b, &tri3);
9922     }
9923     return;
9924   } else {
9925     /* Split the vertices in half. */
9926     divider = vertices >> 1;
9927     /* Recursively triangulate each half. */
9928     divconqrecurse(m, b, sortarray, divider, 1 - axis, farleft, &innerleft);
9929     divconqrecurse(m, b, &sortarray[divider], vertices - divider, 1 - axis,
9930                    &innerright, farright);
9931     if (b->verbose > 1) {
9932       printf("  Joining triangulations with %d and %d vertices.\n", divider,
9933              vertices - divider);
9934     }
9935     /* Merge the two triangulations into one. */
9936     mergehulls(m, b, farleft, &innerleft, &innerright, farright, axis);
9937   }
9938 }
9939 
9940 #ifdef ANSI_DECLARATORS
9941 long removeghosts(struct mesh *m, struct behavior *b, struct otri *startghost)
9942 #else /* not ANSI_DECLARATORS */
9943 long removeghosts(m, b, startghost)
9944 struct mesh *m;
9945 struct behavior *b;
9946 struct otri *startghost;
9947 #endif /* not ANSI_DECLARATORS */
9948 
9949 {
9950   struct otri searchedge;
9951   struct otri dissolveedge;
9952   struct otri deadtriangle;
9953   vertex markorg;
9954   long hullsize;
9955   triangle ptr;                         /* Temporary variable used by sym(). */
9956 
9957   if (b->verbose) {
9958     printf("  Removing ghost triangles.\n");
9959   }
9960   /* Find an edge on the convex hull to start point location from. */
9961   lprev(*startghost, searchedge);
9962   symself(searchedge);
9963   m->dummytri[0] = encode(searchedge);
9964   /* Remove the bounding box and count the convex hull edges. */
9965   otricopy(*startghost, dissolveedge);
9966   hullsize = 0;
9967   do {
9968     hullsize++;
9969     lnext(dissolveedge, deadtriangle);
9970     lprevself(dissolveedge);
9971     symself(dissolveedge);
9972     /* If no PSLG is involved, set the boundary markers of all the vertices */
9973     /*   on the convex hull.  If a PSLG is used, this step is done later.   */
9974     if (!b->poly) {
9975       /* Watch out for the case where all the input vertices are collinear. */
9976       if (dissolveedge.tri != m->dummytri) {
9977         org(dissolveedge, markorg);
9978         if (vertexmark(markorg) == 0) {
9979           setvertexmark(markorg, 1);
9980         }
9981       }
9982     }
9983     /* Remove a bounding triangle from a convex hull triangle. */
9984     dissolve(dissolveedge);
9985     /* Find the next bounding triangle. */
9986     sym(deadtriangle, dissolveedge);
9987     /* Delete the bounding triangle. */
9988     triangledealloc(m, deadtriangle.tri);
9989   } while (!otriequal(dissolveedge, *startghost));
9990   return hullsize;
9991 }
9992 
9993 /*****************************************************************************/
9994 /*                                                                           */
9995 /*  divconqdelaunay()   Form a Delaunay triangulation by the divide-and-     */
9996 /*                      conquer method.                                      */
9997 /*                                                                           */
9998 /*  Sorts the vertices, calls a recursive procedure to triangulate them, and */
9999 /*  removes the bounding box, setting boundary markers as appropriate.       */
10000 /*                                                                           */
10001 /*****************************************************************************/
10002 
10003 #ifdef ANSI_DECLARATORS
10004 long divconqdelaunay(struct mesh *m, struct behavior *b)
10005 #else /* not ANSI_DECLARATORS */
10006 long divconqdelaunay(m, b)
10007 struct mesh *m;
10008 struct behavior *b;
10009 #endif /* not ANSI_DECLARATORS */
10010 
10011 {
10012   vertex *sortarray;
10013   struct otri hullleft, hullright;
10014   int divider;
10015   int i, j;
10016 
10017   if (b->verbose) {
10018     printf("  Sorting vertices.\n");
10019   }
10020 
10021   /* Allocate an array of pointers to vertices for sorting. */
10022   sortarray = (vertex *) trimalloc(m->invertices * (int) sizeof(vertex));
10023   traversalinit(&m->vertices);
10024   for (i = 0; i < m->invertices; i++) {
10025     sortarray[i] = vertextraverse(m);
10026   }
10027   /* Sort the vertices. */
10028   vertexsort(sortarray, m->invertices);
10029   /* Discard duplicate vertices, which can really mess up the algorithm. */
10030   i = 0;
10031   for (j = 1; j < m->invertices; j++) {
10032     if ((sortarray[i][0] == sortarray[j][0])
10033         && (sortarray[i][1] == sortarray[j][1])) {
10034       if (!b->quiet) {
10035         printf(
10036 "Warning:  A duplicate vertex at (%.12g, %.12g) appeared and was ignored.\n",
10037                sortarray[j][0], sortarray[j][1]);
10038       }
10039       setvertextype(sortarray[j], UNDEADVERTEX);
10040       m->undeads++;
10041     } else {
10042       i++;
10043       sortarray[i] = sortarray[j];
10044     }
10045   }
10046   i++;
10047   if (b->dwyer) {
10048     /* Re-sort the array of vertices to accommodate alternating cuts. */
10049     divider = i >> 1;
10050     if (i - divider >= 2) {
10051       if (divider >= 2) {
10052         alternateaxes(sortarray, divider, 1);
10053       }
10054       alternateaxes(&sortarray[divider], i - divider, 1);
10055     }
10056   }
10057 
10058   if (b->verbose) {
10059     printf("  Forming triangulation.\n");
10060   }
10061 
10062   /* Form the Delaunay triangulation. */
10063   divconqrecurse(m, b, sortarray, i, 0, &hullleft, &hullright);
10064   trifree((VOID *) sortarray);
10065 
10066   return removeghosts(m, b, &hullleft);
10067 }
10068 
10069 /**                                                                         **/
10070 /**                                                                         **/
10071 /********* Divide-and-conquer Delaunay triangulation ends here       *********/
10072 
10073 /********* Incremental Delaunay triangulation begins here            *********/
10074 /**                                                                         **/
10075 /**                                                                         **/
10076 
10077 /*****************************************************************************/
10078 /*                                                                           */
10079 /*  boundingbox()   Form an "infinite" bounding triangle to insert vertices  */
10080 /*                  into.                                                    */
10081 /*                                                                           */
10082 /*  The vertices at "infinity" are assigned finite coordinates, which are    */
10083 /*  used by the point location routines, but (mostly) ignored by the         */
10084 /*  Delaunay edge flip routines.                                             */
10085 /*                                                                           */
10086 /*****************************************************************************/
10087 
10088 #ifndef REDUCED
10089 
10090 #ifdef ANSI_DECLARATORS
10091 void boundingbox(struct mesh *m, struct behavior *b)
10092 #else /* not ANSI_DECLARATORS */
10093 void boundingbox(m, b)
10094 struct mesh *m;
10095 struct behavior *b;
10096 #endif /* not ANSI_DECLARATORS */
10097 
10098 {
10099   struct otri inftri;          /* Handle for the triangular bounding box. */
10100   REAL width;
10101 
10102   if (b->verbose) {
10103     printf("  Creating triangular bounding box.\n");
10104   }
10105   /* Find the width (or height, whichever is larger) of the triangulation. */
10106   width = m->xmax - m->xmin;
10107   if (m->ymax - m->ymin > width) {
10108     width = m->ymax - m->ymin;
10109   }
10110   if (width == 0.0) {
10111     width = 1.0;
10112   }
10113   /* Create the vertices of the bounding box. */
10114   m->infvertex1 = (vertex) trimalloc(m->vertices.itembytes);
10115   m->infvertex2 = (vertex) trimalloc(m->vertices.itembytes);
10116   m->infvertex3 = (vertex) trimalloc(m->vertices.itembytes);
10117   m->infvertex1[0] = m->xmin - 50.0 * width;
10118   m->infvertex1[1] = m->ymin - 40.0 * width;
10119   m->infvertex2[0] = m->xmax + 50.0 * width;
10120   m->infvertex2[1] = m->ymin - 40.0 * width;
10121   m->infvertex3[0] = 0.5 * (m->xmin + m->xmax);
10122   m->infvertex3[1] = m->ymax + 60.0 * width;
10123 
10124   /* Create the bounding box. */
10125   maketriangle(m, b, &inftri);
10126   setorg(inftri, m->infvertex1);
10127   setdest(inftri, m->infvertex2);
10128   setapex(inftri, m->infvertex3);
10129   /* Link dummytri to the bounding box so we can always find an */
10130   /*   edge to begin searching (point location) from.           */
10131   m->dummytri[0] = (triangle) inftri.tri;
10132   if (b->verbose > 2) {
10133     printf("  Creating ");
10134     printtriangle(m, b, &inftri);
10135   }
10136 }
10137 
10138 #endif /* not REDUCED */
10139 
10140 /*****************************************************************************/
10141 /*                                                                           */
10142 /*  removebox()   Remove the "infinite" bounding triangle, setting boundary  */
10143 /*                markers as appropriate.                                    */
10144 /*                                                                           */
10145 /*  The triangular bounding box has three boundary triangles (one for each   */
10146 /*  side of the bounding box), and a bunch of triangles fanning out from     */
10147 /*  the three bounding box vertices (one triangle for each edge of the       */
10148 /*  convex hull of the inner mesh).  This routine removes these triangles.   */
10149 /*                                                                           */
10150 /*  Returns the number of edges on the convex hull of the triangulation.     */
10151 /*                                                                           */
10152 /*****************************************************************************/
10153 
10154 #ifndef REDUCED
10155 
10156 #ifdef ANSI_DECLARATORS
10157 long removebox(struct mesh *m, struct behavior *b)
10158 #else /* not ANSI_DECLARATORS */
10159 long removebox(m, b)
10160 struct mesh *m;
10161 struct behavior *b;
10162 #endif /* not ANSI_DECLARATORS */
10163 
10164 {
10165   struct otri deadtriangle;
10166   struct otri searchedge;
10167   struct otri checkedge;
10168   struct otri nextedge, finaledge, dissolveedge;
10169   vertex markorg;
10170   long hullsize;
10171   triangle ptr;                         /* Temporary variable used by sym(). */
10172 
10173   if (b->verbose) {
10174     printf("  Removing triangular bounding box.\n");
10175   }
10176   /* Find a boundary triangle. */
10177   nextedge.tri = m->dummytri;
10178   nextedge.orient = 0;
10179   symself(nextedge);
10180   /* Mark a place to stop. */
10181   lprev(nextedge, finaledge);
10182   lnextself(nextedge);
10183   symself(nextedge);
10184   /* Find a triangle (on the boundary of the vertex set) that isn't */
10185   /*   a bounding box triangle.                                     */
10186   lprev(nextedge, searchedge);
10187   symself(searchedge);
10188   /* Check whether nextedge is another boundary triangle */
10189   /*   adjacent to the first one.                        */
10190   lnext(nextedge, checkedge);
10191   symself(checkedge);
10192   if (checkedge.tri == m->dummytri) {
10193     /* Go on to the next triangle.  There are only three boundary   */
10194     /*   triangles, and this next triangle cannot be the third one, */
10195     /*   so it's safe to stop here.                                 */
10196     lprevself(searchedge);
10197     symself(searchedge);
10198   }
10199   /* Find a new boundary edge to search from, as the current search */
10200   /*   edge lies on a bounding box triangle and will be deleted.    */
10201   m->dummytri[0] = encode(searchedge);
10202   hullsize = -2l;
10203   while (!otriequal(nextedge, finaledge)) {
10204     hullsize++;
10205     lprev(nextedge, dissolveedge);
10206     symself(dissolveedge);
10207     /* If not using a PSLG, the vertices should be marked now. */
10208     /*   (If using a PSLG, markhull() will do the job.)        */
10209     if (!b->poly) {
10210       /* Be careful!  One must check for the case where all the input     */
10211       /*   vertices are collinear, and thus all the triangles are part of */
10212       /*   the bounding box.  Otherwise, the setvertexmark() call below   */
10213       /*   will cause a bad pointer reference.                            */
10214       if (dissolveedge.tri != m->dummytri) {
10215         org(dissolveedge, markorg);
10216         if (vertexmark(markorg) == 0) {
10217           setvertexmark(markorg, 1);
10218         }
10219       }
10220     }
10221     /* Disconnect the bounding box triangle from the mesh triangle. */
10222     dissolve(dissolveedge);
10223     lnext(nextedge, deadtriangle);
10224     sym(deadtriangle, nextedge);
10225     /* Get rid of the bounding box triangle. */
10226     triangledealloc(m, deadtriangle.tri);
10227     /* Do we need to turn the corner? */
10228     if (nextedge.tri == m->dummytri) {
10229       /* Turn the corner. */
10230       otricopy(dissolveedge, nextedge);
10231     }
10232   }
10233   triangledealloc(m, finaledge.tri);
10234 
10235   trifree((VOID *) m->infvertex1);  /* Deallocate the bounding box vertices. */
10236   trifree((VOID *) m->infvertex2);
10237   trifree((VOID *) m->infvertex3);
10238 
10239   return hullsize;
10240 }
10241 
10242 #endif /* not REDUCED */
10243 
10244 /*****************************************************************************/
10245 /*                                                                           */
10246 /*  incrementaldelaunay()   Form a Delaunay triangulation by incrementally   */
10247 /*                          inserting vertices.                              */
10248 /*                                                                           */
10249 /*  Returns the number of edges on the convex hull of the triangulation.     */
10250 /*                                                                           */
10251 /*****************************************************************************/
10252 
10253 #ifndef REDUCED
10254 
10255 #ifdef ANSI_DECLARATORS
10256 long incrementaldelaunay(struct mesh *m, struct behavior *b)
10257 #else /* not ANSI_DECLARATORS */
10258 long incrementaldelaunay(m, b)
10259 struct mesh *m;
10260 struct behavior *b;
10261 #endif /* not ANSI_DECLARATORS */
10262 
10263 {
10264   struct otri starttri;
10265   vertex vertexloop;
10266 
10267   /* Create a triangular bounding box. */
10268   boundingbox(m, b);
10269   if (b->verbose) {
10270     printf("  Incrementally inserting vertices.\n");
10271   }
10272   traversalinit(&m->vertices);
10273   vertexloop = vertextraverse(m);
10274   while (vertexloop != (vertex) NULL) {
10275     starttri.tri = m->dummytri;
10276     if (insertvertex(m, b, vertexloop, &starttri, (struct osub *) NULL, 0, 0)
10277         == DUPLICATEVERTEX) {
10278       if (!b->quiet) {
10279         printf(
10280 "Warning:  A duplicate vertex at (%.12g, %.12g) appeared and was ignored.\n",
10281                vertexloop[0], vertexloop[1]);
10282       }
10283       setvertextype(vertexloop, UNDEADVERTEX);
10284       m->undeads++;
10285     }
10286     vertexloop = vertextraverse(m);
10287   }
10288   /* Remove the bounding box. */
10289   return removebox(m, b);
10290 }
10291 
10292 #endif /* not REDUCED */
10293 
10294 /**                                                                         **/
10295 /**                                                                         **/
10296 /********* Incremental Delaunay triangulation ends here              *********/
10297 
10298 /********* Sweepline Delaunay triangulation begins here              *********/
10299 /**                                                                         **/
10300 /**                                                                         **/
10301 
10302 #ifndef REDUCED
10303 
10304 #ifdef ANSI_DECLARATORS
10305 void eventheapinsert(struct event **heap, int heapsize, struct event *newevent)
10306 #else /* not ANSI_DECLARATORS */
10307 void eventheapinsert(heap, heapsize, newevent)
10308 struct event **heap;
10309 int heapsize;
10310 struct event *newevent;
10311 #endif /* not ANSI_DECLARATORS */
10312 
10313 {
10314   REAL eventx, eventy;
10315   int eventnum;
10316   int parent;
10317   int notdone;
10318 
10319   eventx = newevent->xkey;
10320   eventy = newevent->ykey;
10321   eventnum = heapsize;
10322   notdone = eventnum > 0;
10323   while (notdone) {
10324     parent = (eventnum - 1) >> 1;
10325     if ((heap[parent]->ykey < eventy) ||
10326         ((heap[parent]->ykey == eventy)
10327          && (heap[parent]->xkey <= eventx))) {
10328       notdone = 0;
10329     } else {
10330       heap[eventnum] = heap[parent];
10331       heap[eventnum]->heapposition = eventnum;
10332 
10333       eventnum = parent;
10334       notdone = eventnum > 0;
10335     }
10336   }
10337   heap[eventnum] = newevent;
10338   newevent->heapposition = eventnum;
10339 }
10340 
10341 #endif /* not REDUCED */
10342 
10343 #ifndef REDUCED
10344 
10345 #ifdef ANSI_DECLARATORS
10346 void eventheapify(struct event **heap, int heapsize, int eventnum)
10347 #else /* not ANSI_DECLARATORS */
10348 void eventheapify(heap, heapsize, eventnum)
10349 struct event **heap;
10350 int heapsize;
10351 int eventnum;
10352 #endif /* not ANSI_DECLARATORS */
10353 
10354 {
10355   struct event *thisevent;
10356   REAL eventx, eventy;
10357   int leftchild, rightchild;
10358   int smallest;
10359   int notdone;
10360 
10361   thisevent = heap[eventnum];
10362   eventx = thisevent->xkey;
10363   eventy = thisevent->ykey;
10364   leftchild = 2 * eventnum + 1;
10365   notdone = leftchild < heapsize;
10366   while (notdone) {
10367     if ((heap[leftchild]->ykey < eventy) ||
10368         ((heap[leftchild]->ykey == eventy)
10369          && (heap[leftchild]->xkey < eventx))) {
10370       smallest = leftchild;
10371     } else {
10372       smallest = eventnum;
10373     }
10374     rightchild = leftchild + 1;
10375     if (rightchild < heapsize) {
10376       if ((heap[rightchild]->ykey < heap[smallest]->ykey) ||
10377           ((heap[rightchild]->ykey == heap[smallest]->ykey)
10378            && (heap[rightchild]->xkey < heap[smallest]->xkey))) {
10379         smallest = rightchild;
10380       }
10381     }
10382     if (smallest == eventnum) {
10383       notdone = 0;
10384     } else {
10385       heap[eventnum] = heap[smallest];
10386       heap[eventnum]->heapposition = eventnum;
10387       heap[smallest] = thisevent;
10388       thisevent->heapposition = smallest;
10389 
10390       eventnum = smallest;
10391       leftchild = 2 * eventnum + 1;
10392       notdone = leftchild < heapsize;
10393     }
10394   }
10395 }
10396 
10397 #endif /* not REDUCED */
10398 
10399 #ifndef REDUCED
10400 
10401 #ifdef ANSI_DECLARATORS
10402 void eventheapdelete(struct event **heap, int heapsize, int eventnum)
10403 #else /* not ANSI_DECLARATORS */
10404 void eventheapdelete(heap, heapsize, eventnum)
10405 struct event **heap;
10406 int heapsize;
10407 int eventnum;
10408 #endif /* not ANSI_DECLARATORS */
10409 
10410 {
10411   struct event *moveevent;
10412   REAL eventx, eventy;
10413   int parent;
10414   int notdone;
10415 
10416   moveevent = heap[heapsize - 1];
10417   if (eventnum > 0) {
10418     eventx = moveevent->xkey;
10419     eventy = moveevent->ykey;
10420     do {
10421       parent = (eventnum - 1) >> 1;
10422       if ((heap[parent]->ykey < eventy) ||
10423           ((heap[parent]->ykey == eventy)
10424            && (heap[parent]->xkey <= eventx))) {
10425         notdone = 0;
10426       } else {
10427         heap[eventnum] = heap[parent];
10428         heap[eventnum]->heapposition = eventnum;
10429 
10430         eventnum = parent;
10431         notdone = eventnum > 0;
10432       }
10433     } while (notdone);
10434   }
10435   heap[eventnum] = moveevent;
10436   moveevent->heapposition = eventnum;
10437   eventheapify(heap, heapsize - 1, eventnum);
10438 }
10439 
10440 #endif /* not REDUCED */
10441 
10442 #ifndef REDUCED
10443 
10444 #ifdef ANSI_DECLARATORS
10445 void createeventheap(struct mesh *m, struct event ***eventheap,
10446                      struct event **events, struct event **freeevents)
10447 #else /* not ANSI_DECLARATORS */
10448 void createeventheap(m, eventheap, events, freeevents)
10449 struct mesh *m;
10450 struct event ***eventheap;
10451 struct event **events;
10452 struct event **freeevents;
10453 #endif /* not ANSI_DECLARATORS */
10454 
10455 {
10456   vertex thisvertex;
10457   int maxevents;
10458   int i;
10459 
10460   maxevents = (3 * m->invertices) / 2;
10461   *eventheap = (struct event **) trimalloc(maxevents *
10462                                            (int) sizeof(struct event *));
10463   *events = (struct event *) trimalloc(maxevents * (int) sizeof(struct event));
10464   traversalinit(&m->vertices);
10465   for (i = 0; i < m->invertices; i++) {
10466     thisvertex = vertextraverse(m);
10467     (*events)[i].eventptr = (VOID *) thisvertex;
10468     (*events)[i].xkey = thisvertex[0];
10469     (*events)[i].ykey = thisvertex[1];
10470     eventheapinsert(*eventheap, i, *events + i);
10471   }
10472   *freeevents = (struct event *) NULL;
10473   for (i = maxevents - 1; i >= m->invertices; i--) {
10474     (*events)[i].eventptr = (VOID *) *freeevents;
10475     *freeevents = *events + i;
10476   }
10477 }
10478 
10479 #endif /* not REDUCED */
10480 
10481 #ifndef REDUCED
10482 
10483 #ifdef ANSI_DECLARATORS
10484 int rightofhyperbola(struct mesh *m, struct otri *fronttri, vertex newsite)
10485 #else /* not ANSI_DECLARATORS */
10486 int rightofhyperbola(m, fronttri, newsite)
10487 struct mesh *m;
10488 struct otri *fronttri;
10489 vertex newsite;
10490 #endif /* not ANSI_DECLARATORS */
10491 
10492 {
10493   vertex leftvertex, rightvertex;
10494   REAL dxa, dya, dxb, dyb;
10495 
10496   m->hyperbolacount++;
10497 
10498   dest(*fronttri, leftvertex);
10499   apex(*fronttri, rightvertex);
10500   if ((leftvertex[1] < rightvertex[1]) ||
10501       ((leftvertex[1] == rightvertex[1]) &&
10502        (leftvertex[0] < rightvertex[0]))) {
10503     if (newsite[0] >= rightvertex[0]) {
10504       return 1;
10505     }
10506   } else {
10507     if (newsite[0] <= leftvertex[0]) {
10508       return 0;
10509     }
10510   }
10511   dxa = leftvertex[0] - newsite[0];
10512   dya = leftvertex[1] - newsite[1];
10513   dxb = rightvertex[0] - newsite[0];
10514   dyb = rightvertex[1] - newsite[1];
10515   return dya * (dxb * dxb + dyb * dyb) > dyb * (dxa * dxa + dya * dya);
10516 }
10517 
10518 #endif /* not REDUCED */
10519 
10520 #ifndef REDUCED
10521 
10522 #ifdef ANSI_DECLARATORS
10523 REAL circletop(struct mesh *m, vertex pa, vertex pb, vertex pc, REAL ccwabc)
10524 #else /* not ANSI_DECLARATORS */
10525 REAL circletop(m, pa, pb, pc, ccwabc)
10526 struct mesh *m;
10527 vertex pa;
10528 vertex pb;
10529 vertex pc;
10530 REAL ccwabc;
10531 #endif /* not ANSI_DECLARATORS */
10532 
10533 {
10534   REAL xac, yac, xbc, ybc, xab, yab;
10535   REAL aclen2, bclen2, ablen2;
10536 
10537   m->circletopcount++;
10538 
10539   xac = pa[0] - pc[0];
10540   yac = pa[1] - pc[1];
10541   xbc = pb[0] - pc[0];
10542   ybc = pb[1] - pc[1];
10543   xab = pa[0] - pb[0];
10544   yab = pa[1] - pb[1];
10545   aclen2 = xac * xac + yac * yac;
10546   bclen2 = xbc * xbc + ybc * ybc;
10547   ablen2 = xab * xab + yab * yab;
10548   return pc[1] + (xac * bclen2 - xbc * aclen2 + sqrt(aclen2 * bclen2 * ablen2))
10549                / (2.0 * ccwabc);
10550 }
10551 
10552 #endif /* not REDUCED */
10553 
10554 #ifndef REDUCED
10555 
10556 #ifdef ANSI_DECLARATORS
10557 void check4deadevent(struct otri *checktri, struct event **freeevents,
10558                      struct event **eventheap, int *heapsize)
10559 #else /* not ANSI_DECLARATORS */
10560 void check4deadevent(checktri, freeevents, eventheap, heapsize)
10561 struct otri *checktri;
10562 struct event **freeevents;
10563 struct event **eventheap;
10564 int *heapsize;
10565 #endif /* not ANSI_DECLARATORS */
10566 
10567 {
10568   struct event *deadevent;
10569   vertex eventvertex;
10570   int eventnum;
10571 
10572   org(*checktri, eventvertex);
10573   if (eventvertex != (vertex) NULL) {
10574     deadevent = (struct event *) eventvertex;
10575     eventnum = deadevent->heapposition;
10576     deadevent->eventptr = (VOID *) *freeevents;
10577     *freeevents = deadevent;
10578     eventheapdelete(eventheap, *heapsize, eventnum);
10579     (*heapsize)--;
10580     setorg(*checktri, NULL);
10581   }
10582 }
10583 
10584 #endif /* not REDUCED */
10585 
10586 #ifndef REDUCED
10587 
10588 #ifdef ANSI_DECLARATORS
10589 struct splaynode *splay(struct mesh *m, struct splaynode *splaytree,
10590                         vertex searchpoint, struct otri *searchtri)
10591 #else /* not ANSI_DECLARATORS */
10592 struct splaynode *splay(m, splaytree, searchpoint, searchtri)
10593 struct mesh *m;
10594 struct splaynode *splaytree;
10595 vertex searchpoint;
10596 struct otri *searchtri;
10597 #endif /* not ANSI_DECLARATORS */
10598 
10599 {
10600   struct splaynode *child, *grandchild;
10601   struct splaynode *lefttree, *righttree;
10602   struct splaynode *leftright;
10603   vertex checkvertex;
10604   int rightofroot, rightofchild;
10605 
10606   if (splaytree == (struct splaynode *) NULL) {
10607     return (struct splaynode *) NULL;
10608   }
10609   dest(splaytree->keyedge, checkvertex);
10610   if (checkvertex == splaytree->keydest) {
10611     rightofroot = rightofhyperbola(m, &splaytree->keyedge, searchpoint);
10612     if (rightofroot) {
10613       otricopy(splaytree->keyedge, *searchtri);
10614       child = splaytree->rchild;
10615     } else {
10616       child = splaytree->lchild;
10617     }
10618     if (child == (struct splaynode *) NULL) {
10619       return splaytree;
10620     }
10621     dest(child->keyedge, checkvertex);
10622     if (checkvertex != child->keydest) {
10623       child = splay(m, child, searchpoint, searchtri);
10624       if (child == (struct splaynode *) NULL) {
10625         if (rightofroot) {
10626           splaytree->rchild = (struct splaynode *) NULL;
10627         } else {
10628           splaytree->lchild = (struct splaynode *) NULL;
10629         }
10630         return splaytree;
10631       }
10632     }
10633     rightofchild = rightofhyperbola(m, &child->keyedge, searchpoint);
10634     if (rightofchild) {
10635       otricopy(child->keyedge, *searchtri);
10636       grandchild = splay(m, child->rchild, searchpoint, searchtri);
10637       child->rchild = grandchild;
10638     } else {
10639       grandchild = splay(m, child->lchild, searchpoint, searchtri);
10640       child->lchild = grandchild;
10641     }
10642     if (grandchild == (struct splaynode *) NULL) {
10643       if (rightofroot) {
10644         splaytree->rchild = child->lchild;
10645         child->lchild = splaytree;
10646       } else {
10647         splaytree->lchild = child->rchild;
10648         child->rchild = splaytree;
10649       }
10650       return child;
10651     }
10652     if (rightofchild) {
10653       if (rightofroot) {
10654         splaytree->rchild = child->lchild;
10655         child->lchild = splaytree;
10656       } else {
10657         splaytree->lchild = grandchild->rchild;
10658         grandchild->rchild = splaytree;
10659       }
10660       child->rchild = grandchild->lchild;
10661       grandchild->lchild = child;
10662     } else {
10663       if (rightofroot) {
10664         splaytree->rchild = grandchild->lchild;
10665         grandchild->lchild = splaytree;
10666       } else {
10667         splaytree->lchild = child->rchild;
10668         child->rchild = splaytree;
10669       }
10670       child->lchild = grandchild->rchild;
10671       grandchild->rchild = child;
10672     }
10673     return grandchild;
10674   } else {
10675     lefttree = splay(m, splaytree->lchild, searchpoint, searchtri);
10676     righttree = splay(m, splaytree->rchild, searchpoint, searchtri);
10677 
10678     pooldealloc(&m->splaynodes, (VOID *) splaytree);
10679     if (lefttree == (struct splaynode *) NULL) {
10680       return righttree;
10681     } else if (righttree == (struct splaynode *) NULL) {
10682       return lefttree;
10683     } else if (lefttree->rchild == (struct splaynode *) NULL) {
10684       lefttree->rchild = righttree->lchild;
10685       righttree->lchild = lefttree;
10686       return righttree;
10687     } else if (righttree->lchild == (struct splaynode *) NULL) {
10688       righttree->lchild = lefttree->rchild;
10689       lefttree->rchild = righttree;
10690       return lefttree;
10691     } else {
10692 /*      printf("Holy Toledo!!!\n"); */
10693       leftright = lefttree->rchild;
10694       while (leftright->rchild != (struct splaynode *) NULL) {
10695         leftright = leftright->rchild;
10696       }
10697       leftright->rchild = righttree;
10698       return lefttree;
10699     }
10700   }
10701 }
10702 
10703 #endif /* not REDUCED */
10704 
10705 #ifndef REDUCED
10706 
10707 #ifdef ANSI_DECLARATORS
10708 struct splaynode *splayinsert(struct mesh *m, struct splaynode *splayroot,
10709                               struct otri *newkey, vertex searchpoint)
10710 #else /* not ANSI_DECLARATORS */
10711 struct splaynode *splayinsert(m, splayroot, newkey, searchpoint)
10712 struct mesh *m;
10713 struct splaynode *splayroot;
10714 struct otri *newkey;
10715 vertex searchpoint;
10716 #endif /* not ANSI_DECLARATORS */
10717 
10718 {
10719   struct splaynode *newsplaynode;
10720 
10721   newsplaynode = (struct splaynode *) poolalloc(&m->splaynodes);
10722   otricopy(*newkey, newsplaynode->keyedge);
10723   dest(*newkey, newsplaynode->keydest);
10724   if (splayroot == (struct splaynode *) NULL) {
10725     newsplaynode->lchild = (struct splaynode *) NULL;
10726     newsplaynode->rchild = (struct splaynode *) NULL;
10727   } else if (rightofhyperbola(m, &splayroot->keyedge, searchpoint)) {
10728     newsplaynode->lchild = splayroot;
10729     newsplaynode->rchild = splayroot->rchild;
10730     splayroot->rchild = (struct splaynode *) NULL;
10731   } else {
10732     newsplaynode->lchild = splayroot->lchild;
10733     newsplaynode->rchild = splayroot;
10734     splayroot->lchild = (struct splaynode *) NULL;
10735   }
10736   return newsplaynode;
10737 }
10738 
10739 #endif /* not REDUCED */
10740 
10741 #ifndef REDUCED
10742 
10743 #ifdef ANSI_DECLARATORS
10744 struct splaynode *circletopinsert(struct mesh *m, struct behavior *b,
10745                                   struct splaynode *splayroot,
10746                                   struct otri *newkey,
10747                                   vertex pa, vertex pb, vertex pc, REAL topy)
10748 #else /* not ANSI_DECLARATORS */
10749 struct splaynode *circletopinsert(m, b, splayroot, newkey, pa, pb, pc, topy)
10750 struct mesh *m;
10751 struct behavior *b;
10752 struct splaynode *splayroot;
10753 struct otri *newkey;
10754 vertex pa;
10755 vertex pb;
10756 vertex pc;
10757 REAL topy;
10758 #endif /* not ANSI_DECLARATORS */
10759 
10760 {
10761   REAL ccwabc;
10762   REAL xac, yac, xbc, ybc;
10763   REAL aclen2, bclen2;
10764   REAL searchpoint[2];
10765   struct otri dummytri;
10766 
10767   ccwabc = counterclockwise(m, b, pa, pb, pc);
10768   xac = pa[0] - pc[0];
10769   yac = pa[1] - pc[1];
10770   xbc = pb[0] - pc[0];
10771   ybc = pb[1] - pc[1];
10772   aclen2 = xac * xac + yac * yac;
10773   bclen2 = xbc * xbc + ybc * ybc;
10774   searchpoint[0] = pc[0] - (yac * bclen2 - ybc * aclen2) / (2.0 * ccwabc);
10775   searchpoint[1] = topy;
10776   return splayinsert(m, splay(m, splayroot, (vertex) searchpoint, &dummytri),
10777                      newkey, (vertex) searchpoint);
10778 }
10779 
10780 #endif /* not REDUCED */
10781 
10782 #ifndef REDUCED
10783 
10784 #ifdef ANSI_DECLARATORS
10785 struct splaynode *frontlocate(struct mesh *m, struct splaynode *splayroot,
10786                               struct otri *bottommost, vertex searchvertex,
10787                               struct otri *searchtri, int *farright)
10788 #else /* not ANSI_DECLARATORS */
10789 struct splaynode *frontlocate(m, splayroot, bottommost, searchvertex,
10790                               searchtri, farright)
10791 struct mesh *m;
10792 struct splaynode *splayroot;
10793 struct otri *bottommost;
10794 vertex searchvertex;
10795 struct otri *searchtri;
10796 int *farright;
10797 #endif /* not ANSI_DECLARATORS */
10798 
10799 {
10800   int farrightflag;
10801   triangle ptr;                       /* Temporary variable used by onext(). */
10802 
10803   otricopy(*bottommost, *searchtri);
10804   splayroot = splay(m, splayroot, searchvertex, searchtri);
10805 
10806   farrightflag = 0;
10807   while (!farrightflag && rightofhyperbola(m, searchtri, searchvertex)) {
10808     onextself(*searchtri);
10809     farrightflag = otriequal(*searchtri, *bottommost);
10810   }
10811   *farright = farrightflag;
10812   return splayroot;
10813 }
10814 
10815 #endif /* not REDUCED */
10816 
10817 #ifndef REDUCED
10818 
10819 #ifdef ANSI_DECLARATORS
10820 long sweeplinedelaunay(struct mesh *m, struct behavior *b)
10821 #else /* not ANSI_DECLARATORS */
10822 long sweeplinedelaunay(m, b)
10823 struct mesh *m;
10824 struct behavior *b;
10825 #endif /* not ANSI_DECLARATORS */
10826 
10827 {
10828   struct event **eventheap;
10829   struct event *events;
10830   struct event *freeevents;
10831   struct event *nextevent;
10832   struct event *newevent;
10833   struct splaynode *splayroot;
10834   struct otri bottommost;
10835   struct otri searchtri;
10836   struct otri fliptri;
10837   struct otri lefttri, righttri, farlefttri, farrighttri;
10838   struct otri inserttri;
10839   vertex firstvertex, secondvertex;
10840   vertex nextvertex, lastvertex;
10841   vertex connectvertex;
10842   vertex leftvertex, midvertex, rightvertex;
10843   REAL lefttest, righttest;
10844   int heapsize;
10845   int check4events, farrightflag;
10846   triangle ptr;   /* Temporary variable used by sym(), onext(), and oprev(). */
10847 
10848   poolinit(&m->splaynodes, sizeof(struct splaynode), SPLAYNODEPERBLOCK,
10849            SPLAYNODEPERBLOCK, 0);
10850   splayroot = (struct splaynode *) NULL;
10851 
10852   if (b->verbose) {
10853     printf("  Placing vertices in event heap.\n");
10854   }
10855   createeventheap(m, &eventheap, &events, &freeevents);
10856   heapsize = m->invertices;
10857 
10858   if (b->verbose) {
10859     printf("  Forming triangulation.\n");
10860   }
10861   maketriangle(m, b, &lefttri);
10862   maketriangle(m, b, &righttri);
10863   bond(lefttri, righttri);
10864   lnextself(lefttri);
10865   lprevself(righttri);
10866   bond(lefttri, righttri);
10867   lnextself(lefttri);
10868   lprevself(righttri);
10869   bond(lefttri, righttri);
10870   firstvertex = (vertex) eventheap[0]->eventptr;
10871   eventheap[0]->eventptr = (VOID *) freeevents;
10872   freeevents = eventheap[0];
10873   eventheapdelete(eventheap, heapsize, 0);
10874   heapsize--;
10875   do {
10876     if (heapsize == 0) {
10877       printf("Error:  Input vertices are all identical.\n");
10878       triexit(1);
10879     }
10880     secondvertex = (vertex) eventheap[0]->eventptr;
10881     eventheap[0]->eventptr = (VOID *) freeevents;
10882     freeevents = eventheap[0];
10883     eventheapdelete(eventheap, heapsize, 0);
10884     heapsize--;
10885     if ((firstvertex[0] == secondvertex[0]) &&
10886         (firstvertex[1] == secondvertex[1])) {
10887       if (!b->quiet) {
10888         printf(
10889 "Warning:  A duplicate vertex at (%.12g, %.12g) appeared and was ignored.\n",
10890                secondvertex[0], secondvertex[1]);
10891       }
10892       setvertextype(secondvertex, UNDEADVERTEX);
10893       m->undeads++;
10894     }
10895   } while ((firstvertex[0] == secondvertex[0]) &&
10896            (firstvertex[1] == secondvertex[1]));
10897   setorg(lefttri, firstvertex);
10898   setdest(lefttri, secondvertex);
10899   setorg(righttri, secondvertex);
10900   setdest(righttri, firstvertex);
10901   lprev(lefttri, bottommost);
10902   lastvertex = secondvertex;
10903   while (heapsize > 0) {
10904     nextevent = eventheap[0];
10905     eventheapdelete(eventheap, heapsize, 0);
10906     heapsize--;
10907     check4events = 1;
10908     if (nextevent->xkey < m->xmin) {
10909       decode(nextevent->eventptr, fliptri);
10910       oprev(fliptri, farlefttri);
10911       check4deadevent(&farlefttri, &freeevents, eventheap, &heapsize);
10912       onext(fliptri, farrighttri);
10913       check4deadevent(&farrighttri, &freeevents, eventheap, &heapsize);
10914 
10915       if (otriequal(farlefttri, bottommost)) {
10916         lprev(fliptri, bottommost);
10917       }
10918       flip(m, b, &fliptri);
10919       setapex(fliptri, NULL);
10920       lprev(fliptri, lefttri);
10921       lnext(fliptri, righttri);
10922       sym(lefttri, farlefttri);
10923 
10924       if (randomnation(SAMPLERATE) == 0) {
10925         symself(fliptri);
10926         dest(fliptri, leftvertex);
10927         apex(fliptri, midvertex);
10928         org(fliptri, rightvertex);
10929         splayroot = circletopinsert(m, b, splayroot, &lefttri, leftvertex,
10930                                     midvertex, rightvertex, nextevent->ykey);
10931       }
10932     } else {
10933       nextvertex = (vertex) nextevent->eventptr;
10934       if ((nextvertex[0] == lastvertex[0]) &&
10935           (nextvertex[1] == lastvertex[1])) {
10936         if (!b->quiet) {
10937           printf(
10938 "Warning:  A duplicate vertex at (%.12g, %.12g) appeared and was ignored.\n",
10939                  nextvertex[0], nextvertex[1]);
10940         }
10941         setvertextype(nextvertex, UNDEADVERTEX);
10942         m->undeads++;
10943         check4events = 0;
10944       } else {
10945         lastvertex = nextvertex;
10946 
10947         splayroot = frontlocate(m, splayroot, &bottommost, nextvertex,
10948                                 &searchtri, &farrightflag);
10949 /*
10950         otricopy(bottommost, searchtri);
10951         farrightflag = 0;
10952         while (!farrightflag && rightofhyperbola(m, &searchtri, nextvertex)) {
10953           onextself(searchtri);
10954           farrightflag = otriequal(searchtri, bottommost);
10955         }
10956 */
10957 
10958         check4deadevent(&searchtri, &freeevents, eventheap, &heapsize);
10959 
10960         otricopy(searchtri, farrighttri);
10961         sym(searchtri, farlefttri);
10962         maketriangle(m, b, &lefttri);
10963         maketriangle(m, b, &righttri);
10964         dest(farrighttri, connectvertex);
10965         setorg(lefttri, connectvertex);
10966         setdest(lefttri, nextvertex);
10967         setorg(righttri, nextvertex);
10968         setdest(righttri, connectvertex);
10969         bond(lefttri, righttri);
10970         lnextself(lefttri);
10971         lprevself(righttri);
10972         bond(lefttri, righttri);
10973         lnextself(lefttri);
10974         lprevself(righttri);
10975         bond(lefttri, farlefttri);
10976         bond(righttri, farrighttri);
10977         if (!farrightflag && otriequal(farrighttri, bottommost)) {
10978           otricopy(lefttri, bottommost);
10979         }
10980 
10981         if (randomnation(SAMPLERATE) == 0) {
10982           splayroot = splayinsert(m, splayroot, &lefttri, nextvertex);
10983         } else if (randomnation(SAMPLERATE) == 0) {
10984           lnext(righttri, inserttri);
10985           splayroot = splayinsert(m, splayroot, &inserttri, nextvertex);
10986         }
10987       }
10988     }
10989     nextevent->eventptr = (VOID *) freeevents;
10990     freeevents = nextevent;
10991 
10992     if (check4events) {
10993       apex(farlefttri, leftvertex);
10994       dest(lefttri, midvertex);
10995       apex(lefttri, rightvertex);
10996       lefttest = counterclockwise(m, b, leftvertex, midvertex, rightvertex);
10997       if (lefttest > 0.0) {
10998         newevent = freeevents;
10999         freeevents = (struct event *) freeevents->eventptr;
11000         newevent->xkey = m->xminextreme;
11001         newevent->ykey = circletop(m, leftvertex, midvertex, rightvertex,
11002                                    lefttest);
11003         newevent->eventptr = (VOID *) encode(lefttri);
11004         eventheapinsert(eventheap, heapsize, newevent);
11005         heapsize++;
11006         setorg(lefttri, newevent);
11007       }
11008       apex(righttri, leftvertex);
11009       org(righttri, midvertex);
11010       apex(farrighttri, rightvertex);
11011       righttest = counterclockwise(m, b, leftvertex, midvertex, rightvertex);
11012       if (righttest > 0.0) {
11013         newevent = freeevents;
11014         freeevents = (struct event *) freeevents->eventptr;
11015         newevent->xkey = m->xminextreme;
11016         newevent->ykey = circletop(m, leftvertex, midvertex, rightvertex,
11017                                    righttest);
11018         newevent->eventptr = (VOID *) encode(farrighttri);
11019         eventheapinsert(eventheap, heapsize, newevent);
11020         heapsize++;
11021         setorg(farrighttri, newevent);
11022       }
11023     }
11024   }
11025 
11026   pooldeinit(&m->splaynodes);
11027   lprevself(bottommost);
11028   return removeghosts(m, b, &bottommost);
11029 }
11030 
11031 #endif /* not REDUCED */
11032 
11033 /**                                                                         **/
11034 /**                                                                         **/
11035 /********* Sweepline Delaunay triangulation ends here                *********/
11036 
11037 /********* General mesh construction routines begin here             *********/
11038 /**                                                                         **/
11039 /**                                                                         **/
11040 
11041 /*****************************************************************************/
11042 /*                                                                           */
11043 /*  delaunay()   Form a Delaunay triangulation.                              */
11044 /*                                                                           */
11045 /*****************************************************************************/
11046 
11047 #ifdef ANSI_DECLARATORS
11048 long delaunay(struct mesh *m, struct behavior *b)
11049 #else /* not ANSI_DECLARATORS */
11050 long delaunay(m, b)
11051 struct mesh *m;
11052 struct behavior *b;
11053 #endif /* not ANSI_DECLARATORS */
11054 
11055 {
11056   long hulledges;
11057 
11058   m->eextras = 0;
11059   initializetrisubpools(m, b);
11060 
11061 #ifdef REDUCED
11062   if (!b->quiet) {
11063     printf(
11064       "Constructing Delaunay triangulation by divide-and-conquer method.\n");
11065   }
11066   hulledges = divconqdelaunay(m, b);
11067 #else /* not REDUCED */
11068   if (!b->quiet) {
11069     printf("Constructing Delaunay triangulation ");
11070     if (b->incremental) {
11071       printf("by incremental method.\n");
11072     } else if (b->sweepline) {
11073       printf("by sweepline method.\n");
11074     } else {
11075       printf("by divide-and-conquer method.\n");
11076     }
11077   }
11078   if (b->incremental) {
11079     hulledges = incrementaldelaunay(m, b);
11080   } else if (b->sweepline) {
11081     hulledges = sweeplinedelaunay(m, b);
11082   } else {
11083     hulledges = divconqdelaunay(m, b);
11084   }
11085 #endif /* not REDUCED */
11086 
11087   if (m->triangles.items == 0) {
11088     /* The input vertices were all collinear, so there are no triangles. */
11089     return 0l;
11090   } else {
11091     return hulledges;
11092   }
11093 }
11094 
11095 /*****************************************************************************/
11096 /*                                                                           */
11097 /*  reconstruct()   Reconstruct a triangulation from its .ele (and possibly  */
11098 /*                  .poly) file.  Used when the -r switch is used.           */
11099 /*                                                                           */
11100 /*  Reads an .ele file and reconstructs the original mesh.  If the -p switch */
11101 /*  is used, this procedure will also read a .poly file and reconstruct the  */
11102 /*  subsegments of the original mesh.  If the -a switch is used, this        */
11103 /*  procedure will also read an .area file and set a maximum area constraint */
11104 /*  on each triangle.                                                        */
11105 /*                                                                           */
11106 /*  Vertices that are not corners of triangles, such as nodes on edges of    */
11107 /*  subparametric elements, are discarded.                                   */
11108 /*                                                                           */
11109 /*  This routine finds the adjacencies between triangles (and subsegments)   */
11110 /*  by forming one stack of triangles for each vertex.  Each triangle is on  */
11111 /*  three different stacks simultaneously.  Each triangle's subsegment       */
11112 /*  pointers are used to link the items in each stack.  This memory-saving   */
11113 /*  feature makes the code harder to read.  The most important thing to keep */
11114 /*  in mind is that each triangle is removed from a stack precisely when     */
11115 /*  the corresponding pointer is adjusted to refer to a subsegment rather    */
11116 /*  than the next triangle of the stack.                                     */
11117 /*                                                                           */
11118 /*****************************************************************************/
11119 
11120 #ifndef CDT_ONLY
11121 
11122 #ifdef TRILIBRARY
11123 
11124 #ifdef ANSI_DECLARATORS
11125 int reconstruct(struct mesh *m, struct behavior *b, int *trianglelist,
11126                 REAL *triangleattriblist, REAL *trianglearealist,
11127                 int elements, int corners, int attribs,
11128                 int *segmentlist,int *segmentmarkerlist, int numberofsegments)
11129 #else /* not ANSI_DECLARATORS */
11130 int reconstruct(m, b, trianglelist, triangleattriblist, trianglearealist,
11131                 elements, corners, attribs, segmentlist, segmentmarkerlist,
11132                 numberofsegments)
11133 struct mesh *m;
11134 struct behavior *b;
11135 int *trianglelist;
11136 REAL *triangleattriblist;
11137 REAL *trianglearealist;
11138 int elements;
11139 int corners;
11140 int attribs;
11141 int *segmentlist;
11142 int *segmentmarkerlist;
11143 int numberofsegments;
11144 #endif /* not ANSI_DECLARATORS */
11145 
11146 #else /* not TRILIBRARY */
11147 
11148 #ifdef ANSI_DECLARATORS
11149 long reconstruct(struct mesh *m, struct behavior *b, char *elefilename,
11150                  char *areafilename, char *polyfilename, FILE *polyfile)
11151 #else /* not ANSI_DECLARATORS */
11152 long reconstruct(m, b, elefilename, areafilename, polyfilename, polyfile)
11153 struct mesh *m;
11154 struct behavior *b;
11155 char *elefilename;
11156 char *areafilename;
11157 char *polyfilename;
11158 FILE *polyfile;
11159 #endif /* not ANSI_DECLARATORS */
11160 
11161 #endif /* not TRILIBRARY */
11162 
11163 {
11164 #ifdef TRILIBRARY
11165   int vertexindex;
11166   int attribindex;
11167 #else /* not TRILIBRARY */
11168   FILE *elefile;
11169   FILE *areafile;
11170   char inputline[INPUTLINESIZE];
11171   char *stringptr;
11172   int areaelements;
11173 #endif /* not TRILIBRARY */
11174   struct otri triangleloop;
11175   struct otri triangleleft;
11176   struct otri checktri;
11177   struct otri checkleft;
11178   struct otri checkneighbor;
11179   struct osub subsegloop;
11180   triangle *vertexarray;
11181   triangle *prevlink;
11182   triangle nexttri;
11183   vertex tdest, tapex;
11184   vertex checkdest, checkapex;
11185   vertex shorg;
11186   vertex killvertex;
11187   vertex segmentorg, segmentdest;
11188   REAL area;
11189   int corner[3];
11190   int end[2];
11191   int killvertexindex;
11192   int incorners;
11193   int segmentmarkers;
11194   int boundmarker;
11195   int aroundvertex;
11196   long hullsize;
11197   int notfound;
11198   long elementnumber, segmentnumber;
11199   int i, j;
11200   triangle ptr;                         /* Temporary variable used by sym(). */
11201 
11202 #ifdef TRILIBRARY
11203   m->inelements = elements;
11204   incorners = corners;
11205   if (incorners < 3) {
11206     printf("Error:  Triangles must have at least 3 vertices.\n");
11207     triexit(1);
11208   }
11209   m->eextras = attribs;
11210 #else /* not TRILIBRARY */
11211   /* Read the triangles from an .ele file. */
11212   if (!b->quiet) {
11213     printf("Opening %s.\n", elefilename);
11214   }
11215   elefile = fopen(elefilename, "r");
11216   if (elefile == (FILE *) NULL) {
11217     printf("  Error:  Cannot access file %s.\n", elefilename);
11218     triexit(1);
11219   }
11220   /* Read number of triangles, number of vertices per triangle, and */
11221   /*   number of triangle attributes from .ele file.                */
11222   stringptr = readline(inputline, elefile, elefilename);
11223   m->inelements = (int) strtol(stringptr, &stringptr, 0);
11224   stringptr = findfield(stringptr);
11225   if (*stringptr == '\0') {
11226     incorners = 3;
11227   } else {
11228     incorners = (int) strtol(stringptr, &stringptr, 0);
11229     if (incorners < 3) {
11230       printf("Error:  Triangles in %s must have at least 3 vertices.\n",
11231              elefilename);
11232       triexit(1);
11233     }
11234   }
11235   stringptr = findfield(stringptr);
11236   if (*stringptr == '\0') {
11237     m->eextras = 0;
11238   } else {
11239     m->eextras = (int) strtol(stringptr, &stringptr, 0);
11240   }
11241 #endif /* not TRILIBRARY */
11242 
11243   initializetrisubpools(m, b);
11244 
11245   /* Create the triangles. */
11246   for (elementnumber = 1; elementnumber <= m->inelements; elementnumber++) {
11247     maketriangle(m, b, &triangleloop);
11248     /* Mark the triangle as living. */
11249     triangleloop.tri[3] = (triangle) triangleloop.tri;
11250   }
11251 
11252   segmentmarkers = 0;
11253   if (b->poly) {
11254 #ifdef TRILIBRARY
11255     m->insegments = numberofsegments;
11256     segmentmarkers = segmentmarkerlist != (int *) NULL;
11257 #else /* not TRILIBRARY */
11258     /* Read number of segments and number of segment */
11259     /*   boundary markers from .poly file.           */
11260     stringptr = readline(inputline, polyfile, b->inpolyfilename);
11261     m->insegments = (int) strtol(stringptr, &stringptr, 0);
11262     stringptr = findfield(stringptr);
11263     if (*stringptr != '\0') {
11264       segmentmarkers = (int) strtol(stringptr, &stringptr, 0);
11265     }
11266 #endif /* not TRILIBRARY */
11267 
11268     /* Create the subsegments. */
11269     for (segmentnumber = 1; segmentnumber <= m->insegments; segmentnumber++) {
11270       makesubseg(m, &subsegloop);
11271       /* Mark the subsegment as living. */
11272       subsegloop.ss[2] = (subseg) subsegloop.ss;
11273     }
11274   }
11275 
11276 #ifdef TRILIBRARY
11277   vertexindex = 0;
11278   attribindex = 0;
11279 #else /* not TRILIBRARY */
11280   if (b->vararea) {
11281     /* Open an .area file, check for consistency with the .ele file. */
11282     if (!b->quiet) {
11283       printf("Opening %s.\n", areafilename);
11284     }
11285     areafile = fopen(areafilename, "r");
11286     if (areafile == (FILE *) NULL) {
11287       printf("  Error:  Cannot access file %s.\n", areafilename);
11288       triexit(1);
11289     }
11290     stringptr = readline(inputline, areafile, areafilename);
11291     areaelements = (int) strtol(stringptr, &stringptr, 0);
11292     if (areaelements != m->inelements) {
11293       printf("Error:  %s and %s disagree on number of triangles.\n",
11294              elefilename, areafilename);
11295       triexit(1);
11296     }
11297   }
11298 #endif /* not TRILIBRARY */
11299 
11300   if (!b->quiet) {
11301     printf("Reconstructing mesh.\n");
11302   }
11303   /* Allocate a temporary array that maps each vertex to some adjacent */
11304   /*   triangle.  I took care to allocate all the permanent memory for */
11305   /*   triangles and subsegments first.                                */
11306   vertexarray = (triangle *) trimalloc(m->vertices.items *
11307                                        (int) sizeof(triangle));
11308   /* Each vertex is initially unrepresented. */
11309   for (i = 0; i < m->vertices.items; i++) {
11310     vertexarray[i] = (triangle) m->dummytri;
11311   }
11312 
11313   if (b->verbose) {
11314     printf("  Assembling triangles.\n");
11315   }
11316   /* Read the triangles from the .ele file, and link */
11317   /*   together those that share an edge.            */
11318   traversalinit(&m->triangles);
11319   triangleloop.tri = triangletraverse(m);
11320   elementnumber = b->firstnumber;
11321   while (triangleloop.tri != (triangle *) NULL) {
11322 #ifdef TRILIBRARY
11323     /* Copy the triangle's three corners. */
11324     for (j = 0; j < 3; j++) {
11325       corner[j] = trianglelist[vertexindex++];
11326       if ((corner[j] < b->firstnumber) ||
11327           (corner[j] >= b->firstnumber + m->invertices)) {
11328         printf("Error:  Triangle %ld has an invalid vertex index.\n",
11329                elementnumber);
11330         triexit(1);
11331       }
11332     }
11333 #else /* not TRILIBRARY */
11334     /* Read triangle number and the triangle's three corners. */
11335     stringptr = readline(inputline, elefile, elefilename);
11336     for (j = 0; j < 3; j++) {
11337       stringptr = findfield(stringptr);
11338       if (*stringptr == '\0') {
11339         printf("Error:  Triangle %ld is missing vertex %d in %s.\n",
11340                elementnumber, j + 1, elefilename);
11341         triexit(1);
11342       } else {
11343         corner[j] = (int) strtol(stringptr, &stringptr, 0);
11344         if ((corner[j] < b->firstnumber) ||
11345             (corner[j] >= b->firstnumber + m->invertices)) {
11346           printf("Error:  Triangle %ld has an invalid vertex index.\n",
11347                  elementnumber);
11348           triexit(1);
11349         }
11350       }
11351     }
11352 #endif /* not TRILIBRARY */
11353 
11354     /* Find out about (and throw away) extra nodes. */
11355     for (j = 3; j < incorners; j++) {
11356 #ifdef TRILIBRARY
11357       killvertexindex = trianglelist[vertexindex++];
11358 #else /* not TRILIBRARY */
11359       stringptr = findfield(stringptr);
11360       if (*stringptr != '\0') {
11361         killvertexindex = (int) strtol(stringptr, &stringptr, 0);
11362 #endif /* not TRILIBRARY */
11363         if ((killvertexindex >= b->firstnumber) &&
11364             (killvertexindex < b->firstnumber + m->invertices)) {
11365           /* Delete the non-corner vertex if it's not already deleted. */
11366           killvertex = getvertex(m, b, killvertexindex);
11367           if (vertextype(killvertex) != DEADVERTEX) {
11368             vertexdealloc(m, killvertex);
11369           }
11370         }
11371 #ifndef TRILIBRARY
11372       }
11373 #endif /* not TRILIBRARY */
11374     }
11375 
11376     /* Read the triangle's attributes. */
11377     for (j = 0; j < m->eextras; j++) {
11378 #ifdef TRILIBRARY
11379       setelemattribute(triangleloop, j, triangleattriblist[attribindex++]);
11380 #else /* not TRILIBRARY */
11381       stringptr = findfield(stringptr);
11382       if (*stringptr == '\0') {
11383         setelemattribute(triangleloop, j, 0);
11384       } else {
11385         setelemattribute(triangleloop, j,
11386                          (REAL) strtod(stringptr, &stringptr));
11387       }
11388 #endif /* not TRILIBRARY */
11389     }
11390 
11391     if (b->vararea) {
11392 #ifdef TRILIBRARY
11393       area = trianglearealist[elementnumber - b->firstnumber];
11394 #else /* not TRILIBRARY */
11395       /* Read an area constraint from the .area file. */
11396       stringptr = readline(inputline, areafile, areafilename);
11397       stringptr = findfield(stringptr);
11398       if (*stringptr == '\0') {
11399         area = -1.0;                      /* No constraint on this triangle. */
11400       } else {
11401         area = (REAL) strtod(stringptr, &stringptr);
11402       }
11403 #endif /* not TRILIBRARY */
11404       setareabound(triangleloop, area);
11405     }
11406 
11407     /* Set the triangle's vertices. */
11408     triangleloop.orient = 0;
11409     setorg(triangleloop, getvertex(m, b, corner[0]));
11410     setdest(triangleloop, getvertex(m, b, corner[1]));
11411     setapex(triangleloop, getvertex(m, b, corner[2]));
11412     /* Try linking the triangle to others that share these vertices. */
11413     for (triangleloop.orient = 0; triangleloop.orient < 3;
11414          triangleloop.orient++) {
11415       /* Take the number for the origin of triangleloop. */
11416       aroundvertex = corner[triangleloop.orient];
11417       /* Look for other triangles having this vertex. */
11418       nexttri = vertexarray[aroundvertex - b->firstnumber];
11419       /* Link the current triangle to the next one in the stack. */
11420       triangleloop.tri[6 + triangleloop.orient] = nexttri;
11421       /* Push the current triangle onto the stack. */
11422       vertexarray[aroundvertex - b->firstnumber] = encode(triangleloop);
11423       decode(nexttri, checktri);
11424       if (checktri.tri != m->dummytri) {
11425         dest(triangleloop, tdest);
11426         apex(triangleloop, tapex);
11427         /* Look for other triangles that share an edge. */
11428         do {
11429           dest(checktri, checkdest);
11430           apex(checktri, checkapex);
11431           if (tapex == checkdest) {
11432             /* The two triangles share an edge; bond them together. */
11433             lprev(triangleloop, triangleleft);
11434             bond(triangleleft, checktri);
11435           }
11436           if (tdest == checkapex) {
11437             /* The two triangles share an edge; bond them together. */
11438             lprev(checktri, checkleft);
11439             bond(triangleloop, checkleft);
11440           }
11441           /* Find the next triangle in the stack. */
11442           nexttri = checktri.tri[6 + checktri.orient];
11443           decode(nexttri, checktri);
11444         } while (checktri.tri != m->dummytri);
11445       }
11446     }
11447     triangleloop.tri = triangletraverse(m);
11448     elementnumber++;
11449   }
11450 
11451 #ifdef TRILIBRARY
11452   vertexindex = 0;
11453 #else /* not TRILIBRARY */
11454   fclose(elefile);
11455   if (b->vararea) {
11456     fclose(areafile);
11457   }
11458 #endif /* not TRILIBRARY */
11459 
11460   hullsize = 0;                      /* Prepare to count the boundary edges. */
11461   if (b->poly) {
11462     if (b->verbose) {
11463       printf("  Marking segments in triangulation.\n");
11464     }
11465     /* Read the segments from the .poly file, and link them */
11466     /*   to their neighboring triangles.                    */
11467     boundmarker = 0;
11468     traversalinit(&m->subsegs);
11469     subsegloop.ss = subsegtraverse(m);
11470     segmentnumber = b->firstnumber;
11471     while (subsegloop.ss != (subseg *) NULL) {
11472 #ifdef TRILIBRARY
11473       end[0] = segmentlist[vertexindex++];
11474       end[1] = segmentlist[vertexindex++];
11475       if (segmentmarkers) {
11476         boundmarker = segmentmarkerlist[segmentnumber - b->firstnumber];
11477       }
11478 #else /* not TRILIBRARY */
11479       /* Read the endpoints of each segment, and possibly a boundary marker. */
11480       stringptr = readline(inputline, polyfile, b->inpolyfilename);
11481       /* Skip the first (segment number) field. */
11482       stringptr = findfield(stringptr);
11483       if (*stringptr == '\0') {
11484         printf("Error:  Segment %ld has no endpoints in %s.\n", segmentnumber,
11485                polyfilename);
11486         triexit(1);
11487       } else {
11488         end[0] = (int) strtol(stringptr, &stringptr, 0);
11489       }
11490       stringptr = findfield(stringptr);
11491       if (*stringptr == '\0') {
11492         printf("Error:  Segment %ld is missing its second endpoint in %s.\n",
11493                segmentnumber, polyfilename);
11494         triexit(1);
11495       } else {
11496         end[1] = (int) strtol(stringptr, &stringptr, 0);
11497       }
11498       if (segmentmarkers) {
11499         stringptr = findfield(stringptr);
11500         if (*stringptr == '\0') {
11501           boundmarker = 0;
11502         } else {
11503           boundmarker = (int) strtol(stringptr, &stringptr, 0);
11504         }
11505       }
11506 #endif /* not TRILIBRARY */
11507       for (j = 0; j < 2; j++) {
11508         if ((end[j] < b->firstnumber) ||
11509             (end[j] >= b->firstnumber + m->invertices)) {
11510           printf("Error:  Segment %ld has an invalid vertex index.\n",
11511                  segmentnumber);
11512           triexit(1);
11513         }
11514       }
11515 
11516       /* set the subsegment's vertices. */
11517       subsegloop.ssorient = 0;
11518       segmentorg = getvertex(m, b, end[0]);
11519       segmentdest = getvertex(m, b, end[1]);
11520       setsorg(subsegloop, segmentorg);
11521       setsdest(subsegloop, segmentdest);
11522       setsegorg(subsegloop, segmentorg);
11523       setsegdest(subsegloop, segmentdest);
11524       setmark(subsegloop, boundmarker);
11525       /* Try linking the subsegment to triangles that share these vertices. */
11526       for (subsegloop.ssorient = 0; subsegloop.ssorient < 2;
11527            subsegloop.ssorient++) {
11528         /* Take the number for the destination of subsegloop. */
11529         aroundvertex = end[1 - subsegloop.ssorient];
11530         /* Look for triangles having this vertex. */
11531         prevlink = &vertexarray[aroundvertex - b->firstnumber];
11532         nexttri = vertexarray[aroundvertex - b->firstnumber];
11533         decode(nexttri, checktri);
11534         sorg(subsegloop, shorg);
11535         notfound = 1;
11536         /* Look for triangles having this edge.  Note that I'm only       */
11537         /*   comparing each triangle's destination with the subsegment;   */
11538         /*   each triangle's apex is handled through a different vertex.  */
11539         /*   Because each triangle appears on three vertices' lists, each */
11540         /*   occurrence of a triangle on a list can (and does) represent  */
11541         /*   an edge.  In this way, most edges are represented twice, and */
11542         /*   every triangle-subsegment bond is represented once.          */
11543         while (notfound && (checktri.tri != m->dummytri)) {
11544           dest(checktri, checkdest);
11545           if (shorg == checkdest) {
11546             /* We have a match.  Remove this triangle from the list. */
11547             *prevlink = checktri.tri[6 + checktri.orient];
11548             /* Bond the subsegment to the triangle. */
11549             tsbond(checktri, subsegloop);
11550             /* Check if this is a boundary edge. */
11551             sym(checktri, checkneighbor);
11552             if (checkneighbor.tri == m->dummytri) {
11553               /* The next line doesn't insert a subsegment (because there's */
11554               /*   already one there), but it sets the boundary markers of  */
11555               /*   the existing subsegment and its vertices.                */
11556               insertsubseg(m, b, &checktri, 1);
11557               hullsize++;
11558             }
11559             notfound = 0;
11560           }
11561           /* Find the next triangle in the stack. */
11562           prevlink = &checktri.tri[6 + checktri.orient];
11563           nexttri = checktri.tri[6 + checktri.orient];
11564           decode(nexttri, checktri);
11565         }
11566       }
11567       subsegloop.ss = subsegtraverse(m);
11568       segmentnumber++;
11569     }
11570   }
11571 
11572   /* Mark the remaining edges as not being attached to any subsegment. */
11573   /* Also, count the (yet uncounted) boundary edges.                   */
11574   for (i = 0; i < m->vertices.items; i++) {
11575     /* Search the stack of triangles adjacent to a vertex. */
11576     nexttri = vertexarray[i];
11577     decode(nexttri, checktri);
11578     while (checktri.tri != m->dummytri) {
11579       /* Find the next triangle in the stack before this */
11580       /*   information gets overwritten.                 */
11581       nexttri = checktri.tri[6 + checktri.orient];
11582       /* No adjacent subsegment.  (This overwrites the stack info.) */
11583       tsdissolve(checktri);
11584       sym(checktri, checkneighbor);
11585       if (checkneighbor.tri == m->dummytri) {
11586         insertsubseg(m, b, &checktri, 1);
11587         hullsize++;
11588       }
11589       decode(nexttri, checktri);
11590     }
11591   }
11592 
11593   trifree((VOID *) vertexarray);
11594   return hullsize;
11595 }
11596 
11597 #endif /* not CDT_ONLY */
11598 
11599 /**                                                                         **/
11600 /**                                                                         **/
11601 /********* General mesh construction routines end here               *********/
11602 
11603 /********* Segment insertion begins here                             *********/
11604 /**                                                                         **/
11605 /**                                                                         **/
11606 
11607 /*****************************************************************************/
11608 /*                                                                           */
11609 /*  finddirection()   Find the first triangle on the path from one point     */
11610 /*                    to another.                                            */
11611 /*                                                                           */
11612 /*  Finds the triangle that intersects a line segment drawn from the         */
11613 /*  origin of `searchtri' to the point `searchpoint', and returns the result */
11614 /*  in `searchtri'.  The origin of `searchtri' does not change, even though  */
11615 /*  the triangle returned may differ from the one passed in.  This routine   */
11616 /*  is used to find the direction to move in to get from one point to        */
11617 /*  another.                                                                 */
11618 /*                                                                           */
11619 /*  The return value notes whether the destination or apex of the found      */
11620 /*  triangle is collinear with the two points in question.                   */
11621 /*                                                                           */
11622 /*****************************************************************************/
11623 
11624 #ifdef ANSI_DECLARATORS
11625 enum finddirectionresult finddirection(struct mesh *m, struct behavior *b,
11626                                        struct otri *searchtri,
11627                                        vertex searchpoint)
11628 #else /* not ANSI_DECLARATORS */
11629 enum finddirectionresult finddirection(m, b, searchtri, searchpoint)
11630 struct mesh *m;
11631 struct behavior *b;
11632 struct otri *searchtri;
11633 vertex searchpoint;
11634 #endif /* not ANSI_DECLARATORS */
11635 
11636 {
11637   struct otri checktri;
11638   vertex startvertex;
11639   vertex leftvertex, rightvertex;
11640   REAL leftccw, rightccw;
11641   int leftflag, rightflag;
11642   triangle ptr;           /* Temporary variable used by onext() and oprev(). */
11643 
11644   org(*searchtri, startvertex);
11645   dest(*searchtri, rightvertex);
11646   apex(*searchtri, leftvertex);
11647   /* Is `searchpoint' to the left? */
11648   leftccw = counterclockwise(m, b, searchpoint, startvertex, leftvertex);
11649   leftflag = leftccw > 0.0;
11650   /* Is `searchpoint' to the right? */
11651   rightccw = counterclockwise(m, b, startvertex, searchpoint, rightvertex);
11652   rightflag = rightccw > 0.0;
11653   if (leftflag && rightflag) {
11654     /* `searchtri' faces directly away from `searchpoint'.  We could go left */
11655     /*   or right.  Ask whether it's a triangle or a boundary on the left.   */
11656     onext(*searchtri, checktri);
11657     if (checktri.tri == m->dummytri) {
11658       leftflag = 0;
11659     } else {
11660       rightflag = 0;
11661     }
11662   }
11663   while (leftflag) {
11664     /* Turn left until satisfied. */
11665     onextself(*searchtri);
11666     if (searchtri->tri == m->dummytri) {
11667       printf("Internal error in finddirection():  Unable to find a\n");
11668       printf("  triangle leading from (%.12g, %.12g) to", startvertex[0],
11669              startvertex[1]);
11670       printf("  (%.12g, %.12g).\n", searchpoint[0], searchpoint[1]);
11671       internalerror();
11672     }
11673     apex(*searchtri, leftvertex);
11674     rightccw = leftccw;
11675     leftccw = counterclockwise(m, b, searchpoint, startvertex, leftvertex);
11676     leftflag = leftccw > 0.0;
11677   }
11678   while (rightflag) {
11679     /* Turn right until satisfied. */
11680     oprevself(*searchtri);
11681     if (searchtri->tri == m->dummytri) {
11682       printf("Internal error in finddirection():  Unable to find a\n");
11683       printf("  triangle leading from (%.12g, %.12g) to", startvertex[0],
11684              startvertex[1]);
11685       printf("  (%.12g, %.12g).\n", searchpoint[0], searchpoint[1]);
11686       internalerror();
11687     }
11688     dest(*searchtri, rightvertex);
11689     leftccw = rightccw;
11690     rightccw = counterclockwise(m, b, startvertex, searchpoint, rightvertex);
11691     rightflag = rightccw > 0.0;
11692   }
11693   if (leftccw == 0.0) {
11694     return LEFTCOLLINEAR;
11695   } else if (rightccw == 0.0) {
11696     return RIGHTCOLLINEAR;
11697   } else {
11698     return WITHIN;
11699   }
11700 }
11701 
11702 /*****************************************************************************/
11703 /*                                                                           */
11704 /*  segmentintersection()   Find the intersection of an existing segment     */
11705 /*                          and a segment that is being inserted.  Insert    */
11706 /*                          a vertex at the intersection, splitting an       */
11707 /*                          existing subsegment.                             */
11708 /*                                                                           */
11709 /*  The segment being inserted connects the apex of splittri to endpoint2.   */
11710 /*  splitsubseg is the subsegment being split, and MUST adjoin splittri.     */
11711 /*  Hence, endpoints of the subsegment being split are the origin and        */
11712 /*  destination of splittri.                                                 */
11713 /*                                                                           */
11714 /*  On completion, splittri is a handle having the newly inserted            */
11715 /*  intersection point as its origin, and endpoint1 as its destination.      */
11716 /*                                                                           */
11717 /*****************************************************************************/
11718 
11719 #ifdef ANSI_DECLARATORS
11720 void segmentintersection(struct mesh *m, struct behavior *b,
11721                          struct otri *splittri, struct osub *splitsubseg,
11722                          vertex endpoint2)
11723 #else /* not ANSI_DECLARATORS */
11724 void segmentintersection(m, b, splittri, splitsubseg, endpoint2)
11725 struct mesh *m;
11726 struct behavior *b;
11727 struct otri *splittri;
11728 struct osub *splitsubseg;
11729 vertex endpoint2;
11730 #endif /* not ANSI_DECLARATORS */
11731 
11732 {
11733   struct osub opposubseg;
11734   vertex endpoint1;
11735   vertex torg, tdest;
11736   vertex leftvertex, rightvertex;
11737   vertex newvertex;
11738   enum insertvertexresult success;
11739   enum finddirectionresult collinear;
11740   REAL ex, ey;
11741   REAL tx, ty;
11742   REAL etx, ety;
11743   REAL split, denom;
11744   int i;
11745   triangle ptr;                       /* Temporary variable used by onext(). */
11746   subseg sptr;                        /* Temporary variable used by snext(). */
11747 
11748   /* Find the other three segment endpoints. */
11749   apex(*splittri, endpoint1);
11750   org(*splittri, torg);
11751   dest(*splittri, tdest);
11752   /* Segment intersection formulae; see the Antonio reference. */
11753   tx = tdest[0] - torg[0];
11754   ty = tdest[1] - torg[1];
11755   ex = endpoint2[0] - endpoint1[0];
11756   ey = endpoint2[1] - endpoint1[1];
11757   etx = torg[0] - endpoint2[0];
11758   ety = torg[1] - endpoint2[1];
11759   denom = ty * ex - tx * ey;
11760   if (denom == 0.0) {
11761     printf("Internal error in segmentintersection():");
11762     printf("  Attempt to find intersection of parallel segments.\n");
11763     internalerror();
11764   }
11765   split = (ey * etx - ex * ety) / denom;
11766   /* Create the new vertex. */
11767   newvertex = (vertex) poolalloc(&m->vertices);
11768   /* Interpolate its coordinate and attributes. */
11769   for (i = 0; i < 2 + m->nextras; i++) {
11770     newvertex[i] = torg[i] + split * (tdest[i] - torg[i]);
11771   }
11772   setvertexmark(newvertex, mark(*splitsubseg));
11773   setvertextype(newvertex, INPUTVERTEX);
11774   if (b->verbose > 1) {
11775     printf(
11776   "  Splitting subsegment (%.12g, %.12g) (%.12g, %.12g) at (%.12g, %.12g).\n",
11777            torg[0], torg[1], tdest[0], tdest[1], newvertex[0], newvertex[1]);
11778   }
11779   /* Insert the intersection vertex.  This should always succeed. */
11780   success = insertvertex(m, b, newvertex, splittri, splitsubseg, 0, 0);
11781   if (success != SUCCESSFULVERTEX) {
11782     printf("Internal error in segmentintersection():\n");
11783     printf("  Failure to split a segment.\n");
11784     internalerror();
11785   }
11786   /* Record a triangle whose origin is the new vertex. */
11787   setvertex2tri(newvertex, encode(*splittri));
11788   if (m->steinerleft > 0) {
11789     m->steinerleft--;
11790   }
11791 
11792   /* Divide the segment into two, and correct the segment endpoints. */
11793   ssymself(*splitsubseg);
11794   spivot(*splitsubseg, opposubseg);
11795   sdissolve(*splitsubseg);
11796   sdissolve(opposubseg);
11797   do {
11798     setsegorg(*splitsubseg, newvertex);
11799     snextself(*splitsubseg);
11800   } while (splitsubseg->ss != m->dummysub);
11801   do {
11802     setsegorg(opposubseg, newvertex);
11803     snextself(opposubseg);
11804   } while (opposubseg.ss != m->dummysub);
11805 
11806   /* Inserting the vertex may have caused edge flips.  We wish to rediscover */
11807   /*   the edge connecting endpoint1 to the new intersection vertex.         */
11808   collinear = finddirection(m, b, splittri, endpoint1);
11809   dest(*splittri, rightvertex);
11810   apex(*splittri, leftvertex);
11811   if ((leftvertex[0] == endpoint1[0]) && (leftvertex[1] == endpoint1[1])) {
11812     onextself(*splittri);
11813   } else if ((rightvertex[0] != endpoint1[0]) ||
11814              (rightvertex[1] != endpoint1[1])) {
11815     printf("Internal error in segmentintersection():\n");
11816     printf("  Topological inconsistency after splitting a segment.\n");
11817     internalerror();
11818   }
11819   /* `splittri' should have destination endpoint1. */
11820 }
11821 
11822 /*****************************************************************************/
11823 /*                                                                           */
11824 /*  scoutsegment()   Scout the first triangle on the path from one endpoint  */
11825 /*                   to another, and check for completion (reaching the      */
11826 /*                   second endpoint), a collinear vertex, or the            */
11827 /*                   intersection of two segments.                           */
11828 /*                                                                           */
11829 /*  Returns one if the entire segment is successfully inserted, and zero if  */
11830 /*  the job must be finished by conformingedge() or constrainededge().       */
11831 /*                                                                           */
11832 /*  If the first triangle on the path has the second endpoint as its         */
11833 /*  destination or apex, a subsegment is inserted and the job is done.       */
11834 /*                                                                           */
11835 /*  If the first triangle on the path has a destination or apex that lies on */
11836 /*  the segment, a subsegment is inserted connecting the first endpoint to   */
11837 /*  the collinear vertex, and the search is continued from the collinear     */
11838 /*  vertex.                                                                  */
11839 /*                                                                           */
11840 /*  If the first triangle on the path has a subsegment opposite its origin,  */
11841 /*  then there is a segment that intersects the segment being inserted.      */
11842 /*  Their intersection vertex is inserted, splitting the subsegment.         */
11843 /*                                                                           */
11844 /*****************************************************************************/
11845 
11846 #ifdef ANSI_DECLARATORS
11847 int scoutsegment(struct mesh *m, struct behavior *b, struct otri *searchtri,
11848                  vertex endpoint2, int newmark)
11849 #else /* not ANSI_DECLARATORS */
11850 int scoutsegment(m, b, searchtri, endpoint2, newmark)
11851 struct mesh *m;
11852 struct behavior *b;
11853 struct otri *searchtri;
11854 vertex endpoint2;
11855 int newmark;
11856 #endif /* not ANSI_DECLARATORS */
11857 
11858 {
11859   struct otri crosstri;
11860   struct osub crosssubseg;
11861   vertex leftvertex, rightvertex;
11862   enum finddirectionresult collinear;
11863   subseg sptr;                      /* Temporary variable used by tspivot(). */
11864 
11865   collinear = finddirection(m, b, searchtri, endpoint2);
11866   dest(*searchtri, rightvertex);
11867   apex(*searchtri, leftvertex);
11868   if (((leftvertex[0] == endpoint2[0]) && (leftvertex[1] == endpoint2[1])) ||
11869       ((rightvertex[0] == endpoint2[0]) && (rightvertex[1] == endpoint2[1]))) {
11870     /* The segment is already an edge in the mesh. */
11871     if ((leftvertex[0] == endpoint2[0]) && (leftvertex[1] == endpoint2[1])) {
11872       lprevself(*searchtri);
11873     }
11874     /* Insert a subsegment, if there isn't already one there. */
11875     insertsubseg(m, b, searchtri, newmark);
11876     return 1;
11877   } else if (collinear == LEFTCOLLINEAR) {
11878     /* We've collided with a vertex between the segment's endpoints. */
11879     /* Make the collinear vertex be the triangle's origin. */
11880     lprevself(*searchtri);
11881     insertsubseg(m, b, searchtri, newmark);
11882     /* Insert the remainder of the segment. */
11883     return scoutsegment(m, b, searchtri, endpoint2, newmark);
11884   } else if (collinear == RIGHTCOLLINEAR) {
11885     /* We've collided with a vertex between the segment's endpoints. */
11886     insertsubseg(m, b, searchtri, newmark);
11887     /* Make the collinear vertex be the triangle's origin. */
11888     lnextself(*searchtri);
11889     /* Insert the remainder of the segment. */
11890     return scoutsegment(m, b, searchtri, endpoint2, newmark);
11891   } else {
11892     lnext(*searchtri, crosstri);
11893     tspivot(crosstri, crosssubseg);
11894     /* Check for a crossing segment. */
11895     if (crosssubseg.ss == m->dummysub) {
11896       return 0;
11897     } else {
11898       /* Insert a vertex at the intersection. */
11899       segmentintersection(m, b, &crosstri, &crosssubseg, endpoint2);
11900       otricopy(crosstri, *searchtri);
11901       insertsubseg(m, b, searchtri, newmark);
11902       /* Insert the remainder of the segment. */
11903       return scoutsegment(m, b, searchtri, endpoint2, newmark);
11904     }
11905   }
11906 }
11907 
11908 /*****************************************************************************/
11909 /*                                                                           */
11910 /*  conformingedge()   Force a segment into a conforming Delaunay            */
11911 /*                     triangulation by inserting a vertex at its midpoint,  */
11912 /*                     and recursively forcing in the two half-segments if   */
11913 /*                     necessary.                                            */
11914 /*                                                                           */
11915 /*  Generates a sequence of subsegments connecting `endpoint1' to            */
11916 /*  `endpoint2'.  `newmark' is the boundary marker of the segment, assigned  */
11917 /*  to each new splitting vertex and subsegment.                             */
11918 /*                                                                           */
11919 /*  Note that conformingedge() does not always maintain the conforming       */
11920 /*  Delaunay property.  Once inserted, segments are locked into place;       */
11921 /*  vertices inserted later (to force other segments in) may render these    */
11922 /*  fixed segments non-Delaunay.  The conforming Delaunay property will be   */
11923 /*  restored by enforcequality() by splitting encroached subsegments.        */
11924 /*                                                                           */
11925 /*****************************************************************************/
11926 
11927 #ifndef REDUCED
11928 #ifndef CDT_ONLY
11929 
11930 #ifdef ANSI_DECLARATORS
11931 void conformingedge(struct mesh *m, struct behavior *b,
11932                     vertex endpoint1, vertex endpoint2, int newmark)
11933 #else /* not ANSI_DECLARATORS */
11934 void conformingedge(m, b, endpoint1, endpoint2, newmark)
11935 struct mesh *m;
11936 struct behavior *b;
11937 vertex endpoint1;
11938 vertex endpoint2;
11939 int newmark;
11940 #endif /* not ANSI_DECLARATORS */
11941 
11942 {
11943   struct otri searchtri1, searchtri2;
11944   struct osub brokensubseg;
11945   vertex newvertex;
11946   vertex midvertex1, midvertex2;
11947   enum insertvertexresult success;
11948   int i;
11949   subseg sptr;                      /* Temporary variable used by tspivot(). */
11950 
11951   if (b->verbose > 2) {
11952     printf("Forcing segment into triangulation by recursive splitting:\n");
11953     printf("  (%.12g, %.12g) (%.12g, %.12g)\n", endpoint1[0], endpoint1[1],
11954            endpoint2[0], endpoint2[1]);
11955   }
11956   /* Create a new vertex to insert in the middle of the segment. */
11957   newvertex = (vertex) poolalloc(&m->vertices);
11958   /* Interpolate coordinates and attributes. */
11959   for (i = 0; i < 2 + m->nextras; i++) {
11960     newvertex[i] = 0.5 * (endpoint1[i] + endpoint2[i]);
11961   }
11962   setvertexmark(newvertex, newmark);
11963   setvertextype(newvertex, SEGMENTVERTEX);
11964   /* No known triangle to search from. */
11965   searchtri1.tri = m->dummytri;
11966   /* Attempt to insert the new vertex. */
11967   success = insertvertex(m, b, newvertex, &searchtri1, (struct osub *) NULL,
11968                          0, 0);
11969   if (success == DUPLICATEVERTEX) {
11970     if (b->verbose > 2) {
11971       printf("  Segment intersects existing vertex (%.12g, %.12g).\n",
11972              newvertex[0], newvertex[1]);
11973     }
11974     /* Use the vertex that's already there. */
11975     vertexdealloc(m, newvertex);
11976     org(searchtri1, newvertex);
11977   } else {
11978     if (success == VIOLATINGVERTEX) {
11979       if (b->verbose > 2) {
11980         printf("  Two segments intersect at (%.12g, %.12g).\n",
11981                newvertex[0], newvertex[1]);
11982       }
11983       /* By fluke, we've landed right on another segment.  Split it. */
11984       tspivot(searchtri1, brokensubseg);
11985       success = insertvertex(m, b, newvertex, &searchtri1, &brokensubseg,
11986                              0, 0);
11987       if (success != SUCCESSFULVERTEX) {
11988         printf("Internal error in conformingedge():\n");
11989         printf("  Failure to split a segment.\n");
11990         internalerror();
11991       }
11992     }
11993     /* The vertex has been inserted successfully. */
11994     if (m->steinerleft > 0) {
11995       m->steinerleft--;
11996     }
11997   }
11998   otricopy(searchtri1, searchtri2);
11999   /* `searchtri1' and `searchtri2' are fastened at their origins to         */
12000   /*   `newvertex', and will be directed toward `endpoint1' and `endpoint2' */
12001   /*   respectively.  First, we must get `searchtri2' out of the way so it  */
12002   /*   won't be invalidated during the insertion of the first half of the   */
12003   /*   segment.                                                             */
12004   finddirection(m, b, &searchtri2, endpoint2);
12005   if (!scoutsegment(m, b, &searchtri1, endpoint1, newmark)) {
12006     /* The origin of searchtri1 may have changed if a collision with an */
12007     /*   intervening vertex on the segment occurred.                    */
12008     org(searchtri1, midvertex1);
12009     conformingedge(m, b, midvertex1, endpoint1, newmark);
12010   }
12011   if (!scoutsegment(m, b, &searchtri2, endpoint2, newmark)) {
12012     /* The origin of searchtri2 may have changed if a collision with an */
12013     /*   intervening vertex on the segment occurred.                    */
12014     org(searchtri2, midvertex2);
12015     conformingedge(m, b, midvertex2, endpoint2, newmark);
12016   }
12017 }
12018 
12019 #endif /* not CDT_ONLY */
12020 #endif /* not REDUCED */
12021 
12022 /*****************************************************************************/
12023 /*                                                                           */
12024 /*  delaunayfixup()   Enforce the Delaunay condition at an edge, fanning out */
12025 /*                    recursively from an existing vertex.  Pay special      */
12026 /*                    attention to stacking inverted triangles.              */
12027 /*                                                                           */
12028 /*  This is a support routine for inserting segments into a constrained      */
12029 /*  Delaunay triangulation.                                                  */
12030 /*                                                                           */
12031 /*  The origin of fixuptri is treated as if it has just been inserted, and   */
12032 /*  the local Delaunay condition needs to be enforced.  It is only enforced  */
12033 /*  in one sector, however, that being the angular range defined by          */
12034 /*  fixuptri.                                                                */
12035 /*                                                                           */
12036 /*  This routine also needs to make decisions regarding the "stacking" of    */
12037 /*  triangles.  (Read the description of constrainededge() below before      */
12038 /*  reading on here, so you understand the algorithm.)  If the position of   */
12039 /*  the new vertex (the origin of fixuptri) indicates that the vertex before */
12040 /*  it on the polygon is a reflex vertex, then "stack" the triangle by       */
12041 /*  doing nothing.  (fixuptri is an inverted triangle, which is how stacked  */
12042 /*  triangles are identified.)                                               */
12043 /*                                                                           */
12044 /*  Otherwise, check whether the vertex before that was a reflex vertex.     */
12045 /*  If so, perform an edge flip, thereby eliminating an inverted triangle    */
12046 /*  (popping it off the stack).  The edge flip may result in the creation    */
12047 /*  of a new inverted triangle, depending on whether or not the new vertex   */
12048 /*  is visible to the vertex three edges behind on the polygon.              */
12049 /*                                                                           */
12050 /*  If neither of the two vertices behind the new vertex are reflex          */
12051 /*  vertices, fixuptri and fartri, the triangle opposite it, are not         */
12052 /*  inverted; hence, ensure that the edge between them is locally Delaunay.  */
12053 /*                                                                           */
12054 /*  `leftside' indicates whether or not fixuptri is to the left of the       */
12055 /*  segment being inserted.  (Imagine that the segment is pointing up from   */
12056 /*  endpoint1 to endpoint2.)                                                 */
12057 /*                                                                           */
12058 /*****************************************************************************/
12059 
12060 #ifdef ANSI_DECLARATORS
12061 void delaunayfixup(struct mesh *m, struct behavior *b,
12062                    struct otri *fixuptri, int leftside)
12063 #else /* not ANSI_DECLARATORS */
12064 void delaunayfixup(m, b, fixuptri, leftside)
12065 struct mesh *m;
12066 struct behavior *b;
12067 struct otri *fixuptri;
12068 int leftside;
12069 #endif /* not ANSI_DECLARATORS */
12070 
12071 {
12072   struct otri neartri;
12073   struct otri fartri;
12074   struct osub faredge;
12075   vertex nearvertex, leftvertex, rightvertex, farvertex;
12076   triangle ptr;                         /* Temporary variable used by sym(). */
12077   subseg sptr;                      /* Temporary variable used by tspivot(). */
12078 
12079   lnext(*fixuptri, neartri);
12080   sym(neartri, fartri);
12081   /* Check if the edge opposite the origin of fixuptri can be flipped. */
12082   if (fartri.tri == m->dummytri) {
12083     return;
12084   }
12085   tspivot(neartri, faredge);
12086   if (faredge.ss != m->dummysub) {
12087     return;
12088   }
12089   /* Find all the relevant vertices. */
12090   apex(neartri, nearvertex);
12091   org(neartri, leftvertex);
12092   dest(neartri, rightvertex);
12093   apex(fartri, farvertex);
12094   /* Check whether the previous polygon vertex is a reflex vertex. */
12095   if (leftside) {
12096     if (counterclockwise(m, b, nearvertex, leftvertex, farvertex) <= 0.0) {
12097       /* leftvertex is a reflex vertex too.  Nothing can */
12098       /*   be done until a convex section is found.      */
12099       return;
12100     }
12101   } else {
12102     if (counterclockwise(m, b, farvertex, rightvertex, nearvertex) <= 0.0) {
12103       /* rightvertex is a reflex vertex too.  Nothing can */
12104       /*   be done until a convex section is found.       */
12105       return;
12106     }
12107   }
12108   if (counterclockwise(m, b, rightvertex, leftvertex, farvertex) > 0.0) {
12109     /* fartri is not an inverted triangle, and farvertex is not a reflex */
12110     /*   vertex.  As there are no reflex vertices, fixuptri isn't an     */
12111     /*   inverted triangle, either.  Hence, test the edge between the    */
12112     /*   triangles to ensure it is locally Delaunay.                     */
12113     if (incircle(m, b, leftvertex, farvertex, rightvertex, nearvertex) <=
12114         0.0) {
12115       return;
12116     }
12117     /* Not locally Delaunay; go on to an edge flip. */
12118   }        /* else fartri is inverted; remove it from the stack by flipping. */
12119   flip(m, b, &neartri);
12120   lprevself(*fixuptri);    /* Restore the origin of fixuptri after the flip. */
12121   /* Recursively process the two triangles that result from the flip. */
12122   delaunayfixup(m, b, fixuptri, leftside);
12123   delaunayfixup(m, b, &fartri, leftside);
12124 }
12125 
12126 /*****************************************************************************/
12127 /*                                                                           */
12128 /*  constrainededge()   Force a segment into a constrained Delaunay          */
12129 /*                      triangulation by deleting the triangles it           */
12130 /*                      intersects, and triangulating the polygons that      */
12131 /*                      form on each side of it.                             */
12132 /*                                                                           */
12133 /*  Generates a single subsegment connecting `endpoint1' to `endpoint2'.     */
12134 /*  The triangle `starttri' has `endpoint1' as its origin.  `newmark' is the */
12135 /*  boundary marker of the segment.                                          */
12136 /*                                                                           */
12137 /*  To insert a segment, every triangle whose interior intersects the        */
12138 /*  segment is deleted.  The union of these deleted triangles is a polygon   */
12139 /*  (which is not necessarily monotone, but is close enough), which is       */
12140 /*  divided into two polygons by the new segment.  This routine's task is    */
12141 /*  to generate the Delaunay triangulation of these two polygons.            */
12142 /*                                                                           */
12143 /*  You might think of this routine's behavior as a two-step process.  The   */
12144 /*  first step is to walk from endpoint1 to endpoint2, flipping each edge    */
12145 /*  encountered.  This step creates a fan of edges connected to endpoint1,   */
12146 /*  including the desired edge to endpoint2.  The second step enforces the   */
12147 /*  Delaunay condition on each side of the segment in an incremental manner: */
12148 /*  proceeding along the polygon from endpoint1 to endpoint2 (this is done   */
12149 /*  independently on each side of the segment), each vertex is "enforced"    */
12150 /*  as if it had just been inserted, but affecting only the previous         */
12151 /*  vertices.  The result is the same as if the vertices had been inserted   */
12152 /*  in the order they appear on the polygon, so the result is Delaunay.      */
12153 /*                                                                           */
12154 /*  In truth, constrainededge() interleaves these two steps.  The procedure  */
12155 /*  walks from endpoint1 to endpoint2, and each time an edge is encountered  */
12156 /*  and flipped, the newly exposed vertex (at the far end of the flipped     */
12157 /*  edge) is "enforced" upon the previously flipped edges, usually affecting */
12158 /*  only one side of the polygon (depending upon which side of the segment   */
12159 /*  the vertex falls on).                                                    */
12160 /*                                                                           */
12161 /*  The algorithm is complicated by the need to handle polygons that are not */
12162 /*  convex.  Although the polygon is not necessarily monotone, it can be     */
12163 /*  triangulated in a manner similar to the stack-based algorithms for       */
12164 /*  monotone polygons.  For each reflex vertex (local concavity) of the      */
12165 /*  polygon, there will be an inverted triangle formed by one of the edge    */
12166 /*  flips.  (An inverted triangle is one with negative area - that is, its   */
12167 /*  vertices are arranged in clockwise order - and is best thought of as a   */
12168 /*  wrinkle in the fabric of the mesh.)  Each inverted triangle can be       */
12169 /*  thought of as a reflex vertex pushed on the stack, waiting to be fixed   */
12170 /*  later.                                                                   */
12171 /*                                                                           */
12172 /*  A reflex vertex is popped from the stack when a vertex is inserted that  */
12173 /*  is visible to the reflex vertex.  (However, if the vertex behind the     */
12174 /*  reflex vertex is not visible to the reflex vertex, a new inverted        */
12175 /*  triangle will take its place on the stack.)  These details are handled   */
12176 /*  by the delaunayfixup() routine above.                                    */
12177 /*                                                                           */
12178 /*****************************************************************************/
12179 
12180 #ifdef ANSI_DECLARATORS
12181 void constrainededge(struct mesh *m, struct behavior *b,
12182                      struct otri *starttri, vertex endpoint2, int newmark)
12183 #else /* not ANSI_DECLARATORS */
12184 void constrainededge(m, b, starttri, endpoint2, newmark)
12185 struct mesh *m;
12186 struct behavior *b;
12187 struct otri *starttri;
12188 vertex endpoint2;
12189 int newmark;
12190 #endif /* not ANSI_DECLARATORS */
12191 
12192 {
12193   struct otri fixuptri, fixuptri2;
12194   struct osub crosssubseg;
12195   vertex endpoint1;
12196   vertex farvertex;
12197   REAL area;
12198   int collision;
12199   int done;
12200   triangle ptr;             /* Temporary variable used by sym() and oprev(). */
12201   subseg sptr;                      /* Temporary variable used by tspivot(). */
12202 
12203   org(*starttri, endpoint1);
12204   lnext(*starttri, fixuptri);
12205   flip(m, b, &fixuptri);
12206   /* `collision' indicates whether we have found a vertex directly */
12207   /*   between endpoint1 and endpoint2.                            */
12208   collision = 0;
12209   done = 0;
12210   do {
12211     org(fixuptri, farvertex);
12212     /* `farvertex' is the extreme point of the polygon we are "digging" */
12213     /*   to get from endpoint1 to endpoint2.                           */
12214     if ((farvertex[0] == endpoint2[0]) && (farvertex[1] == endpoint2[1])) {
12215       oprev(fixuptri, fixuptri2);
12216       /* Enforce the Delaunay condition around endpoint2. */
12217       delaunayfixup(m, b, &fixuptri, 0);
12218       delaunayfixup(m, b, &fixuptri2, 1);
12219       done = 1;
12220     } else {
12221       /* Check whether farvertex is to the left or right of the segment */
12222       /*   being inserted, to decide which edge of fixuptri to dig      */
12223       /*   through next.                                                */
12224       area = counterclockwise(m, b, endpoint1, endpoint2, farvertex);
12225       if (area == 0.0) {
12226         /* We've collided with a vertex between endpoint1 and endpoint2. */
12227         collision = 1;
12228         oprev(fixuptri, fixuptri2);
12229         /* Enforce the Delaunay condition around farvertex. */
12230         delaunayfixup(m, b, &fixuptri, 0);
12231         delaunayfixup(m, b, &fixuptri2, 1);
12232         done = 1;
12233       } else {
12234         if (area > 0.0) {        /* farvertex is to the left of the segment. */
12235           oprev(fixuptri, fixuptri2);
12236           /* Enforce the Delaunay condition around farvertex, on the */
12237           /*   left side of the segment only.                        */
12238           delaunayfixup(m, b, &fixuptri2, 1);
12239           /* Flip the edge that crosses the segment.  After the edge is */
12240           /*   flipped, one of its endpoints is the fan vertex, and the */
12241           /*   destination of fixuptri is the fan vertex.               */
12242           lprevself(fixuptri);
12243         } else {                /* farvertex is to the right of the segment. */
12244           delaunayfixup(m, b, &fixuptri, 0);
12245           /* Flip the edge that crosses the segment.  After the edge is */
12246           /*   flipped, one of its endpoints is the fan vertex, and the */
12247           /*   destination of fixuptri is the fan vertex.               */
12248           oprevself(fixuptri);
12249         }
12250         /* Check for two intersecting segments. */
12251         tspivot(fixuptri, crosssubseg);
12252         if (crosssubseg.ss == m->dummysub) {
12253           flip(m, b, &fixuptri);    /* May create inverted triangle at left. */
12254         } else {
12255           /* We've collided with a segment between endpoint1 and endpoint2. */
12256           collision = 1;
12257           /* Insert a vertex at the intersection. */
12258           segmentintersection(m, b, &fixuptri, &crosssubseg, endpoint2);
12259           done = 1;
12260         }
12261       }
12262     }
12263   } while (!done);
12264   /* Insert a subsegment to make the segment permanent. */
12265   insertsubseg(m, b, &fixuptri, newmark);
12266   /* If there was a collision with an interceding vertex, install another */
12267   /*   segment connecting that vertex with endpoint2.                     */
12268   if (collision) {
12269     /* Insert the remainder of the segment. */
12270     if (!scoutsegment(m, b, &fixuptri, endpoint2, newmark)) {
12271       constrainededge(m, b, &fixuptri, endpoint2, newmark);
12272     }
12273   }
12274 }
12275 
12276 /*****************************************************************************/
12277 /*                                                                           */
12278 /*  insertsegment()   Insert a PSLG segment into a triangulation.            */
12279 /*                                                                           */
12280 /*****************************************************************************/
12281 
12282 #ifdef ANSI_DECLARATORS
12283 void insertsegment(struct mesh *m, struct behavior *b,
12284                    vertex endpoint1, vertex endpoint2, int newmark)
12285 #else /* not ANSI_DECLARATORS */
12286 void insertsegment(m, b, endpoint1, endpoint2, newmark)
12287 struct mesh *m;
12288 struct behavior *b;
12289 vertex endpoint1;
12290 vertex endpoint2;
12291 int newmark;
12292 #endif /* not ANSI_DECLARATORS */
12293 
12294 {
12295   struct otri searchtri1, searchtri2;
12296   triangle encodedtri;
12297   vertex checkvertex;
12298   triangle ptr;                         /* Temporary variable used by sym(). */
12299 
12300   if (b->verbose > 1) {
12301     printf("  Connecting (%.12g, %.12g) to (%.12g, %.12g).\n",
12302            endpoint1[0], endpoint1[1], endpoint2[0], endpoint2[1]);
12303   }
12304 
12305   /* Find a triangle whose origin is the segment's first endpoint. */
12306   checkvertex = (vertex) NULL;
12307   encodedtri = vertex2tri(endpoint1);
12308   if (encodedtri != (triangle) NULL) {
12309     decode(encodedtri, searchtri1);
12310     org(searchtri1, checkvertex);
12311   }
12312   if (checkvertex != endpoint1) {
12313     /* Find a boundary triangle to search from. */
12314     searchtri1.tri = m->dummytri;
12315     searchtri1.orient = 0;
12316     symself(searchtri1);
12317     /* Search for the segment's first endpoint by point location. */
12318     if (locate(m, b, endpoint1, &searchtri1) != ONVERTEX) {
12319       printf(
12320         "Internal error in insertsegment():  Unable to locate PSLG vertex\n");
12321       printf("  (%.12g, %.12g) in triangulation.\n",
12322              endpoint1[0], endpoint1[1]);
12323       internalerror();
12324     }
12325   }
12326   /* Remember this triangle to improve subsequent point location. */
12327   otricopy(searchtri1, m->recenttri);
12328   /* Scout the beginnings of a path from the first endpoint */
12329   /*   toward the second.                                   */
12330   if (scoutsegment(m, b, &searchtri1, endpoint2, newmark)) {
12331     /* The segment was easily inserted. */
12332     return;
12333   }
12334   /* The first endpoint may have changed if a collision with an intervening */
12335   /*   vertex on the segment occurred.                                      */
12336   org(searchtri1, endpoint1);
12337 
12338   /* Find a triangle whose origin is the segment's second endpoint. */
12339   checkvertex = (vertex) NULL;
12340   encodedtri = vertex2tri(endpoint2);
12341   if (encodedtri != (triangle) NULL) {
12342     decode(encodedtri, searchtri2);
12343     org(searchtri2, checkvertex);
12344   }
12345   if (checkvertex != endpoint2) {
12346     /* Find a boundary triangle to search from. */
12347     searchtri2.tri = m->dummytri;
12348     searchtri2.orient = 0;
12349     symself(searchtri2);
12350     /* Search for the segment's second endpoint by point location. */
12351     if (locate(m, b, endpoint2, &searchtri2) != ONVERTEX) {
12352       printf(
12353         "Internal error in insertsegment():  Unable to locate PSLG vertex\n");
12354       printf("  (%.12g, %.12g) in triangulation.\n",
12355              endpoint2[0], endpoint2[1]);
12356       internalerror();
12357     }
12358   }
12359   /* Remember this triangle to improve subsequent point location. */
12360   otricopy(searchtri2, m->recenttri);
12361   /* Scout the beginnings of a path from the second endpoint */
12362   /*   toward the first.                                     */
12363   if (scoutsegment(m, b, &searchtri2, endpoint1, newmark)) {
12364     /* The segment was easily inserted. */
12365     return;
12366   }
12367   /* The second endpoint may have changed if a collision with an intervening */
12368   /*   vertex on the segment occurred.                                       */
12369   org(searchtri2, endpoint2);
12370 
12371 #ifndef REDUCED
12372 #ifndef CDT_ONLY
12373   if (b->splitseg) {
12374     /* Insert vertices to force the segment into the triangulation. */
12375     conformingedge(m, b, endpoint1, endpoint2, newmark);
12376   } else {
12377 #endif /* not CDT_ONLY */
12378 #endif /* not REDUCED */
12379     /* Insert the segment directly into the triangulation. */
12380     constrainededge(m, b, &searchtri1, endpoint2, newmark);
12381 #ifndef REDUCED
12382 #ifndef CDT_ONLY
12383   }
12384 #endif /* not CDT_ONLY */
12385 #endif /* not REDUCED */
12386 }
12387 
12388 /*****************************************************************************/
12389 /*                                                                           */
12390 /*  markhull()   Cover the convex hull of a triangulation with subsegments.  */
12391 /*                                                                           */
12392 /*****************************************************************************/
12393 
12394 #ifdef ANSI_DECLARATORS
12395 void markhull(struct mesh *m, struct behavior *b)
12396 #else /* not ANSI_DECLARATORS */
12397 void markhull(m, b)
12398 struct mesh *m;
12399 struct behavior *b;
12400 #endif /* not ANSI_DECLARATORS */
12401 
12402 {
12403   struct otri hulltri;
12404   struct otri nexttri;
12405   struct otri starttri;
12406   triangle ptr;             /* Temporary variable used by sym() and oprev(). */
12407 
12408   /* Find a triangle handle on the hull. */
12409   hulltri.tri = m->dummytri;
12410   hulltri.orient = 0;
12411   symself(hulltri);
12412   /* Remember where we started so we know when to stop. */
12413   otricopy(hulltri, starttri);
12414   /* Go once counterclockwise around the convex hull. */
12415   do {
12416     /* Create a subsegment if there isn't already one here. */
12417     insertsubseg(m, b, &hulltri, 1);
12418     /* To find the next hull edge, go clockwise around the next vertex. */
12419     lnextself(hulltri);
12420     oprev(hulltri, nexttri);
12421     while (nexttri.tri != m->dummytri) {
12422       otricopy(nexttri, hulltri);
12423       oprev(hulltri, nexttri);
12424     }
12425   } while (!otriequal(hulltri, starttri));
12426 }
12427 
12428 /*****************************************************************************/
12429 /*                                                                           */
12430 /*  formskeleton()   Create the segments of a triangulation, including PSLG  */
12431 /*                   segments and edges on the convex hull.                  */
12432 /*                                                                           */
12433 /*  The PSLG segments are read from a .poly file.  The return value is the   */
12434 /*  number of segments in the file.                                          */
12435 /*                                                                           */
12436 /*****************************************************************************/
12437 
12438 #ifdef TRILIBRARY
12439 
12440 #ifdef ANSI_DECLARATORS
12441 void formskeleton(struct mesh *m, struct behavior *b, int *segmentlist,
12442                   int *segmentmarkerlist, int numberofsegments)
12443 #else /* not ANSI_DECLARATORS */
12444 void formskeleton(m, b, segmentlist, segmentmarkerlist, numberofsegments)
12445 struct mesh *m;
12446 struct behavior *b;
12447 int *segmentlist;
12448 int *segmentmarkerlist;
12449 int numberofsegments;
12450 #endif /* not ANSI_DECLARATORS */
12451 
12452 #else /* not TRILIBRARY */
12453 
12454 #ifdef ANSI_DECLARATORS
12455 void formskeleton(struct mesh *m, struct behavior *b,
12456                   FILE *polyfile, char *polyfilename)
12457 #else /* not ANSI_DECLARATORS */
12458 void formskeleton(m, b, polyfile, polyfilename)
12459 struct mesh *m;
12460 struct behavior *b;
12461 FILE *polyfile;
12462 char *polyfilename;
12463 #endif /* not ANSI_DECLARATORS */
12464 
12465 #endif /* not TRILIBRARY */
12466 
12467 {
12468 #ifdef TRILIBRARY
12469   char polyfilename[6];
12470   int index;
12471 #else /* not TRILIBRARY */
12472   char inputline[INPUTLINESIZE];
12473   char *stringptr;
12474 #endif /* not TRILIBRARY */
12475   vertex endpoint1, endpoint2;
12476   int segmentmarkers;
12477   int end1, end2;
12478   int boundmarker;
12479   int i;
12480 
12481   if (b->poly) {
12482     if (!b->quiet) {
12483       printf("Recovering segments in Delaunay triangulation.\n");
12484     }
12485 #ifdef TRILIBRARY
12486     strcpy(polyfilename, "input");
12487     m->insegments = numberofsegments;
12488     segmentmarkers = segmentmarkerlist != (int *) NULL;
12489     index = 0;
12490 #else /* not TRILIBRARY */
12491     /* Read the segments from a .poly file. */
12492     /* Read number of segments and number of boundary markers. */
12493     stringptr = readline(inputline, polyfile, polyfilename);
12494     m->insegments = (int) strtol(stringptr, &stringptr, 0);
12495     stringptr = findfield(stringptr);
12496     if (*stringptr == '\0') {
12497       segmentmarkers = 0;
12498     } else {
12499       segmentmarkers = (int) strtol(stringptr, &stringptr, 0);
12500     }
12501 #endif /* not TRILIBRARY */
12502     /* If the input vertices are collinear, there is no triangulation, */
12503     /*   so don't try to insert segments.                              */
12504     if (m->triangles.items == 0) {
12505       return;
12506     }
12507 
12508     /* If segments are to be inserted, compute a mapping */
12509     /*   from vertices to triangles.                     */
12510     if (m->insegments > 0) {
12511       makevertexmap(m, b);
12512       if (b->verbose) {
12513         printf("  Recovering PSLG segments.\n");
12514       }
12515     }
12516 
12517     boundmarker = 0;
12518     /* Read and insert the segments. */
12519     for (i = 0; i < m->insegments; i++) {
12520 #ifdef TRILIBRARY
12521       end1 = segmentlist[index++];
12522       end2 = segmentlist[index++];
12523       if (segmentmarkers) {
12524         boundmarker = segmentmarkerlist[i];
12525       }
12526 #else /* not TRILIBRARY */
12527       stringptr = readline(inputline, polyfile, b->inpolyfilename);
12528       stringptr = findfield(stringptr);
12529       if (*stringptr == '\0') {
12530         printf("Error:  Segment %d has no endpoints in %s.\n",
12531                b->firstnumber + i, polyfilename);
12532         triexit(1);
12533       } else {
12534         end1 = (int) strtol(stringptr, &stringptr, 0);
12535       }
12536       stringptr = findfield(stringptr);
12537       if (*stringptr == '\0') {
12538         printf("Error:  Segment %d is missing its second endpoint in %s.\n",
12539                b->firstnumber + i, polyfilename);
12540         triexit(1);
12541       } else {
12542         end2 = (int) strtol(stringptr, &stringptr, 0);
12543       }
12544       if (segmentmarkers) {
12545         stringptr = findfield(stringptr);
12546         if (*stringptr == '\0') {
12547           boundmarker = 0;
12548         } else {
12549           boundmarker = (int) strtol(stringptr, &stringptr, 0);
12550         }
12551       }
12552 #endif /* not TRILIBRARY */
12553       if ((end1 < b->firstnumber) ||
12554           (end1 >= b->firstnumber + m->invertices)) {
12555         if (!b->quiet) {
12556           printf("Warning:  Invalid first endpoint of segment %d in %s.\n",
12557                  b->firstnumber + i, polyfilename);
12558         }
12559       } else if ((end2 < b->firstnumber) ||
12560                  (end2 >= b->firstnumber + m->invertices)) {
12561         if (!b->quiet) {
12562           printf("Warning:  Invalid second endpoint of segment %d in %s.\n",
12563                  b->firstnumber + i, polyfilename);
12564         }
12565       } else {
12566         /* Find the vertices numbered `end1' and `end2'. */
12567         endpoint1 = getvertex(m, b, end1);
12568         endpoint2 = getvertex(m, b, end2);
12569         if ((endpoint1[0] == endpoint2[0]) && (endpoint1[1] == endpoint2[1])) {
12570           if (!b->quiet) {
12571             printf("Warning:  Endpoints of segment %d are coincident in %s.\n",
12572                    b->firstnumber + i, polyfilename);
12573           }
12574         } else {
12575           insertsegment(m, b, endpoint1, endpoint2, boundmarker);
12576         }
12577       }
12578     }
12579   } else {
12580     m->insegments = 0;
12581   }
12582   if (b->convex || !b->poly) {
12583     /* Enclose the convex hull with subsegments. */
12584     if (b->verbose) {
12585       printf("  Enclosing convex hull with segments.\n");
12586     }
12587     markhull(m, b);
12588   }
12589 }
12590 
12591 /**                                                                         **/
12592 /**                                                                         **/
12593 /********* Segment insertion ends here                               *********/
12594 
12595 /********* Carving out holes and concavities begins here             *********/
12596 /**                                                                         **/
12597 /**                                                                         **/
12598 
12599 /*****************************************************************************/
12600 /*                                                                           */
12601 /*  infecthull()   Virally infect all of the triangles of the convex hull    */
12602 /*                 that are not protected by subsegments.  Where there are   */
12603 /*                 subsegments, set boundary markers as appropriate.         */
12604 /*                                                                           */
12605 /*****************************************************************************/
12606 
12607 #ifdef ANSI_DECLARATORS
12608 void infecthull(struct mesh *m, struct behavior *b)
12609 #else /* not ANSI_DECLARATORS */
12610 void infecthull(m, b)
12611 struct mesh *m;
12612 struct behavior *b;
12613 #endif /* not ANSI_DECLARATORS */
12614 
12615 {
12616   struct otri hulltri;
12617   struct otri nexttri;
12618   struct otri starttri;
12619   struct osub hullsubseg;
12620   triangle **deadtriangle;
12621   vertex horg, hdest;
12622   triangle ptr;                         /* Temporary variable used by sym(). */
12623   subseg sptr;                      /* Temporary variable used by tspivot(). */
12624 
12625   if (b->verbose) {
12626     printf("  Marking concavities (external triangles) for elimination.\n");
12627   }
12628   /* Find a triangle handle on the hull. */
12629   hulltri.tri = m->dummytri;
12630   hulltri.orient = 0;
12631   symself(hulltri);
12632   /* Remember where we started so we know when to stop. */
12633   otricopy(hulltri, starttri);
12634   /* Go once counterclockwise around the convex hull. */
12635   do {
12636     /* Ignore triangles that are already infected. */
12637     if (!infected(hulltri)) {
12638       /* Is the triangle protected by a subsegment? */
12639       tspivot(hulltri, hullsubseg);
12640       if (hullsubseg.ss == m->dummysub) {
12641         /* The triangle is not protected; infect it. */
12642         if (!infected(hulltri)) {
12643           infect(hulltri);
12644           deadtriangle = (triangle **) poolalloc(&m->viri);
12645           *deadtriangle = hulltri.tri;
12646         }
12647       } else {
12648         /* The triangle is protected; set boundary markers if appropriate. */
12649         if (mark(hullsubseg) == 0) {
12650           setmark(hullsubseg, 1);
12651           org(hulltri, horg);
12652           dest(hulltri, hdest);
12653           if (vertexmark(horg) == 0) {
12654             setvertexmark(horg, 1);
12655           }
12656           if (vertexmark(hdest) == 0) {
12657             setvertexmark(hdest, 1);
12658           }
12659         }
12660       }
12661     }
12662     /* To find the next hull edge, go clockwise around the next vertex. */
12663     lnextself(hulltri);
12664     oprev(hulltri, nexttri);
12665     while (nexttri.tri != m->dummytri) {
12666       otricopy(nexttri, hulltri);
12667       oprev(hulltri, nexttri);
12668     }
12669   } while (!otriequal(hulltri, starttri));
12670 }
12671 
12672 /*****************************************************************************/
12673 /*                                                                           */
12674 /*  plague()   Spread the virus from all infected triangles to any neighbors */
12675 /*             not protected by subsegments.  Delete all infected triangles. */
12676 /*                                                                           */
12677 /*  This is the procedure that actually creates holes and concavities.       */
12678 /*                                                                           */
12679 /*  This procedure operates in two phases.  The first phase identifies all   */
12680 /*  the triangles that will die, and marks them as infected.  They are       */
12681 /*  marked to ensure that each triangle is added to the virus pool only      */
12682 /*  once, so the procedure will terminate.                                   */
12683 /*                                                                           */
12684 /*  The second phase actually eliminates the infected triangles.  It also    */
12685 /*  eliminates orphaned vertices.                                            */
12686 /*                                                                           */
12687 /*****************************************************************************/
12688 
12689 #ifdef ANSI_DECLARATORS
12690 void plague(struct mesh *m, struct behavior *b)
12691 #else /* not ANSI_DECLARATORS */
12692 void plague(m, b)
12693 struct mesh *m;
12694 struct behavior *b;
12695 #endif /* not ANSI_DECLARATORS */
12696 
12697 {
12698   struct otri testtri;
12699   struct otri neighbor;
12700   triangle **virusloop;
12701   triangle **deadtriangle;
12702   struct osub neighborsubseg;
12703   vertex testvertex;
12704   vertex norg, ndest;
12705   vertex deadorg, deaddest, deadapex;
12706   int killorg;
12707   triangle ptr;             /* Temporary variable used by sym() and onext(). */
12708   subseg sptr;                      /* Temporary variable used by tspivot(). */
12709 
12710   if (b->verbose) {
12711     printf("  Marking neighbors of marked triangles.\n");
12712   }
12713   /* Loop through all the infected triangles, spreading the virus to */
12714   /*   their neighbors, then to their neighbors' neighbors.          */
12715   traversalinit(&m->viri);
12716   virusloop = (triangle **) traverse(&m->viri);
12717   while (virusloop != (triangle **) NULL) {
12718     testtri.tri = *virusloop;
12719     /* A triangle is marked as infected by messing with one of its pointers */
12720     /*   to subsegments, setting it to an illegal value.  Hence, we have to */
12721     /*   temporarily uninfect this triangle so that we can examine its      */
12722     /*   adjacent subsegments.                                              */
12723     uninfect(testtri);
12724     if (b->verbose > 2) {
12725       /* Assign the triangle an orientation for convenience in */
12726       /*   checking its vertices.                              */
12727       testtri.orient = 0;
12728       org(testtri, deadorg);
12729       dest(testtri, deaddest);
12730       apex(testtri, deadapex);
12731       printf("    Checking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
12732              deadorg[0], deadorg[1], deaddest[0], deaddest[1],
12733              deadapex[0], deadapex[1]);
12734     }
12735     /* Check each of the triangle's three neighbors. */
12736     for (testtri.orient = 0; testtri.orient < 3; testtri.orient++) {
12737       /* Find the neighbor. */
12738       sym(testtri, neighbor);
12739       /* Check for a subsegment between the triangle and its neighbor. */
12740       tspivot(testtri, neighborsubseg);
12741       /* Check if the neighbor is nonexistent or already infected. */
12742       if ((neighbor.tri == m->dummytri) || infected(neighbor)) {
12743         if (neighborsubseg.ss != m->dummysub) {
12744           /* There is a subsegment separating the triangle from its      */
12745           /*   neighbor, but both triangles are dying, so the subsegment */
12746           /*   dies too.                                                 */
12747           subsegdealloc(m, neighborsubseg.ss);
12748           if (neighbor.tri != m->dummytri) {
12749             /* Make sure the subsegment doesn't get deallocated again */
12750             /*   later when the infected neighbor is visited.         */
12751             uninfect(neighbor);
12752             tsdissolve(neighbor);
12753             infect(neighbor);
12754           }
12755         }
12756       } else {                   /* The neighbor exists and is not infected. */
12757         if (neighborsubseg.ss == m->dummysub) {
12758           /* There is no subsegment protecting the neighbor, so */
12759           /*   the neighbor becomes infected.                   */
12760           if (b->verbose > 2) {
12761             org(neighbor, deadorg);
12762             dest(neighbor, deaddest);
12763             apex(neighbor, deadapex);
12764             printf(
12765               "    Marking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
12766                    deadorg[0], deadorg[1], deaddest[0], deaddest[1],
12767                    deadapex[0], deadapex[1]);
12768           }
12769           infect(neighbor);
12770           /* Ensure that the neighbor's neighbors will be infected. */
12771           deadtriangle = (triangle **) poolalloc(&m->viri);
12772           *deadtriangle = neighbor.tri;
12773         } else {               /* The neighbor is protected by a subsegment. */
12774           /* Remove this triangle from the subsegment. */
12775           stdissolve(neighborsubseg);
12776           /* The subsegment becomes a boundary.  Set markers accordingly. */
12777           if (mark(neighborsubseg) == 0) {
12778             setmark(neighborsubseg, 1);
12779           }
12780           org(neighbor, norg);
12781           dest(neighbor, ndest);
12782           if (vertexmark(norg) == 0) {
12783             setvertexmark(norg, 1);
12784           }
12785           if (vertexmark(ndest) == 0) {
12786             setvertexmark(ndest, 1);
12787           }
12788         }
12789       }
12790     }
12791     /* Remark the triangle as infected, so it doesn't get added to the */
12792     /*   virus pool again.                                             */
12793     infect(testtri);
12794     virusloop = (triangle **) traverse(&m->viri);
12795   }
12796 
12797   if (b->verbose) {
12798     printf("  Deleting marked triangles.\n");
12799   }
12800 
12801   traversalinit(&m->viri);
12802   virusloop = (triangle **) traverse(&m->viri);
12803   while (virusloop != (triangle **) NULL) {
12804     testtri.tri = *virusloop;
12805 
12806     /* Check each of the three corners of the triangle for elimination. */
12807     /*   This is done by walking around each vertex, checking if it is  */
12808     /*   still connected to at least one live triangle.                 */
12809     for (testtri.orient = 0; testtri.orient < 3; testtri.orient++) {
12810       org(testtri, testvertex);
12811       /* Check if the vertex has already been tested. */
12812       if (testvertex != (vertex) NULL) {
12813         killorg = 1;
12814         /* Mark the corner of the triangle as having been tested. */
12815         setorg(testtri, NULL);
12816         /* Walk counterclockwise about the vertex. */
12817         onext(testtri, neighbor);
12818         /* Stop upon reaching a boundary or the starting triangle. */
12819         while ((neighbor.tri != m->dummytri) &&
12820                (!otriequal(neighbor, testtri))) {
12821           if (infected(neighbor)) {
12822             /* Mark the corner of this triangle as having been tested. */
12823             setorg(neighbor, NULL);
12824           } else {
12825             /* A live triangle.  The vertex survives. */
12826             killorg = 0;
12827           }
12828           /* Walk counterclockwise about the vertex. */
12829           onextself(neighbor);
12830         }
12831         /* If we reached a boundary, we must walk clockwise as well. */
12832         if (neighbor.tri == m->dummytri) {
12833           /* Walk clockwise about the vertex. */
12834           oprev(testtri, neighbor);
12835           /* Stop upon reaching a boundary. */
12836           while (neighbor.tri != m->dummytri) {
12837             if (infected(neighbor)) {
12838             /* Mark the corner of this triangle as having been tested. */
12839               setorg(neighbor, NULL);
12840             } else {
12841               /* A live triangle.  The vertex survives. */
12842               killorg = 0;
12843             }
12844             /* Walk clockwise about the vertex. */
12845             oprevself(neighbor);
12846           }
12847         }
12848         if (killorg) {
12849           if (b->verbose > 1) {
12850             printf("    Deleting vertex (%.12g, %.12g)\n",
12851                    testvertex[0], testvertex[1]);
12852           }
12853           setvertextype(testvertex, UNDEADVERTEX);
12854           m->undeads++;
12855         }
12856       }
12857     }
12858 
12859     /* Record changes in the number of boundary edges, and disconnect */
12860     /*   dead triangles from their neighbors.                         */
12861     for (testtri.orient = 0; testtri.orient < 3; testtri.orient++) {
12862       sym(testtri, neighbor);
12863       if (neighbor.tri == m->dummytri) {
12864         /* There is no neighboring triangle on this edge, so this edge    */
12865         /*   is a boundary edge.  This triangle is being deleted, so this */
12866         /*   boundary edge is deleted.                                    */
12867         m->hullsize--;
12868       } else {
12869         /* Disconnect the triangle from its neighbor. */
12870         dissolve(neighbor);
12871         /* There is a neighboring triangle on this edge, so this edge */
12872         /*   becomes a boundary edge when this triangle is deleted.   */
12873         m->hullsize++;
12874       }
12875     }
12876     /* Return the dead triangle to the pool of triangles. */
12877     triangledealloc(m, testtri.tri);
12878     virusloop = (triangle **) traverse(&m->viri);
12879   }
12880   /* Empty the virus pool. */
12881   poolrestart(&m->viri);
12882 }
12883 
12884 /*****************************************************************************/
12885 /*                                                                           */
12886 /*  regionplague()   Spread regional attributes and/or area constraints      */
12887 /*                   (from a .poly file) throughout the mesh.                */
12888 /*                                                                           */
12889 /*  This procedure operates in two phases.  The first phase spreads an       */
12890 /*  attribute and/or an area constraint through a (segment-bounded) region.  */
12891 /*  The triangles are marked to ensure that each triangle is added to the    */
12892 /*  virus pool only once, so the procedure will terminate.                   */
12893 /*                                                                           */
12894 /*  The second phase uninfects all infected triangles, returning them to     */
12895 /*  normal.                                                                  */
12896 /*                                                                           */
12897 /*****************************************************************************/
12898 
12899 #ifdef ANSI_DECLARATORS
12900 void regionplague(struct mesh *m, struct behavior *b,
12901                   REAL attribute, REAL area)
12902 #else /* not ANSI_DECLARATORS */
12903 void regionplague(m, b, attribute, area)
12904 struct mesh *m;
12905 struct behavior *b;
12906 REAL attribute;
12907 REAL area;
12908 #endif /* not ANSI_DECLARATORS */
12909 
12910 {
12911   struct otri testtri;
12912   struct otri neighbor;
12913   triangle **virusloop;
12914   triangle **regiontri;
12915   struct osub neighborsubseg;
12916   vertex regionorg, regiondest, regionapex;
12917   triangle ptr;             /* Temporary variable used by sym() and onext(). */
12918   subseg sptr;                      /* Temporary variable used by tspivot(). */
12919 
12920   if (b->verbose > 1) {
12921     printf("  Marking neighbors of marked triangles.\n");
12922   }
12923   /* Loop through all the infected triangles, spreading the attribute      */
12924   /*   and/or area constraint to their neighbors, then to their neighbors' */
12925   /*   neighbors.                                                          */
12926   traversalinit(&m->viri);
12927   virusloop = (triangle **) traverse(&m->viri);
12928   while (virusloop != (triangle **) NULL) {
12929     testtri.tri = *virusloop;
12930     /* A triangle is marked as infected by messing with one of its pointers */
12931     /*   to subsegments, setting it to an illegal value.  Hence, we have to */
12932     /*   temporarily uninfect this triangle so that we can examine its      */
12933     /*   adjacent subsegments.                                              */
12934     uninfect(testtri);
12935     if (b->regionattrib) {
12936       /* Set an attribute. */
12937       setelemattribute(testtri, m->eextras, attribute);
12938     }
12939     if (b->vararea) {
12940       /* Set an area constraint. */
12941       setareabound(testtri, area);
12942     }
12943     if (b->verbose > 2) {
12944       /* Assign the triangle an orientation for convenience in */
12945       /*   checking its vertices.                              */
12946       testtri.orient = 0;
12947       org(testtri, regionorg);
12948       dest(testtri, regiondest);
12949       apex(testtri, regionapex);
12950       printf("    Checking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
12951              regionorg[0], regionorg[1], regiondest[0], regiondest[1],
12952              regionapex[0], regionapex[1]);
12953     }
12954     /* Check each of the triangle's three neighbors. */
12955     for (testtri.orient = 0; testtri.orient < 3; testtri.orient++) {
12956       /* Find the neighbor. */
12957       sym(testtri, neighbor);
12958       /* Check for a subsegment between the triangle and its neighbor. */
12959       tspivot(testtri, neighborsubseg);
12960       /* Make sure the neighbor exists, is not already infected, and */
12961       /*   isn't protected by a subsegment.                          */
12962       if ((neighbor.tri != m->dummytri) && !infected(neighbor)
12963           && (neighborsubseg.ss == m->dummysub)) {
12964         if (b->verbose > 2) {
12965           org(neighbor, regionorg);
12966           dest(neighbor, regiondest);
12967           apex(neighbor, regionapex);
12968           printf("    Marking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
12969                  regionorg[0], regionorg[1], regiondest[0], regiondest[1],
12970                  regionapex[0], regionapex[1]);
12971         }
12972         /* Infect the neighbor. */
12973         infect(neighbor);
12974         /* Ensure that the neighbor's neighbors will be infected. */
12975         regiontri = (triangle **) poolalloc(&m->viri);
12976         *regiontri = neighbor.tri;
12977       }
12978     }
12979     /* Remark the triangle as infected, so it doesn't get added to the */
12980     /*   virus pool again.                                             */
12981     infect(testtri);
12982     virusloop = (triangle **) traverse(&m->viri);
12983   }
12984 
12985   /* Uninfect all triangles. */
12986   if (b->verbose > 1) {
12987     printf("  Unmarking marked triangles.\n");
12988   }
12989   traversalinit(&m->viri);
12990   virusloop = (triangle **) traverse(&m->viri);
12991   while (virusloop != (triangle **) NULL) {
12992     testtri.tri = *virusloop;
12993     uninfect(testtri);
12994     virusloop = (triangle **) traverse(&m->viri);
12995   }
12996   /* Empty the virus pool. */
12997   poolrestart(&m->viri);
12998 }
12999 
13000 /*****************************************************************************/
13001 /*                                                                           */
13002 /*  carveholes()   Find the holes and infect them.  Find the area            */
13003 /*                 constraints and infect them.  Infect the convex hull.     */
13004 /*                 Spread the infection and kill triangles.  Spread the      */
13005 /*                 area constraints.                                         */
13006 /*                                                                           */
13007 /*  This routine mainly calls other routines to carry out all these          */
13008 /*  functions.                                                               */
13009 /*                                                                           */
13010 /*****************************************************************************/
13011 
13012 #ifdef ANSI_DECLARATORS
13013 void carveholes(struct mesh *m, struct behavior *b, REAL *holelist, int holes,
13014                 REAL *regionlist, int regions)
13015 #else /* not ANSI_DECLARATORS */
13016 void carveholes(m, b, holelist, holes, regionlist, regions)
13017 struct mesh *m;
13018 struct behavior *b;
13019 REAL *holelist;
13020 int holes;
13021 REAL *regionlist;
13022 int regions;
13023 #endif /* not ANSI_DECLARATORS */
13024 
13025 {
13026   struct otri searchtri;
13027   struct otri triangleloop;
13028   struct otri *regiontris;
13029   triangle **holetri;
13030   triangle **regiontri;
13031   vertex searchorg, searchdest;
13032   enum locateresult intersect;
13033   int i;
13034   triangle ptr;                         /* Temporary variable used by sym(). */
13035 
13036   if (!(b->quiet || (b->noholes && b->convex))) {
13037     printf("Removing unwanted triangles.\n");
13038     if (b->verbose && (holes > 0)) {
13039       printf("  Marking holes for elimination.\n");
13040     }
13041   }
13042 
13043   if (regions > 0) {
13044     /* Allocate storage for the triangles in which region points fall. */
13045     regiontris = (struct otri *) trimalloc(regions *
13046                                            (int) sizeof(struct otri));
13047   } else {
13048     regiontris = (struct otri *) NULL;
13049   }
13050 
13051   if (((holes > 0) && !b->noholes) || !b->convex || (regions > 0)) {
13052     /* Initialize a pool of viri to be used for holes, concavities, */
13053     /*   regional attributes, and/or regional area constraints.     */
13054     poolinit(&m->viri, sizeof(triangle *), VIRUSPERBLOCK, VIRUSPERBLOCK, 0);
13055   }
13056 
13057   if (!b->convex) {
13058     /* Mark as infected any unprotected triangles on the boundary. */
13059     /*   This is one way by which concavities are created.         */
13060     infecthull(m, b);
13061   }
13062 
13063   if ((holes > 0) && !b->noholes) {
13064     /* Infect each triangle in which a hole lies. */
13065     for (i = 0; i < 2 * holes; i += 2) {
13066       /* Ignore holes that aren't within the bounds of the mesh. */
13067       if ((holelist[i] >= m->xmin) && (holelist[i] <= m->xmax)
13068           && (holelist[i + 1] >= m->ymin) && (holelist[i + 1] <= m->ymax)) {
13069         /* Start searching from some triangle on the outer boundary. */
13070         searchtri.tri = m->dummytri;
13071         searchtri.orient = 0;
13072         symself(searchtri);
13073         /* Ensure that the hole is to the left of this boundary edge; */
13074         /*   otherwise, locate() will falsely report that the hole    */
13075         /*   falls within the starting triangle.                      */
13076         org(searchtri, searchorg);
13077         dest(searchtri, searchdest);
13078         if (counterclockwise(m, b, searchorg, searchdest, &holelist[i]) >
13079             0.0) {
13080           /* Find a triangle that contains the hole. */
13081           intersect = locate(m, b, &holelist[i], &searchtri);
13082           if ((intersect != OUTSIDE) && (!infected(searchtri))) {
13083             /* Infect the triangle.  This is done by marking the triangle  */
13084             /*   as infected and including the triangle in the virus pool. */
13085             infect(searchtri);
13086             holetri = (triangle **) poolalloc(&m->viri);
13087             *holetri = searchtri.tri;
13088           }
13089         }
13090       }
13091     }
13092   }
13093 
13094   /* Now, we have to find all the regions BEFORE we carve the holes, because */
13095   /*   locate() won't work when the triangulation is no longer convex.       */
13096   /*   (Incidentally, this is the reason why regional attributes and area    */
13097   /*   constraints can't be used when refining a preexisting mesh, which     */
13098   /*   might not be convex; they can only be used with a freshly             */
13099   /*   triangulated PSLG.)                                                   */
13100   if (regions > 0) {
13101     /* Find the starting triangle for each region. */
13102     for (i = 0; i < regions; i++) {
13103       regiontris[i].tri = m->dummytri;
13104       /* Ignore region points that aren't within the bounds of the mesh. */
13105       if ((regionlist[4 * i] >= m->xmin) && (regionlist[4 * i] <= m->xmax) &&
13106           (regionlist[4 * i + 1] >= m->ymin) &&
13107           (regionlist[4 * i + 1] <= m->ymax)) {
13108         /* Start searching from some triangle on the outer boundary. */
13109         searchtri.tri = m->dummytri;
13110         searchtri.orient = 0;
13111         symself(searchtri);
13112         /* Ensure that the region point is to the left of this boundary */
13113         /*   edge; otherwise, locate() will falsely report that the     */
13114         /*   region point falls within the starting triangle.           */
13115         org(searchtri, searchorg);
13116         dest(searchtri, searchdest);
13117         if (counterclockwise(m, b, searchorg, searchdest, &regionlist[4 * i]) >
13118             0.0) {
13119           /* Find a triangle that contains the region point. */
13120           intersect = locate(m, b, &regionlist[4 * i], &searchtri);
13121           if ((intersect != OUTSIDE) && (!infected(searchtri))) {
13122             /* Record the triangle for processing after the */
13123             /*   holes have been carved.                    */
13124             otricopy(searchtri, regiontris[i]);
13125           }
13126         }
13127       }
13128     }
13129   }
13130 
13131   if (m->viri.items > 0) {
13132     /* Carve the holes and concavities. */
13133     plague(m, b);
13134   }
13135   /* The virus pool should be empty now. */
13136 
13137   if (regions > 0) {
13138     if (!b->quiet) {
13139       if (b->regionattrib) {
13140         if (b->vararea) {
13141           printf("Spreading regional attributes and area constraints.\n");
13142         } else {
13143           printf("Spreading regional attributes.\n");
13144         }
13145       } else {
13146         printf("Spreading regional area constraints.\n");
13147       }
13148     }
13149     if (b->regionattrib && !b->refine) {
13150       /* Assign every triangle a regional attribute of zero. */
13151       traversalinit(&m->triangles);
13152       triangleloop.orient = 0;
13153       triangleloop.tri = triangletraverse(m);
13154       while (triangleloop.tri != (triangle *) NULL) {
13155         setelemattribute(triangleloop, m->eextras, 0.0);
13156         triangleloop.tri = triangletraverse(m);
13157       }
13158     }
13159     for (i = 0; i < regions; i++) {
13160       if (regiontris[i].tri != m->dummytri) {
13161         /* Make sure the triangle under consideration still exists. */
13162         /*   It may have been eaten by the virus.                   */
13163         if (!deadtri(regiontris[i].tri)) {
13164           /* Put one triangle in the virus pool. */
13165           infect(regiontris[i]);
13166           regiontri = (triangle **) poolalloc(&m->viri);
13167           *regiontri = regiontris[i].tri;
13168           /* Apply one region's attribute and/or area constraint. */
13169           regionplague(m, b, regionlist[4 * i + 2], regionlist[4 * i + 3]);
13170           /* The virus pool should be empty now. */
13171         }
13172       }
13173     }
13174     if (b->regionattrib && !b->refine) {
13175       /* Note the fact that each triangle has an additional attribute. */
13176       m->eextras++;
13177     }
13178   }
13179 
13180   /* Free up memory. */
13181   if (((holes > 0) && !b->noholes) || !b->convex || (regions > 0)) {
13182     pooldeinit(&m->viri);
13183   }
13184   if (regions > 0) {
13185     trifree((VOID *) regiontris);
13186   }
13187 }
13188 
13189 /**                                                                         **/
13190 /**                                                                         **/
13191 /********* Carving out holes and concavities ends here               *********/
13192 
13193 /********* Mesh quality maintenance begins here                      *********/
13194 /**                                                                         **/
13195 /**                                                                         **/
13196 
13197 /*****************************************************************************/
13198 /*                                                                           */
13199 /*  tallyencs()   Traverse the entire list of subsegments, and check each    */
13200 /*                to see if it is encroached.  If so, add it to the list.    */
13201 /*                                                                           */
13202 /*****************************************************************************/
13203 
13204 #ifndef CDT_ONLY
13205 
13206 #ifdef ANSI_DECLARATORS
13207 void tallyencs(struct mesh *m, struct behavior *b)
13208 #else /* not ANSI_DECLARATORS */
13209 void tallyencs(m, b)
13210 struct mesh *m;
13211 struct behavior *b;
13212 #endif /* not ANSI_DECLARATORS */
13213 
13214 {
13215   struct osub subsegloop;
13216   int dummy;
13217 
13218   traversalinit(&m->subsegs);
13219   subsegloop.ssorient = 0;
13220   subsegloop.ss = subsegtraverse(m);
13221   while (subsegloop.ss != (subseg *) NULL) {
13222     /* If the segment is encroached, add it to the list. */
13223     dummy = checkseg4encroach(m, b, &subsegloop);
13224     subsegloop.ss = subsegtraverse(m);
13225   }
13226 }
13227 
13228 #endif /* not CDT_ONLY */
13229 
13230 /*****************************************************************************/
13231 /*                                                                           */
13232 /*  precisionerror()  Print an error message for precision problems.         */
13233 /*                                                                           */
13234 /*****************************************************************************/
13235 
13236 #ifndef CDT_ONLY
13237 
13238 void precisionerror()
13239 {
13240   printf("Try increasing the area criterion and/or reducing the minimum\n");
13241   printf("  allowable angle so that tiny triangles are not created.\n");
13242 #ifdef SINGLE
13243   printf("Alternatively, try recompiling me with double precision\n");
13244   printf("  arithmetic (by removing \"#define SINGLE\" from the\n");
13245   printf("  source file or \"-DSINGLE\" from the makefile).\n");
13246 #endif /* SINGLE */
13247 }
13248 
13249 #endif /* not CDT_ONLY */
13250 
13251 /*****************************************************************************/
13252 /*                                                                           */
13253 /*  splitencsegs()   Split all the encroached subsegments.                   */
13254 /*                                                                           */
13255 /*  Each encroached subsegment is repaired by splitting it - inserting a     */
13256 /*  vertex at or near its midpoint.  Newly inserted vertices may encroach    */
13257 /*  upon other subsegments; these are also repaired.                         */
13258 /*                                                                           */
13259 /*  `triflaws' is a flag that specifies whether one should take note of new  */
13260 /*  bad triangles that result from inserting vertices to repair encroached   */
13261 /*  subsegments.                                                             */
13262 /*                                                                           */
13263 /*****************************************************************************/
13264 
13265 #ifndef CDT_ONLY
13266 
13267 #ifdef ANSI_DECLARATORS
13268 void splitencsegs(struct mesh *m, struct behavior *b, int triflaws)
13269 #else /* not ANSI_DECLARATORS */
13270 void splitencsegs(m, b, triflaws)
13271 struct mesh *m;
13272 struct behavior *b;
13273 int triflaws;
13274 #endif /* not ANSI_DECLARATORS */
13275 
13276 {
13277   struct otri enctri;
13278   struct otri testtri;
13279   struct osub testsh;
13280   struct osub currentenc;
13281   struct badsubseg *encloop;
13282   vertex eorg, edest, eapex;
13283   vertex newvertex;
13284   enum insertvertexresult success;
13285   REAL segmentlength, nearestpoweroftwo;
13286   REAL split;
13287   REAL multiplier, divisor;
13288   int acuteorg, acuteorg2, acutedest, acutedest2;
13289   int dummy;
13290   int i;
13291   triangle ptr;                     /* Temporary variable used by stpivot(). */
13292   subseg sptr;                        /* Temporary variable used by snext(). */
13293 
13294   /* Note that steinerleft == -1 if an unlimited number */
13295   /*   of Steiner points is allowed.                    */
13296   while ((m->badsubsegs.items > 0) && (m->steinerleft != 0)) {
13297     traversalinit(&m->badsubsegs);
13298     encloop = badsubsegtraverse(m);
13299     while ((encloop != (struct badsubseg *) NULL) && (m->steinerleft != 0)) {
13300       sdecode(encloop->encsubseg, currentenc);
13301       sorg(currentenc, eorg);
13302       sdest(currentenc, edest);
13303       /* Make sure that this segment is still the same segment it was   */
13304       /*   when it was determined to be encroached.  If the segment was */
13305       /*   enqueued multiple times (because several newly inserted      */
13306       /*   vertices encroached it), it may have already been split.     */
13307       if (!deadsubseg(currentenc.ss) &&
13308           (eorg == encloop->subsegorg) && (edest == encloop->subsegdest)) {
13309         /* To decide where to split a segment, we need to know if the   */
13310         /*   segment shares an endpoint with an adjacent segment.       */
13311         /*   The concern is that, if we simply split every encroached   */
13312         /*   segment in its center, two adjacent segments with a small  */
13313         /*   angle between them might lead to an infinite loop; each    */
13314         /*   vertex added to split one segment will encroach upon the   */
13315         /*   other segment, which must then be split with a vertex that */
13316         /*   will encroach upon the first segment, and so on forever.   */
13317         /* To avoid this, imagine a set of concentric circles, whose    */
13318         /*   radii are powers of two, about each segment endpoint.      */
13319         /*   These concentric circles determine where the segment is    */
13320         /*   split.  (If both endpoints are shared with adjacent        */
13321         /*   segments, split the segment in the middle, and apply the   */
13322         /*   concentric circles for later splittings.)                  */
13323 
13324         /* Is the origin shared with another segment? */
13325         stpivot(currentenc, enctri);
13326         lnext(enctri, testtri);
13327         tspivot(testtri, testsh);
13328         acuteorg = testsh.ss != m->dummysub;
13329         /* Is the destination shared with another segment? */
13330         lnextself(testtri);
13331         tspivot(testtri, testsh);
13332         acutedest = testsh.ss != m->dummysub;
13333 
13334         /* If we're using Chew's algorithm (rather than Ruppert's) */
13335         /*   to define encroachment, delete free vertices from the */
13336         /*   subsegment's diametral circle.                        */
13337         if (!b->conformdel && !acuteorg && !acutedest) {
13338           apex(enctri, eapex);
13339           while ((vertextype(eapex) == FREEVERTEX) &&
13340                  ((eorg[0] - eapex[0]) * (edest[0] - eapex[0]) +
13341                   (eorg[1] - eapex[1]) * (edest[1] - eapex[1]) < 0.0)) {
13342             deletevertex(m, b, &testtri);
13343             stpivot(currentenc, enctri);
13344             apex(enctri, eapex);
13345             lprev(enctri, testtri);
13346           }
13347         }
13348 
13349         /* Now, check the other side of the segment, if there's a triangle */
13350         /*   there.                                                        */
13351         sym(enctri, testtri);
13352         if (testtri.tri != m->dummytri) {
13353           /* Is the destination shared with another segment? */
13354           lnextself(testtri);
13355           tspivot(testtri, testsh);
13356           acutedest2 = testsh.ss != m->dummysub;
13357           acutedest = acutedest || acutedest2;
13358           /* Is the origin shared with another segment? */
13359           lnextself(testtri);
13360           tspivot(testtri, testsh);
13361           acuteorg2 = testsh.ss != m->dummysub;
13362           acuteorg = acuteorg || acuteorg2;
13363 
13364           /* Delete free vertices from the subsegment's diametral circle. */
13365           if (!b->conformdel && !acuteorg2 && !acutedest2) {
13366             org(testtri, eapex);
13367             while ((vertextype(eapex) == FREEVERTEX) &&
13368                    ((eorg[0] - eapex[0]) * (edest[0] - eapex[0]) +
13369                     (eorg[1] - eapex[1]) * (edest[1] - eapex[1]) < 0.0)) {
13370               deletevertex(m, b, &testtri);
13371               sym(enctri, testtri);
13372               apex(testtri, eapex);
13373               lprevself(testtri);
13374             }
13375           }
13376         }
13377 
13378         /* Use the concentric circles if exactly one endpoint is shared */
13379         /*   with another adjacent segment.                             */
13380         if (acuteorg || acutedest) {
13381           segmentlength = sqrt((edest[0] - eorg[0]) * (edest[0] - eorg[0]) +
13382                                (edest[1] - eorg[1]) * (edest[1] - eorg[1]));
13383           /* Find the power of two that most evenly splits the segment.  */
13384           /*   The worst case is a 2:1 ratio between subsegment lengths. */
13385           nearestpoweroftwo = 1.0;
13386           while (segmentlength > 3.0 * nearestpoweroftwo) {
13387             nearestpoweroftwo *= 2.0;
13388           }
13389           while (segmentlength < 1.5 * nearestpoweroftwo) {
13390             nearestpoweroftwo *= 0.5;
13391           }
13392           /* Where do we split the segment? */
13393           split = nearestpoweroftwo / segmentlength;
13394           if (acutedest) {
13395             split = 1.0 - split;
13396           }
13397         } else {
13398           /* If we're not worried about adjacent segments, split */
13399           /*   this segment in the middle.                       */
13400           split = 0.5;
13401         }
13402 
13403         /* Create the new vertex. */
13404         newvertex = (vertex) poolalloc(&m->vertices);
13405         /* Interpolate its coordinate and attributes. */
13406         for (i = 0; i < 2 + m->nextras; i++) {
13407           newvertex[i] = eorg[i] + split * (edest[i] - eorg[i]);
13408         }
13409 
13410         if (!b->noexact) {
13411           /* Roundoff in the above calculation may yield a `newvertex'   */
13412           /*   that is not precisely collinear with `eorg' and `edest'.  */
13413           /*   Improve collinearity by one step of iterative refinement. */
13414           multiplier = counterclockwise(m, b, eorg, edest, newvertex);
13415           divisor = ((eorg[0] - edest[0]) * (eorg[0] - edest[0]) +
13416                      (eorg[1] - edest[1]) * (eorg[1] - edest[1]));
13417           if ((multiplier != 0.0) && (divisor != 0.0)) {
13418             multiplier = multiplier / divisor;
13419             /* Watch out for NANs. */
13420             if (multiplier == multiplier) {
13421               newvertex[0] += multiplier * (edest[1] - eorg[1]);
13422               newvertex[1] += multiplier * (eorg[0] - edest[0]);
13423             }
13424           }
13425         }
13426 
13427         setvertexmark(newvertex, mark(currentenc));
13428         setvertextype(newvertex, SEGMENTVERTEX);
13429         if (b->verbose > 1) {
13430           printf(
13431   "  Splitting subsegment (%.12g, %.12g) (%.12g, %.12g) at (%.12g, %.12g).\n",
13432                  eorg[0], eorg[1], edest[0], edest[1],
13433                  newvertex[0], newvertex[1]);
13434         }
13435         /* Check whether the new vertex lies on an endpoint. */
13436         if (((newvertex[0] == eorg[0]) && (newvertex[1] == eorg[1])) ||
13437             ((newvertex[0] == edest[0]) && (newvertex[1] == edest[1]))) {
13438           printf("Error:  Ran out of precision at (%.12g, %.12g).\n",
13439                  newvertex[0], newvertex[1]);
13440           printf("I attempted to split a segment to a smaller size than\n");
13441           printf("  can be accommodated by the finite precision of\n");
13442           printf("  floating point arithmetic.\n");
13443           precisionerror();
13444           triexit(1);
13445         }
13446         /* Insert the splitting vertex.  This should always succeed. */
13447         success = insertvertex(m, b, newvertex, &enctri, &currentenc,
13448                                1, triflaws);
13449         if ((success != SUCCESSFULVERTEX) && (success != ENCROACHINGVERTEX)) {
13450           printf("Internal error in splitencsegs():\n");
13451           printf("  Failure to split a segment.\n");
13452           internalerror();
13453         }
13454         if (m->steinerleft > 0) {
13455           m->steinerleft--;
13456         }
13457         /* Check the two new subsegments to see if they're encroached. */
13458         dummy = checkseg4encroach(m, b, &currentenc);
13459         snextself(currentenc);
13460         dummy = checkseg4encroach(m, b, &currentenc);
13461       }
13462 
13463       badsubsegdealloc(m, encloop);
13464       encloop = badsubsegtraverse(m);
13465     }
13466   }
13467 }
13468 
13469 #endif /* not CDT_ONLY */
13470 
13471 /*****************************************************************************/
13472 /*                                                                           */
13473 /*  tallyfaces()   Test every triangle in the mesh for quality measures.     */
13474 /*                                                                           */
13475 /*****************************************************************************/
13476 
13477 #ifndef CDT_ONLY
13478 
13479 #ifdef ANSI_DECLARATORS
13480 void tallyfaces(struct mesh *m, struct behavior *b)
13481 #else /* not ANSI_DECLARATORS */
13482 void tallyfaces(m, b)
13483 struct mesh *m;
13484 struct behavior *b;
13485 #endif /* not ANSI_DECLARATORS */
13486 
13487 {
13488   struct otri triangleloop;
13489 
13490   if (b->verbose) {
13491     printf("  Making a list of bad triangles.\n");
13492   }
13493   traversalinit(&m->triangles);
13494   triangleloop.orient = 0;
13495   triangleloop.tri = triangletraverse(m);
13496   while (triangleloop.tri != (triangle *) NULL) {
13497     /* If the triangle is bad, enqueue it. */
13498     testtriangle(m, b, &triangleloop);
13499     triangleloop.tri = triangletraverse(m);
13500   }
13501 }
13502 
13503 #endif /* not CDT_ONLY */
13504 
13505 /*****************************************************************************/
13506 /*                                                                           */
13507 /*  splittriangle()   Inserts a vertex at the circumcenter of a triangle.    */
13508 /*                    Deletes the newly inserted vertex if it encroaches     */
13509 /*                    upon a segment.                                        */
13510 /*                                                                           */
13511 /*****************************************************************************/
13512 
13513 #ifndef CDT_ONLY
13514 
13515 #ifdef ANSI_DECLARATORS
13516 void splittriangle(struct mesh *m, struct behavior *b,
13517                    struct badtriang *badtri)
13518 #else /* not ANSI_DECLARATORS */
13519 void splittriangle(m, b, badtri)
13520 struct mesh *m;
13521 struct behavior *b;
13522 struct badtriang *badtri;
13523 #endif /* not ANSI_DECLARATORS */
13524 
13525 {
13526   struct otri badotri;
13527   vertex borg, bdest, bapex;
13528   vertex newvertex;
13529   REAL xi, eta;
13530   enum insertvertexresult success;
13531   int errorflag;
13532   int i;
13533 
13534   decode(badtri->poortri, badotri);
13535   org(badotri, borg);
13536   dest(badotri, bdest);
13537   apex(badotri, bapex);
13538   /* Make sure that this triangle is still the same triangle it was      */
13539   /*   when it was tested and determined to be of bad quality.           */
13540   /*   Subsequent transformations may have made it a different triangle. */
13541   if (!deadtri(badotri.tri) && (borg == badtri->triangorg) &&
13542       (bdest == badtri->triangdest) && (bapex == badtri->triangapex)) {
13543     if (b->verbose > 1) {
13544       printf("  Splitting this triangle at its circumcenter:\n");
13545       printf("    (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n", borg[0],
13546              borg[1], bdest[0], bdest[1], bapex[0], bapex[1]);
13547     }
13548 
13549     errorflag = 0;
13550     /* Create a new vertex at the triangle's circumcenter. */
13551     newvertex = (vertex) poolalloc(&m->vertices);
13552     findcircumcenter(m, b, borg, bdest, bapex, newvertex, &xi, &eta, 1);
13553 
13554     /* Check whether the new vertex lies on a triangle vertex. */
13555     if (((newvertex[0] == borg[0]) && (newvertex[1] == borg[1])) ||
13556         ((newvertex[0] == bdest[0]) && (newvertex[1] == bdest[1])) ||
13557         ((newvertex[0] == bapex[0]) && (newvertex[1] == bapex[1]))) {
13558       if (!b->quiet) {
13559         printf(
13560              "Warning:  New vertex (%.12g, %.12g) falls on existing vertex.\n",
13561                newvertex[0], newvertex[1]);
13562         errorflag = 1;
13563       }
13564       vertexdealloc(m, newvertex);
13565     } else {
13566       for (i = 2; i < 2 + m->nextras; i++) {
13567         /* Interpolate the vertex attributes at the circumcenter. */
13568         newvertex[i] = borg[i] + xi * (bdest[i] - borg[i])
13569                               + eta * (bapex[i] - borg[i]);
13570       }
13571       /* The new vertex must be in the interior, and therefore is a */
13572       /*   free vertex with a marker of zero.                       */
13573       setvertexmark(newvertex, 0);
13574       setvertextype(newvertex, FREEVERTEX);
13575 
13576       /* Ensure that the handle `badotri' does not represent the longest  */
13577       /*   edge of the triangle.  This ensures that the circumcenter must */
13578       /*   fall to the left of this edge, so point location will work.    */
13579       /*   (If the angle org-apex-dest exceeds 90 degrees, then the       */
13580       /*   circumcenter lies outside the org-dest edge, and eta is        */
13581       /*   negative.  Roundoff error might prevent eta from being         */
13582       /*   negative when it should be, so I test eta against xi.)         */
13583       if (eta < xi) {
13584         lprevself(badotri);
13585       }
13586 
13587       /* Insert the circumcenter, searching from the edge of the triangle, */
13588       /*   and maintain the Delaunay property of the triangulation.        */
13589       success = insertvertex(m, b, newvertex, &badotri, (struct osub *) NULL,
13590                              1, 1);
13591       if (success == SUCCESSFULVERTEX) {
13592         if (m->steinerleft > 0) {
13593           m->steinerleft--;
13594         }
13595       } else if (success == ENCROACHINGVERTEX) {
13596         /* If the newly inserted vertex encroaches upon a subsegment, */
13597         /*   delete the new vertex.                                   */
13598         undovertex(m, b);
13599         if (b->verbose > 1) {
13600           printf("  Rejecting (%.12g, %.12g).\n", newvertex[0], newvertex[1]);
13601         }
13602         vertexdealloc(m, newvertex);
13603       } else if (success == VIOLATINGVERTEX) {
13604         /* Failed to insert the new vertex, but some subsegment was */
13605         /*   marked as being encroached.                            */
13606         vertexdealloc(m, newvertex);
13607       } else {                                 /* success == DUPLICATEVERTEX */
13608         /* Couldn't insert the new vertex because a vertex is already there. */
13609         if (!b->quiet) {
13610           printf(
13611             "Warning:  New vertex (%.12g, %.12g) falls on existing vertex.\n",
13612                  newvertex[0], newvertex[1]);
13613           errorflag = 1;
13614         }
13615         vertexdealloc(m, newvertex);
13616       }
13617     }
13618     if (errorflag) {
13619       if (b->verbose) {
13620         printf("  The new vertex is at the circumcenter of triangle\n");
13621         printf("    (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
13622                borg[0], borg[1], bdest[0], bdest[1], bapex[0], bapex[1]);
13623       }
13624       printf("This probably means that I am trying to refine triangles\n");
13625       printf("  to a smaller size than can be accommodated by the finite\n");
13626       printf("  precision of floating point arithmetic.  (You can be\n");
13627       printf("  sure of this if I fail to terminate.)\n");
13628       precisionerror();
13629     }
13630   }
13631 }
13632 
13633 #endif /* not CDT_ONLY */
13634 
13635 /*****************************************************************************/
13636 /*                                                                           */
13637 /*  enforcequality()   Remove all the encroached subsegments and bad         */
13638 /*                     triangles from the triangulation.                     */
13639 /*                                                                           */
13640 /*****************************************************************************/
13641 
13642 #ifndef CDT_ONLY
13643 
13644 #ifdef ANSI_DECLARATORS
13645 void enforcequality(struct mesh *m, struct behavior *b)
13646 #else /* not ANSI_DECLARATORS */
13647 void enforcequality(m, b)
13648 struct mesh *m;
13649 struct behavior *b;
13650 #endif /* not ANSI_DECLARATORS */
13651 
13652 {
13653   struct badtriang *badtri;
13654   int i;
13655 
13656   if (!b->quiet) {
13657     printf("Adding Steiner points to enforce quality.\n");
13658   }
13659   /* Initialize the pool of encroached subsegments. */
13660   poolinit(&m->badsubsegs, sizeof(struct badsubseg), BADSUBSEGPERBLOCK,
13661            BADSUBSEGPERBLOCK, 0);
13662   if (b->verbose) {
13663     printf("  Looking for encroached subsegments.\n");
13664   }
13665   /* Test all segments to see if they're encroached. */
13666   tallyencs(m, b);
13667   if (b->verbose && (m->badsubsegs.items > 0)) {
13668     printf("  Splitting encroached subsegments.\n");
13669   }
13670   /* Fix encroached subsegments without noting bad triangles. */
13671   splitencsegs(m, b, 0);
13672   /* At this point, if we haven't run out of Steiner points, the */
13673   /*   triangulation should be (conforming) Delaunay.            */
13674 
13675   /* Next, we worry about enforcing triangle quality. */
13676   if ((b->minangle > 0.0) || b->vararea || b->fixedarea || b->usertest) {
13677     /* Initialize the pool of bad triangles. */
13678     poolinit(&m->badtriangles, sizeof(struct badtriang), BADTRIPERBLOCK,
13679              BADTRIPERBLOCK, 0);
13680     /* Initialize the queues of bad triangles. */
13681     for (i = 0; i < 4096; i++) {
13682       m->queuefront[i] = (struct badtriang *) NULL;
13683     }
13684     m->firstnonemptyq = -1;
13685     /* Test all triangles to see if they're bad. */
13686     tallyfaces(m, b);
13687     /* Initialize the pool of recently flipped triangles. */
13688     poolinit(&m->flipstackers, sizeof(struct flipstacker), FLIPSTACKERPERBLOCK,
13689              FLIPSTACKERPERBLOCK, 0);
13690     m->checkquality = 1;
13691     if (b->verbose) {
13692       printf("  Splitting bad triangles.\n");
13693     }
13694     while ((m->badtriangles.items > 0) && (m->steinerleft != 0)) {
13695       /* Fix one bad triangle by inserting a vertex at its circumcenter. */
13696       badtri = dequeuebadtriang(m);
13697       splittriangle(m, b, badtri);
13698       if (m->badsubsegs.items > 0) {
13699         /* Put bad triangle back in queue for another try later. */
13700         enqueuebadtriang(m, b, badtri);
13701         /* Fix any encroached subsegments that resulted. */
13702         /*   Record any new bad triangles that result.   */
13703         splitencsegs(m, b, 1);
13704       } else {
13705         /* Return the bad triangle to the pool. */
13706         pooldealloc(&m->badtriangles, (VOID *) badtri);
13707       }
13708     }
13709   }
13710   /* At this point, if the "-D" switch was selected and we haven't run out  */
13711   /*   of Steiner points, the triangulation should be (conforming) Delaunay */
13712   /*   and have no low-quality triangles.                                   */
13713 
13714   /* Might we have run out of Steiner points too soon? */
13715   if (!b->quiet && b->conformdel && (m->badsubsegs.items > 0) &&
13716       (m->steinerleft == 0)) {
13717     printf("\nWarning:  I ran out of Steiner points, but the mesh has\n");
13718     if (m->badsubsegs.items == 1) {
13719       printf("  one encroached subsegment, and therefore might not be truly\n"
13720              );
13721     } else {
13722       printf("  %ld encroached subsegments, and therefore might not be truly\n"
13723              , m->badsubsegs.items);
13724     }
13725     printf("  Delaunay.  If the Delaunay property is important to you,\n");
13726     printf("  try increasing the number of Steiner points (controlled by\n");
13727     printf("  the -S switch) slightly and try again.\n\n");
13728   }
13729 }
13730 
13731 #endif /* not CDT_ONLY */
13732 
13733 /**                                                                         **/
13734 /**                                                                         **/
13735 /********* Mesh quality maintenance ends here                        *********/
13736 
13737 /*****************************************************************************/
13738 /*                                                                           */
13739 /*  highorder()   Create extra nodes for quadratic subparametric elements.   */
13740 /*                                                                           */
13741 /*****************************************************************************/
13742 
13743 #ifdef ANSI_DECLARATORS
13744 void highorder(struct mesh *m, struct behavior *b)
13745 #else /* not ANSI_DECLARATORS */
13746 void highorder(m, b)
13747 struct mesh *m;
13748 struct behavior *b;
13749 #endif /* not ANSI_DECLARATORS */
13750 
13751 {
13752   struct otri triangleloop, trisym;
13753   struct osub checkmark;
13754   vertex newvertex;
13755   vertex torg, tdest;
13756   int i;
13757   triangle ptr;                         /* Temporary variable used by sym(). */
13758   subseg sptr;                      /* Temporary variable used by tspivot(). */
13759 
13760   if (!b->quiet) {
13761     printf("Adding vertices for second-order triangles.\n");
13762   }
13763   /* The following line ensures that dead items in the pool of nodes    */
13764   /*   cannot be allocated for the extra nodes associated with high     */
13765   /*   order elements.  This ensures that the primary nodes (at the     */
13766   /*   corners of elements) will occur earlier in the output files, and */
13767   /*   have lower indices, than the extra nodes.                        */
13768   m->vertices.deaditemstack = (VOID *) NULL;
13769 
13770   traversalinit(&m->triangles);
13771   triangleloop.tri = triangletraverse(m);
13772   /* To loop over the set of edges, loop over all triangles, and look at   */
13773   /*   the three edges of each triangle.  If there isn't another triangle  */
13774   /*   adjacent to the edge, operate on the edge.  If there is another     */
13775   /*   adjacent triangle, operate on the edge only if the current triangle */
13776   /*   has a smaller pointer than its neighbor.  This way, each edge is    */
13777   /*   considered only once.                                               */
13778   while (triangleloop.tri != (triangle *) NULL) {
13779     for (triangleloop.orient = 0; triangleloop.orient < 3;
13780          triangleloop.orient++) {
13781       sym(triangleloop, trisym);
13782       if ((triangleloop.tri < trisym.tri) || (trisym.tri == m->dummytri)) {
13783         org(triangleloop, torg);
13784         dest(triangleloop, tdest);
13785         /* Create a new node in the middle of the edge.  Interpolate */
13786         /*   its attributes.                                         */
13787         newvertex = (vertex) poolalloc(&m->vertices);
13788         for (i = 0; i < 2 + m->nextras; i++) {
13789           newvertex[i] = 0.5 * (torg[i] + tdest[i]);
13790         }
13791         /* Set the new node's marker to zero or one, depending on */
13792         /*   whether it lies on a boundary.                       */
13793         setvertexmark(newvertex, trisym.tri == m->dummytri);
13794         setvertextype(newvertex,
13795                       trisym.tri == m->dummytri ? FREEVERTEX : SEGMENTVERTEX);
13796         if (b->usesegments) {
13797           tspivot(triangleloop, checkmark);
13798           /* If this edge is a segment, transfer the marker to the new node. */
13799           if (checkmark.ss != m->dummysub) {
13800             setvertexmark(newvertex, mark(checkmark));
13801             setvertextype(newvertex, SEGMENTVERTEX);
13802           }
13803         }
13804         if (b->verbose > 1) {
13805           printf("  Creating (%.12g, %.12g).\n", newvertex[0], newvertex[1]);
13806         }
13807         /* Record the new node in the (one or two) adjacent elements. */
13808         triangleloop.tri[m->highorderindex + triangleloop.orient] =
13809                 (triangle) newvertex;
13810         if (trisym.tri != m->dummytri) {
13811           trisym.tri[m->highorderindex + trisym.orient] = (triangle) newvertex;
13812         }
13813       }
13814     }
13815     triangleloop.tri = triangletraverse(m);
13816   }
13817 }
13818 
13819 /********* File I/O routines begin here                              *********/
13820 /**                                                                         **/
13821 /**                                                                         **/
13822 
13823 /*****************************************************************************/
13824 /*                                                                           */
13825 /*  readline()   Read a nonempty line from a file.                           */
13826 /*                                                                           */
13827 /*  A line is considered "nonempty" if it contains something that looks like */
13828 /*  a number.  Comments (prefaced by `#') are ignored.                       */
13829 /*                                                                           */
13830 /*****************************************************************************/
13831 
13832 #ifndef TRILIBRARY
13833 
13834 #ifdef ANSI_DECLARATORS
13835 char *readline(char *string, FILE *infile, char *infilename)
13836 #else /* not ANSI_DECLARATORS */
13837 char *readline(string, infile, infilename)
13838 char *string;
13839 FILE *infile;
13840 char *infilename;
13841 #endif /* not ANSI_DECLARATORS */
13842 
13843 {
13844   char *result;
13845 
13846   /* Search for something that looks like a number. */
13847   do {
13848     result = fgets(string, INPUTLINESIZE, infile);
13849     if (result == (char *) NULL) {
13850       printf("  Error:  Unexpected end of file in %s.\n", infilename);
13851       triexit(1);
13852     }
13853     /* Skip anything that doesn't look like a number, a comment, */
13854     /*   or the end of a line.                                   */
13855     while ((*result != '\0') && (*result != '#')
13856            && (*result != '.') && (*result != '+') && (*result != '-')
13857            && ((*result < '0') || (*result > '9'))) {
13858       result++;
13859     }
13860   /* If it's a comment or end of line, read another line and try again. */
13861   } while ((*result == '#') || (*result == '\0'));
13862   return result;
13863 }
13864 
13865 #endif /* not TRILIBRARY */
13866 
13867 /*****************************************************************************/
13868 /*                                                                           */
13869 /*  findfield()   Find the next field of a string.                           */
13870 /*                                                                           */
13871 /*  Jumps past the current field by searching for whitespace, then jumps     */
13872 /*  past the whitespace to find the next field.                              */
13873 /*                                                                           */
13874 /*****************************************************************************/
13875 
13876 #ifndef TRILIBRARY
13877 
13878 #ifdef ANSI_DECLARATORS
13879 char *findfield(char *string)
13880 #else /* not ANSI_DECLARATORS */
13881 char *findfield(string)
13882 char *string;
13883 #endif /* not ANSI_DECLARATORS */
13884 
13885 {
13886   char *result;
13887 
13888   result = string;
13889   /* Skip the current field.  Stop upon reaching whitespace. */
13890   while ((*result != '\0') && (*result != '#')
13891          && (*result != ' ') && (*result != '\t')) {
13892     result++;
13893   }
13894   /* Now skip the whitespace and anything else that doesn't look like a */
13895   /*   number, a comment, or the end of a line.                         */
13896   while ((*result != '\0') && (*result != '#')
13897          && (*result != '.') && (*result != '+') && (*result != '-')
13898          && ((*result < '0') || (*result > '9'))) {
13899     result++;
13900   }
13901   /* Check for a comment (prefixed with `#'). */
13902   if (*result == '#') {
13903     *result = '\0';
13904   }
13905   return result;
13906 }
13907 
13908 #endif /* not TRILIBRARY */
13909 
13910 /*****************************************************************************/
13911 /*                                                                           */
13912 /*  readnodes()   Read the vertices from a file, which may be a .node or     */
13913 /*                .poly file.                                                */
13914 /*                                                                           */
13915 /*****************************************************************************/
13916 
13917 #ifndef TRILIBRARY
13918 
13919 #ifdef ANSI_DECLARATORS
13920 void readnodes(struct mesh *m, struct behavior *b, char *nodefilename,
13921                char *polyfilename, FILE **polyfile)
13922 #else /* not ANSI_DECLARATORS */
13923 void readnodes(m, b, nodefilename, polyfilename, polyfile)
13924 struct mesh *m;
13925 struct behavior *b;
13926 char *nodefilename;
13927 char *polyfilename;
13928 FILE **polyfile;
13929 #endif /* not ANSI_DECLARATORS */
13930 
13931 {
13932   FILE *infile;
13933   vertex vertexloop;
13934   char inputline[INPUTLINESIZE];
13935   char *stringptr;
13936   char *infilename;
13937   REAL x, y;
13938   int firstnode;
13939   int nodemarkers;
13940   int currentmarker;
13941   int i, j;
13942 
13943   if (b->poly) {
13944     /* Read the vertices from a .poly file. */
13945     if (!b->quiet) {
13946       printf("Opening %s.\n", polyfilename);
13947     }
13948     *polyfile = fopen(polyfilename, "r");
13949     if (*polyfile == (FILE *) NULL) {
13950       printf("  Error:  Cannot access file %s.\n", polyfilename);
13951       triexit(1);
13952     }
13953     /* Read number of vertices, number of dimensions, number of vertex */
13954     /*   attributes, and number of boundary markers.                   */
13955     stringptr = readline(inputline, *polyfile, polyfilename);
13956     m->invertices = (int) strtol(stringptr, &stringptr, 0);
13957     stringptr = findfield(stringptr);
13958     if (*stringptr == '\0') {
13959       m->mesh_dim = 2;
13960     } else {
13961       m->mesh_dim = (int) strtol(stringptr, &stringptr, 0);
13962     }
13963     stringptr = findfield(stringptr);
13964     if (*stringptr == '\0') {
13965       m->nextras = 0;
13966     } else {
13967       m->nextras = (int) strtol(stringptr, &stringptr, 0);
13968     }
13969     stringptr = findfield(stringptr);
13970     if (*stringptr == '\0') {
13971       nodemarkers = 0;
13972     } else {
13973       nodemarkers = (int) strtol(stringptr, &stringptr, 0);
13974     }
13975     if (m->invertices > 0) {
13976       infile = *polyfile;
13977       infilename = polyfilename;
13978       m->readnodefile = 0;
13979     } else {
13980       /* If the .poly file claims there are zero vertices, that means that */
13981       /*   the vertices should be read from a separate .node file.         */
13982       m->readnodefile = 1;
13983       infilename = nodefilename;
13984     }
13985   } else {
13986     m->readnodefile = 1;
13987     infilename = nodefilename;
13988     *polyfile = (FILE *) NULL;
13989   }
13990 
13991   if (m->readnodefile) {
13992     /* Read the vertices from a .node file. */
13993     if (!b->quiet) {
13994       printf("Opening %s.\n", nodefilename);
13995     }
13996     infile = fopen(nodefilename, "r");
13997     if (infile == (FILE *) NULL) {
13998       printf("  Error:  Cannot access file %s.\n", nodefilename);
13999       triexit(1);
14000     }
14001     /* Read number of vertices, number of dimensions, number of vertex */
14002     /*   attributes, and number of boundary markers.                   */
14003     stringptr = readline(inputline, infile, nodefilename);
14004     m->invertices = (int) strtol(stringptr, &stringptr, 0);
14005     stringptr = findfield(stringptr);
14006     if (*stringptr == '\0') {
14007       m->mesh_dim = 2;
14008     } else {
14009       m->mesh_dim = (int) strtol(stringptr, &stringptr, 0);
14010     }
14011     stringptr = findfield(stringptr);
14012     if (*stringptr == '\0') {
14013       m->nextras = 0;
14014     } else {
14015       m->nextras = (int) strtol(stringptr, &stringptr, 0);
14016     }
14017     stringptr = findfield(stringptr);
14018     if (*stringptr == '\0') {
14019       nodemarkers = 0;
14020     } else {
14021       nodemarkers = (int) strtol(stringptr, &stringptr, 0);
14022     }
14023   }
14024 
14025   if (m->invertices < 3) {
14026     printf("Error:  Input must have at least three input vertices.\n");
14027     triexit(1);
14028   }
14029   if (m->mesh_dim != 2) {
14030     printf("Error:  Triangle only works with two-dimensional meshes.\n");
14031     triexit(1);
14032   }
14033   if (m->nextras == 0) {
14034     b->weighted = 0;
14035   }
14036 
14037   initializevertexpool(m, b);
14038 
14039   /* Read the vertices. */
14040   for (i = 0; i < m->invertices; i++) {
14041     vertexloop = (vertex) poolalloc(&m->vertices);
14042     stringptr = readline(inputline, infile, infilename);
14043     if (i == 0) {
14044       firstnode = (int) strtol(stringptr, &stringptr, 0);
14045       if ((firstnode == 0) || (firstnode == 1)) {
14046         b->firstnumber = firstnode;
14047       }
14048     }
14049     stringptr = findfield(stringptr);
14050     if (*stringptr == '\0') {
14051       printf("Error:  Vertex %d has no x coordinate.\n", b->firstnumber + i);
14052       triexit(1);
14053     }
14054     x = (REAL) strtod(stringptr, &stringptr);
14055     stringptr = findfield(stringptr);
14056     if (*stringptr == '\0') {
14057       printf("Error:  Vertex %d has no y coordinate.\n", b->firstnumber + i);
14058       triexit(1);
14059     }
14060     y = (REAL) strtod(stringptr, &stringptr);
14061     vertexloop[0] = x;
14062     vertexloop[1] = y;
14063     /* Read the vertex attributes. */
14064     for (j = 2; j < 2 + m->nextras; j++) {
14065       stringptr = findfield(stringptr);
14066       if (*stringptr == '\0') {
14067         vertexloop[j] = 0.0;
14068       } else {
14069         vertexloop[j] = (REAL) strtod(stringptr, &stringptr);
14070       }
14071     }
14072     if (nodemarkers) {
14073       /* Read a vertex marker. */
14074       stringptr = findfield(stringptr);
14075       if (*stringptr == '\0') {
14076         setvertexmark(vertexloop, 0);
14077       } else {
14078         currentmarker = (int) strtol(stringptr, &stringptr, 0);
14079         setvertexmark(vertexloop, currentmarker);
14080       }
14081     } else {
14082       /* If no markers are specified in the file, they default to zero. */
14083       setvertexmark(vertexloop, 0);
14084     }
14085     setvertextype(vertexloop, INPUTVERTEX);
14086     /* Determine the smallest and largest x and y coordinates. */
14087     if (i == 0) {
14088       m->xmin = m->xmax = x;
14089       m->ymin = m->ymax = y;
14090     } else {
14091       m->xmin = (x < m->xmin) ? x : m->xmin;
14092       m->xmax = (x > m->xmax) ? x : m->xmax;
14093       m->ymin = (y < m->ymin) ? y : m->ymin;
14094       m->ymax = (y > m->ymax) ? y : m->ymax;
14095     }
14096   }
14097   if (m->readnodefile) {
14098     fclose(infile);
14099   }
14100 
14101   /* Nonexistent x value used as a flag to mark circle events in sweepline */
14102   /*   Delaunay algorithm.                                                 */
14103   m->xminextreme = 10 * m->xmin - 9 * m->xmax;
14104 }
14105 
14106 #endif /* not TRILIBRARY */
14107 
14108 /*****************************************************************************/
14109 /*                                                                           */
14110 /*  transfernodes()   Read the vertices from memory.                         */
14111 /*                                                                           */
14112 /*****************************************************************************/
14113 
14114 #ifdef TRILIBRARY
14115 
14116 #ifdef ANSI_DECLARATORS
14117 void transfernodes(struct mesh *m, struct behavior *b, REAL *pointlist,
14118                    REAL *pointattriblist, int *pointmarkerlist,
14119                    int numberofpoints, int numberofpointattribs)
14120 #else /* not ANSI_DECLARATORS */
14121 void transfernodes(m, b, pointlist, pointattriblist, pointmarkerlist,
14122                    numberofpoints, numberofpointattribs)
14123 struct mesh *m;
14124 struct behavior *b;
14125 REAL *pointlist;
14126 REAL *pointattriblist;
14127 int *pointmarkerlist;
14128 int numberofpoints;
14129 int numberofpointattribs;
14130 #endif /* not ANSI_DECLARATORS */
14131 
14132 {
14133   vertex vertexloop;
14134   REAL x, y;
14135   int i, j;
14136   int coordindex;
14137   int attribindex;
14138 
14139   m->invertices = numberofpoints;
14140   m->mesh_dim = 2;
14141   m->nextras = numberofpointattribs;
14142   m->readnodefile = 0;
14143   if (m->invertices < 3) {
14144     printf("Error:  Input must have at least three input vertices.\n");
14145     triexit(1);
14146   }
14147   if (m->nextras == 0) {
14148     b->weighted = 0;
14149   }
14150 
14151   initializevertexpool(m, b);
14152 
14153   /* Read the vertices. */
14154   coordindex = 0;
14155   attribindex = 0;
14156   for (i = 0; i < m->invertices; i++) {
14157     vertexloop = (vertex) poolalloc(&m->vertices);
14158     /* Read the vertex coordinates. */
14159     x = vertexloop[0] = pointlist[coordindex++];
14160     y = vertexloop[1] = pointlist[coordindex++];
14161     /* Read the vertex attributes. */
14162     for (j = 0; j < numberofpointattribs; j++) {
14163       vertexloop[2 + j] = pointattriblist[attribindex++];
14164     }
14165     if (pointmarkerlist != (int *) NULL) {
14166       /* Read a vertex marker. */
14167       setvertexmark(vertexloop, pointmarkerlist[i]);
14168     } else {
14169       /* If no markers are specified, they default to zero. */
14170       setvertexmark(vertexloop, 0);
14171     }
14172     setvertextype(vertexloop, INPUTVERTEX);
14173     /* Determine the smallest and largest x and y coordinates. */
14174     if (i == 0) {
14175       m->xmin = m->xmax = x;
14176       m->ymin = m->ymax = y;
14177     } else {
14178       m->xmin = (x < m->xmin) ? x : m->xmin;
14179       m->xmax = (x > m->xmax) ? x : m->xmax;
14180       m->ymin = (y < m->ymin) ? y : m->ymin;
14181       m->ymax = (y > m->ymax) ? y : m->ymax;
14182     }
14183   }
14184 
14185   /* Nonexistent x value used as a flag to mark circle events in sweepline */
14186   /*   Delaunay algorithm.                                                 */
14187   m->xminextreme = 10 * m->xmin - 9 * m->xmax;
14188 }
14189 
14190 #endif /* TRILIBRARY */
14191 
14192 /*****************************************************************************/
14193 /*                                                                           */
14194 /*  readholes()   Read the holes, and possibly regional attributes and area  */
14195 /*                constraints, from a .poly file.                            */
14196 /*                                                                           */
14197 /*****************************************************************************/
14198 
14199 #ifndef TRILIBRARY
14200 
14201 #ifdef ANSI_DECLARATORS
14202 void readholes(struct mesh *m, struct behavior *b,
14203                FILE *polyfile, char *polyfilename, REAL **hlist, int *holes,
14204                REAL **rlist, int *regions)
14205 #else /* not ANSI_DECLARATORS */
14206 void readholes(m, b, polyfile, polyfilename, hlist, holes, rlist, regions)
14207 struct mesh *m;
14208 struct behavior *b;
14209 FILE *polyfile;
14210 char *polyfilename;
14211 REAL **hlist;
14212 int *holes;
14213 REAL **rlist;
14214 int *regions;
14215 #endif /* not ANSI_DECLARATORS */
14216 
14217 {
14218   REAL *holelist;
14219   REAL *regionlist;
14220   char inputline[INPUTLINESIZE];
14221   char *stringptr;
14222   int index;
14223   int i;
14224 
14225   /* Read the holes. */
14226   stringptr = readline(inputline, polyfile, polyfilename);
14227   *holes = (int) strtol(stringptr, &stringptr, 0);
14228   if (*holes > 0) {
14229     holelist = (REAL *) trimalloc(2 * *holes * (int) sizeof(REAL));
14230     *hlist = holelist;
14231     for (i = 0; i < 2 * *holes; i += 2) {
14232       stringptr = readline(inputline, polyfile, polyfilename);
14233       stringptr = findfield(stringptr);
14234       if (*stringptr == '\0') {
14235         printf("Error:  Hole %d has no x coordinate.\n",
14236                b->firstnumber + (i >> 1));
14237         triexit(1);
14238       } else {
14239         holelist[i] = (REAL) strtod(stringptr, &stringptr);
14240       }
14241       stringptr = findfield(stringptr);
14242       if (*stringptr == '\0') {
14243         printf("Error:  Hole %d has no y coordinate.\n",
14244                b->firstnumber + (i >> 1));
14245         triexit(1);
14246       } else {
14247         holelist[i + 1] = (REAL) strtod(stringptr, &stringptr);
14248       }
14249     }
14250   } else {
14251     *hlist = (REAL *) NULL;
14252   }
14253 
14254 #ifndef CDT_ONLY
14255   if ((b->regionattrib || b->vararea) && !b->refine) {
14256     /* Read the area constraints. */
14257     stringptr = readline(inputline, polyfile, polyfilename);
14258     *regions = (int) strtol(stringptr, &stringptr, 0);
14259     if (*regions > 0) {
14260       regionlist = (REAL *) trimalloc(4 * *regions * (int) sizeof(REAL));
14261       *rlist = regionlist;
14262       index = 0;
14263       for (i = 0; i < *regions; i++) {
14264         stringptr = readline(inputline, polyfile, polyfilename);
14265         stringptr = findfield(stringptr);
14266         if (*stringptr == '\0') {
14267           printf("Error:  Region %d has no x coordinate.\n",
14268                  b->firstnumber + i);
14269           triexit(1);
14270         } else {
14271           regionlist[index++] = (REAL) strtod(stringptr, &stringptr);
14272         }
14273         stringptr = findfield(stringptr);
14274         if (*stringptr == '\0') {
14275           printf("Error:  Region %d has no y coordinate.\n",
14276                  b->firstnumber + i);
14277           triexit(1);
14278         } else {
14279           regionlist[index++] = (REAL) strtod(stringptr, &stringptr);
14280         }
14281         stringptr = findfield(stringptr);
14282         if (*stringptr == '\0') {
14283           printf(
14284             "Error:  Region %d has no region attribute or area constraint.\n",
14285                  b->firstnumber + i);
14286           triexit(1);
14287         } else {
14288           regionlist[index++] = (REAL) strtod(stringptr, &stringptr);
14289         }
14290         stringptr = findfield(stringptr);
14291         if (*stringptr == '\0') {
14292           regionlist[index] = regionlist[index - 1];
14293         } else {
14294           regionlist[index] = (REAL) strtod(stringptr, &stringptr);
14295         }
14296         index++;
14297       }
14298     }
14299   } else {
14300     /* Set `*regions' to zero to avoid an accidental free() later. */
14301     *regions = 0;
14302     *rlist = (REAL *) NULL;
14303   }
14304 #endif /* not CDT_ONLY */
14305 
14306   fclose(polyfile);
14307 }
14308 
14309 #endif /* not TRILIBRARY */
14310 
14311 /*****************************************************************************/
14312 /*                                                                           */
14313 /*  finishfile()   Write the command line to the output file so the user     */
14314 /*                 can remember how the file was generated.  Close the file. */
14315 /*                                                                           */
14316 /*****************************************************************************/
14317 
14318 #ifndef TRILIBRARY
14319 
14320 #ifdef ANSI_DECLARATORS
14321 void finishfile(FILE *outfile, int argc, char **argv)
14322 #else /* not ANSI_DECLARATORS */
14323 void finishfile(outfile, argc, argv)
14324 FILE *outfile;
14325 int argc;
14326 char **argv;
14327 #endif /* not ANSI_DECLARATORS */
14328 
14329 {
14330   int i;
14331 
14332   fprintf(outfile, "# Generated by");
14333   for (i = 0; i < argc; i++) {
14334     fprintf(outfile, " ");
14335     fputs(argv[i], outfile);
14336   }
14337   fprintf(outfile, "\n");
14338   fclose(outfile);
14339 }
14340 
14341 #endif /* not TRILIBRARY */
14342 
14343 /*****************************************************************************/
14344 /*                                                                           */
14345 /*  writenodes()   Number the vertices and write them to a .node file.       */
14346 /*                                                                           */
14347 /*  To save memory, the vertex numbers are written over the boundary markers */
14348 /*  after the vertices are written to a file.                                */
14349 /*                                                                           */
14350 /*****************************************************************************/
14351 
14352 #ifdef TRILIBRARY
14353 
14354 #ifdef ANSI_DECLARATORS
14355 void writenodes(struct mesh *m, struct behavior *b, REAL **pointlist,
14356                 REAL **pointattriblist, int **pointmarkerlist)
14357 #else /* not ANSI_DECLARATORS */
14358 void writenodes(m, b, pointlist, pointattriblist, pointmarkerlist)
14359 struct mesh *m;
14360 struct behavior *b;
14361 REAL **pointlist;
14362 REAL **pointattriblist;
14363 int **pointmarkerlist;
14364 #endif /* not ANSI_DECLARATORS */
14365 
14366 #else /* not TRILIBRARY */
14367 
14368 #ifdef ANSI_DECLARATORS
14369 void writenodes(struct mesh *m, struct behavior *b, char *nodefilename,
14370                 int argc, char **argv)
14371 #else /* not ANSI_DECLARATORS */
14372 void writenodes(m, b, nodefilename, argc, argv)
14373 struct mesh *m;
14374 struct behavior *b;
14375 char *nodefilename;
14376 int argc;
14377 char **argv;
14378 #endif /* not ANSI_DECLARATORS */
14379 
14380 #endif /* not TRILIBRARY */
14381 
14382 {
14383 #ifdef TRILIBRARY
14384   REAL *plist;
14385   REAL *palist;
14386   int *pmlist;
14387   int coordindex;
14388   int attribindex;
14389 #else /* not TRILIBRARY */
14390   FILE *outfile;
14391 #endif /* not TRILIBRARY */
14392   vertex vertexloop;
14393   long outvertices;
14394   int vertexnumber;
14395   int i;
14396 
14397   if (b->jettison) {
14398     outvertices = m->vertices.items - m->undeads;
14399   } else {
14400     outvertices = m->vertices.items;
14401   }
14402 
14403 #ifdef TRILIBRARY
14404   if (!b->quiet) {
14405     printf("Writing vertices.\n");
14406   }
14407   /* Allocate memory for output vertices if necessary. */
14408   if (*pointlist == (REAL *) NULL) {
14409     *pointlist = (REAL *) trimalloc((int) (outvertices * 2 * sizeof(REAL)));
14410   }
14411   /* Allocate memory for output vertex attributes if necessary. */
14412   if ((m->nextras > 0) && (*pointattriblist == (REAL *) NULL)) {
14413     *pointattriblist = (REAL *) trimalloc((int) (outvertices * m->nextras *
14414                                                  sizeof(REAL)));
14415   }
14416   /* Allocate memory for output vertex markers if necessary. */
14417   if (!b->nobound && (*pointmarkerlist == (int *) NULL)) {
14418     *pointmarkerlist = (int *) trimalloc((int) (outvertices * sizeof(int)));
14419   }
14420   plist = *pointlist;
14421   palist = *pointattriblist;
14422   pmlist = *pointmarkerlist;
14423   coordindex = 0;
14424   attribindex = 0;
14425 #else /* not TRILIBRARY */
14426   if (!b->quiet) {
14427     printf("Writing %s.\n", nodefilename);
14428   }
14429   outfile = fopen(nodefilename, "w");
14430   if (outfile == (FILE *) NULL) {
14431     printf("  Error:  Cannot create file %s.\n", nodefilename);
14432     triexit(1);
14433   }
14434   /* Number of vertices, number of dimensions, number of vertex attributes, */
14435   /*   and number of boundary markers (zero or one).                        */
14436   fprintf(outfile, "%ld  %d  %d  %d\n", outvertices, m->mesh_dim,
14437           m->nextras, 1 - b->nobound);
14438 #endif /* not TRILIBRARY */
14439 
14440   traversalinit(&m->vertices);
14441   vertexnumber = b->firstnumber;
14442   vertexloop = vertextraverse(m);
14443   while (vertexloop != (vertex) NULL) {
14444     if (!b->jettison || (vertextype(vertexloop) != UNDEADVERTEX)) {
14445 #ifdef TRILIBRARY
14446       /* X and y coordinates. */
14447       plist[coordindex++] = vertexloop[0];
14448       plist[coordindex++] = vertexloop[1];
14449       /* Vertex attributes. */
14450       for (i = 0; i < m->nextras; i++) {
14451         palist[attribindex++] = vertexloop[2 + i];
14452       }
14453       if (!b->nobound) {
14454         /* Copy the boundary marker. */
14455         pmlist[vertexnumber - b->firstnumber] = vertexmark(vertexloop);
14456       }
14457 #else /* not TRILIBRARY */
14458       /* Vertex number, x and y coordinates. */
14459       fprintf(outfile, "%4d    %.17g  %.17g", vertexnumber, vertexloop[0],
14460               vertexloop[1]);
14461       for (i = 0; i < m->nextras; i++) {
14462         /* Write an attribute. */
14463         fprintf(outfile, "  %.17g", vertexloop[i + 2]);
14464       }
14465       if (b->nobound) {
14466         fprintf(outfile, "\n");
14467       } else {
14468         /* Write the boundary marker. */
14469         fprintf(outfile, "    %d\n", vertexmark(vertexloop));
14470       }
14471 #endif /* not TRILIBRARY */
14472 
14473       setvertexmark(vertexloop, vertexnumber);
14474       vertexnumber++;
14475     }
14476     vertexloop = vertextraverse(m);
14477   }
14478 
14479 #ifndef TRILIBRARY
14480   finishfile(outfile, argc, argv);
14481 #endif /* not TRILIBRARY */
14482 }
14483 
14484 /*****************************************************************************/
14485 /*                                                                           */
14486 /*  numbernodes()   Number the vertices.                                     */
14487 /*                                                                           */
14488 /*  Each vertex is assigned a marker equal to its number.                    */
14489 /*                                                                           */
14490 /*  Used when writenodes() is not called because no .node file is written.   */
14491 /*                                                                           */
14492 /*****************************************************************************/
14493 
14494 #ifdef ANSI_DECLARATORS
14495 void numbernodes(struct mesh *m, struct behavior *b)
14496 #else /* not ANSI_DECLARATORS */
14497 void numbernodes(m, b)
14498 struct mesh *m;
14499 struct behavior *b;
14500 #endif /* not ANSI_DECLARATORS */
14501 
14502 {
14503   vertex vertexloop;
14504   int vertexnumber;
14505 
14506   traversalinit(&m->vertices);
14507   vertexnumber = b->firstnumber;
14508   vertexloop = vertextraverse(m);
14509   while (vertexloop != (vertex) NULL) {
14510     setvertexmark(vertexloop, vertexnumber);
14511     if (!b->jettison || (vertextype(vertexloop) != UNDEADVERTEX)) {
14512       vertexnumber++;
14513     }
14514     vertexloop = vertextraverse(m);
14515   }
14516 }
14517 
14518 /*****************************************************************************/
14519 /*                                                                           */
14520 /*  writeelements()   Write the triangles to an .ele file.                   */
14521 /*                                                                           */
14522 /*****************************************************************************/
14523 
14524 #ifdef TRILIBRARY
14525 
14526 #ifdef ANSI_DECLARATORS
14527 void writeelements(struct mesh *m, struct behavior *b,
14528                    int **trianglelist, REAL **triangleattriblist)
14529 #else /* not ANSI_DECLARATORS */
14530 void writeelements(m, b, trianglelist, triangleattriblist)
14531 struct mesh *m;
14532 struct behavior *b;
14533 int **trianglelist;
14534 REAL **triangleattriblist;
14535 #endif /* not ANSI_DECLARATORS */
14536 
14537 #else /* not TRILIBRARY */
14538 
14539 #ifdef ANSI_DECLARATORS
14540 void writeelements(struct mesh *m, struct behavior *b, char *elefilename,
14541                    int argc, char **argv)
14542 #else /* not ANSI_DECLARATORS */
14543 void writeelements(m, b, elefilename, argc, argv)
14544 struct mesh *m;
14545 struct behavior *b;
14546 char *elefilename;
14547 int argc;
14548 char **argv;
14549 #endif /* not ANSI_DECLARATORS */
14550 
14551 #endif /* not TRILIBRARY */
14552 
14553 {
14554 #ifdef TRILIBRARY
14555   int *tlist;
14556   REAL *talist;
14557   int vertexindex;
14558   int attribindex;
14559 #else /* not TRILIBRARY */
14560   FILE *outfile;
14561 #endif /* not TRILIBRARY */
14562   struct otri triangleloop;
14563   vertex p1, p2, p3;
14564   vertex mid1, mid2, mid3;
14565   long elementnumber;
14566   int i;
14567 
14568 #ifdef TRILIBRARY
14569   if (!b->quiet) {
14570     printf("Writing triangles.\n");
14571   }
14572   /* Allocate memory for output triangles if necessary. */
14573   if (*trianglelist == (int *) NULL) {
14574     *trianglelist = (int *) trimalloc((int) (m->triangles.items *
14575                                              ((b->order + 1) * (b->order + 2) /
14576                                               2) * sizeof(int)));
14577   }
14578   /* Allocate memory for output triangle attributes if necessary. */
14579   if ((m->eextras > 0) && (*triangleattriblist == (REAL *) NULL)) {
14580     *triangleattriblist = (REAL *) trimalloc((int) (m->triangles.items *
14581                                                     m->eextras *
14582                                                     sizeof(REAL)));
14583   }
14584   tlist = *trianglelist;
14585   talist = *triangleattriblist;
14586   vertexindex = 0;
14587   attribindex = 0;
14588 #else /* not TRILIBRARY */
14589   if (!b->quiet) {
14590     printf("Writing %s.\n", elefilename);
14591   }
14592   outfile = fopen(elefilename, "w");
14593   if (outfile == (FILE *) NULL) {
14594     printf("  Error:  Cannot create file %s.\n", elefilename);
14595     triexit(1);
14596   }
14597   /* Number of triangles, vertices per triangle, attributes per triangle. */
14598   fprintf(outfile, "%ld  %d  %d\n", m->triangles.items,
14599           (b->order + 1) * (b->order + 2) / 2, m->eextras);
14600 #endif /* not TRILIBRARY */
14601 
14602   traversalinit(&m->triangles);
14603   triangleloop.tri = triangletraverse(m);
14604   triangleloop.orient = 0;
14605   elementnumber = b->firstnumber;
14606   while (triangleloop.tri != (triangle *) NULL) {
14607     org(triangleloop, p1);
14608     dest(triangleloop, p2);
14609     apex(triangleloop, p3);
14610     if (b->order == 1) {
14611 #ifdef TRILIBRARY
14612       tlist[vertexindex++] = vertexmark(p1);
14613       tlist[vertexindex++] = vertexmark(p2);
14614       tlist[vertexindex++] = vertexmark(p3);
14615 #else /* not TRILIBRARY */
14616       /* Triangle number, indices for three vertices. */
14617       fprintf(outfile, "%4ld    %4d  %4d  %4d", elementnumber,
14618               vertexmark(p1), vertexmark(p2), vertexmark(p3));
14619 #endif /* not TRILIBRARY */
14620     } else {
14621       mid1 = (vertex) triangleloop.tri[m->highorderindex + 1];
14622       mid2 = (vertex) triangleloop.tri[m->highorderindex + 2];
14623       mid3 = (vertex) triangleloop.tri[m->highorderindex];
14624 #ifdef TRILIBRARY
14625       tlist[vertexindex++] = vertexmark(p1);
14626       tlist[vertexindex++] = vertexmark(p2);
14627       tlist[vertexindex++] = vertexmark(p3);
14628       tlist[vertexindex++] = vertexmark(mid1);
14629       tlist[vertexindex++] = vertexmark(mid2);
14630       tlist[vertexindex++] = vertexmark(mid3);
14631 #else /* not TRILIBRARY */
14632       /* Triangle number, indices for six vertices. */
14633       fprintf(outfile, "%4ld    %4d  %4d  %4d  %4d  %4d  %4d", elementnumber,
14634               vertexmark(p1), vertexmark(p2), vertexmark(p3), vertexmark(mid1),
14635               vertexmark(mid2), vertexmark(mid3));
14636 #endif /* not TRILIBRARY */
14637     }
14638 
14639 #ifdef TRILIBRARY
14640     for (i = 0; i < m->eextras; i++) {
14641       talist[attribindex++] = elemattribute(triangleloop, i);
14642     }
14643 #else /* not TRILIBRARY */
14644     for (i = 0; i < m->eextras; i++) {
14645       fprintf(outfile, "  %.17g", elemattribute(triangleloop, i));
14646     }
14647     fprintf(outfile, "\n");
14648 #endif /* not TRILIBRARY */
14649 
14650     triangleloop.tri = triangletraverse(m);
14651     elementnumber++;
14652   }
14653 
14654 #ifndef TRILIBRARY
14655   finishfile(outfile, argc, argv);
14656 #endif /* not TRILIBRARY */
14657 }
14658 
14659 /*****************************************************************************/
14660 /*                                                                           */
14661 /*  writepoly()   Write the segments and holes to a .poly file.              */
14662 /*                                                                           */
14663 /*****************************************************************************/
14664 
14665 #ifdef TRILIBRARY
14666 
14667 #ifdef ANSI_DECLARATORS
14668 void writepoly(struct mesh *m, struct behavior *b,
14669                int **segmentlist, int **segmentmarkerlist)
14670 #else /* not ANSI_DECLARATORS */
14671 void writepoly(m, b, segmentlist, segmentmarkerlist)
14672 struct mesh *m;
14673 struct behavior *b;
14674 int **segmentlist;
14675 int **segmentmarkerlist;
14676 #endif /* not ANSI_DECLARATORS */
14677 
14678 #else /* not TRILIBRARY */
14679 
14680 #ifdef ANSI_DECLARATORS
14681 void writepoly(struct mesh *m, struct behavior *b, char *polyfilename,
14682                REAL *holelist, int holes, REAL *regionlist, int regions,
14683                int argc, char **argv)
14684 #else /* not ANSI_DECLARATORS */
14685 void writepoly(m, b, polyfilename, holelist, holes, regionlist, regions,
14686                argc, argv)
14687 struct mesh *m;
14688 struct behavior *b;
14689 char *polyfilename;
14690 REAL *holelist;
14691 int holes;
14692 REAL *regionlist;
14693 int regions;
14694 int argc;
14695 char **argv;
14696 #endif /* not ANSI_DECLARATORS */
14697 
14698 #endif /* not TRILIBRARY */
14699 
14700 {
14701 #ifdef TRILIBRARY
14702   int *slist;
14703   int *smlist;
14704   int index;
14705 #else /* not TRILIBRARY */
14706   FILE *outfile;
14707   long holenumber, regionnumber;
14708 #endif /* not TRILIBRARY */
14709   struct osub subsegloop;
14710   vertex endpoint1, endpoint2;
14711   long subsegnumber;
14712 
14713 #ifdef TRILIBRARY
14714   if (!b->quiet) {
14715     printf("Writing segments.\n");
14716   }
14717   /* Allocate memory for output segments if necessary. */
14718   if (*segmentlist == (int *) NULL) {
14719     *segmentlist = (int *) trimalloc((int) (m->subsegs.items * 2 *
14720                                             sizeof(int)));
14721   }
14722   /* Allocate memory for output segment markers if necessary. */
14723   if (!b->nobound && (*segmentmarkerlist == (int *) NULL)) {
14724     *segmentmarkerlist = (int *) trimalloc((int) (m->subsegs.items *
14725                                                   sizeof(int)));
14726   }
14727   slist = *segmentlist;
14728   smlist = *segmentmarkerlist;
14729   index = 0;
14730 #else /* not TRILIBRARY */
14731   if (!b->quiet) {
14732     printf("Writing %s.\n", polyfilename);
14733   }
14734   outfile = fopen(polyfilename, "w");
14735   if (outfile == (FILE *) NULL) {
14736     printf("  Error:  Cannot create file %s.\n", polyfilename);
14737     triexit(1);
14738   }
14739   /* The zero indicates that the vertices are in a separate .node file. */
14740   /*   Followed by number of dimensions, number of vertex attributes,   */
14741   /*   and number of boundary markers (zero or one).                    */
14742   fprintf(outfile, "%d  %d  %d  %d\n", 0, m->mesh_dim, m->nextras,
14743           1 - b->nobound);
14744   /* Number of segments, number of boundary markers (zero or one). */
14745   fprintf(outfile, "%ld  %d\n", m->subsegs.items, 1 - b->nobound);
14746 #endif /* not TRILIBRARY */
14747 
14748   traversalinit(&m->subsegs);
14749   subsegloop.ss = subsegtraverse(m);
14750   subsegloop.ssorient = 0;
14751   subsegnumber = b->firstnumber;
14752   while (subsegloop.ss != (subseg *) NULL) {
14753     sorg(subsegloop, endpoint1);
14754     sdest(subsegloop, endpoint2);
14755 #ifdef TRILIBRARY
14756     /* Copy indices of the segment's two endpoints. */
14757     slist[index++] = vertexmark(endpoint1);
14758     slist[index++] = vertexmark(endpoint2);
14759     if (!b->nobound) {
14760       /* Copy the boundary marker. */
14761       smlist[subsegnumber - b->firstnumber] = mark(subsegloop);
14762     }
14763 #else /* not TRILIBRARY */
14764     /* Segment number, indices of its two endpoints, and possibly a marker. */
14765     if (b->nobound) {
14766       fprintf(outfile, "%4ld    %4d  %4d\n", subsegnumber,
14767               vertexmark(endpoint1), vertexmark(endpoint2));
14768     } else {
14769       fprintf(outfile, "%4ld    %4d  %4d    %4d\n", subsegnumber,
14770               vertexmark(endpoint1), vertexmark(endpoint2), mark(subsegloop));
14771     }
14772 #endif /* not TRILIBRARY */
14773 
14774     subsegloop.ss = subsegtraverse(m);
14775     subsegnumber++;
14776   }
14777 
14778 #ifndef TRILIBRARY
14779 #ifndef CDT_ONLY
14780   fprintf(outfile, "%d\n", holes);
14781   if (holes > 0) {
14782     for (holenumber = 0; holenumber < holes; holenumber++) {
14783       /* Hole number, x and y coordinates. */
14784       fprintf(outfile, "%4ld   %.17g  %.17g\n", b->firstnumber + holenumber,
14785               holelist[2 * holenumber], holelist[2 * holenumber + 1]);
14786     }
14787   }
14788   if (regions > 0) {
14789     fprintf(outfile, "%d\n", regions);
14790     for (regionnumber = 0; regionnumber < regions; regionnumber++) {
14791       /* Region number, x and y coordinates, attribute, maximum area. */
14792       fprintf(outfile, "%4ld   %.17g  %.17g  %.17g  %.17g\n",
14793               b->firstnumber + regionnumber,
14794               regionlist[4 * regionnumber], regionlist[4 * regionnumber + 1],
14795               regionlist[4 * regionnumber + 2],
14796               regionlist[4 * regionnumber + 3]);
14797     }
14798   }
14799 #endif /* not CDT_ONLY */
14800 
14801   finishfile(outfile, argc, argv);
14802 #endif /* not TRILIBRARY */
14803 }
14804 
14805 /*****************************************************************************/
14806 /*                                                                           */
14807 /*  writeedges()   Write the edges to an .edge file.                         */
14808 /*                                                                           */
14809 /*****************************************************************************/
14810 
14811 #ifdef TRILIBRARY
14812 
14813 #ifdef ANSI_DECLARATORS
14814 void writeedges(struct mesh *m, struct behavior *b,
14815                 int **edgelist, int **edgemarkerlist)
14816 #else /* not ANSI_DECLARATORS */
14817 void writeedges(m, b, edgelist, edgemarkerlist)
14818 struct mesh *m;
14819 struct behavior *b;
14820 int **edgelist;
14821 int **edgemarkerlist;
14822 #endif /* not ANSI_DECLARATORS */
14823 
14824 #else /* not TRILIBRARY */
14825 
14826 #ifdef ANSI_DECLARATORS
14827 void writeedges(struct mesh *m, struct behavior *b, char *edgefilename,
14828                 int argc, char **argv)
14829 #else /* not ANSI_DECLARATORS */
14830 void writeedges(m, b, edgefilename, argc, argv)
14831 struct mesh *m;
14832 struct behavior *b;
14833 char *edgefilename;
14834 int argc;
14835 char **argv;
14836 #endif /* not ANSI_DECLARATORS */
14837 
14838 #endif /* not TRILIBRARY */
14839 
14840 {
14841 #ifdef TRILIBRARY
14842   int *elist;
14843   int *emlist;
14844   int index;
14845 #else /* not TRILIBRARY */
14846   FILE *outfile;
14847 #endif /* not TRILIBRARY */
14848   struct otri triangleloop, trisym;
14849   struct osub checkmark;
14850   vertex p1, p2;
14851   long edgenumber;
14852   triangle ptr;                         /* Temporary variable used by sym(). */
14853   subseg sptr;                      /* Temporary variable used by tspivot(). */
14854 
14855 #ifdef TRILIBRARY
14856   if (!b->quiet) {
14857     printf("Writing edges.\n");
14858   }
14859   /* Allocate memory for edges if necessary. */
14860   if (*edgelist == (int *) NULL) {
14861     *edgelist = (int *) trimalloc((int) (m->edges * 2 * sizeof(int)));
14862   }
14863   /* Allocate memory for edge markers if necessary. */
14864   if (!b->nobound && (*edgemarkerlist == (int *) NULL)) {
14865     *edgemarkerlist = (int *) trimalloc((int) (m->edges * sizeof(int)));
14866   }
14867   elist = *edgelist;
14868   emlist = *edgemarkerlist;
14869   index = 0;
14870 #else /* not TRILIBRARY */
14871   if (!b->quiet) {
14872     printf("Writing %s.\n", edgefilename);
14873   }
14874   outfile = fopen(edgefilename, "w");
14875   if (outfile == (FILE *) NULL) {
14876     printf("  Error:  Cannot create file %s.\n", edgefilename);
14877     triexit(1);
14878   }
14879   /* Number of edges, number of boundary markers (zero or one). */
14880   fprintf(outfile, "%ld  %d\n", m->edges, 1 - b->nobound);
14881 #endif /* not TRILIBRARY */
14882 
14883   traversalinit(&m->triangles);
14884   triangleloop.tri = triangletraverse(m);
14885   edgenumber = b->firstnumber;
14886   /* To loop over the set of edges, loop over all triangles, and look at   */
14887   /*   the three edges of each triangle.  If there isn't another triangle  */
14888   /*   adjacent to the edge, operate on the edge.  If there is another     */
14889   /*   adjacent triangle, operate on the edge only if the current triangle */
14890   /*   has a smaller pointer than its neighbor.  This way, each edge is    */
14891   /*   considered only once.                                               */
14892   while (triangleloop.tri != (triangle *) NULL) {
14893     for (triangleloop.orient = 0; triangleloop.orient < 3;
14894          triangleloop.orient++) {
14895       sym(triangleloop, trisym);
14896       if ((triangleloop.tri < trisym.tri) || (trisym.tri == m->dummytri)) {
14897         org(triangleloop, p1);
14898         dest(triangleloop, p2);
14899 #ifdef TRILIBRARY
14900         elist[index++] = vertexmark(p1);
14901         elist[index++] = vertexmark(p2);
14902 #endif /* TRILIBRARY */
14903         if (b->nobound) {
14904 #ifndef TRILIBRARY
14905           /* Edge number, indices of two endpoints. */
14906           fprintf(outfile, "%4ld   %d  %d\n", edgenumber,
14907                   vertexmark(p1), vertexmark(p2));
14908 #endif /* not TRILIBRARY */
14909         } else {
14910           /* Edge number, indices of two endpoints, and a boundary marker. */
14911           /*   If there's no subsegment, the boundary marker is zero.      */
14912           if (b->usesegments) {
14913             tspivot(triangleloop, checkmark);
14914             if (checkmark.ss == m->dummysub) {
14915 #ifdef TRILIBRARY
14916               emlist[edgenumber - b->firstnumber] = 0;
14917 #else /* not TRILIBRARY */
14918               fprintf(outfile, "%4ld   %d  %d  %d\n", edgenumber,
14919                       vertexmark(p1), vertexmark(p2), 0);
14920 #endif /* not TRILIBRARY */
14921             } else {
14922 #ifdef TRILIBRARY
14923               emlist[edgenumber - b->firstnumber] = mark(checkmark);
14924 #else /* not TRILIBRARY */
14925               fprintf(outfile, "%4ld   %d  %d  %d\n", edgenumber,
14926                       vertexmark(p1), vertexmark(p2), mark(checkmark));
14927 #endif /* not TRILIBRARY */
14928             }
14929           } else {
14930 #ifdef TRILIBRARY
14931             emlist[edgenumber - b->firstnumber] = trisym.tri == m->dummytri;
14932 #else /* not TRILIBRARY */
14933             fprintf(outfile, "%4ld   %d  %d  %d\n", edgenumber,
14934                     vertexmark(p1), vertexmark(p2), trisym.tri == m->dummytri);
14935 #endif /* not TRILIBRARY */
14936           }
14937         }
14938         edgenumber++;
14939       }
14940     }
14941     triangleloop.tri = triangletraverse(m);
14942   }
14943 
14944 #ifndef TRILIBRARY
14945   finishfile(outfile, argc, argv);
14946 #endif /* not TRILIBRARY */
14947 }
14948 
14949 /*****************************************************************************/
14950 /*                                                                           */
14951 /*  writevoronoi()   Write the Voronoi diagram to a .v.node and .v.edge      */
14952 /*                   file.                                                   */
14953 /*                                                                           */
14954 /*  The Voronoi diagram is the geometric dual of the Delaunay triangulation. */
14955 /*  Hence, the Voronoi vertices are listed by traversing the Delaunay        */
14956 /*  triangles, and the Voronoi edges are listed by traversing the Delaunay   */
14957 /*  edges.                                                                   */
14958 /*                                                                           */
14959 /*  WARNING:  In order to assign numbers to the Voronoi vertices, this       */
14960 /*  procedure messes up the subsegments or the extra nodes of every          */
14961 /*  element.  Hence, you should call this procedure last.                    */
14962 /*                                                                           */
14963 /*****************************************************************************/
14964 
14965 #ifdef TRILIBRARY
14966 
14967 #ifdef ANSI_DECLARATORS
14968 void writevoronoi(struct mesh *m, struct behavior *b, REAL **vpointlist,
14969                   REAL **vpointattriblist, int **vpointmarkerlist,
14970                   int **vedgelist, int **vedgemarkerlist, REAL **vnormlist)
14971 #else /* not ANSI_DECLARATORS */
14972 void writevoronoi(m, b, vpointlist, vpointattriblist, vpointmarkerlist,
14973                   vedgelist, vedgemarkerlist, vnormlist)
14974 struct mesh *m;
14975 struct behavior *b;
14976 REAL **vpointlist;
14977 REAL **vpointattriblist;
14978 int **vpointmarkerlist;
14979 int **vedgelist;
14980 int **vedgemarkerlist;
14981 REAL **vnormlist;
14982 #endif /* not ANSI_DECLARATORS */
14983 
14984 #else /* not TRILIBRARY */
14985 
14986 #ifdef ANSI_DECLARATORS
14987 void writevoronoi(struct mesh *m, struct behavior *b, char *vnodefilename,
14988                   char *vedgefilename, int argc, char **argv)
14989 #else /* not ANSI_DECLARATORS */
14990 void writevoronoi(m, b, vnodefilename, vedgefilename, argc, argv)
14991 struct mesh *m;
14992 struct behavior *b;
14993 char *vnodefilename;
14994 char *vedgefilename;
14995 int argc;
14996 char **argv;
14997 #endif /* not ANSI_DECLARATORS */
14998 
14999 #endif /* not TRILIBRARY */
15000 
15001 {
15002 #ifdef TRILIBRARY
15003   REAL *plist;
15004   REAL *palist;
15005   int *elist;
15006   REAL *normlist;
15007   int coordindex;
15008   int attribindex;
15009 #else /* not TRILIBRARY */
15010   FILE *outfile;
15011 #endif /* not TRILIBRARY */
15012   struct otri triangleloop, trisym;
15013   vertex torg, tdest, tapex;
15014   REAL circumcenter[2];
15015   REAL xi, eta;
15016   long vnodenumber, vedgenumber;
15017   int p1, p2;
15018   int i;
15019   triangle ptr;                         /* Temporary variable used by sym(). */
15020 
15021 #ifdef TRILIBRARY
15022   if (!b->quiet) {
15023     printf("Writing Voronoi vertices.\n");
15024   }
15025   /* Allocate memory for Voronoi vertices if necessary. */
15026   if (*vpointlist == (REAL *) NULL) {
15027     *vpointlist = (REAL *) trimalloc((int) (m->triangles.items * 2 *
15028                                             sizeof(REAL)));
15029   }
15030   /* Allocate memory for Voronoi vertex attributes if necessary. */
15031   if (*vpointattriblist == (REAL *) NULL) {
15032     *vpointattriblist = (REAL *) trimalloc((int) (m->triangles.items *
15033                                                   m->nextras * sizeof(REAL)));
15034   }
15035   *vpointmarkerlist = (int *) NULL;
15036   plist = *vpointlist;
15037   palist = *vpointattriblist;
15038   coordindex = 0;
15039   attribindex = 0;
15040 #else /* not TRILIBRARY */
15041   if (!b->quiet) {
15042     printf("Writing %s.\n", vnodefilename);
15043   }
15044   outfile = fopen(vnodefilename, "w");
15045   if (outfile == (FILE *) NULL) {
15046     printf("  Error:  Cannot create file %s.\n", vnodefilename);
15047     triexit(1);
15048   }
15049   /* Number of triangles, two dimensions, number of vertex attributes, */
15050   /*   no markers.                                                     */
15051   fprintf(outfile, "%ld  %d  %d  %d\n", m->triangles.items, 2, m->nextras, 0);
15052 #endif /* not TRILIBRARY */
15053 
15054   traversalinit(&m->triangles);
15055   triangleloop.tri = triangletraverse(m);
15056   triangleloop.orient = 0;
15057   vnodenumber = b->firstnumber;
15058   while (triangleloop.tri != (triangle *) NULL) {
15059     org(triangleloop, torg);
15060     dest(triangleloop, tdest);
15061     apex(triangleloop, tapex);
15062     findcircumcenter(m, b, torg, tdest, tapex, circumcenter, &xi, &eta, 0);
15063 #ifdef TRILIBRARY
15064     /* X and y coordinates. */
15065     plist[coordindex++] = circumcenter[0];
15066     plist[coordindex++] = circumcenter[1];
15067     for (i = 2; i < 2 + m->nextras; i++) {
15068       /* Interpolate the vertex attributes at the circumcenter. */
15069       palist[attribindex++] = torg[i] + xi * (tdest[i] - torg[i])
15070                                      + eta * (tapex[i] - torg[i]);
15071     }
15072 #else /* not TRILIBRARY */
15073     /* Voronoi vertex number, x and y coordinates. */
15074     fprintf(outfile, "%4ld    %.17g  %.17g", vnodenumber, circumcenter[0],
15075             circumcenter[1]);
15076     for (i = 2; i < 2 + m->nextras; i++) {
15077       /* Interpolate the vertex attributes at the circumcenter. */
15078       fprintf(outfile, "  %.17g", torg[i] + xi * (tdest[i] - torg[i])
15079                                          + eta * (tapex[i] - torg[i]));
15080     }
15081     fprintf(outfile, "\n");
15082 #endif /* not TRILIBRARY */
15083 
15084     * (int *) (triangleloop.tri + 6) = (int) vnodenumber;
15085     triangleloop.tri = triangletraverse(m);
15086     vnodenumber++;
15087   }
15088 
15089 #ifndef TRILIBRARY
15090   finishfile(outfile, argc, argv);
15091 #endif /* not TRILIBRARY */
15092 
15093 #ifdef TRILIBRARY
15094   if (!b->quiet) {
15095     printf("Writing Voronoi edges.\n");
15096   }
15097   /* Allocate memory for output Voronoi edges if necessary. */
15098   if (*vedgelist == (int *) NULL) {
15099     *vedgelist = (int *) trimalloc((int) (m->edges * 2 * sizeof(int)));
15100   }
15101   *vedgemarkerlist = (int *) NULL;
15102   /* Allocate memory for output Voronoi norms if necessary. */
15103   if (*vnormlist == (REAL *) NULL) {
15104     *vnormlist = (REAL *) trimalloc((int) (m->edges * 2 * sizeof(REAL)));
15105   }
15106   elist = *vedgelist;
15107   normlist = *vnormlist;
15108   coordindex = 0;
15109 #else /* not TRILIBRARY */
15110   if (!b->quiet) {
15111     printf("Writing %s.\n", vedgefilename);
15112   }
15113   outfile = fopen(vedgefilename, "w");
15114   if (outfile == (FILE *) NULL) {
15115     printf("  Error:  Cannot create file %s.\n", vedgefilename);
15116     triexit(1);
15117   }
15118   /* Number of edges, zero boundary markers. */
15119   fprintf(outfile, "%ld  %d\n", m->edges, 0);
15120 #endif /* not TRILIBRARY */
15121 
15122   traversalinit(&m->triangles);
15123   triangleloop.tri = triangletraverse(m);
15124   vedgenumber = b->firstnumber;
15125   /* To loop over the set of edges, loop over all triangles, and look at   */
15126   /*   the three edges of each triangle.  If there isn't another triangle  */
15127   /*   adjacent to the edge, operate on the edge.  If there is another     */
15128   /*   adjacent triangle, operate on the edge only if the current triangle */
15129   /*   has a smaller pointer than its neighbor.  This way, each edge is    */
15130   /*   considered only once.                                               */
15131   while (triangleloop.tri != (triangle *) NULL) {
15132     for (triangleloop.orient = 0; triangleloop.orient < 3;
15133          triangleloop.orient++) {
15134       sym(triangleloop, trisym);
15135       if ((triangleloop.tri < trisym.tri) || (trisym.tri == m->dummytri)) {
15136         /* Find the number of this triangle (and Voronoi vertex). */
15137         p1 = * (int *) (triangleloop.tri + 6);
15138         if (trisym.tri == m->dummytri) {
15139           org(triangleloop, torg);
15140           dest(triangleloop, tdest);
15141 #ifdef TRILIBRARY
15142           /* Copy an infinite ray.  Index of one endpoint, and -1. */
15143           elist[coordindex] = p1;
15144           normlist[coordindex++] = tdest[1] - torg[1];
15145           elist[coordindex] = -1;
15146           normlist[coordindex++] = torg[0] - tdest[0];
15147 #else /* not TRILIBRARY */
15148           /* Write an infinite ray.  Edge number, index of one endpoint, -1, */
15149           /*   and x and y coordinates of a vector representing the          */
15150           /*   direction of the ray.                                         */
15151           fprintf(outfile, "%4ld   %d  %d   %.17g  %.17g\n", vedgenumber,
15152                   p1, -1, tdest[1] - torg[1], torg[0] - tdest[0]);
15153 #endif /* not TRILIBRARY */
15154         } else {
15155           /* Find the number of the adjacent triangle (and Voronoi vertex). */
15156           p2 = * (int *) (trisym.tri + 6);
15157           /* Finite edge.  Write indices of two endpoints. */
15158 #ifdef TRILIBRARY
15159           elist[coordindex] = p1;
15160           normlist[coordindex++] = 0.0;
15161           elist[coordindex] = p2;
15162           normlist[coordindex++] = 0.0;
15163 #else /* not TRILIBRARY */
15164           fprintf(outfile, "%4ld   %d  %d\n", vedgenumber, p1, p2);
15165 #endif /* not TRILIBRARY */
15166         }
15167         vedgenumber++;
15168       }
15169     }
15170     triangleloop.tri = triangletraverse(m);
15171   }
15172 
15173 #ifndef TRILIBRARY
15174   finishfile(outfile, argc, argv);
15175 #endif /* not TRILIBRARY */
15176 }
15177 
15178 #ifdef TRILIBRARY
15179 
15180 #ifdef ANSI_DECLARATORS
15181 void writeneighbors(struct mesh *m, struct behavior *b, int **neighborlist)
15182 #else /* not ANSI_DECLARATORS */
15183 void writeneighbors(m, b, neighborlist)
15184 struct mesh *m;
15185 struct behavior *b;
15186 int **neighborlist;
15187 #endif /* not ANSI_DECLARATORS */
15188 
15189 #else /* not TRILIBRARY */
15190 
15191 #ifdef ANSI_DECLARATORS
15192 void writeneighbors(struct mesh *m, struct behavior *b, char *neighborfilename,
15193                     int argc, char **argv)
15194 #else /* not ANSI_DECLARATORS */
15195 void writeneighbors(m, b, neighborfilename, argc, argv)
15196 struct mesh *m;
15197 struct behavior *b;
15198 char *neighborfilename;
15199 int argc;
15200 char **argv;
15201 #endif /* not ANSI_DECLARATORS */
15202 
15203 #endif /* not TRILIBRARY */
15204 
15205 {
15206 #ifdef TRILIBRARY
15207   int *nlist;
15208   int index;
15209 #else /* not TRILIBRARY */
15210   FILE *outfile;
15211 #endif /* not TRILIBRARY */
15212   struct otri triangleloop, trisym;
15213   long elementnumber;
15214   int neighbor1, neighbor2, neighbor3;
15215   triangle ptr;                         /* Temporary variable used by sym(). */
15216 
15217 #ifdef TRILIBRARY
15218   if (!b->quiet) {
15219     printf("Writing neighbors.\n");
15220   }
15221   /* Allocate memory for neighbors if necessary. */
15222   if (*neighborlist == (int *) NULL) {
15223     *neighborlist = (int *) trimalloc((int) (m->triangles.items * 3 *
15224                                              sizeof(int)));
15225   }
15226   nlist = *neighborlist;
15227   index = 0;
15228 #else /* not TRILIBRARY */
15229   if (!b->quiet) {
15230     printf("Writing %s.\n", neighborfilename);
15231   }
15232   outfile = fopen(neighborfilename, "w");
15233   if (outfile == (FILE *) NULL) {
15234     printf("  Error:  Cannot create file %s.\n", neighborfilename);
15235     triexit(1);
15236   }
15237   /* Number of triangles, three neighbors per triangle. */
15238   fprintf(outfile, "%ld  %d\n", m->triangles.items, 3);
15239 #endif /* not TRILIBRARY */
15240 
15241   traversalinit(&m->triangles);
15242   triangleloop.tri = triangletraverse(m);
15243   triangleloop.orient = 0;
15244   elementnumber = b->firstnumber;
15245   while (triangleloop.tri != (triangle *) NULL) {
15246     * (int *) (triangleloop.tri + 6) = (int) elementnumber;
15247     triangleloop.tri = triangletraverse(m);
15248     elementnumber++;
15249   }
15250   * (int *) (m->dummytri + 6) = -1;
15251 
15252   traversalinit(&m->triangles);
15253   triangleloop.tri = triangletraverse(m);
15254   elementnumber = b->firstnumber;
15255   while (triangleloop.tri != (triangle *) NULL) {
15256     triangleloop.orient = 1;
15257     sym(triangleloop, trisym);
15258     neighbor1 = * (int *) (trisym.tri + 6);
15259     triangleloop.orient = 2;
15260     sym(triangleloop, trisym);
15261     neighbor2 = * (int *) (trisym.tri + 6);
15262     triangleloop.orient = 0;
15263     sym(triangleloop, trisym);
15264     neighbor3 = * (int *) (trisym.tri + 6);
15265 #ifdef TRILIBRARY
15266     nlist[index++] = neighbor1;
15267     nlist[index++] = neighbor2;
15268     nlist[index++] = neighbor3;
15269 #else /* not TRILIBRARY */
15270     /* Triangle number, neighboring triangle numbers. */
15271     fprintf(outfile, "%4ld    %d  %d  %d\n", elementnumber,
15272             neighbor1, neighbor2, neighbor3);
15273 #endif /* not TRILIBRARY */
15274 
15275     triangleloop.tri = triangletraverse(m);
15276     elementnumber++;
15277   }
15278 
15279 #ifndef TRILIBRARY
15280   finishfile(outfile, argc, argv);
15281 #endif /* not TRILIBRARY */
15282 }
15283 
15284 /*****************************************************************************/
15285 /*                                                                           */
15286 /*  writeoff()   Write the triangulation to an .off file.                    */
15287 /*                                                                           */
15288 /*  OFF stands for the Object File Format, a format used by the Geometry     */
15289 /*  Center's Geomview package.                                               */
15290 /*                                                                           */
15291 /*****************************************************************************/
15292 
15293 #ifndef TRILIBRARY
15294 
15295 #ifdef ANSI_DECLARATORS
15296 void writeoff(struct mesh *m, struct behavior *b, char *offfilename,
15297               int argc, char **argv)
15298 #else /* not ANSI_DECLARATORS */
15299 void writeoff(m, b, offfilename, argc, argv)
15300 struct mesh *m;
15301 struct behavior *b;
15302 char *offfilename;
15303 int argc;
15304 char **argv;
15305 #endif /* not ANSI_DECLARATORS */
15306 
15307 {
15308   FILE *outfile;
15309   struct otri triangleloop;
15310   vertex vertexloop;
15311   vertex p1, p2, p3;
15312   long outvertices;
15313 
15314   if (!b->quiet) {
15315     printf("Writing %s.\n", offfilename);
15316   }
15317 
15318   if (b->jettison) {
15319     outvertices = m->vertices.items - m->undeads;
15320   } else {
15321     outvertices = m->vertices.items;
15322   }
15323 
15324   outfile = fopen(offfilename, "w");
15325   if (outfile == (FILE *) NULL) {
15326     printf("  Error:  Cannot create file %s.\n", offfilename);
15327     triexit(1);
15328   }
15329   /* Number of vertices, triangles, and edges. */
15330   fprintf(outfile, "OFF\n%ld  %ld  %ld\n", outvertices, m->triangles.items,
15331           m->edges);
15332 
15333   /* Write the vertices. */
15334   traversalinit(&m->vertices);
15335   vertexloop = vertextraverse(m);
15336   while (vertexloop != (vertex) NULL) {
15337     if (!b->jettison || (vertextype(vertexloop) != UNDEADVERTEX)) {
15338       /* The "0.0" is here because the OFF format uses 3D coordinates. */
15339       fprintf(outfile, " %.17g  %.17g  %.17g\n", vertexloop[0], vertexloop[1],
15340               0.0);
15341     }
15342     vertexloop = vertextraverse(m);
15343   }
15344 
15345   /* Write the triangles. */
15346   traversalinit(&m->triangles);
15347   triangleloop.tri = triangletraverse(m);
15348   triangleloop.orient = 0;
15349   while (triangleloop.tri != (triangle *) NULL) {
15350     org(triangleloop, p1);
15351     dest(triangleloop, p2);
15352     apex(triangleloop, p3);
15353     /* The "3" means a three-vertex polygon. */
15354     fprintf(outfile, " 3   %4d  %4d  %4d\n", vertexmark(p1) - b->firstnumber,
15355             vertexmark(p2) - b->firstnumber, vertexmark(p3) - b->firstnumber);
15356     triangleloop.tri = triangletraverse(m);
15357   }
15358   finishfile(outfile, argc, argv);
15359 }
15360 
15361 #endif /* not TRILIBRARY */
15362 
15363 /**                                                                         **/
15364 /**                                                                         **/
15365 /********* File I/O routines end here                                *********/
15366 
15367 /*****************************************************************************/
15368 /*                                                                           */
15369 /*  quality_statistics()   Print statistics about the quality of the mesh.   */
15370 /*                                                                           */
15371 /*****************************************************************************/
15372 
15373 #ifdef ANSI_DECLARATORS
15374 void quality_statistics(struct mesh *m, struct behavior *b)
15375 #else /* not ANSI_DECLARATORS */
15376 void quality_statistics(m, b)
15377 struct mesh *m;
15378 struct behavior *b;
15379 #endif /* not ANSI_DECLARATORS */
15380 
15381 {
15382   struct otri triangleloop;
15383   vertex p[3];
15384   REAL cossquaretable[8];
15385   REAL ratiotable[16];
15386   REAL dx[3], dy[3];
15387   REAL edgelength[3];
15388   REAL dotproduct;
15389   REAL cossquare;
15390   REAL triarea;
15391   REAL shortest, longest;
15392   REAL trilongest2;
15393   REAL smallestarea, biggestarea;
15394   REAL triminaltitude2;
15395   REAL minaltitude;
15396   REAL triaspect2;
15397   REAL worstaspect;
15398   REAL smallestangle, biggestangle;
15399   REAL radconst, degconst;
15400   int angletable[18];
15401   int aspecttable[16];
15402   int aspectindex;
15403   int tendegree;
15404   int acutebiggest;
15405   int i, ii, j, k;
15406 
15407   printf("Mesh quality statistics:\n\n");
15408   radconst = PI / 18.0;
15409   degconst = 180.0 / PI;
15410   for (i = 0; i < 8; i++) {
15411     cossquaretable[i] = cos(radconst * (REAL) (i + 1));
15412     cossquaretable[i] = cossquaretable[i] * cossquaretable[i];
15413   }
15414   for (i = 0; i < 18; i++) {
15415     angletable[i] = 0;
15416   }
15417 
15418   ratiotable[0]  =      1.5;      ratiotable[1]  =     2.0;
15419   ratiotable[2]  =      2.5;      ratiotable[3]  =     3.0;
15420   ratiotable[4]  =      4.0;      ratiotable[5]  =     6.0;
15421   ratiotable[6]  =     10.0;      ratiotable[7]  =    15.0;
15422   ratiotable[8]  =     25.0;      ratiotable[9]  =    50.0;
15423   ratiotable[10] =    100.0;      ratiotable[11] =   300.0;
15424   ratiotable[12] =   1000.0;      ratiotable[13] = 10000.0;
15425   ratiotable[14] = 100000.0;      ratiotable[15] =     0.0;
15426   for (i = 0; i < 16; i++) {
15427     aspecttable[i] = 0;
15428   }
15429 
15430   worstaspect = 0.0;
15431   minaltitude = m->xmax - m->xmin + m->ymax - m->ymin;
15432   minaltitude = minaltitude * minaltitude;
15433   shortest = minaltitude;
15434   longest = 0.0;
15435   smallestarea = minaltitude;
15436   biggestarea = 0.0;
15437   worstaspect = 0.0;
15438   smallestangle = 0.0;
15439   biggestangle = 2.0;
15440   acutebiggest = 1;
15441 
15442   traversalinit(&m->triangles);
15443   triangleloop.tri = triangletraverse(m);
15444   triangleloop.orient = 0;
15445   while (triangleloop.tri != (triangle *) NULL) {
15446     org(triangleloop, p[0]);
15447     dest(triangleloop, p[1]);
15448     apex(triangleloop, p[2]);
15449     trilongest2 = 0.0;
15450 
15451     for (i = 0; i < 3; i++) {
15452       j = plus1mod3[i];
15453       k = minus1mod3[i];
15454       dx[i] = p[j][0] - p[k][0];
15455       dy[i] = p[j][1] - p[k][1];
15456       edgelength[i] = dx[i] * dx[i] + dy[i] * dy[i];
15457       if (edgelength[i] > trilongest2) {
15458         trilongest2 = edgelength[i];
15459       }
15460       if (edgelength[i] > longest) {
15461         longest = edgelength[i];
15462       }
15463       if (edgelength[i] < shortest) {
15464         shortest = edgelength[i];
15465       }
15466     }
15467 
15468     triarea = counterclockwise(m, b, p[0], p[1], p[2]);
15469     if (triarea < smallestarea) {
15470       smallestarea = triarea;
15471     }
15472     if (triarea > biggestarea) {
15473       biggestarea = triarea;
15474     }
15475     triminaltitude2 = triarea * triarea / trilongest2;
15476     if (triminaltitude2 < minaltitude) {
15477       minaltitude = triminaltitude2;
15478     }
15479     triaspect2 = trilongest2 / triminaltitude2;
15480     if (triaspect2 > worstaspect) {
15481       worstaspect = triaspect2;
15482     }
15483     aspectindex = 0;
15484     while ((triaspect2 > ratiotable[aspectindex] * ratiotable[aspectindex])
15485            && (aspectindex < 15)) {
15486       aspectindex++;
15487     }
15488     aspecttable[aspectindex]++;
15489 
15490     for (i = 0; i < 3; i++) {
15491       j = plus1mod3[i];
15492       k = minus1mod3[i];
15493       dotproduct = dx[j] * dx[k] + dy[j] * dy[k];
15494       cossquare = dotproduct * dotproduct / (edgelength[j] * edgelength[k]);
15495       tendegree = 8;
15496       for (ii = 7; ii >= 0; ii--) {
15497         if (cossquare > cossquaretable[ii]) {
15498           tendegree = ii;
15499         }
15500       }
15501       if (dotproduct <= 0.0) {
15502         angletable[tendegree]++;
15503         if (cossquare > smallestangle) {
15504           smallestangle = cossquare;
15505         }
15506         if (acutebiggest && (cossquare < biggestangle)) {
15507           biggestangle = cossquare;
15508         }
15509       } else {
15510         angletable[17 - tendegree]++;
15511         if (acutebiggest || (cossquare > biggestangle)) {
15512           biggestangle = cossquare;
15513           acutebiggest = 0;
15514         }
15515       }
15516     }
15517     triangleloop.tri = triangletraverse(m);
15518   }
15519 
15520   shortest = sqrt(shortest);
15521   longest = sqrt(longest);
15522   minaltitude = sqrt(minaltitude);
15523   worstaspect = sqrt(worstaspect);
15524   smallestarea *= 0.5;
15525   biggestarea *= 0.5;
15526   if (smallestangle >= 1.0) {
15527     smallestangle = 0.0;
15528   } else {
15529     smallestangle = degconst * acos(sqrt(smallestangle));
15530   }
15531   if (biggestangle >= 1.0) {
15532     biggestangle = 180.0;
15533   } else {
15534     if (acutebiggest) {
15535       biggestangle = degconst * acos(sqrt(biggestangle));
15536     } else {
15537       biggestangle = 180.0 - degconst * acos(sqrt(biggestangle));
15538     }
15539   }
15540 
15541   printf("  Smallest area: %16.5g   |  Largest area: %16.5g\n",
15542          smallestarea, biggestarea);
15543   printf("  Shortest edge: %16.5g   |  Longest edge: %16.5g\n",
15544          shortest, longest);
15545   printf("  Shortest altitude: %12.5g   |  Largest aspect ratio: %8.5g\n\n",
15546          minaltitude, worstaspect);
15547 
15548   printf("  Triangle aspect ratio histogram:\n");
15549   printf("  1.1547 - %-6.6g    :  %8d    | %6.6g - %-6.6g     :  %8d\n",
15550          ratiotable[0], aspecttable[0], ratiotable[7], ratiotable[8],
15551          aspecttable[8]);
15552   for (i = 1; i < 7; i++) {
15553     printf("  %6.6g - %-6.6g    :  %8d    | %6.6g - %-6.6g     :  %8d\n",
15554            ratiotable[i - 1], ratiotable[i], aspecttable[i],
15555            ratiotable[i + 7], ratiotable[i + 8], aspecttable[i + 8]);
15556   }
15557   printf("  %6.6g - %-6.6g    :  %8d    | %6.6g -            :  %8d\n",
15558          ratiotable[6], ratiotable[7], aspecttable[7], ratiotable[14],
15559          aspecttable[15]);
15560   printf("  (Aspect ratio is longest edge divided by shortest altitude)\n\n");
15561 
15562   printf("  Smallest angle: %15.5g   |  Largest angle: %15.5g\n\n",
15563          smallestangle, biggestangle);
15564 
15565   printf("  Angle histogram:\n");
15566   for (i = 0; i < 9; i++) {
15567     printf("    %3d - %3d degrees:  %8d    |    %3d - %3d degrees:  %8d\n",
15568            i * 10, i * 10 + 10, angletable[i],
15569            i * 10 + 90, i * 10 + 100, angletable[i + 9]);
15570   }
15571   printf("\n");
15572 }
15573 
15574 /*****************************************************************************/
15575 /*                                                                           */
15576 /*  statistics()   Print all sorts of cool facts.                            */
15577 /*                                                                           */
15578 /*****************************************************************************/
15579 
15580 #ifdef ANSI_DECLARATORS
15581 void statistics(struct mesh *m, struct behavior *b)
15582 #else /* not ANSI_DECLARATORS */
15583 void statistics(m, b)
15584 struct mesh *m;
15585 struct behavior *b;
15586 #endif /* not ANSI_DECLARATORS */
15587 
15588 {
15589   printf("\nStatistics:\n\n");
15590   printf("  Input vertices: %d\n", m->invertices);
15591   if (b->refine) {
15592     printf("  Input triangles: %d\n", m->inelements);
15593   }
15594   if (b->poly) {
15595     printf("  Input segments: %d\n", m->insegments);
15596     if (!b->refine) {
15597       printf("  Input holes: %d\n", m->holes);
15598     }
15599   }
15600 
15601   printf("\n  Mesh vertices: %ld\n", m->vertices.items - m->undeads);
15602   printf("  Mesh triangles: %ld\n", m->triangles.items);
15603   printf("  Mesh edges: %ld\n", m->edges);
15604   printf("  Mesh exterior boundary edges: %ld\n", m->hullsize);
15605   if (b->poly || b->refine) {
15606     printf("  Mesh interior boundary edges: %ld\n",
15607            m->subsegs.items - m->hullsize);
15608     printf("  Mesh subsegments (constrained edges): %ld\n",
15609            m->subsegs.items);
15610   }
15611   printf("\n");
15612 
15613   if (b->verbose) {
15614     quality_statistics(m, b);
15615     printf("Memory allocation statistics:\n\n");
15616     printf("  Maximum number of vertices: %ld\n", m->vertices.maxitems);
15617     printf("  Maximum number of triangles: %ld\n", m->triangles.maxitems);
15618     if (m->subsegs.maxitems > 0) {
15619       printf("  Maximum number of subsegments: %ld\n", m->subsegs.maxitems);
15620     }
15621     if (m->viri.maxitems > 0) {
15622       printf("  Maximum number of viri: %ld\n", m->viri.maxitems);
15623     }
15624     if (m->badsubsegs.maxitems > 0) {
15625       printf("  Maximum number of encroached subsegments: %ld\n",
15626              m->badsubsegs.maxitems);
15627     }
15628     if (m->badtriangles.maxitems > 0) {
15629       printf("  Maximum number of bad triangles: %ld\n",
15630              m->badtriangles.maxitems);
15631     }
15632     if (m->flipstackers.maxitems > 0) {
15633       printf("  Maximum number of stacked triangle flips: %ld\n",
15634              m->flipstackers.maxitems);
15635     }
15636     if (m->splaynodes.maxitems > 0) {
15637       printf("  Maximum number of splay tree nodes: %ld\n",
15638              m->splaynodes.maxitems);
15639     }
15640     printf("  Approximate heap memory use (bytes): %ld\n\n",
15641            m->vertices.maxitems * m->vertices.itembytes +
15642            m->triangles.maxitems * m->triangles.itembytes +
15643            m->subsegs.maxitems * m->subsegs.itembytes +
15644            m->viri.maxitems * m->viri.itembytes +
15645            m->badsubsegs.maxitems * m->badsubsegs.itembytes +
15646            m->badtriangles.maxitems * m->badtriangles.itembytes +
15647            m->flipstackers.maxitems * m->flipstackers.itembytes +
15648            m->splaynodes.maxitems * m->splaynodes.itembytes);
15649 
15650     printf("Algorithmic statistics:\n\n");
15651     if (!b->weighted) {
15652       printf("  Number of incircle tests: %ld\n", m->incirclecount);
15653     } else {
15654       printf("  Number of 3D orientation tests: %ld\n", m->orient3dcount);
15655     }
15656     printf("  Number of 2D orientation tests: %ld\n", m->counterclockcount);
15657     if (m->hyperbolacount > 0) {
15658       printf("  Number of right-of-hyperbola tests: %ld\n",
15659              m->hyperbolacount);
15660     }
15661     if (m->circletopcount > 0) {
15662       printf("  Number of circle top computations: %ld\n",
15663              m->circletopcount);
15664     }
15665     if (m->circumcentercount > 0) {
15666       printf("  Number of triangle circumcenter computations: %ld\n",
15667              m->circumcentercount);
15668     }
15669     printf("\n");
15670   }
15671 }
15672 
15673 /*****************************************************************************/
15674 /*                                                                           */
15675 /*  main() or triangulate()   Gosh, do everything.                           */
15676 /*                                                                           */
15677 /*  The sequence is roughly as follows.  Many of these steps can be skipped, */
15678 /*  depending on the command line switches.                                  */
15679 /*                                                                           */
15680 /*  - Initialize constants and parse the command line.                       */
15681 /*  - Read the vertices from a file and either                               */
15682 /*    - triangulate them (no -r), or                                         */
15683 /*    - read an old mesh from files and reconstruct it (-r).                 */
15684 /*  - Insert the PSLG segments (-p), and possibly segments on the convex     */
15685 /*      hull (-c).                                                           */
15686 /*  - Read the holes (-p), regional attributes (-pA), and regional area      */
15687 /*      constraints (-pa).  Carve the holes and concavities, and spread the  */
15688 /*      regional attributes and area constraints.                            */
15689 /*  - Enforce the constraints on minimum angle (-q) and maximum area (-a).   */
15690 /*      Also enforce the conforming Delaunay property (-q and -a).           */
15691 /*  - Compute the number of edges in the resulting mesh.                     */
15692 /*  - Promote the mesh's linear triangles to higher order elements (-o).     */
15693 /*  - Write the output files and print the statistics.                       */
15694 /*  - Check the consistency and Delaunay property of the mesh (-C).          */
15695 /*                                                                           */
15696 /*****************************************************************************/
15697 
15698 #ifdef TRILIBRARY
15699 
15700 #ifdef ANSI_DECLARATORS
15701 void triangulate(char *triswitches, struct triangulateio *in,
15702                  struct triangulateio *out, struct triangulateio *vorout)
15703 #else /* not ANSI_DECLARATORS */
15704 void triangulate(triswitches, in, out, vorout)
15705 char *triswitches;
15706 struct triangulateio *in;
15707 struct triangulateio *out;
15708 struct triangulateio *vorout;
15709 #endif /* not ANSI_DECLARATORS */
15710 
15711 #else /* not TRILIBRARY */
15712 
15713 #ifdef ANSI_DECLARATORS
15714 int main(int argc, char **argv)
15715 #else /* not ANSI_DECLARATORS */
15716 int main(argc, argv)
15717 int argc;
15718 char **argv;
15719 #endif /* not ANSI_DECLARATORS */
15720 
15721 #endif /* not TRILIBRARY */
15722 
15723 {
15724   struct mesh m;
15725   struct behavior b;
15726   REAL *holearray;                                        /* Array of holes. */
15727   REAL *regionarray;   /* Array of regional attributes and area constraints. */
15728 #ifndef TRILIBRARY
15729   FILE *polyfile;
15730 #endif /* not TRILIBRARY */
15731 #ifndef NO_TIMER
15732   /* Variables for timing the performance of Triangle.  The types are */
15733   /*   defined in sys/time.h.                                         */
15734   struct timeval tv0, tv1, tv2, tv3, tv4, tv5, tv6;
15735   struct timezone tz;
15736 #endif /* not NO_TIMER */
15737 
15738 #ifndef NO_TIMER
15739   gettimeofday(&tv0, &tz);
15740 #endif /* not NO_TIMER */
15741 
15742   triangleinit(&m);
15743 #ifdef TRILIBRARY
15744   parsecommandline(1, &triswitches, &b);
15745 #else /* not TRILIBRARY */
15746   parsecommandline(argc, argv, &b);
15747 #endif /* not TRILIBRARY */
15748   m.steinerleft = b.steiner;
15749 
15750 #ifdef TRILIBRARY
15751   transfernodes(&m, &b, in->pointlist, in->pointattributelist,
15752                 in->pointmarkerlist, in->numberofpoints,
15753                 in->numberofpointattributes);
15754 #else /* not TRILIBRARY */
15755   readnodes(&m, &b, b.innodefilename, b.inpolyfilename, &polyfile);
15756 #endif /* not TRILIBRARY */
15757 
15758 #ifndef NO_TIMER
15759   if (!b.quiet) {
15760     gettimeofday(&tv1, &tz);
15761   }
15762 #endif /* not NO_TIMER */
15763 
15764 #ifdef CDT_ONLY
15765   m.hullsize = delaunay(&m, &b);                /* Triangulate the vertices. */
15766 #else /* not CDT_ONLY */
15767   if (b.refine) {
15768     /* Read and reconstruct a mesh. */
15769 #ifdef TRILIBRARY
15770     m.hullsize = reconstruct(&m, &b, in->trianglelist,
15771                              in->triangleattributelist, in->trianglearealist,
15772                              in->numberoftriangles, in->numberofcorners,
15773                              in->numberoftriangleattributes,
15774                              in->segmentlist, in->segmentmarkerlist,
15775                              in->numberofsegments);
15776 #else /* not TRILIBRARY */
15777     m.hullsize = reconstruct(&m, &b, b.inelefilename, b.areafilename,
15778                              b.inpolyfilename, polyfile);
15779 #endif /* not TRILIBRARY */
15780   } else {
15781     m.hullsize = delaunay(&m, &b);              /* Triangulate the vertices. */
15782   }
15783 #endif /* not CDT_ONLY */
15784 
15785 #ifndef NO_TIMER
15786   if (!b.quiet) {
15787     gettimeofday(&tv2, &tz);
15788     if (b.refine) {
15789       printf("Mesh reconstruction");
15790     } else {
15791       printf("Delaunay");
15792     }
15793     printf(" milliseconds:  %ld\n", 1000l * (tv2.tv_sec - tv1.tv_sec) +
15794            (tv2.tv_usec - tv1.tv_usec) / 1000l);
15795   }
15796 #endif /* not NO_TIMER */
15797 
15798   /* Ensure that no vertex can be mistaken for a triangular bounding */
15799   /*   box vertex in insertvertex().                                 */
15800   m.infvertex1 = (vertex) NULL;
15801   m.infvertex2 = (vertex) NULL;
15802   m.infvertex3 = (vertex) NULL;
15803 
15804   if (b.usesegments) {
15805     m.checksegments = 1;                /* Segments will be introduced next. */
15806     if (!b.refine) {
15807       /* Insert PSLG segments and/or convex hull segments. */
15808 #ifdef TRILIBRARY
15809       formskeleton(&m, &b, in->segmentlist,
15810                    in->segmentmarkerlist, in->numberofsegments);
15811 #else /* not TRILIBRARY */
15812       formskeleton(&m, &b, polyfile, b.inpolyfilename);
15813 #endif /* not TRILIBRARY */
15814     }
15815   }
15816 
15817 #ifndef NO_TIMER
15818   if (!b.quiet) {
15819     gettimeofday(&tv3, &tz);
15820     if (b.usesegments && !b.refine) {
15821       printf("Segment milliseconds:  %ld\n",
15822              1000l * (tv3.tv_sec - tv2.tv_sec) +
15823              (tv3.tv_usec - tv2.tv_usec) / 1000l);
15824     }
15825   }
15826 #endif /* not NO_TIMER */
15827 
15828   if (b.poly && (m.triangles.items > 0)) {
15829 #ifdef TRILIBRARY
15830     holearray = in->holelist;
15831     m.holes = in->numberofholes;
15832     regionarray = in->regionlist;
15833     m.regions = in->numberofregions;
15834 #else /* not TRILIBRARY */
15835     readholes(&m, &b, polyfile, b.inpolyfilename, &holearray, &m.holes,
15836               &regionarray, &m.regions);
15837 #endif /* not TRILIBRARY */
15838     if (!b.refine) {
15839       /* Carve out holes and concavities. */
15840       carveholes(&m, &b, holearray, m.holes, regionarray, m.regions);
15841     }
15842   } else {
15843     /* Without a PSLG, there can be no holes or regional attributes   */
15844     /*   or area constraints.  The following are set to zero to avoid */
15845     /*   an accidental free() later.                                  */
15846     m.holes = 0;
15847     m.regions = 0;
15848   }
15849 
15850 #ifndef NO_TIMER
15851   if (!b.quiet) {
15852     gettimeofday(&tv4, &tz);
15853     if (b.poly && !b.refine) {
15854       printf("Hole milliseconds:  %ld\n", 1000l * (tv4.tv_sec - tv3.tv_sec) +
15855              (tv4.tv_usec - tv3.tv_usec) / 1000l);
15856     }
15857   }
15858 #endif /* not NO_TIMER */
15859 
15860 #ifndef CDT_ONLY
15861   if (b.quality && (m.triangles.items > 0)) {
15862     enforcequality(&m, &b);           /* Enforce angle and area constraints. */
15863   }
15864 #endif /* not CDT_ONLY */
15865 
15866 #ifndef NO_TIMER
15867   if (!b.quiet) {
15868     gettimeofday(&tv5, &tz);
15869 #ifndef CDT_ONLY
15870     if (b.quality) {
15871       printf("Quality milliseconds:  %ld\n",
15872              1000l * (tv5.tv_sec - tv4.tv_sec) +
15873              (tv5.tv_usec - tv4.tv_usec) / 1000l);
15874     }
15875 #endif /* not CDT_ONLY */
15876   }
15877 #endif /* not NO_TIMER */
15878 
15879   /* Calculate the number of edges. */
15880   m.edges = (3l * m.triangles.items + m.hullsize) / 2l;
15881 
15882   if (b.order > 1) {
15883     highorder(&m, &b);       /* Promote elements to higher polynomial order. */
15884   }
15885   if (!b.quiet) {
15886     printf("\n");
15887   }
15888 
15889 #ifdef TRILIBRARY
15890   if (b.jettison) {
15891     out->numberofpoints = m.vertices.items - m.undeads;
15892   } else {
15893     out->numberofpoints = m.vertices.items;
15894   }
15895   out->numberofpointattributes = m.nextras;
15896   out->numberoftriangles = m.triangles.items;
15897   out->numberofcorners = (b.order + 1) * (b.order + 2) / 2;
15898   out->numberoftriangleattributes = m.eextras;
15899   out->numberofedges = m.edges;
15900   if (b.usesegments) {
15901     out->numberofsegments = m.subsegs.items;
15902   } else {
15903     out->numberofsegments = m.hullsize;
15904   }
15905   if (vorout != (struct triangulateio *) NULL) {
15906     vorout->numberofpoints = m.triangles.items;
15907     vorout->numberofpointattributes = m.nextras;
15908     vorout->numberofedges = m.edges;
15909   }
15910 #endif /* TRILIBRARY */
15911   /* If not using iteration numbers, don't write a .node file if one was */
15912   /*   read, because the original one would be overwritten!              */
15913   if (b.nonodewritten || (b.noiterationnum && m.readnodefile)) {
15914     if (!b.quiet) {
15915 #ifdef TRILIBRARY
15916       printf("NOT writing vertices.\n");
15917 #else /* not TRILIBRARY */
15918       printf("NOT writing a .node file.\n");
15919 #endif /* not TRILIBRARY */
15920     }
15921     numbernodes(&m, &b);         /* We must remember to number the vertices. */
15922   } else {
15923     /* writenodes() numbers the vertices too. */
15924 #ifdef TRILIBRARY
15925     writenodes(&m, &b, &out->pointlist, &out->pointattributelist,
15926                &out->pointmarkerlist);
15927 #else /* not TRILIBRARY */
15928     writenodes(&m, &b, b.outnodefilename, argc, argv);
15929 #endif /* TRILIBRARY */
15930   }
15931   if (b.noelewritten) {
15932     if (!b.quiet) {
15933 #ifdef TRILIBRARY
15934       printf("NOT writing triangles.\n");
15935 #else /* not TRILIBRARY */
15936       printf("NOT writing an .ele file.\n");
15937 #endif /* not TRILIBRARY */
15938     }
15939   } else {
15940 #ifdef TRILIBRARY
15941     writeelements(&m, &b, &out->trianglelist, &out->triangleattributelist);
15942 #else /* not TRILIBRARY */
15943     writeelements(&m, &b, b.outelefilename, argc, argv);
15944 #endif /* not TRILIBRARY */
15945   }
15946   /* The -c switch (convex switch) causes a PSLG to be written */
15947   /*   even if none was read.                                  */
15948   if (b.poly || b.convex) {
15949     /* If not using iteration numbers, don't overwrite the .poly file. */
15950     if (b.nopolywritten || b.noiterationnum) {
15951       if (!b.quiet) {
15952 #ifdef TRILIBRARY
15953         printf("NOT writing segments.\n");
15954 #else /* not TRILIBRARY */
15955         printf("NOT writing a .poly file.\n");
15956 #endif /* not TRILIBRARY */
15957       }
15958     } else {
15959 #ifdef TRILIBRARY
15960       writepoly(&m, &b, &out->segmentlist, &out->segmentmarkerlist);
15961       out->numberofholes = m.holes;
15962       out->numberofregions = m.regions;
15963       if (b.poly) {
15964         out->holelist = in->holelist;
15965         out->regionlist = in->regionlist;
15966       } else {
15967         out->holelist = (REAL *) NULL;
15968         out->regionlist = (REAL *) NULL;
15969       }
15970 #else /* not TRILIBRARY */
15971       writepoly(&m, &b, b.outpolyfilename, holearray, m.holes, regionarray,
15972                 m.regions, argc, argv);
15973 #endif /* not TRILIBRARY */
15974     }
15975   }
15976 #ifndef TRILIBRARY
15977 #ifndef CDT_ONLY
15978   if (m.regions > 0) {
15979     trifree((VOID *) regionarray);
15980   }
15981 #endif /* not CDT_ONLY */
15982   if (m.holes > 0) {
15983     trifree((VOID *) holearray);
15984   }
15985   if (b.geomview) {
15986     writeoff(&m, &b, b.offfilename, argc, argv);
15987   }
15988 #endif /* not TRILIBRARY */
15989   if (b.edgesout) {
15990 #ifdef TRILIBRARY
15991     writeedges(&m, &b, &out->edgelist, &out->edgemarkerlist);
15992 #else /* not TRILIBRARY */
15993     writeedges(&m, &b, b.edgefilename, argc, argv);
15994 #endif /* not TRILIBRARY */
15995   }
15996   if (b.voronoi) {
15997 #ifdef TRILIBRARY
15998     writevoronoi(&m, &b, &vorout->pointlist, &vorout->pointattributelist,
15999                  &vorout->pointmarkerlist, &vorout->edgelist,
16000                  &vorout->edgemarkerlist, &vorout->normlist);
16001 #else /* not TRILIBRARY */
16002     writevoronoi(&m, &b, b.vnodefilename, b.vedgefilename, argc, argv);
16003 #endif /* not TRILIBRARY */
16004   }
16005   if (b.neighbors) {
16006 #ifdef TRILIBRARY
16007     writeneighbors(&m, &b, &out->neighborlist);
16008 #else /* not TRILIBRARY */
16009     writeneighbors(&m, &b, b.neighborfilename, argc, argv);
16010 #endif /* not TRILIBRARY */
16011   }
16012 
16013   if (!b.quiet) {
16014 #ifndef NO_TIMER
16015     gettimeofday(&tv6, &tz);
16016     printf("\nOutput milliseconds:  %ld\n",
16017            1000l * (tv6.tv_sec - tv5.tv_sec) +
16018            (tv6.tv_usec - tv5.tv_usec) / 1000l);
16019     printf("Total running milliseconds:  %ld\n",
16020            1000l * (tv6.tv_sec - tv0.tv_sec) +
16021            (tv6.tv_usec - tv0.tv_usec) / 1000l);
16022 #endif /* not NO_TIMER */
16023 
16024     statistics(&m, &b);
16025   }
16026 
16027 #ifndef REDUCED
16028   if (b.docheck) {
16029     checkmesh(&m, &b);
16030     checkdelaunay(&m, &b);
16031   }
16032 #endif /* not REDUCED */
16033 
16034   triangledeinit(&m, &b);
16035 #ifndef TRILIBRARY
16036   return 0;
16037 #endif /* not TRILIBRARY */
16038 }
16039