1 /*
2  * Modifed Triangle - this version has been altered for compatibility
3  * with libMesh non-double precision options.
4  */
5 
6 
7 /*****************************************************************************/
8 /*                                                                           */
9 /*      888888888        ,o,                          / 888                  */
10 /*         888    88o88o  "    o8888o  88o8888o o88888o 888  o88888o         */
11 /*         888    888    888       88b 888  888 888 888 888 d888  88b        */
12 /*         888    888    888  o88^o888 888  888 "88888" 888 8888oo888        */
13 /*         888    888    888 C888  888 888  888  /      888 q888             */
14 /*         888    888    888  "88o^888 888  888 Cb      888  "88oooo"        */
15 /*                                              "8oo8D                       */
16 /*                                                                           */
17 /*  A Two-Dimensional Quality Mesh Generator and Delaunay Triangulator.      */
18 /*  (triangle.c)                                                             */
19 /*                                                                           */
20 /*  Version 1.6                                                              */
21 /*  July 28, 2005                                                            */
22 /*                                                                           */
23 /*  Copyright 1993, 1995, 1997, 1998, 2002, 2005                             */
24 /*  Jonathan Richard Shewchuk                                                */
25 /*  2360 Woolsey #H                                                          */
26 /*  Berkeley, California  94705-1927                                         */
27 /*  jrs@cs.berkeley.edu                                                      */
28 /*                                                                           */
29 /*  This program may be freely redistributed under the condition that the    */
30 /*    copyright notices (including this entire header and the copyright      */
31 /*    notice printed when the `-h' switch is selected) are not removed, and  */
32 /*    no compensation is received.  Private, research, and institutional     */
33 /*    use is free.  You may distribute modified versions of this code UNDER  */
34 /*    THE CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE TO IT IN THE   */
35 /*    SAME FILE REMAIN UNDER COPYRIGHT OF THE ORIGINAL AUTHOR, BOTH SOURCE   */
36 /*    AND OBJECT CODE ARE MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR    */
37 /*    NOTICE IS GIVEN OF THE MODIFICATIONS.  Distribution of this code as    */
38 /*    part of a commercial system is permissible ONLY BY DIRECT ARRANGEMENT  */
39 /*    WITH THE AUTHOR.  (If you are not directly supplying this code to a    */
40 /*    customer, and you are instead telling them how they can obtain it for  */
41 /*    free, then you are not required to make any arrangement with me.)      */
42 /*                                                                           */
43 /*  Hypertext instructions for Triangle are available on the Web at          */
44 /*                                                                           */
45 /*      http://www.cs.cmu.edu/~quake/triangle.html                           */
46 /*                                                                           */
47 /*  Disclaimer:  Neither I nor Carnegie Mellon warrant this code in any way  */
48 /*    whatsoever.  This code is provided "as-is".  Use at your own risk.     */
49 /*                                                                           */
50 /*  Some of the references listed below are marked with an asterisk.  [*]    */
51 /*    These references are available for downloading from the Web page       */
52 /*                                                                           */
53 /*      http://www.cs.cmu.edu/~quake/triangle.research.html                  */
54 /*                                                                           */
55 /*  Three papers discussing aspects of Triangle are available.  A short      */
56 /*    overview appears in "Triangle:  Engineering a 2D Quality Mesh          */
57 /*    Generator and Delaunay Triangulator," in Applied Computational         */
58 /*    Geometry:  Towards Geometric Engineering, Ming C. Lin and Dinesh       */
59 /*    Manocha, editors, Lecture Notes in Computer Science volume 1148,       */
60 /*    pages 203-222, Springer-Verlag, Berlin, May 1996 (from the First ACM   */
61 /*    Workshop on Applied Computational Geometry).  [*]                      */
62 /*                                                                           */
63 /*    The algorithms are discussed in the greatest detail in "Delaunay       */
64 /*    Refinement Algorithms for Triangular Mesh Generation," Computational   */
65 /*    Geometry:  Theory and Applications 22(1-3):21-74, May 2002.  [*]       */
66 /*                                                                           */
67 /*    More detail about the data structures may be found in my dissertation: */
68 /*    "Delaunay Refinement Mesh Generation," Ph.D. thesis, Technical Report  */
69 /*    CMU-CS-97-137, School of Computer Science, Carnegie Mellon University, */
70 /*    Pittsburgh, Pennsylvania, 18 May 1997.  [*]                            */
71 /*                                                                           */
72 /*  Triangle was created as part of the Quake Project in the School of       */
73 /*    Computer Science at Carnegie Mellon University.  For further           */
74 /*    information, see Hesheng Bao, Jacobo Bielak, Omar Ghattas, Loukas F.   */
75 /*    Kallivokas, David R. O'Hallaron, Jonathan R. Shewchuk, and Jifeng Xu,  */
76 /*    "Large-scale Simulation of Elastic Wave Propagation in Heterogeneous   */
77 /*    Media on Parallel Computers," Computer Methods in Applied Mechanics    */
78 /*    and Engineering 152(1-2):85-102, 22 January 1998.                      */
79 /*                                                                           */
80 /*  Triangle's Delaunay refinement algorithm for quality mesh generation is  */
81 /*    a hybrid of one due to Jim Ruppert, "A Delaunay Refinement Algorithm   */
82 /*    for Quality 2-Dimensional Mesh Generation," Journal of Algorithms      */
83 /*    18(3):548-585, May 1995 [*], and one due to L. Paul Chew, "Guaranteed- */
84 /*    Quality Mesh Generation for Curved Surfaces," Proceedings of the Ninth */
85 /*    Annual Symposium on Computational Geometry (San Diego, California),    */
86 /*    pages 274-280, Association for Computing Machinery, May 1993,          */
87 /*    http://portal.acm.org/citation.cfm?id=161150 .                         */
88 /*                                                                           */
89 /*  The Delaunay refinement algorithm has been modified so that it meshes    */
90 /*    domains with small input angles well, as described in Gary L. Miller,  */
91 /*    Steven E. Pav, and Noel J. Walkington, "When and Why Ruppert's         */
92 /*    Algorithm Works," Twelfth International Meshing Roundtable, pages      */
93 /*    91-102, Sandia National Laboratories, September 2003.  [*]             */
94 /*                                                                           */
95 /*  My implementation of the divide-and-conquer and incremental Delaunay     */
96 /*    triangulation algorithms follows closely the presentation of Guibas    */
97 /*    and Stolfi, even though I use a triangle-based data structure instead  */
98 /*    of their quad-edge data structure.  (In fact, I originally implemented */
99 /*    Triangle using the quad-edge data structure, but the switch to a       */
100 /*    triangle-based data structure sped Triangle by a factor of two.)  The  */
101 /*    mesh manipulation primitives and the two aforementioned Delaunay       */
102 /*    triangulation algorithms are described by Leonidas J. Guibas and Jorge */
103 /*    Stolfi, "Primitives for the Manipulation of General Subdivisions and   */
104 /*    the Computation of Voronoi Diagrams," ACM Transactions on Graphics     */
105 /*    4(2):74-123, April 1985, http://portal.acm.org/citation.cfm?id=282923 .*/
106 /*                                                                           */
107 /*  Their O(n log n) divide-and-conquer algorithm is adapted from Der-Tsai   */
108 /*    Lee and Bruce J. Schachter, "Two Algorithms for Constructing the       */
109 /*    Delaunay Triangulation," International Journal of Computer and         */
110 /*    Information Science 9(3):219-242, 1980.  Triangle's improvement of the */
111 /*    divide-and-conquer algorithm by alternating between vertical and       */
112 /*    horizontal cuts was introduced by Rex A. Dwyer, "A Faster Divide-and-  */
113 /*    Conquer Algorithm for Constructing Delaunay Triangulations,"           */
114 /*    Algorithmica 2(2):137-151, 1987.                                       */
115 /*                                                                           */
116 /*  The incremental insertion algorithm was first proposed by C. L. Lawson,  */
117 /*    "Software for C1 Surface Interpolation," in Mathematical Software III, */
118 /*    John R. Rice, editor, Academic Press, New York, pp. 161-194, 1977.     */
119 /*    For point location, I use the algorithm of Ernst P. Mucke, Isaac       */
120 /*    Saias, and Binhai Zhu, "Fast Randomized Point Location Without         */
121 /*    Preprocessing in Two- and Three-Dimensional Delaunay Triangulations,"  */
122 /*    Proceedings of the Twelfth Annual Symposium on Computational Geometry, */
123 /*    ACM, May 1996.  [*]  If I were to randomize the order of vertex        */
124 /*    insertion (I currently don't bother), their result combined with the   */
125 /*    result of Kenneth L. Clarkson and Peter W. Shor, "Applications of      */
126 /*    Random Sampling in Computational Geometry II," Discrete &              */
127 /*    Computational Geometry 4(1):387-421, 1989, would yield an expected     */
128 /*    O(n^{4/3}) bound on running time.                                      */
129 /*                                                                           */
130 /*  The O(n log n) sweepline Delaunay triangulation algorithm is taken from  */
131 /*    Steven Fortune, "A Sweepline Algorithm for Voronoi Diagrams",          */
132 /*    Algorithmica 2(2):153-174, 1987.  A random sample of edges on the      */
133 /*    boundary of the triangulation are maintained in a splay tree for the   */
134 /*    purpose of point location.  Splay trees are described by Daniel        */
135 /*    Dominic Sleator and Robert Endre Tarjan, "Self-Adjusting Binary Search */
136 /*    Trees," Journal of the ACM 32(3):652-686, July 1985,                   */
137 /*    http://portal.acm.org/citation.cfm?id=3835 .                           */
138 /*                                                                           */
139 /*  The algorithms for exact computation of the signs of determinants are    */
140 /*    described in Jonathan Richard Shewchuk, "Adaptive Precision Floating-  */
141 /*    Point Arithmetic and Fast Robust Geometric Predicates," Discrete &     */
142 /*    Computational Geometry 18(3):305-363, October 1997.  (Also available   */
143 /*    as Technical Report CMU-CS-96-140, School of Computer Science,         */
144 /*    Carnegie Mellon University, Pittsburgh, Pennsylvania, May 1996.)  [*]  */
145 /*    An abbreviated version appears as Jonathan Richard Shewchuk, "Robust   */
146 /*    Adaptive Floating-Point Geometric Predicates," Proceedings of the      */
147 /*    Twelfth Annual Symposium on Computational Geometry, ACM, May 1996. [*] */
148 /*    Many of the ideas for my exact arithmetic routines originate with      */
149 /*    Douglas M. Priest, "Algorithms for Arbitrary Precision Floating Point  */
150 /*    Arithmetic," Tenth Symposium on Computer Arithmetic, pp. 132-143, IEEE */
151 /*    Computer Society Press, 1991.  [*]  Many of the ideas for the correct  */
152 /*    evaluation of the signs of determinants are taken from Steven Fortune  */
153 /*    and Christopher J. Van Wyk, "Efficient Exact Arithmetic for Computa-   */
154 /*    tional Geometry," Proceedings of the Ninth Annual Symposium on         */
155 /*    Computational Geometry, ACM, pp. 163-172, May 1993, and from Steven    */
156 /*    Fortune, "Numerical Stability of Algorithms for 2D Delaunay Triangu-   */
157 /*    lations," International Journal of Computational Geometry & Applica-   */
158 /*    tions 5(1-2):193-213, March-June 1995.                                 */
159 /*                                                                           */
160 /*  The method of inserting new vertices off-center (not precisely at the    */
161 /*    circumcenter of every poor-quality triangle) is from Alper Ungor,      */
162 /*    "Off-centers:  A New Type of Steiner Points for Computing Size-Optimal */
163 /*    Quality-Guaranteed Delaunay Triangulations," Proceedings of LATIN      */
164 /*    2004 (Buenos Aires, Argentina), April 2004.                            */
165 /*                                                                           */
166 /*  For definitions of and results involving Delaunay triangulations,        */
167 /*    constrained and conforming versions thereof, and other aspects of      */
168 /*    triangular mesh generation, see the excellent survey by Marshall Bern  */
169 /*    and David Eppstein, "Mesh Generation and Optimal Triangulation," in    */
170 /*    Computing and Euclidean Geometry, Ding-Zhu Du and Frank Hwang,         */
171 /*    editors, World Scientific, Singapore, pp. 23-90, 1992.  [*]            */
172 /*                                                                           */
173 /*  The time for incrementally adding PSLG (planar straight line graph)      */
174 /*    segments to create a constrained Delaunay triangulation is probably    */
175 /*    O(t^2) per segment in the worst case and O(t) per segment in the       */
176 /*    common case, where t is the number of triangles that intersect the     */
177 /*    segment before it is inserted.  This doesn't count point location,     */
178 /*    which can be much more expensive.  I could improve this to O(d log d)  */
179 /*    time, but d is usually quite small, so it's not worth the bother.      */
180 /*    (This note does not apply when the -s switch is used, invoking a       */
181 /*    different method is used to insert segments.)                          */
182 /*                                                                           */
183 /*  The time for deleting a vertex from a Delaunay triangulation is O(d^2)   */
184 /*    in the worst case and O(d) in the common case, where d is the degree   */
185 /*    of the vertex being deleted.  I could improve this to O(d log d) time, */
186 /*    but d is usually quite small, so it's not worth the bother.            */
187 /*                                                                           */
188 /*  Ruppert's Delaunay refinement algorithm typically generates triangles    */
189 /*    at a linear rate (constant time per triangle) after the initial        */
190 /*    triangulation is formed.  There may be pathological cases where        */
191 /*    quadratic time is required, but these never arise in practice.         */
192 /*                                                                           */
193 /*  The geometric predicates (circumcenter calculations, segment             */
194 /*    intersection formulae, etc.) appear in my "Lecture Notes on Geometric  */
195 /*    Robustness" at http://www.cs.berkeley.edu/~jrs/mesh .                  */
196 /*                                                                           */
197 /*  If you make any improvements to this code, please please please let me   */
198 /*    know, so that I may obtain the improvements.  Even if you don't change */
199 /*    the code, I'd still love to hear what it's being used for.             */
200 /*                                                                           */
201 /*****************************************************************************/
202 
203 /* For single precision (which will save some memory and reduce paging),     */
204 /*   define the symbol SINGLE by using the -DSINGLE compiler switch or by    */
205 /*   writing "#define SINGLE" below.                                         */
206 /*                                                                           */
207 /* For double precision (which will allow you to refine meshes to a smaller  */
208 /*   edge length), leave SINGLE undefined.                                   */
209 /*                                                                           */
210 /* Double precision uses more memory, but improves the resolution of the     */
211 /*   meshes you can generate with Triangle.  It also reduces the likelihood  */
212 /*   of a floating exception due to overflow.  Finally, it is much faster    */
213 /*   than single precision on 64-bit architectures like the DEC Alpha.  I    */
214 /*   recommend double precision unless you want to generate a mesh for which */
215 /*   you do not have enough memory.                                          */
216 
217 /* #define SINGLE */
218 
219 /* #ifdef SINGLE */
220 /* #define REAL float */
221 /* #else */ /* not SINGLE */
222 /* #define REAL double */
223 /* #endif */ /* not SINGLE */
224 
225 /* Use libMesh-defined precision */
226 #include "libmesh/libmesh_config.h"
227 typedef LIBMESH_DEFAULT_SCALAR_TYPE REAL;
228 
229 /* If yours is not a Unix system, define the NO_TIMER compiler switch to     */
230 /*   remove the Unix-specific timing code.                                   */
231 
232 /* #define NO_TIMER */
233 
234 /* To insert lots of self-checks for internal errors, define the SELF_CHECK  */
235 /*   symbol.  This will slow down the program significantly.  It is best to  */
236 /*   define the symbol using the -DSELF_CHECK compiler switch, but you could */
237 /*   write "#define SELF_CHECK" below.  If you are modifying this code, I    */
238 /*   recommend you turn self-checks on until your work is debugged.          */
239 
240 /* #define SELF_CHECK */
241 
242 /* To compile Triangle as a callable object library (triangle.o), define the */
243 /*   TRILIBRARY symbol.  Read the file triangle.h for details on how to call */
244 /*   the procedure triangulate() that results.                               */
245 
246 /* #define TRILIBRARY */
247 
248 /* It is possible to generate a smaller version of Triangle using one or     */
249 /*   both of the following symbols.  Define the REDUCED symbol to eliminate  */
250 /*   all features that are primarily of research interest; specifically, the */
251 /*   -i, -F, -s, and -C switches.  Define the CDT_ONLY symbol to eliminate   */
252 /*   all meshing algorithms above and beyond constrained Delaunay            */
253 /*   triangulation; specifically, the -r, -q, -a, -u, -D, -S, and -s         */
254 /*   switches.  These reductions are most likely to be useful when           */
255 /*   generating an object library (triangle.o) by defining the TRILIBRARY    */
256 /*   symbol.                                                                 */
257 
258 /* #define REDUCED */
259 /* #define CDT_ONLY */
260 
261 /* On some machines, my exact arithmetic routines might be defeated by the   */
262 /*   use of internal extended precision floating-point registers.  The best  */
263 /*   way to solve this problem is to set the floating-point registers to use */
264 /*   single or double precision internally.  On 80x86 processors, this may   */
265 /*   be accomplished by setting the CPU86 symbol for the Microsoft C         */
266 /*   compiler, or the LINUX symbol for the gcc compiler running on Linux.    */
267 /*                                                                           */
268 /* An inferior solution is to declare certain values as `volatile', thus     */
269 /*   forcing them to be stored to memory and rounded off.  Unfortunately,    */
270 /*   this solution might slow Triangle down quite a bit.  To use volatile    */
271 /*   values, write "#define INEXACT volatile" below.  Normally, however,     */
272 /*   INEXACT should be defined to be nothing.  ("#define INEXACT".)          */
273 /*                                                                           */
274 /* For more discussion, see http://www.cs.cmu.edu/~quake/robust.pc.html .    */
275 /*   For yet more discussion, see Section 5 of my paper, "Adaptive Precision */
276 /*   Floating-Point Arithmetic and Fast Robust Geometric Predicates" (also   */
277 /*   available as Section 6.6 of my dissertation).                           */
278 
279 /* #define CPU86 */
280 /* #define LINUX */
281 
282 #define INEXACT /* Nothing */
283 /* #define INEXACT volatile */
284 
285 /* Maximum number of characters in a file name (including the null).         */
286 
287 #define FILENAMESIZE 2048
288 
289 /* Maximum number of characters in a line read from a file (including the    */
290 /*   null).                                                                  */
291 
292 #define INPUTLINESIZE 1024
293 
294 /* For efficiency, a variety of data structures are allocated in bulk.  The  */
295 /*   following constants determine how many of each structure is allocated   */
296 /*   at once.                                                                */
297 
298 #define TRIPERBLOCK 4092           /* Number of triangles allocated at once. */
299 #define SUBSEGPERBLOCK 508       /* Number of subsegments allocated at once. */
300 #define VERTEXPERBLOCK 4092         /* Number of vertices allocated at once. */
301 #define VIRUSPERBLOCK 1020   /* Number of virus triangles allocated at once. */
302 /* Number of encroached subsegments allocated at once. */
303 #define BADSUBSEGPERBLOCK 252
304 /* Number of skinny triangles allocated at once. */
305 #define BADTRIPERBLOCK 4092
306 /* Number of flipped triangles allocated at once. */
307 #define FLIPSTACKERPERBLOCK 252
308 /* Number of splay tree nodes allocated at once. */
309 #define SPLAYNODEPERBLOCK 508
310 
311 /* The vertex types.   A DEADVERTEX has been deleted entirely.  An           */
312 /*   UNDEADVERTEX is not part of the mesh, but is written to the output      */
313 /*   .node file and affects the node indexing in the other output files.     */
314 
315 #define INPUTVERTEX 0
316 #define SEGMENTVERTEX 1
317 #define FREEVERTEX 2
318 #define DEADVERTEX -32768
319 #define UNDEADVERTEX -32767
320 
321 /* The next line is used to outsmart some very stupid compilers.  If your    */
322 /*   compiler is smarter, feel free to replace the "int" with "void".        */
323 /*   Not that it matters.                                                    */
324 
325 #define VOID int
326 
327 /* Two constants for algorithms based on random sampling.  Both constants    */
328 /*   have been chosen empirically to optimize their respective algorithms.   */
329 
330 /* Used for the point location scheme of Mucke, Saias, and Zhu, to decide    */
331 /*   how large a random sample of triangles to inspect.                      */
332 
333 #define SAMPLEFACTOR 11
334 
335 /* Used in Fortune's sweepline Delaunay algorithm to determine what fraction */
336 /*   of boundary edges should be maintained in the splay tree for point      */
337 /*   location on the front.                                                  */
338 
339 #define SAMPLERATE 10
340 
341 /* A number that speaks for itself, every kissable digit.                    */
342 
343 #define PI 3.141592653589793238462643383279502884197169399375105820974944592308
344 
345 /* Another fave.                                                             */
346 
347 #define SQUAREROOTTWO 1.4142135623730950488016887242096980785696718753769480732
348 
349 /* And here's one for those of you who are intimidated by math.              */
350 
351 #define ONETHIRD 0.333333333333333333333333333333333333333333333333333333333333
352 
353 #include <stdio.h>
354 #include <stdlib.h>
355 #include <string.h>
356 #include <math.h>
357 #ifndef NO_TIMER
358 #include <sys/time.h>
359 #endif /* not NO_TIMER */
360 #ifdef CPU86
361 #include <float.h>
362 #endif /* CPU86 */
363 #ifdef LINUX
364 #include <fpu_control.h>
365 #endif /* LINUX */
366 #ifdef TRILIBRARY
367 #include "triangle.h"
368 #endif /* TRILIBRARY */
369 
370 /* A few forward declarations.                                               */
371 
372 #ifndef TRILIBRARY
373 char *readline();
374 char *findfield();
375 #endif /* not TRILIBRARY */
376 
377 /* Labels that signify the result of point location.  The result of a        */
378 /*   search indicates that the point falls in the interior of a triangle, on */
379 /*   an edge, on a vertex, or outside the mesh.                              */
380 
381 enum locateresult {INTRIANGLE, ONEDGE, ONVERTEX, OUTSIDE};
382 
383 /* Labels that signify the result of vertex insertion.  The result indicates */
384 /*   that the vertex was inserted with complete success, was inserted but    */
385 /*   encroaches upon a subsegment, was not inserted because it lies on a     */
386 /*   segment, or was not inserted because another vertex occupies the same   */
387 /*   location.                                                               */
388 
389 enum insertvertexresult {SUCCESSFULVERTEX, ENCROACHINGVERTEX, VIOLATINGVERTEX,
390                          DUPLICATEVERTEX};
391 
392 /* Labels that signify the result of direction finding.  The result          */
393 /*   indicates that a segment connecting the two query points falls within   */
394 /*   the direction triangle, along the left edge of the direction triangle,  */
395 /*   or along the right edge of the direction triangle.                      */
396 
397 enum finddirectionresult {WITHIN, LEFTCOLLINEAR, RIGHTCOLLINEAR};
398 
399 /*****************************************************************************/
400 /*                                                                           */
401 /*  The basic mesh data structures                                           */
402 /*                                                                           */
403 /*  There are three:  vertices, triangles, and subsegments (abbreviated      */
404 /*  `subseg').  These three data structures, linked by pointers, comprise    */
405 /*  the mesh.  A vertex simply represents a mesh vertex and its properties.  */
406 /*  A triangle is a triangle.  A subsegment is a special data structure used */
407 /*  to represent an impenetrable edge of the mesh (perhaps on the outer      */
408 /*  boundary, on the boundary of a hole, or part of an internal boundary     */
409 /*  separating two triangulated regions).  Subsegments represent boundaries, */
410 /*  defined by the user, that triangles may not lie across.                  */
411 /*                                                                           */
412 /*  A triangle consists of a list of three vertices, a list of three         */
413 /*  adjoining triangles, a list of three adjoining subsegments (when         */
414 /*  segments exist), an arbitrary number of optional user-defined            */
415 /*  floating-point attributes, and an optional area constraint.  The latter  */
416 /*  is an upper bound on the permissible area of each triangle in a region,  */
417 /*  used for mesh refinement.                                                */
418 /*                                                                           */
419 /*  For a triangle on a boundary of the mesh, some or all of the neighboring */
420 /*  triangles may not be present.  For a triangle in the interior of the     */
421 /*  mesh, often no neighboring subsegments are present.  Such absent         */
422 /*  triangles and subsegments are never represented by NULL pointers; they   */
423 /*  are represented by two special records:  `dummytri', the triangle that   */
424 /*  fills "outer space", and `dummysub', the omnipresent subsegment.         */
425 /*  `dummytri' and `dummysub' are used for several reasons; for instance,    */
426 /*  they can be dereferenced and their contents examined without violating   */
427 /*  protected memory.                                                        */
428 /*                                                                           */
429 /*  However, it is important to understand that a triangle includes other    */
430 /*  information as well.  The pointers to adjoining vertices, triangles, and */
431 /*  subsegments are ordered in a way that indicates their geometric relation */
432 /*  to each other.  Furthermore, each of these pointers contains orientation */
433 /*  information.  Each pointer to an adjoining triangle indicates which face */
434 /*  of that triangle is contacted.  Similarly, each pointer to an adjoining  */
435 /*  subsegment indicates which side of that subsegment is contacted, and how */
436 /*  the subsegment is oriented relative to the triangle.                     */
437 /*                                                                           */
438 /*  The data structure representing a subsegment may be thought to be        */
439 /*  abutting the edge of one or two triangle data structures:  either        */
440 /*  sandwiched between two triangles, or resting against one triangle on an  */
441 /*  exterior boundary or hole boundary.                                      */
442 /*                                                                           */
443 /*  A subsegment consists of a list of four vertices--the vertices of the    */
444 /*  subsegment, and the vertices of the segment it is a part of--a list of   */
445 /*  two adjoining subsegments, and a list of two adjoining triangles.  One   */
446 /*  of the two adjoining triangles may not be present (though there should   */
447 /*  always be one), and neighboring subsegments might not be present.        */
448 /*  Subsegments also store a user-defined integer "boundary marker".         */
449 /*  Typically, this integer is used to indicate what boundary conditions are */
450 /*  to be applied at that location in a finite element simulation.           */
451 /*                                                                           */
452 /*  Like triangles, subsegments maintain information about the relative      */
453 /*  orientation of neighboring objects.                                      */
454 /*                                                                           */
455 /*  Vertices are relatively simple.  A vertex is a list of floating-point    */
456 /*  numbers, starting with the x, and y coordinates, followed by an          */
457 /*  arbitrary number of optional user-defined floating-point attributes,     */
458 /*  followed by an integer boundary marker.  During the segment insertion    */
459 /*  phase, there is also a pointer from each vertex to a triangle that may   */
460 /*  contain it.  Each pointer is not always correct, but when one is, it     */
461 /*  speeds up segment insertion.  These pointers are assigned values once    */
462 /*  at the beginning of the segment insertion phase, and are not used or     */
463 /*  updated except during this phase.  Edge flipping during segment          */
464 /*  insertion will render some of them incorrect.  Hence, don't rely upon    */
465 /*  them for anything.                                                       */
466 /*                                                                           */
467 /*  Other than the exception mentioned above, vertices have no information   */
468 /*  about what triangles, subfacets, or subsegments they are linked to.      */
469 /*                                                                           */
470 /*****************************************************************************/
471 
472 /*****************************************************************************/
473 /*                                                                           */
474 /*  Handles                                                                  */
475 /*                                                                           */
476 /*  The oriented triangle (`otri') and oriented subsegment (`osub') data     */
477 /*  structures defined below do not themselves store any part of the mesh.   */
478 /*  The mesh itself is made of `triangle's, `subseg's, and `vertex's.        */
479 /*                                                                           */
480 /*  Oriented triangles and oriented subsegments will usually be referred to  */
481 /*  as "handles."  A handle is essentially a pointer into the mesh; it       */
482 /*  allows you to "hold" one particular part of the mesh.  Handles are used  */
483 /*  to specify the regions in which one is traversing and modifying the mesh.*/
484 /*  A single `triangle' may be held by many handles, or none at all.  (The   */
485 /*  latter case is not a memory leak, because the triangle is still          */
486 /*  connected to other triangles in the mesh.)                               */
487 /*                                                                           */
488 /*  An `otri' is a handle that holds a triangle.  It holds a specific edge   */
489 /*  of the triangle.  An `osub' is a handle that holds a subsegment.  It     */
490 /*  holds either the left or right side of the subsegment.                   */
491 /*                                                                           */
492 /*  Navigation about the mesh is accomplished through a set of mesh          */
493 /*  manipulation primitives, further below.  Many of these primitives take   */
494 /*  a handle and produce a new handle that holds the mesh near the first     */
495 /*  handle.  Other primitives take two handles and glue the corresponding    */
496 /*  parts of the mesh together.  The orientation of the handles is           */
497 /*  important.  For instance, when two triangles are glued together by the   */
498 /*  bond() primitive, they are glued at the edges on which the handles lie.  */
499 /*                                                                           */
500 /*  Because vertices have no information about which triangles they are      */
501 /*  attached to, I commonly represent a vertex by use of a handle whose      */
502 /*  origin is the vertex.  A single handle can simultaneously represent a    */
503 /*  triangle, an edge, and a vertex.                                         */
504 /*                                                                           */
505 /*****************************************************************************/
506 
507 /* The triangle data structure.  Each triangle contains three pointers to    */
508 /*   adjoining triangles, plus three pointers to vertices, plus three        */
509 /*   pointers to subsegments (declared below; these pointers are usually     */
510 /*   `dummysub').  It may or may not also contain user-defined attributes    */
511 /*   and/or a floating-point "area constraint."  It may also contain extra   */
512 /*   pointers for nodes, when the user asks for high-order elements.         */
513 /*   Because the size and structure of a `triangle' is not decided until     */
514 /*   runtime, I haven't simply declared the type `triangle' as a struct.     */
515 
516 typedef REAL **triangle;            /* Really:  typedef triangle *triangle   */
517 
518 /* An oriented triangle:  includes a pointer to a triangle and orientation.  */
519 /*   The orientation denotes an edge of the triangle.  Hence, there are      */
520 /*   three possible orientations.  By convention, each edge always points    */
521 /*   counterclockwise about the corresponding triangle.                      */
522 
523 struct otri {
524   triangle *tri;
525   int orient;                                         /* Ranges from 0 to 2. */
526 };
527 
528 /* The subsegment data structure.  Each subsegment contains two pointers to  */
529 /*   adjoining subsegments, plus four pointers to vertices, plus two         */
530 /*   pointers to adjoining triangles, plus one boundary marker, plus one     */
531 /*   segment number.                                                         */
532 
533 typedef REAL **subseg;                  /* Really:  typedef subseg *subseg   */
534 
535 /* An oriented subsegment:  includes a pointer to a subsegment and an        */
536 /*   orientation.  The orientation denotes a side of the edge.  Hence, there */
537 /*   are two possible orientations.  By convention, the edge is always       */
538 /*   directed so that the "side" denoted is the right side of the edge.      */
539 
540 struct osub {
541   subseg *ss;
542   int ssorient;                                       /* Ranges from 0 to 1. */
543 };
544 
545 /* The vertex data structure.  Each vertex is actually an array of REALs.    */
546 /*   The number of REALs is unknown until runtime.  An integer boundary      */
547 /*   marker, and sometimes a pointer to a triangle, is appended after the    */
548 /*   REALs.                                                                  */
549 
550 typedef REAL *vertex;
551 
552 /* A queue used to store encroached subsegments.  Each subsegment's vertices */
553 /*   are stored so that we can check whether a subsegment is still the same. */
554 
555 struct badsubseg {
556   subseg encsubseg;                             /* An encroached subsegment. */
557   vertex subsegorg, subsegdest;                         /* Its two vertices. */
558 };
559 
560 /* A queue used to store bad triangles.  The key is the square of the cosine */
561 /*   of the smallest angle of the triangle.  Each triangle's vertices are    */
562 /*   stored so that one can check whether a triangle is still the same.      */
563 
564 struct badtriang {
565   triangle poortri;                       /* A skinny or too-large triangle. */
566   REAL key;                             /* cos^2 of smallest (apical) angle. */
567   vertex triangorg, triangdest, triangapex;           /* Its three vertices. */
568   struct badtriang *nexttriang;             /* Pointer to next bad triangle. */
569 };
570 
571 /* A stack of triangles flipped during the most recent vertex insertion.     */
572 /*   The stack is used to undo the vertex insertion if the vertex encroaches */
573 /*   upon a subsegment.                                                      */
574 
575 struct flipstacker {
576   triangle flippedtri;                       /* A recently flipped triangle. */
577   struct flipstacker *prevflip;               /* Previous flip in the stack. */
578 };
579 
580 /* A node in a heap used to store events for the sweepline Delaunay          */
581 /*   algorithm.  Nodes do not point directly to their parents or children in */
582 /*   the heap.  Instead, each node knows its position in the heap, and can   */
583 /*   look up its parent and children in a separate array.  The `eventptr'    */
584 /*   points either to a `vertex' or to a triangle (in encoded format, so     */
585 /*   that an orientation is included).  In the latter case, the origin of    */
586 /*   the oriented triangle is the apex of a "circle event" of the sweepline  */
587 /*   algorithm.  To distinguish site events from circle events, all circle   */
588 /*   events are given an invalid (smaller than `xmin') x-coordinate `xkey'.  */
589 
590 struct event {
591   REAL xkey, ykey;                              /* Coordinates of the event. */
592   VOID *eventptr;      /* Can be a vertex or the location of a circle event. */
593   int heapposition;              /* Marks this event's position in the heap. */
594 };
595 
596 /* A node in the splay tree.  Each node holds an oriented ghost triangle     */
597 /*   that represents a boundary edge of the growing triangulation.  When a   */
598 /*   circle event covers two boundary edges with a triangle, so that they    */
599 /*   are no longer boundary edges, those edges are not immediately deleted   */
600 /*   from the tree; rather, they are lazily deleted when they are next       */
601 /*   encountered.  (Since only a random sample of boundary edges are kept    */
602 /*   in the tree, lazy deletion is faster.)  `keydest' is used to verify     */
603 /*   that a triangle is still the same as when it entered the splay tree; if */
604 /*   it has been rotated (due to a circle event), it no longer represents a  */
605 /*   boundary edge and should be deleted.                                    */
606 
607 struct splaynode {
608   struct otri keyedge;                     /* Lprev of an edge on the front. */
609   vertex keydest;           /* Used to verify that splay node is still live. */
610   struct splaynode *lchild, *rchild;              /* Children in splay tree. */
611 };
612 
613 /* A type used to allocate memory.  firstblock is the first block of items.  */
614 /*   nowblock is the block from which items are currently being allocated.   */
615 /*   nextitem points to the next slab of free memory for an item.            */
616 /*   deaditemstack is the head of a linked list (stack) of deallocated items */
617 /*   that can be recycled.  unallocateditems is the number of items that     */
618 /*   remain to be allocated from nowblock.                                   */
619 /*                                                                           */
620 /* Traversal is the process of walking through the entire list of items, and */
621 /*   is separate from allocation.  Note that a traversal will visit items on */
622 /*   the "deaditemstack" stack as well as live items.  pathblock points to   */
623 /*   the block currently being traversed.  pathitem points to the next item  */
624 /*   to be traversed.  pathitemsleft is the number of items that remain to   */
625 /*   be traversed in pathblock.                                              */
626 /*                                                                           */
627 /* alignbytes determines how new records should be aligned in memory.        */
628 /*   itembytes is the length of a record in bytes (after rounding up).       */
629 /*   itemsperblock is the number of items allocated at once in a single      */
630 /*   block.  itemsfirstblock is the number of items in the first block,      */
631 /*   which can vary from the others.  items is the number of currently       */
632 /*   allocated items.  maxitems is the maximum number of items that have     */
633 /*   been allocated at once; it is the current number of items plus the      */
634 /*   number of records kept on deaditemstack.                                */
635 
636 struct memorypool {
637   VOID **firstblock, **nowblock;
638   VOID *nextitem;
639   VOID *deaditemstack;
640   VOID **pathblock;
641   VOID *pathitem;
642   int alignbytes;
643   int itembytes;
644   int itemsperblock;
645   int itemsfirstblock;
646   long items, maxitems;
647   int unallocateditems;
648   int pathitemsleft;
649 };
650 
651 
652 /* Global constants.                                                         */
653 
654 REAL splitter=0.;       /* Used to split REAL factors for exact multiplication. */
655 REAL epsilon=0.;                             /* Floating-point machine epsilon. */
656 REAL resulterrbound=0.;
657 REAL ccwerrboundA=0., ccwerrboundB=0., ccwerrboundC=0.;
658 REAL iccerrboundA=0., iccerrboundB=0., iccerrboundC=0.;
659 REAL o3derrboundA=0., o3derrboundB=0., o3derrboundC=0.;
660 
661 /* Random number seed is not constant, but I've made it global anyway.       */
662 
663 unsigned long randomseed;                     /* Current random number seed. */
664 
665 
666 /* Mesh data structure.  Triangle operates on only one mesh, but the mesh    */
667 /*   structure is used (instead of global variables) to allow reentrancy.    */
668 
669 struct mesh {
670 
671 /* Variables used to allocate memory for triangles, subsegments, vertices,   */
672 /*   viri (triangles being eaten), encroached segments, bad (skinny or too   */
673 /*   large) triangles, and splay tree nodes.                                 */
674 
675   struct memorypool triangles;
676   struct memorypool subsegs;
677   struct memorypool vertices;
678   struct memorypool viri;
679   struct memorypool badsubsegs;
680   struct memorypool badtriangles;
681   struct memorypool flipstackers;
682   struct memorypool splaynodes;
683 
684 /* Variables that maintain the bad triangle queues.  The queues are          */
685 /*   ordered from 4095 (highest priority) to 0 (lowest priority).            */
686 
687   struct badtriang *queuefront[4096];
688   struct badtriang *queuetail[4096];
689   int nextnonemptyq[4096];
690   int firstnonemptyq;
691 
692 /* Variable that maintains the stack of recently flipped triangles.          */
693 
694   struct flipstacker *lastflip;
695 
696 /* Other variables. */
697 
698   REAL xmin, xmax, ymin, ymax;                            /* x and y bounds. */
699   REAL xminextreme;      /* Nonexistent x value used as a flag in sweepline. */
700   int invertices;                               /* Number of input vertices. */
701   int inelements;                              /* Number of input triangles. */
702   int insegments;                               /* Number of input segments. */
703   int holes;                                       /* Number of input holes. */
704   int regions;                                   /* Number of input regions. */
705   int undeads;    /* Number of input vertices that don't appear in the mesh. */
706   long edges;                                     /* Number of output edges. */
707   int mesh_dim;                                /* Dimension (ought to be 2). */
708   int nextras;                           /* Number of attributes per vertex. */
709   int eextras;                         /* Number of attributes per triangle. */
710   long hullsize;                          /* Number of edges in convex hull. */
711   int steinerleft;                 /* Number of Steiner points not yet used. */
712   int vertexmarkindex;         /* Index to find boundary marker of a vertex. */
713   int vertex2triindex;     /* Index to find a triangle adjacent to a vertex. */
714   int highorderindex;  /* Index to find extra nodes for high-order elements. */
715   int elemattribindex;            /* Index to find attributes of a triangle. */
716   int areaboundindex;             /* Index to find area bound of a triangle. */
717   int checksegments;         /* Are there segments in the triangulation yet? */
718   int checkquality;                  /* Has quality triangulation begun yet? */
719   int readnodefile;                           /* Has a .node file been read? */
720   long samples;              /* Number of random samples for point location. */
721 
722   long incirclecount;                 /* Number of incircle tests performed. */
723   long counterclockcount;     /* Number of counterclockwise tests performed. */
724   long orient3dcount;           /* Number of 3D orientation tests performed. */
725   long hyperbolacount;      /* Number of right-of-hyperbola tests performed. */
726   long circumcentercount;  /* Number of circumcenter calculations performed. */
727   long circletopcount;       /* Number of circle top calculations performed. */
728 
729 /* Triangular bounding box vertices.                                         */
730 
731   vertex infvertex1, infvertex2, infvertex3;
732 
733 /* Pointer to the `triangle' that occupies all of "outer space."             */
734 
735   triangle *dummytri;
736   triangle *dummytribase;    /* Keep base address so we can free() it later. */
737 
738 /* Pointer to the omnipresent subsegment.  Referenced by any triangle or     */
739 /*   subsegment that isn't really connected to a subsegment at that          */
740 /*   location.                                                               */
741 
742   subseg *dummysub;
743   subseg *dummysubbase;      /* Keep base address so we can free() it later. */
744 
745 /* Pointer to a recently visited triangle.  Improves point location if       */
746 /*   proximate vertices are inserted sequentially.                           */
747 
748   struct otri recenttri;
749 
750 };                                                  /* End of `struct mesh'. */
751 
752 
753 /* Data structure for command line switches and file names.  This structure  */
754 /*   is used (instead of global variables) to allow reentrancy.              */
755 
756 struct behavior {
757 
758 /* Switches for the triangulator.                                            */
759 /*   poly: -p switch.  refine: -r switch.                                    */
760 /*   quality: -q switch.                                                     */
761 /*     minangle: minimum angle bound, specified after -q switch.             */
762 /*     goodangle: cosine squared of minangle.                                */
763 /*     offconstant: constant used to place off-center Steiner points.        */
764 /*   vararea: -a switch without number.                                      */
765 /*   fixedarea: -a switch with number.                                       */
766 /*     maxarea: maximum area bound, specified after -a switch.               */
767 /*   usertest: -u switch.                                                    */
768 /*   regionattrib: -A switch.  convex: -c switch.                            */
769 /*   weighted: 1 for -w switch, 2 for -W switch.  jettison: -j switch        */
770 /*   firstnumber: inverse of -z switch.  All items are numbered starting     */
771 /*     from `firstnumber'.                                                   */
772 /*   edgesout: -e switch.  voronoi: -v switch.                               */
773 /*   neighbors: -n switch.  geomview: -g switch.                             */
774 /*   nobound: -B switch.  nopolywritten: -P switch.                          */
775 /*   nonodewritten: -N switch.  noelewritten: -E switch.                     */
776 /*   noiterationnum: -I switch.  noholes: -O switch.                         */
777 /*   noexact: -X switch.                                                     */
778 /*   order: element order, specified after -o switch.                        */
779 /*   nobisect: count of how often -Y switch is selected.                     */
780 /*   steiner: maximum number of Steiner points, specified after -S switch.   */
781 /*   incremental: -i switch.  sweepline: -F switch.                          */
782 /*   dwyer: inverse of -l switch.                                            */
783 /*   splitseg: -s switch.                                                    */
784 /*   conformdel: -D switch.  docheck: -C switch.                             */
785 /*   quiet: -Q switch.  verbose: count of how often -V switch is selected.   */
786 /*   usesegments: -p, -r, -q, or -c switch; determines whether segments are  */
787 /*     used at all.                                                          */
788 /*                                                                           */
789 /* Read the instructions to find out the meaning of these switches.          */
790 
791   int poly, refine, quality, vararea, fixedarea, usertest;
792   int regionattrib, convex, weighted, jettison;
793   int firstnumber;
794   int edgesout, voronoi, neighbors, geomview;
795   int nobound, nopolywritten, nonodewritten, noelewritten, noiterationnum;
796   int noholes, noexact, conformdel;
797   int incremental, sweepline, dwyer;
798   int splitseg;
799   int docheck;
800   int quiet, verbose;
801   int usesegments;
802   int order;
803   int nobisect;
804   int steiner;
805   REAL minangle, goodangle, offconstant;
806   REAL maxarea;
807 
808 /* Variables for file names.                                                 */
809 
810 #ifndef TRILIBRARY
811   char innodefilename[FILENAMESIZE];
812   char inelefilename[FILENAMESIZE];
813   char inpolyfilename[FILENAMESIZE];
814   char areafilename[FILENAMESIZE];
815   char outnodefilename[FILENAMESIZE];
816   char outelefilename[FILENAMESIZE];
817   char outpolyfilename[FILENAMESIZE];
818   char edgefilename[FILENAMESIZE];
819   char vnodefilename[FILENAMESIZE];
820   char vedgefilename[FILENAMESIZE];
821   char neighborfilename[FILENAMESIZE];
822   char offfilename[FILENAMESIZE];
823 #endif /* not TRILIBRARY */
824 
825 };                                              /* End of `struct behavior'. */
826 
827 
828 /*****************************************************************************/
829 /*                                                                           */
830 /*  Mesh manipulation primitives.  Each triangle contains three pointers to  */
831 /*  other triangles, with orientations.  Each pointer points not to the      */
832 /*  first byte of a triangle, but to one of the first three bytes of a       */
833 /*  triangle.  It is necessary to extract both the triangle itself and the   */
834 /*  orientation.  To save memory, I keep both pieces of information in one   */
835 /*  pointer.  To make this possible, I assume that all triangles are aligned */
836 /*  to four-byte boundaries.  The decode() routine below decodes a pointer,  */
837 /*  extracting an orientation (in the range 0 to 2) and a pointer to the     */
838 /*  beginning of a triangle.  The encode() routine compresses a pointer to a */
839 /*  triangle and an orientation into a single pointer.  My assumptions that  */
840 /*  triangles are four-byte-aligned and that the `unsigned long' type is     */
841 /*  long enough to hold a pointer are two of the few kludges in this program.*/
842 /*                                                                           */
843 /*  Subsegments are manipulated similarly.  A pointer to a subsegment        */
844 /*  carries both an address and an orientation in the range 0 to 1.          */
845 /*                                                                           */
846 /*  The other primitives take an oriented triangle or oriented subsegment,   */
847 /*  and return an oriented triangle or oriented subsegment or vertex; or     */
848 /*  they change the connections in the data structure.                       */
849 /*                                                                           */
850 /*  Below, triangles and subsegments are denoted by their vertices.  The     */
851 /*  triangle abc has origin (org) a, destination (dest) b, and apex (apex)   */
852 /*  c.  These vertices occur in counterclockwise order about the triangle.   */
853 /*  The handle abc may simultaneously denote vertex a, edge ab, and triangle */
854 /*  abc.                                                                     */
855 /*                                                                           */
856 /*  Similarly, the subsegment ab has origin (sorg) a and destination (sdest) */
857 /*  b.  If ab is thought to be directed upward (with b directly above a),    */
858 /*  then the handle ab is thought to grasp the right side of ab, and may     */
859 /*  simultaneously denote vertex a and edge ab.                              */
860 /*                                                                           */
861 /*  An asterisk (*) denotes a vertex whose identity is unknown.              */
862 /*                                                                           */
863 /*  Given this notation, a partial list of mesh manipulation primitives      */
864 /*  follows.                                                                 */
865 /*                                                                           */
866 /*                                                                           */
867 /*  For triangles:                                                           */
868 /*                                                                           */
869 /*  sym:  Find the abutting triangle; same edge.                             */
870 /*  sym(abc) -> ba*                                                          */
871 /*                                                                           */
872 /*  lnext:  Find the next edge (counterclockwise) of a triangle.             */
873 /*  lnext(abc) -> bca                                                        */
874 /*                                                                           */
875 /*  lprev:  Find the previous edge (clockwise) of a triangle.                */
876 /*  lprev(abc) -> cab                                                        */
877 /*                                                                           */
878 /*  onext:  Find the next edge counterclockwise with the same origin.        */
879 /*  onext(abc) -> ac*                                                        */
880 /*                                                                           */
881 /*  oprev:  Find the next edge clockwise with the same origin.               */
882 /*  oprev(abc) -> a*b                                                        */
883 /*                                                                           */
884 /*  dnext:  Find the next edge counterclockwise with the same destination.   */
885 /*  dnext(abc) -> *ba                                                        */
886 /*                                                                           */
887 /*  dprev:  Find the next edge clockwise with the same destination.          */
888 /*  dprev(abc) -> cb*                                                        */
889 /*                                                                           */
890 /*  rnext:  Find the next edge (counterclockwise) of the adjacent triangle.  */
891 /*  rnext(abc) -> *a*                                                        */
892 /*                                                                           */
893 /*  rprev:  Find the previous edge (clockwise) of the adjacent triangle.     */
894 /*  rprev(abc) -> b**                                                        */
895 /*                                                                           */
896 /*  org:  Origin          dest:  Destination          apex:  Apex            */
897 /*  org(abc) -> a         dest(abc) -> b              apex(abc) -> c         */
898 /*                                                                           */
899 /*  bond:  Bond two triangles together at the resepective handles.           */
900 /*  bond(abc, bad)                                                           */
901 /*                                                                           */
902 /*                                                                           */
903 /*  For subsegments:                                                         */
904 /*                                                                           */
905 /*  ssym:  Reverse the orientation of a subsegment.                          */
906 /*  ssym(ab) -> ba                                                           */
907 /*                                                                           */
908 /*  spivot:  Find adjoining subsegment with the same origin.                 */
909 /*  spivot(ab) -> a*                                                         */
910 /*                                                                           */
911 /*  snext:  Find next subsegment in sequence.                                */
912 /*  snext(ab) -> b*                                                          */
913 /*                                                                           */
914 /*  sorg:  Origin                      sdest:  Destination                   */
915 /*  sorg(ab) -> a                      sdest(ab) -> b                        */
916 /*                                                                           */
917 /*  sbond:  Bond two subsegments together at the respective origins.         */
918 /*  sbond(ab, ac)                                                            */
919 /*                                                                           */
920 /*                                                                           */
921 /*  For interacting tetrahedra and subfacets:                                */
922 /*                                                                           */
923 /*  tspivot:  Find a subsegment abutting a triangle.                         */
924 /*  tspivot(abc) -> ba                                                       */
925 /*                                                                           */
926 /*  stpivot:  Find a triangle abutting a subsegment.                         */
927 /*  stpivot(ab) -> ba*                                                       */
928 /*                                                                           */
929 /*  tsbond:  Bond a triangle to a subsegment.                                */
930 /*  tsbond(abc, ba)                                                          */
931 /*                                                                           */
932 /*****************************************************************************/
933 
934 /********* Mesh manipulation primitives begin here                   *********/
935 /**                                                                         **/
936 /**                                                                         **/
937 
938 /* Fast lookup arrays to speed some of the mesh manipulation primitives.     */
939 
940 int plus1mod3[3] = {1, 2, 0};
941 int minus1mod3[3] = {2, 0, 1};
942 
943 /********* Primitives for triangles                                  *********/
944 /*                                                                           */
945 /*                                                                           */
946 
947 /* decode() converts a pointer to an oriented triangle.  The orientation is  */
948 /*   extracted from the two least significant bits of the pointer.           */
949 
950 #define decode(ptr, otri)                                                     \
951   (otri).orient = (int) ((unsigned long) (ptr) & (unsigned long) 3l);         \
952   (otri).tri = (triangle *)                                                   \
953                   ((unsigned long) (ptr) ^ (unsigned long) (otri).orient)
954 
955 /* encode() compresses an oriented triangle into a single pointer.  It       */
956 /*   relies on the assumption that all triangles are aligned to four-byte    */
957 /*   boundaries, so the two least significant bits of (otri).tri are zero.   */
958 
959 #define encode(otri)                                                          \
960   (triangle) ((unsigned long) (otri).tri | (unsigned long) (otri).orient)
961 
962 /* The following handle manipulation primitives are all described by Guibas  */
963 /*   and Stolfi.  However, Guibas and Stolfi use an edge-based data          */
964 /*   structure, whereas I use a triangle-based data structure.               */
965 
966 /* sym() finds the abutting triangle, on the same edge.  Note that the edge  */
967 /*   direction is necessarily reversed, because the handle specified by an   */
968 /*   oriented triangle is directed counterclockwise around the triangle.     */
969 
970 #define sym(otri1, otri2)                                                     \
971   ptr = (otri1).tri[(otri1).orient];                                          \
972   decode(ptr, otri2);
973 
974 #define symself(otri)                                                         \
975   ptr = (otri).tri[(otri).orient];                                            \
976   decode(ptr, otri);
977 
978 /* lnext() finds the next edge (counterclockwise) of a triangle.             */
979 
980 #define lnext(otri1, otri2)                                                   \
981   (otri2).tri = (otri1).tri;                                                  \
982   (otri2).orient = plus1mod3[(otri1).orient]
983 
984 #define lnextself(otri)                                                       \
985   (otri).orient = plus1mod3[(otri).orient]
986 
987 /* lprev() finds the previous edge (clockwise) of a triangle.                */
988 
989 #define lprev(otri1, otri2)                                                   \
990   (otri2).tri = (otri1).tri;                                                  \
991   (otri2).orient = minus1mod3[(otri1).orient]
992 
993 #define lprevself(otri)                                                       \
994   (otri).orient = minus1mod3[(otri).orient]
995 
996 /* onext() spins counterclockwise around a vertex; that is, it finds the     */
997 /*   next edge with the same origin in the counterclockwise direction.  This */
998 /*   edge is part of a different triangle.                                   */
999 
1000 #define onext(otri1, otri2)                                                   \
1001   lprev(otri1, otri2);                                                        \
1002   symself(otri2);
1003 
1004 #define onextself(otri)                                                       \
1005   lprevself(otri);                                                            \
1006   symself(otri);
1007 
1008 /* oprev() spins clockwise around a vertex; that is, it finds the next edge  */
1009 /*   with the same origin in the clockwise direction.  This edge is part of  */
1010 /*   a different triangle.                                                   */
1011 
1012 #define oprev(otri1, otri2)                                                   \
1013   sym(otri1, otri2);                                                          \
1014   lnextself(otri2);
1015 
1016 #define oprevself(otri)                                                       \
1017   symself(otri);                                                              \
1018   lnextself(otri);
1019 
1020 /* dnext() spins counterclockwise around a vertex; that is, it finds the     */
1021 /*   next edge with the same destination in the counterclockwise direction.  */
1022 /*   This edge is part of a different triangle.                              */
1023 
1024 #define dnext(otri1, otri2)                                                   \
1025   sym(otri1, otri2);                                                          \
1026   lprevself(otri2);
1027 
1028 #define dnextself(otri)                                                       \
1029   symself(otri);                                                              \
1030   lprevself(otri);
1031 
1032 /* dprev() spins clockwise around a vertex; that is, it finds the next edge  */
1033 /*   with the same destination in the clockwise direction.  This edge is     */
1034 /*   part of a different triangle.                                           */
1035 
1036 #define dprev(otri1, otri2)                                                   \
1037   lnext(otri1, otri2);                                                        \
1038   symself(otri2);
1039 
1040 #define dprevself(otri)                                                       \
1041   lnextself(otri);                                                            \
1042   symself(otri);
1043 
1044 /* rnext() moves one edge counterclockwise about the adjacent triangle.      */
1045 /*   (It's best understood by reading Guibas and Stolfi.  It involves        */
1046 /*   changing triangles twice.)                                              */
1047 
1048 #define rnext(otri1, otri2)                                                   \
1049   sym(otri1, otri2);                                                          \
1050   lnextself(otri2);                                                           \
1051   symself(otri2);
1052 
1053 #define rnextself(otri)                                                       \
1054   symself(otri);                                                              \
1055   lnextself(otri);                                                            \
1056   symself(otri);
1057 
1058 /* rprev() moves one edge clockwise about the adjacent triangle.             */
1059 /*   (It's best understood by reading Guibas and Stolfi.  It involves        */
1060 /*   changing triangles twice.)                                              */
1061 
1062 #define rprev(otri1, otri2)                                                   \
1063   sym(otri1, otri2);                                                          \
1064   lprevself(otri2);                                                           \
1065   symself(otri2);
1066 
1067 #define rprevself(otri)                                                       \
1068   symself(otri);                                                              \
1069   lprevself(otri);                                                            \
1070   symself(otri);
1071 
1072 /* These primitives determine or set the origin, destination, or apex of a   */
1073 /* triangle.                                                                 */
1074 
1075 #define org(otri, vertexptr)                                                  \
1076   vertexptr = (vertex) (otri).tri[plus1mod3[(otri).orient] + 3]
1077 
1078 #define dest(otri, vertexptr)                                                 \
1079   vertexptr = (vertex) (otri).tri[minus1mod3[(otri).orient] + 3]
1080 
1081 #define apex(otri, vertexptr)                                                 \
1082   vertexptr = (vertex) (otri).tri[(otri).orient + 3]
1083 
1084 #define setorg(otri, vertexptr)                                               \
1085   (otri).tri[plus1mod3[(otri).orient] + 3] = (triangle) vertexptr
1086 
1087 #define setdest(otri, vertexptr)                                              \
1088   (otri).tri[minus1mod3[(otri).orient] + 3] = (triangle) vertexptr
1089 
1090 #define setapex(otri, vertexptr)                                              \
1091   (otri).tri[(otri).orient + 3] = (triangle) vertexptr
1092 
1093 /* Bond two triangles together.                                              */
1094 
1095 #define bond(otri1, otri2)                                                    \
1096   (otri1).tri[(otri1).orient] = encode(otri2);                                \
1097   (otri2).tri[(otri2).orient] = encode(otri1)
1098 
1099 /* Dissolve a bond (from one side).  Note that the other triangle will still */
1100 /*   think it's connected to this triangle.  Usually, however, the other     */
1101 /*   triangle is being deleted entirely, or bonded to another triangle, so   */
1102 /*   it doesn't matter.                                                      */
1103 
1104 #define dissolve(otri)                                                        \
1105   (otri).tri[(otri).orient] = (triangle) m->dummytri
1106 
1107 /* Copy an oriented triangle.                                                */
1108 
1109 #define otricopy(otri1, otri2)                                                \
1110   (otri2).tri = (otri1).tri;                                                  \
1111   (otri2).orient = (otri1).orient
1112 
1113 /* Test for equality of oriented triangles.                                  */
1114 
1115 #define otriequal(otri1, otri2)                                               \
1116   (((otri1).tri == (otri2).tri) &&                                            \
1117    ((otri1).orient == (otri2).orient))
1118 
1119 /* Primitives to infect or cure a triangle with the virus.  These rely on    */
1120 /*   the assumption that all subsegments are aligned to four-byte boundaries.*/
1121 
1122 #define infect(otri)                                                          \
1123   (otri).tri[6] = (triangle)                                                  \
1124                     ((unsigned long) (otri).tri[6] | (unsigned long) 2l)
1125 
1126 #define uninfect(otri)                                                        \
1127   (otri).tri[6] = (triangle)                                                  \
1128                     ((unsigned long) (otri).tri[6] & ~ (unsigned long) 2l)
1129 
1130 /* Test a triangle for viral infection.                                      */
1131 
1132 #define infected(otri)                                                        \
1133   (((unsigned long) (otri).tri[6] & (unsigned long) 2l) != 0l)
1134 
1135 /* Check or set a triangle's attributes.                                     */
1136 
1137 #define elemattribute(otri, attnum)                                           \
1138   ((REAL *) (otri).tri)[m->elemattribindex + (attnum)]
1139 
1140 #define setelemattribute(otri, attnum, value)                                 \
1141   ((REAL *) (otri).tri)[m->elemattribindex + (attnum)] = value
1142 
1143 /* Check or set a triangle's maximum area bound.                             */
1144 
1145 #define areabound(otri)  ((REAL *) (otri).tri)[m->areaboundindex]
1146 
1147 #define setareabound(otri, value)                                             \
1148   ((REAL *) (otri).tri)[m->areaboundindex] = value
1149 
1150 /* Check or set a triangle's deallocation.  Its second pointer is set to     */
1151 /*   NULL to indicate that it is not allocated.  (Its first pointer is used  */
1152 /*   for the stack of dead items.)  Its fourth pointer (its first vertex)    */
1153 /*   is set to NULL in case a `badtriang' structure points to it.            */
1154 
1155 #define deadtri(tria)  ((tria)[1] == (triangle) NULL)
1156 
1157 #define killtri(tria)                                                         \
1158   (tria)[1] = (triangle) NULL;                                                \
1159   (tria)[3] = (triangle) NULL
1160 
1161 /********* Primitives for subsegments                                *********/
1162 /*                                                                           */
1163 /*                                                                           */
1164 
1165 /* sdecode() converts a pointer to an oriented subsegment.  The orientation  */
1166 /*   is extracted from the least significant bit of the pointer.  The two    */
1167 /*   least significant bits (one for orientation, one for viral infection)   */
1168 /*   are masked out to produce the real pointer.                             */
1169 
1170 #define sdecode(sptr, osub)                                                   \
1171   (osub).ssorient = (int) ((unsigned long) (sptr) & (unsigned long) 1l);      \
1172   (osub).ss = (subseg *)                                                      \
1173               ((unsigned long) (sptr) & ~ (unsigned long) 3l)
1174 
1175 /* sencode() compresses an oriented subsegment into a single pointer.  It    */
1176 /*   relies on the assumption that all subsegments are aligned to two-byte   */
1177 /*   boundaries, so the least significant bit of (osub).ss is zero.          */
1178 
1179 #define sencode(osub)                                                         \
1180   (subseg) ((unsigned long) (osub).ss | (unsigned long) (osub).ssorient)
1181 
1182 /* ssym() toggles the orientation of a subsegment.                           */
1183 
1184 #define ssym(osub1, osub2)                                                    \
1185   (osub2).ss = (osub1).ss;                                                    \
1186   (osub2).ssorient = 1 - (osub1).ssorient
1187 
1188 #define ssymself(osub)                                                        \
1189   (osub).ssorient = 1 - (osub).ssorient
1190 
1191 /* spivot() finds the other subsegment (from the same segment) that shares   */
1192 /*   the same origin.                                                        */
1193 
1194 #define spivot(osub1, osub2)                                                  \
1195   sptr = (osub1).ss[(osub1).ssorient];                                        \
1196   sdecode(sptr, osub2)
1197 
1198 #define spivotself(osub)                                                      \
1199   sptr = (osub).ss[(osub).ssorient];                                          \
1200   sdecode(sptr, osub)
1201 
1202 /* snext() finds the next subsegment (from the same segment) in sequence;    */
1203 /*   one whose origin is the input subsegment's destination.                 */
1204 
1205 #define snext(osub1, osub2)                                                   \
1206   sptr = (osub1).ss[1 - (osub1).ssorient];                                    \
1207   sdecode(sptr, osub2)
1208 
1209 #define snextself(osub)                                                       \
1210   sptr = (osub).ss[1 - (osub).ssorient];                                      \
1211   sdecode(sptr, osub)
1212 
1213 /* These primitives determine or set the origin or destination of a          */
1214 /*   subsegment or the segment that includes it.                             */
1215 
1216 #define sorg(osub, vertexptr)                                                 \
1217   vertexptr = (vertex) (osub).ss[2 + (osub).ssorient]
1218 
1219 #define sdest(osub, vertexptr)                                                \
1220   vertexptr = (vertex) (osub).ss[3 - (osub).ssorient]
1221 
1222 #define setsorg(osub, vertexptr)                                              \
1223   (osub).ss[2 + (osub).ssorient] = (subseg) vertexptr
1224 
1225 #define setsdest(osub, vertexptr)                                             \
1226   (osub).ss[3 - (osub).ssorient] = (subseg) vertexptr
1227 
1228 #define segorg(osub, vertexptr)                                               \
1229   vertexptr = (vertex) (osub).ss[4 + (osub).ssorient]
1230 
1231 #define segdest(osub, vertexptr)                                              \
1232   vertexptr = (vertex) (osub).ss[5 - (osub).ssorient]
1233 
1234 #define setsegorg(osub, vertexptr)                                            \
1235   (osub).ss[4 + (osub).ssorient] = (subseg) vertexptr
1236 
1237 #define setsegdest(osub, vertexptr)                                           \
1238   (osub).ss[5 - (osub).ssorient] = (subseg) vertexptr
1239 
1240 /* These primitives read or set a boundary marker.  Boundary markers are     */
1241 /*   used to hold user-defined tags for setting boundary conditions in       */
1242 /*   finite element solvers.                                                 */
1243 
1244 #define mark(osub)  (* (int *) ((osub).ss + 8))
1245 
1246 #define setmark(osub, value)                                                  \
1247   * (int *) ((osub).ss + 8) = value
1248 
1249 /* Bond two subsegments together.                                            */
1250 
1251 #define sbond(osub1, osub2)                                                   \
1252   (osub1).ss[(osub1).ssorient] = sencode(osub2);                              \
1253   (osub2).ss[(osub2).ssorient] = sencode(osub1)
1254 
1255 /* Dissolve a subsegment bond (from one side).  Note that the other          */
1256 /*   subsegment will still think it's connected to this subsegment.          */
1257 
1258 #define sdissolve(osub)                                                       \
1259   (osub).ss[(osub).ssorient] = (subseg) m->dummysub
1260 
1261 /* Copy a subsegment.                                                        */
1262 
1263 #define subsegcopy(osub1, osub2)                                              \
1264   (osub2).ss = (osub1).ss;                                                    \
1265   (osub2).ssorient = (osub1).ssorient
1266 
1267 /* Test for equality of subsegments.                                         */
1268 
1269 #define subsegequal(osub1, osub2)                                             \
1270   (((osub1).ss == (osub2).ss) &&                                              \
1271    ((osub1).ssorient == (osub2).ssorient))
1272 
1273 /* Check or set a subsegment's deallocation.  Its second pointer is set to   */
1274 /*   NULL to indicate that it is not allocated.  (Its first pointer is used  */
1275 /*   for the stack of dead items.)  Its third pointer (its first vertex)     */
1276 /*   is set to NULL in case a `badsubseg' structure points to it.            */
1277 
1278 #define deadsubseg(sub)  ((sub)[1] == (subseg) NULL)
1279 
1280 #define killsubseg(sub)                                                       \
1281   (sub)[1] = (subseg) NULL;                                                   \
1282   (sub)[2] = (subseg) NULL
1283 
1284 /********* Primitives for interacting triangles and subsegments      *********/
1285 /*                                                                           */
1286 /*                                                                           */
1287 
1288 /* tspivot() finds a subsegment abutting a triangle.                         */
1289 
1290 #define tspivot(otri, osub)                                                   \
1291   sptr = (subseg) (otri).tri[6 + (otri).orient];                              \
1292   sdecode(sptr, osub)
1293 
1294 /* stpivot() finds a triangle abutting a subsegment.  It requires that the   */
1295 /*   variable `ptr' of type `triangle' be defined.                           */
1296 
1297 #define stpivot(osub, otri)                                                   \
1298   ptr = (triangle) (osub).ss[6 + (osub).ssorient];                            \
1299   decode(ptr, otri)
1300 
1301 /* Bond a triangle to a subsegment.                                          */
1302 
1303 #define tsbond(otri, osub)                                                    \
1304   (otri).tri[6 + (otri).orient] = (triangle) sencode(osub);                   \
1305   (osub).ss[6 + (osub).ssorient] = (subseg) encode(otri)
1306 
1307 /* Dissolve a bond (from the triangle side).                                 */
1308 
1309 #define tsdissolve(otri)                                                      \
1310   (otri).tri[6 + (otri).orient] = (triangle) m->dummysub
1311 
1312 /* Dissolve a bond (from the subsegment side).                               */
1313 
1314 #define stdissolve(osub)                                                      \
1315   (osub).ss[6 + (osub).ssorient] = (subseg) m->dummytri
1316 
1317 /********* Primitives for vertices                                   *********/
1318 /*                                                                           */
1319 /*                                                                           */
1320 
1321 #define vertexmark(vx)  ((int *) (vx))[m->vertexmarkindex]
1322 
1323 #define setvertexmark(vx, value)                                              \
1324   ((int *) (vx))[m->vertexmarkindex] = value
1325 
1326 #define vertextype(vx)  ((int *) (vx))[m->vertexmarkindex + 1]
1327 
1328 #define setvertextype(vx, value)                                              \
1329   ((int *) (vx))[m->vertexmarkindex + 1] = value
1330 
1331 #define vertex2tri(vx)  ((triangle *) (vx))[m->vertex2triindex]
1332 
1333 #define setvertex2tri(vx, value)                                              \
1334   ((triangle *) (vx))[m->vertex2triindex] = value
1335 
1336 /**                                                                         **/
1337 /**                                                                         **/
1338 /********* Mesh manipulation primitives end here                     *********/
1339 
1340 /********* User-defined triangle evaluation routine begins here      *********/
1341 /**                                                                         **/
1342 /**                                                                         **/
1343 
1344 /*****************************************************************************/
1345 /*                                                                           */
1346 /*  triunsuitable()   Determine if a triangle is unsuitable, and thus must   */
1347 /*                    be further refined.                                    */
1348 /*                                                                           */
1349 /*  You may write your own procedure that decides whether or not a selected  */
1350 /*  triangle is too big (and needs to be refined).  There are two ways to do */
1351 /*  this.                                                                    */
1352 /*                                                                           */
1353 /*  (1)  Modify the procedure `triunsuitable' below, then recompile          */
1354 /*  Triangle.                                                                */
1355 /*                                                                           */
1356 /*  (2)  Define the symbol EXTERNAL_TEST (either by adding the definition    */
1357 /*  to this file, or by using the appropriate compiler switch).  This way,   */
1358 /*  you can compile triangle.c separately from your test.  Write your own    */
1359 /*  `triunsuitable' procedure in a separate C file (using the same prototype */
1360 /*  as below).  Compile it and link the object code with triangle.o.         */
1361 /*                                                                           */
1362 /*  This procedure returns 1 if the triangle is too large and should be      */
1363 /*  refined; 0 otherwise.                                                    */
1364 /*                                                                           */
1365 /*****************************************************************************/
1366 
1367 #ifdef EXTERNAL_TEST
1368 
1369 int triunsuitable();
1370 
1371 #else /* not EXTERNAL_TEST */
1372 
1373 #ifdef ANSI_DECLARATORS
1374 int triunsuitable(vertex triorg, vertex tridest, vertex triapex, REAL area)
1375 #else /* not ANSI_DECLARATORS */
1376 int triunsuitable(triorg, tridest, triapex, area)
1377 vertex triorg;                              /* The triangle's origin vertex. */
1378 vertex tridest;                        /* The triangle's destination vertex. */
1379 vertex triapex;                               /* The triangle's apex vertex. */
1380 REAL area;                                      /* The area of the triangle. */
1381 #endif /* not ANSI_DECLARATORS */
1382 
1383 {
1384   REAL dxoa, dxda, dxod;
1385   REAL dyoa, dyda, dyod;
1386   REAL oalen, dalen, odlen;
1387   REAL maxlen;
1388 
1389   dxoa = triorg[0] - triapex[0];
1390   dyoa = triorg[1] - triapex[1];
1391   dxda = tridest[0] - triapex[0];
1392   dyda = tridest[1] - triapex[1];
1393   dxod = triorg[0] - tridest[0];
1394   dyod = triorg[1] - tridest[1];
1395   /* Find the squares of the lengths of the triangle's three edges. */
1396   oalen = dxoa * dxoa + dyoa * dyoa;
1397   dalen = dxda * dxda + dyda * dyda;
1398   odlen = dxod * dxod + dyod * dyod;
1399   /* Find the square of the length of the longest edge. */
1400   maxlen = (dalen > oalen) ? dalen : oalen;
1401   maxlen = (odlen > maxlen) ? odlen : maxlen;
1402 
1403   if (maxlen > 0.05 * (triorg[0] * triorg[0] + triorg[1] * triorg[1]) + 0.02) {
1404     return 1;
1405   } else {
1406     return 0;
1407   }
1408 }
1409 
1410 #endif /* not EXTERNAL_TEST */
1411 
1412 /**                                                                         **/
1413 /**                                                                         **/
1414 /********* User-defined triangle evaluation routine ends here        *********/
1415 
1416 /********* Memory allocation and program exit wrappers begin here    *********/
1417 /**                                                                         **/
1418 /**                                                                         **/
1419 
1420 #ifdef ANSI_DECLARATORS
1421 void triexit(int status)
1422 #else /* not ANSI_DECLARATORS */
1423 void triexit(status)
1424 int status;
1425 #endif /* not ANSI_DECLARATORS */
1426 
1427 {
1428   exit(status);
1429 }
1430 
1431 #ifdef ANSI_DECLARATORS
1432 VOID *trimalloc(int size)
1433 #else /* not ANSI_DECLARATORS */
1434 VOID *trimalloc(size)
1435 int size;
1436 #endif /* not ANSI_DECLARATORS */
1437 
1438 {
1439   VOID *memptr;
1440 
1441   memptr = (VOID *) malloc((unsigned int) size);
1442   if (memptr == (VOID *) NULL) {
1443     printf("Error:  Out of memory.\n");
1444     triexit(1);
1445   }
1446   return(memptr);
1447 }
1448 
1449 #ifdef ANSI_DECLARATORS
1450 void trifree(VOID *memptr)
1451 #else /* not ANSI_DECLARATORS */
1452 void trifree(memptr)
1453 VOID *memptr;
1454 #endif /* not ANSI_DECLARATORS */
1455 
1456 {
1457   free(memptr);
1458 }
1459 
1460 /**                                                                         **/
1461 /**                                                                         **/
1462 /********* Memory allocation and program exit wrappers end here      *********/
1463 
1464 /********* User interaction routines begin here                      *********/
1465 /**                                                                         **/
1466 /**                                                                         **/
1467 
1468 /*****************************************************************************/
1469 /*                                                                           */
1470 /*  syntax()   Print list of command line switches.                          */
1471 /*                                                                           */
1472 /*****************************************************************************/
1473 
1474 #ifndef TRILIBRARY
1475 
syntax()1476 void syntax()
1477 {
1478 #ifdef CDT_ONLY
1479 #ifdef REDUCED
1480   printf("triangle [-pAcjevngBPNEIOXzo_lQVh] input_file\n");
1481 #else /* not REDUCED */
1482   printf("triangle [-pAcjevngBPNEIOXzo_iFlCQVh] input_file\n");
1483 #endif /* not REDUCED */
1484 #else /* not CDT_ONLY */
1485 #ifdef REDUCED
1486   printf("triangle [-prq__a__uAcDjevngBPNEIOXzo_YS__lQVh] input_file\n");
1487 #else /* not REDUCED */
1488   printf("triangle [-prq__a__uAcDjevngBPNEIOXzo_YS__iFlsCQVh] input_file\n");
1489 #endif /* not REDUCED */
1490 #endif /* not CDT_ONLY */
1491 
1492   printf("    -p  Triangulates a Planar Straight Line Graph (.poly file).\n");
1493 #ifndef CDT_ONLY
1494   printf("    -r  Refines a previously generated mesh.\n");
1495   printf(
1496     "    -q  Quality mesh generation.  A minimum angle may be specified.\n");
1497   printf("    -a  Applies a maximum triangle area constraint.\n");
1498   printf("    -u  Applies a user-defined triangle constraint.\n");
1499 #endif /* not CDT_ONLY */
1500   printf(
1501     "    -A  Applies attributes to identify triangles in certain regions.\n");
1502   printf("    -c  Encloses the convex hull with segments.\n");
1503 #ifndef CDT_ONLY
1504   printf("    -D  Conforming Delaunay:  all triangles are truly Delaunay.\n");
1505 #endif /* not CDT_ONLY */
1506 /*
1507   printf("    -w  Weighted Delaunay triangulation.\n");
1508   printf("    -W  Regular triangulation (lower hull of a height field).\n");
1509 */
1510   printf("    -j  Jettison unused vertices from output .node file.\n");
1511   printf("    -e  Generates an edge list.\n");
1512   printf("    -v  Generates a Voronoi diagram.\n");
1513   printf("    -n  Generates a list of triangle neighbors.\n");
1514   printf("    -g  Generates an .off file for Geomview.\n");
1515   printf("    -B  Suppresses output of boundary information.\n");
1516   printf("    -P  Suppresses output of .poly file.\n");
1517   printf("    -N  Suppresses output of .node file.\n");
1518   printf("    -E  Suppresses output of .ele file.\n");
1519   printf("    -I  Suppresses mesh iteration numbers.\n");
1520   printf("    -O  Ignores holes in .poly file.\n");
1521   printf("    -X  Suppresses use of exact arithmetic.\n");
1522   printf("    -z  Numbers all items starting from zero (rather than one).\n");
1523   printf("    -o2 Generates second-order subparametric elements.\n");
1524 #ifndef CDT_ONLY
1525   printf("    -Y  Suppresses boundary segment splitting.\n");
1526   printf("    -S  Specifies maximum number of added Steiner points.\n");
1527 #endif /* not CDT_ONLY */
1528 #ifndef REDUCED
1529   printf("    -i  Uses incremental method, rather than divide-and-conquer.\n");
1530   printf("    -F  Uses Fortune's sweepline algorithm, rather than d-and-c.\n");
1531 #endif /* not REDUCED */
1532   printf("    -l  Uses vertical cuts only, rather than alternating cuts.\n");
1533 #ifndef REDUCED
1534 #ifndef CDT_ONLY
1535   printf(
1536     "    -s  Force segments into mesh by splitting (instead of using CDT).\n");
1537 #endif /* not CDT_ONLY */
1538   printf("    -C  Check consistency of final mesh.\n");
1539 #endif /* not REDUCED */
1540   printf("    -Q  Quiet:  No terminal output except errors.\n");
1541   printf("    -V  Verbose:  Detailed information on what I'm doing.\n");
1542   printf("    -h  Help:  Detailed instructions for Triangle.\n");
1543   triexit(0);
1544 }
1545 
1546 #endif /* not TRILIBRARY */
1547 
1548 /*****************************************************************************/
1549 /*                                                                           */
1550 /*  info()   Print out complete instructions.                                */
1551 /*                                                                           */
1552 /*****************************************************************************/
1553 
1554 #ifndef TRILIBRARY
1555 
info()1556 void info()
1557 {
1558   printf("Triangle\n");
1559   printf(
1560 "A Two-Dimensional Quality Mesh Generator and Delaunay Triangulator.\n");
1561   printf("Version 1.6\n\n");
1562   printf(
1563 "Copyright 1993, 1995, 1997, 1998, 2002, 2005 Jonathan Richard Shewchuk\n");
1564   printf("2360 Woolsey #H / Berkeley, California 94705-1927\n");
1565   printf("Bugs/comments to jrs@cs.berkeley.edu\n");
1566   printf(
1567 "Created as part of the Quake project (tools for earthquake simulation).\n");
1568   printf(
1569 "Supported in part by NSF Grant CMS-9318163 and an NSERC 1967 Scholarship.\n");
1570   printf("There is no warranty whatsoever.  Use at your own risk.\n");
1571 #ifdef SINGLE
1572   printf("This executable is compiled for single precision arithmetic.\n\n\n");
1573 #else /* not SINGLE */
1574   printf("This executable is compiled for double precision arithmetic.\n\n\n");
1575 #endif /* not SINGLE */
1576   printf(
1577 "Triangle generates exact Delaunay triangulations, constrained Delaunay\n");
1578   printf(
1579 "triangulations, conforming Delaunay triangulations, Voronoi diagrams, and\n");
1580   printf(
1581 "high-quality triangular meshes.  The latter can be generated with no small\n"
1582 );
1583   printf(
1584 "or large angles, and are thus suitable for finite element analysis.  If no\n"
1585 );
1586   printf(
1587 "command line switch is specified, your .node input file is read, and the\n");
1588   printf(
1589 "Delaunay triangulation is returned in .node and .ele output files.  The\n");
1590   printf("command syntax is:\n\n");
1591   printf("triangle [-prq__a__uAcDjevngBPNEIOXzo_YS__iFlsCQVh] input_file\n\n");
1592   printf(
1593 "Underscores indicate that numbers may optionally follow certain switches.\n");
1594   printf(
1595 "Do not leave any space between a switch and its numeric parameter.\n");
1596   printf(
1597 "input_file must be a file with extension .node, or extension .poly if the\n");
1598   printf(
1599 "-p switch is used.  If -r is used, you must supply .node and .ele files,\n");
1600   printf(
1601 "and possibly a .poly file and an .area file as well.  The formats of these\n"
1602 );
1603   printf("files are described below.\n\n");
1604   printf("Command Line Switches:\n\n");
1605   printf(
1606 "    -p  Reads a Planar Straight Line Graph (.poly file), which can specify\n"
1607 );
1608   printf(
1609 "        vertices, segments, holes, regional attributes, and regional area\n");
1610   printf(
1611 "        constraints.  Generates a constrained Delaunay triangulation (CDT)\n"
1612 );
1613   printf(
1614 "        fitting the input; or, if -s, -q, -a, or -u is used, a conforming\n");
1615   printf(
1616 "        constrained Delaunay triangulation (CCDT).  If you want a truly\n");
1617   printf(
1618 "        Delaunay (not just constrained Delaunay) triangulation, use -D as\n");
1619   printf(
1620 "        well.  When -p is not used, Triangle reads a .node file by default.\n"
1621 );
1622   printf(
1623 "    -r  Refines a previously generated mesh.  The mesh is read from a .node\n"
1624 );
1625   printf(
1626 "        file and an .ele file.  If -p is also used, a .poly file is read\n");
1627   printf(
1628 "        and used to constrain segments in the mesh.  If -a is also used\n");
1629   printf(
1630 "        (with no number following), an .area file is read and used to\n");
1631   printf(
1632 "        impose area constraints on the mesh.  Further details on refinement\n"
1633 );
1634   printf("        appear below.\n");
1635   printf(
1636 "    -q  Quality mesh generation by Delaunay refinement (a hybrid of Paul\n");
1637   printf(
1638 "        Chew's and Jim Ruppert's algorithms).  Adds vertices to the mesh to\n"
1639 );
1640   printf(
1641 "        ensure that all angles are between 20 and 140 degrees.  An\n");
1642   printf(
1643 "        alternative bound on the minimum angle, replacing 20 degrees, may\n");
1644   printf(
1645 "        be specified after the `q'.  The specified angle may include a\n");
1646   printf(
1647 "        decimal point, but not exponential notation.  Note that a bound of\n"
1648 );
1649   printf(
1650 "        theta degrees on the smallest angle also implies a bound of\n");
1651   printf(
1652 "        (180 - 2 theta) on the largest angle.  If the minimum angle is 28.6\n"
1653 );
1654   printf(
1655 "        degrees or smaller, Triangle is mathematically guaranteed to\n");
1656   printf(
1657 "        terminate (assuming infinite precision arithmetic--Triangle may\n");
1658   printf(
1659 "        fail to terminate if you run out of precision).  In practice,\n");
1660   printf(
1661 "        Triangle often succeeds for minimum angles up to 34 degrees.  For\n");
1662   printf(
1663 "        some meshes, however, you might need to reduce the minimum angle to\n"
1664 );
1665   printf(
1666 "        avoid problems associated with insufficient floating-point\n");
1667   printf("        precision.\n");
1668   printf(
1669 "    -a  Imposes a maximum triangle area.  If a number follows the `a', no\n");
1670   printf(
1671 "        triangle is generated whose area is larger than that number.  If no\n"
1672 );
1673   printf(
1674 "        number is specified, an .area file (if -r is used) or .poly file\n");
1675   printf(
1676 "        (if -r is not used) specifies a set of maximum area constraints.\n");
1677   printf(
1678 "        An .area file contains a separate area constraint for each\n");
1679   printf(
1680 "        triangle, and is useful for refining a finite element mesh based on\n"
1681 );
1682   printf(
1683 "        a posteriori error estimates.  A .poly file can optionally contain\n"
1684 );
1685   printf(
1686 "        an area constraint for each segment-bounded region, thereby\n");
1687   printf(
1688 "        controlling triangle densities in a first triangulation of a PSLG.\n"
1689 );
1690   printf(
1691 "        You can impose both a fixed area constraint and a varying area\n");
1692   printf(
1693 "        constraint by invoking the -a switch twice, once with and once\n");
1694   printf(
1695 "        without a number following.  Each area specified may include a\n");
1696   printf("        decimal point.\n");
1697   printf(
1698 "    -u  Imposes a user-defined constraint on triangle size.  There are two\n"
1699 );
1700   printf(
1701 "        ways to use this feature.  One is to edit the triunsuitable()\n");
1702   printf(
1703 "        procedure in triangle.c to encode any constraint you like, then\n");
1704   printf(
1705 "        recompile Triangle.  The other is to compile triangle.c with the\n");
1706   printf(
1707 "        EXTERNAL_TEST symbol set (compiler switch -DEXTERNAL_TEST), then\n");
1708   printf(
1709 "        link Triangle with a separate object file that implements\n");
1710   printf(
1711 "        triunsuitable().  In either case, the -u switch causes the user-\n");
1712   printf("        defined test to be applied to every triangle.\n");
1713   printf(
1714 "    -A  Assigns an additional floating-point attribute to each triangle\n");
1715   printf(
1716 "        that identifies what segment-bounded region each triangle belongs\n");
1717   printf(
1718 "        to.  Attributes are assigned to regions by the .poly file.  If a\n");
1719   printf(
1720 "        region is not explicitly marked by the .poly file, triangles in\n");
1721   printf(
1722 "        that region are assigned an attribute of zero.  The -A switch has\n");
1723   printf(
1724 "        an effect only when the -p switch is used and the -r switch is not.\n"
1725 );
1726   printf(
1727 "    -c  Creates segments on the convex hull of the triangulation.  If you\n");
1728   printf(
1729 "        are triangulating a vertex set, this switch causes a .poly file to\n"
1730 );
1731   printf(
1732 "        be written, containing all edges of the convex hull.  If you are\n");
1733   printf(
1734 "        triangulating a PSLG, this switch specifies that the whole convex\n");
1735   printf(
1736 "        hull of the PSLG should be triangulated, regardless of what\n");
1737   printf(
1738 "        segments the PSLG has.  If you do not use this switch when\n");
1739   printf(
1740 "        triangulating a PSLG, Triangle assumes that you have identified the\n"
1741 );
1742   printf(
1743 "        region to be triangulated by surrounding it with segments of the\n");
1744   printf(
1745 "        input PSLG.  Beware:  if you are not careful, this switch can cause\n"
1746 );
1747   printf(
1748 "        the introduction of an extremely thin angle between a PSLG segment\n"
1749 );
1750   printf(
1751 "        and a convex hull segment, which can cause overrefinement (and\n");
1752   printf(
1753 "        possibly failure if Triangle runs out of precision).  If you are\n");
1754   printf(
1755 "        refining a mesh, the -c switch works differently:  it causes a\n");
1756   printf(
1757 "        .poly file to be written containing the boundary edges of the mesh\n"
1758 );
1759   printf("        (useful if no .poly file was read).\n");
1760   printf(
1761 "    -D  Conforming Delaunay triangulation:  use this switch if you want to\n"
1762 );
1763   printf(
1764 "        ensure that all the triangles in the mesh are Delaunay, and not\n");
1765   printf(
1766 "        merely constrained Delaunay; or if you want to ensure that all the\n"
1767 );
1768   printf(
1769 "        Voronoi vertices lie within the triangulation.  (Some finite volume\n"
1770 );
1771   printf(
1772 "        methods have this requirement.)  This switch invokes Ruppert's\n");
1773   printf(
1774 "        original algorithm, which splits every subsegment whose diametral\n");
1775   printf(
1776 "        circle is encroached.  It usually increases the number of vertices\n"
1777 );
1778   printf("        and triangles.\n");
1779   printf(
1780 "    -j  Jettisons vertices that are not part of the final triangulation\n");
1781   printf(
1782 "        from the output .node file.  By default, Triangle copies all\n");
1783   printf(
1784 "        vertices in the input .node file to the output .node file, in the\n");
1785   printf(
1786 "        same order, so their indices do not change.  The -j switch prevents\n"
1787 );
1788   printf(
1789 "        duplicated input vertices, or vertices `eaten' by holes, from\n");
1790   printf(
1791 "        appearing in the output .node file.  Thus, if two input vertices\n");
1792   printf(
1793 "        have exactly the same coordinates, only the first appears in the\n");
1794   printf(
1795 "        output.  If any vertices are jettisoned, the vertex numbering in\n");
1796   printf(
1797 "        the output .node file differs from that of the input .node file.\n");
1798   printf(
1799 "    -e  Outputs (to an .edge file) a list of edges of the triangulation.\n");
1800   printf(
1801 "    -v  Outputs the Voronoi diagram associated with the triangulation.\n");
1802   printf(
1803 "        Does not attempt to detect degeneracies, so some Voronoi vertices\n");
1804   printf(
1805 "        may be duplicated.  See the discussion of Voronoi diagrams below.\n");
1806   printf(
1807 "    -n  Outputs (to a .neigh file) a list of triangles neighboring each\n");
1808   printf("        triangle.\n");
1809   printf(
1810 "    -g  Outputs the mesh to an Object File Format (.off) file, suitable for\n"
1811 );
1812   printf("        viewing with the Geometry Center's Geomview package.\n");
1813   printf(
1814 "    -B  No boundary markers in the output .node, .poly, and .edge output\n");
1815   printf(
1816 "        files.  See the detailed discussion of boundary markers below.\n");
1817   printf(
1818 "    -P  No output .poly file.  Saves disk space, but you lose the ability\n");
1819   printf(
1820 "        to maintain constraining segments on later refinements of the mesh.\n"
1821 );
1822   printf("    -N  No output .node file.\n");
1823   printf("    -E  No output .ele file.\n");
1824   printf(
1825 "    -I  No iteration numbers.  Suppresses the output of .node and .poly\n");
1826   printf(
1827 "        files, so your input files won't be overwritten.  (If your input is\n"
1828 );
1829   printf(
1830 "        a .poly file only, a .node file is written.)  Cannot be used with\n");
1831   printf(
1832 "        the -r switch, because that would overwrite your input .ele file.\n");
1833   printf(
1834 "        Shouldn't be used with the -q, -a, -u, or -s switch if you are\n");
1835   printf(
1836 "        using a .node file for input, because no .node file is written, so\n"
1837 );
1838   printf("        there is no record of any added Steiner points.\n");
1839   printf("    -O  No holes.  Ignores the holes in the .poly file.\n");
1840   printf(
1841 "    -X  No exact arithmetic.  Normally, Triangle uses exact floating-point\n"
1842 );
1843   printf(
1844 "        arithmetic for certain tests if it thinks the inexact tests are not\n"
1845 );
1846   printf(
1847 "        accurate enough.  Exact arithmetic ensures the robustness of the\n");
1848   printf(
1849 "        triangulation algorithms, despite floating-point roundoff error.\n");
1850   printf(
1851 "        Disabling exact arithmetic with the -X switch causes a small\n");
1852   printf(
1853 "        improvement in speed and creates the possibility that Triangle will\n"
1854 );
1855   printf("        fail to produce a valid mesh.  Not recommended.\n");
1856   printf(
1857 "    -z  Numbers all items starting from zero (rather than one).  Note that\n"
1858 );
1859   printf(
1860 "        this switch is normally overridden by the value used to number the\n"
1861 );
1862   printf(
1863 "        first vertex of the input .node or .poly file.  However, this\n");
1864   printf(
1865 "        switch is useful when calling Triangle from another program.\n");
1866   printf(
1867 "    -o2 Generates second-order subparametric elements with six nodes each.\n"
1868 );
1869   printf(
1870 "    -Y  No new vertices on the boundary.  This switch is useful when the\n");
1871   printf(
1872 "        mesh boundary must be preserved so that it conforms to some\n");
1873   printf(
1874 "        adjacent mesh.  Be forewarned that you will probably sacrifice much\n"
1875 );
1876   printf(
1877 "        of the quality of the mesh; Triangle will try, but the resulting\n");
1878   printf(
1879 "        mesh may contain poorly shaped triangles.  Works well if all the\n");
1880   printf(
1881 "        boundary vertices are closely spaced.  Specify this switch twice\n");
1882   printf(
1883 "        (`-YY') to prevent all segment splitting, including internal\n");
1884   printf("        boundaries.\n");
1885   printf(
1886 "    -S  Specifies the maximum number of Steiner points (vertices that are\n");
1887   printf(
1888 "        not in the input, but are added to meet the constraints on minimum\n"
1889 );
1890   printf(
1891 "        angle and maximum area).  The default is to allow an unlimited\n");
1892   printf(
1893 "        number.  If you specify this switch with no number after it,\n");
1894   printf(
1895 "        the limit is set to zero.  Triangle always adds vertices at segment\n"
1896 );
1897   printf(
1898 "        intersections, even if it needs to use more vertices than the limit\n"
1899 );
1900   printf(
1901 "        you set.  When Triangle inserts segments by splitting (-s), it\n");
1902   printf(
1903 "        always adds enough vertices to ensure that all the segments of the\n"
1904 );
1905   printf("        PLSG are recovered, ignoring the limit if necessary.\n");
1906   printf(
1907 "    -i  Uses an incremental rather than a divide-and-conquer algorithm to\n");
1908   printf(
1909 "        construct a Delaunay triangulation.  Try it if the divide-and-\n");
1910   printf("        conquer algorithm fails.\n");
1911   printf(
1912 "    -F  Uses Steven Fortune's sweepline algorithm to construct a Delaunay\n");
1913   printf(
1914 "        triangulation.  Warning:  does not use exact arithmetic for all\n");
1915   printf("        calculations.  An exact result is not guaranteed.\n");
1916   printf(
1917 "    -l  Uses only vertical cuts in the divide-and-conquer algorithm.  By\n");
1918   printf(
1919 "        default, Triangle alternates between vertical and horizontal cuts,\n"
1920 );
1921   printf(
1922 "        which usually improve the speed except with vertex sets that are\n");
1923   printf(
1924 "        small or short and wide.  This switch is primarily of theoretical\n");
1925   printf("        interest.\n");
1926   printf(
1927 "    -s  Specifies that segments should be forced into the triangulation by\n"
1928 );
1929   printf(
1930 "        recursively splitting them at their midpoints, rather than by\n");
1931   printf(
1932 "        generating a constrained Delaunay triangulation.  Segment splitting\n"
1933 );
1934   printf(
1935 "        is true to Ruppert's original algorithm, but can create needlessly\n"
1936 );
1937   printf(
1938 "        small triangles.  This switch is primarily of theoretical interest.\n"
1939 );
1940   printf(
1941 "    -C  Check the consistency of the final mesh.  Uses exact arithmetic for\n"
1942 );
1943   printf(
1944 "        checking, even if the -X switch is used.  Useful if you suspect\n");
1945   printf("        Triangle is buggy.\n");
1946   printf(
1947 "    -Q  Quiet:  Suppresses all explanation of what Triangle is doing,\n");
1948   printf("        unless an error occurs.\n");
1949   printf(
1950 "    -V  Verbose:  Gives detailed information about what Triangle is doing.\n"
1951 );
1952   printf(
1953 "        Add more `V's for increasing amount of detail.  `-V' is most\n");
1954   printf(
1955 "        useful; itgives information on algorithmic progress and much more\n");
1956   printf(
1957 "        detailed statistics.  `-VV' gives vertex-by-vertex details, and\n");
1958   printf(
1959 "        prints so much that Triangle runs much more slowly.  `-VVVV' gives\n"
1960 );
1961   printf("        information only a debugger could love.\n");
1962   printf("    -h  Help:  Displays these instructions.\n");
1963   printf("\n");
1964   printf("Definitions:\n");
1965   printf("\n");
1966   printf(
1967 "  A Delaunay triangulation of a vertex set is a triangulation whose\n");
1968   printf(
1969 "  vertices are the vertex set, that covers the convex hull of the vertex\n");
1970   printf(
1971 "  set.  A Delaunay triangulation has the property that no vertex lies\n");
1972   printf(
1973 "  inside the circumscribing circle (circle that passes through all three\n");
1974   printf("  vertices) of any triangle in the triangulation.\n\n");
1975   printf(
1976 "  A Voronoi diagram of a vertex set is a subdivision of the plane into\n");
1977   printf(
1978 "  polygonal cells (some of which may be unbounded, meaning infinitely\n");
1979   printf(
1980 "  large), where each cell is the set of points in the plane that are closer\n"
1981 );
1982   printf(
1983 "  to some input vertex than to any other input vertex.  The Voronoi diagram\n"
1984 );
1985   printf("  is a geometric dual of the Delaunay triangulation.\n\n");
1986   printf(
1987 "  A Planar Straight Line Graph (PSLG) is a set of vertices and segments.\n");
1988   printf(
1989 "  Segments are simply edges, whose endpoints are all vertices in the PSLG.\n"
1990 );
1991   printf(
1992 "  Segments may intersect each other only at their endpoints.  The file\n");
1993   printf("  format for PSLGs (.poly files) is described below.\n\n");
1994   printf(
1995 "  A constrained Delaunay triangulation (CDT) of a PSLG is similar to a\n");
1996   printf(
1997 "  Delaunay triangulation, but each PSLG segment is present as a single edge\n"
1998 );
1999   printf(
2000 "  of the CDT.  (A constrained Delaunay triangulation is not truly a\n");
2001   printf(
2002 "  Delaunay triangulation, because some of its triangles might not be\n");
2003   printf(
2004 "  Delaunay.)  By definition, a CDT does not have any vertices other than\n");
2005   printf(
2006 "  those specified in the input PSLG.  Depending on context, a CDT might\n");
2007   printf(
2008 "  cover the convex hull of the PSLG, or it might cover only a segment-\n");
2009   printf("  bounded region (e.g. a polygon).\n\n");
2010   printf(
2011 "  A conforming Delaunay triangulation of a PSLG is a triangulation in which\n"
2012 );
2013   printf(
2014 "  each triangle is truly Delaunay, and each PSLG segment is represented by\n"
2015 );
2016   printf(
2017 "  a linear contiguous sequence of edges of the triangulation.  New vertices\n"
2018 );
2019   printf(
2020 "  (not part of the PSLG) may appear, and each input segment may have been\n");
2021   printf(
2022 "  subdivided into shorter edges (subsegments) by these additional vertices.\n"
2023 );
2024   printf(
2025 "  The new vertices are frequently necessary to maintain the Delaunay\n");
2026   printf("  property while ensuring that every segment is represented.\n\n");
2027   printf(
2028 "  A conforming constrained Delaunay triangulation (CCDT) of a PSLG is a\n");
2029   printf(
2030 "  triangulation of a PSLG whose triangles are constrained Delaunay.  New\n");
2031   printf("  vertices may appear, and input segments may be subdivided into\n");
2032   printf(
2033 "  subsegments, but not to guarantee that segments are respected; rather, to\n"
2034 );
2035   printf(
2036 "  improve the quality of the triangles.  The high-quality meshes produced\n");
2037   printf(
2038 "  by the -q switch are usually CCDTs, but can be made conforming Delaunay\n");
2039   printf("  with the -D switch.\n\n");
2040   printf("File Formats:\n\n");
2041   printf(
2042 "  All files may contain comments prefixed by the character '#'.  Vertices,\n"
2043 );
2044   printf(
2045 "  triangles, edges, holes, and maximum area constraints must be numbered\n");
2046   printf(
2047 "  consecutively, starting from either 1 or 0.  Whichever you choose, all\n");
2048   printf(
2049 "  input files must be consistent; if the vertices are numbered from 1, so\n");
2050   printf(
2051 "  must be all other objects.  Triangle automatically detects your choice\n");
2052   printf(
2053 "  while reading the .node (or .poly) file.  (When calling Triangle from\n");
2054   printf(
2055 "  another program, use the -z switch if you wish to number objects from\n");
2056   printf("  zero.)  Examples of these file formats are given below.\n\n");
2057   printf("  .node files:\n");
2058   printf(
2059 "    First line:  <# of vertices> <dimension (must be 2)> <# of attributes>\n"
2060 );
2061   printf(
2062 "                                           <# of boundary markers (0 or 1)>\n"
2063 );
2064   printf(
2065 "    Remaining lines:  <vertex #> <x> <y> [attributes] [boundary marker]\n");
2066   printf("\n");
2067   printf(
2068 "    The attributes, which are typically floating-point values of physical\n");
2069   printf(
2070 "    quantities (such as mass or conductivity) associated with the nodes of\n"
2071 );
2072   printf(
2073 "    a finite element mesh, are copied unchanged to the output mesh.  If -q,\n"
2074 );
2075   printf(
2076 "    -a, -u, -D, or -s is selected, each new Steiner point added to the mesh\n"
2077 );
2078   printf("    has attributes assigned to it by linear interpolation.\n\n");
2079   printf(
2080 "    If the fourth entry of the first line is `1', the last column of the\n");
2081   printf(
2082 "    remainder of the file is assumed to contain boundary markers.  Boundary\n"
2083 );
2084   printf(
2085 "    markers are used to identify boundary vertices and vertices resting on\n"
2086 );
2087   printf(
2088 "    PSLG segments; a complete description appears in a section below.  The\n"
2089 );
2090   printf(
2091 "    .node file produced by Triangle contains boundary markers in the last\n");
2092   printf("    column unless they are suppressed by the -B switch.\n\n");
2093   printf("  .ele files:\n");
2094   printf(
2095 "    First line:  <# of triangles> <nodes per triangle> <# of attributes>\n");
2096   printf(
2097 "    Remaining lines:  <triangle #> <node> <node> <node> ... [attributes]\n");
2098   printf("\n");
2099   printf(
2100 "    Nodes are indices into the corresponding .node file.  The first three\n");
2101   printf(
2102 "    nodes are the corner vertices, and are listed in counterclockwise order\n"
2103 );
2104   printf(
2105 "    around each triangle.  (The remaining nodes, if any, depend on the type\n"
2106 );
2107   printf("    of finite element used.)\n\n");
2108   printf(
2109 "    The attributes are just like those of .node files.  Because there is no\n"
2110 );
2111   printf(
2112 "    simple mapping from input to output triangles, Triangle attempts to\n");
2113   printf(
2114 "    interpolate attributes, and may cause a lot of diffusion of attributes\n"
2115 );
2116   printf(
2117 "    among nearby triangles as the triangulation is refined.  Attributes do\n"
2118 );
2119   printf("    not diffuse across segments, so attributes used to identify\n");
2120   printf("    segment-bounded regions remain intact.\n\n");
2121   printf(
2122 "    In .ele files produced by Triangle, each triangular element has three\n");
2123   printf(
2124 "    nodes (vertices) unless the -o2 switch is used, in which case\n");
2125   printf(
2126 "    subparametric quadratic elements with six nodes each are generated.\n");
2127   printf(
2128 "    The first three nodes are the corners in counterclockwise order, and\n");
2129   printf(
2130 "    the fourth, fifth, and sixth nodes lie on the midpoints of the edges\n");
2131   printf(
2132 "    opposite the first, second, and third vertices, respectively.\n");
2133   printf("\n");
2134   printf("  .poly files:\n");
2135   printf(
2136 "    First line:  <# of vertices> <dimension (must be 2)> <# of attributes>\n"
2137 );
2138   printf(
2139 "                                           <# of boundary markers (0 or 1)>\n"
2140 );
2141   printf(
2142 "    Following lines:  <vertex #> <x> <y> [attributes] [boundary marker]\n");
2143   printf("    One line:  <# of segments> <# of boundary markers (0 or 1)>\n");
2144   printf(
2145 "    Following lines:  <segment #> <endpoint> <endpoint> [boundary marker]\n");
2146   printf("    One line:  <# of holes>\n");
2147   printf("    Following lines:  <hole #> <x> <y>\n");
2148   printf(
2149 "    Optional line:  <# of regional attributes and/or area constraints>\n");
2150   printf(
2151 "    Optional following lines:  <region #> <x> <y> <attribute> <max area>\n");
2152   printf("\n");
2153   printf(
2154 "    A .poly file represents a PSLG, as well as some additional information.\n"
2155 );
2156   printf(
2157 "    The first section lists all the vertices, and is identical to the\n");
2158   printf(
2159 "    format of .node files.  <# of vertices> may be set to zero to indicate\n"
2160 );
2161   printf(
2162 "    that the vertices are listed in a separate .node file; .poly files\n");
2163   printf(
2164 "    produced by Triangle always have this format.  A vertex set represented\n"
2165 );
2166   printf(
2167 "    this way has the advantage that it may easily be triangulated with or\n");
2168   printf(
2169 "    without segments (depending on whether the -p switch is invoked).\n");
2170   printf("\n");
2171   printf(
2172 "    The second section lists the segments.  Segments are edges whose\n");
2173   printf(
2174 "    presence in the triangulation is enforced.  (Depending on the choice of\n"
2175 );
2176   printf(
2177 "    switches, segment might be subdivided into smaller edges).  Each\n");
2178   printf(
2179 "    segment is specified by listing the indices of its two endpoints.  This\n"
2180 );
2181   printf(
2182 "    means that you must include its endpoints in the vertex list.  Each\n");
2183   printf("    segment, like each point, may have a boundary marker.\n\n");
2184   printf(
2185 "    If -q, -a, -u, and -s are not selected, Triangle produces a constrained\n"
2186 );
2187   printf(
2188 "    Delaunay triangulation (CDT), in which each segment appears as a single\n"
2189 );
2190   printf(
2191 "    edge in the triangulation.  If -q, -a, -u, or -s is selected, Triangle\n"
2192 );
2193   printf(
2194 "    produces a conforming constrained Delaunay triangulation (CCDT), in\n");
2195   printf(
2196 "    which segments may be subdivided into smaller edges.  If -D is\n");
2197   printf(
2198 "    selected, Triangle produces a conforming Delaunay triangulation, so\n");
2199   printf(
2200 "    that every triangle is Delaunay, and not just constrained Delaunay.\n");
2201   printf("\n");
2202   printf(
2203 "    The third section lists holes (and concavities, if -c is selected) in\n");
2204   printf(
2205 "    the triangulation.  Holes are specified by identifying a point inside\n");
2206   printf(
2207 "    each hole.  After the triangulation is formed, Triangle creates holes\n");
2208   printf(
2209 "    by eating triangles, spreading out from each hole point until its\n");
2210   printf(
2211 "    progress is blocked by segments in the PSLG.  You must be careful to\n");
2212   printf(
2213 "    enclose each hole in segments, or your whole triangulation might be\n");
2214   printf(
2215 "    eaten away.  If the two triangles abutting a segment are eaten, the\n");
2216   printf(
2217 "    segment itself is also eaten.  Do not place a hole directly on a\n");
2218   printf("    segment; if you do, Triangle chooses one side of the segment\n");
2219   printf("    arbitrarily.\n\n");
2220   printf(
2221 "    The optional fourth section lists regional attributes (to be assigned\n");
2222   printf(
2223 "    to all triangles in a region) and regional constraints on the maximum\n");
2224   printf(
2225 "    triangle area.  Triangle reads this section only if the -A switch is\n");
2226   printf(
2227 "    used or the -a switch is used without a number following it, and the -r\n"
2228 );
2229   printf(
2230 "    switch is not used.  Regional attributes and area constraints are\n");
2231   printf(
2232 "    propagated in the same manner as holes:  you specify a point for each\n");
2233   printf(
2234 "    attribute and/or constraint, and the attribute and/or constraint\n");
2235   printf(
2236 "    affects the whole region (bounded by segments) containing the point.\n");
2237   printf(
2238 "    If two values are written on a line after the x and y coordinate, the\n");
2239   printf(
2240 "    first such value is assumed to be a regional attribute (but is only\n");
2241   printf(
2242 "    applied if the -A switch is selected), and the second value is assumed\n"
2243 );
2244   printf(
2245 "    to be a regional area constraint (but is only applied if the -a switch\n"
2246 );
2247   printf(
2248 "    is selected).  You may specify just one value after the coordinates,\n");
2249   printf(
2250 "    which can serve as both an attribute and an area constraint, depending\n"
2251 );
2252   printf(
2253 "    on the choice of switches.  If you are using the -A and -a switches\n");
2254   printf(
2255 "    simultaneously and wish to assign an attribute to some region without\n");
2256   printf("    imposing an area constraint, use a negative maximum area.\n\n");
2257   printf(
2258 "    When a triangulation is created from a .poly file, you must either\n");
2259   printf(
2260 "    enclose the entire region to be triangulated in PSLG segments, or\n");
2261   printf(
2262 "    use the -c switch, which automatically creates extra segments that\n");
2263   printf(
2264 "    enclose the convex hull of the PSLG.  If you do not use the -c switch,\n"
2265 );
2266   printf(
2267 "    Triangle eats all triangles that are not enclosed by segments; if you\n");
2268   printf(
2269 "    are not careful, your whole triangulation may be eaten away.  If you do\n"
2270 );
2271   printf(
2272 "    use the -c switch, you can still produce concavities by the appropriate\n"
2273 );
2274   printf(
2275 "    placement of holes just inside the boundary of the convex hull.\n");
2276   printf("\n");
2277   printf(
2278 "    An ideal PSLG has no intersecting segments, nor any vertices that lie\n");
2279   printf(
2280 "    upon segments (except, of course, the endpoints of each segment).  You\n"
2281 );
2282   printf(
2283 "    aren't required to make your .poly files ideal, but you should be aware\n"
2284 );
2285   printf(
2286 "    of what can go wrong.  Segment intersections are relatively safe--\n");
2287   printf(
2288 "    Triangle calculates the intersection points for you and adds them to\n");
2289   printf(
2290 "    the triangulation--as long as your machine's floating-point precision\n");
2291   printf(
2292 "    doesn't become a problem.  You are tempting the fates if you have three\n"
2293 );
2294   printf(
2295 "    segments that cross at the same location, and expect Triangle to figure\n"
2296 );
2297   printf(
2298 "    out where the intersection point is.  Thanks to floating-point roundoff\n"
2299 );
2300   printf(
2301 "    error, Triangle will probably decide that the three segments intersect\n"
2302 );
2303   printf(
2304 "    at three different points, and you will find a minuscule triangle in\n");
2305   printf(
2306 "    your output--unless Triangle tries to refine the tiny triangle, uses\n");
2307   printf(
2308 "    up the last bit of machine precision, and fails to terminate at all.\n");
2309   printf(
2310 "    You're better off putting the intersection point in the input files,\n");
2311   printf(
2312 "    and manually breaking up each segment into two.  Similarly, if you\n");
2313   printf(
2314 "    place a vertex at the middle of a segment, and hope that Triangle will\n"
2315 );
2316   printf(
2317 "    break up the segment at that vertex, you might get lucky.  On the other\n"
2318 );
2319   printf(
2320 "    hand, Triangle might decide that the vertex doesn't lie precisely on\n");
2321   printf(
2322 "    the segment, and you'll have a needle-sharp triangle in your output--or\n"
2323 );
2324   printf("    a lot of tiny triangles if you're generating a quality mesh.\n");
2325   printf("\n");
2326   printf(
2327 "    When Triangle reads a .poly file, it also writes a .poly file, which\n");
2328   printf(
2329 "    includes all the subsegments--the edges that are parts of input\n");
2330   printf(
2331 "    segments.  If the -c switch is used, the output .poly file also\n");
2332   printf(
2333 "    includes all of the edges on the convex hull.  Hence, the output .poly\n"
2334 );
2335   printf(
2336 "    file is useful for finding edges associated with input segments and for\n"
2337 );
2338   printf(
2339 "    setting boundary conditions in finite element simulations.  Moreover,\n");
2340   printf(
2341 "    you will need the output .poly file if you plan to refine the output\n");
2342   printf(
2343 "    mesh, and don't want segments to be missing in later triangulations.\n");
2344   printf("\n");
2345   printf("  .area files:\n");
2346   printf("    First line:  <# of triangles>\n");
2347   printf("    Following lines:  <triangle #> <maximum area>\n");
2348   printf("\n");
2349   printf(
2350 "    An .area file associates with each triangle a maximum area that is used\n"
2351 );
2352   printf(
2353 "    for mesh refinement.  As with other file formats, every triangle must\n");
2354   printf(
2355 "    be represented, and the triangles must be numbered consecutively.  A\n");
2356   printf(
2357 "    triangle may be left unconstrained by assigning it a negative maximum\n");
2358   printf("    area.\n\n");
2359   printf("  .edge files:\n");
2360   printf("    First line:  <# of edges> <# of boundary markers (0 or 1)>\n");
2361   printf(
2362 "    Following lines:  <edge #> <endpoint> <endpoint> [boundary marker]\n");
2363   printf("\n");
2364   printf(
2365 "    Endpoints are indices into the corresponding .node file.  Triangle can\n"
2366 );
2367   printf(
2368 "    produce .edge files (use the -e switch), but cannot read them.  The\n");
2369   printf(
2370 "    optional column of boundary markers is suppressed by the -B switch.\n");
2371   printf("\n");
2372   printf(
2373 "    In Voronoi diagrams, one also finds a special kind of edge that is an\n");
2374   printf(
2375 "    infinite ray with only one endpoint.  For these edges, a different\n");
2376   printf("    format is used:\n\n");
2377   printf("        <edge #> <endpoint> -1 <direction x> <direction y>\n\n");
2378   printf(
2379 "    The `direction' is a floating-point vector that indicates the direction\n"
2380 );
2381   printf("    of the infinite ray.\n\n");
2382   printf("  .neigh files:\n");
2383   printf(
2384 "    First line:  <# of triangles> <# of neighbors per triangle (always 3)>\n"
2385 );
2386   printf(
2387 "    Following lines:  <triangle #> <neighbor> <neighbor> <neighbor>\n");
2388   printf("\n");
2389   printf(
2390 "    Neighbors are indices into the corresponding .ele file.  An index of -1\n"
2391 );
2392   printf(
2393 "    indicates no neighbor (because the triangle is on an exterior\n");
2394   printf(
2395 "    boundary).  The first neighbor of triangle i is opposite the first\n");
2396   printf("    corner of triangle i, and so on.\n\n");
2397   printf(
2398 "    Triangle can produce .neigh files (use the -n switch), but cannot read\n"
2399 );
2400   printf("    them.\n\n");
2401   printf("Boundary Markers:\n\n");
2402   printf(
2403 "  Boundary markers are tags used mainly to identify which output vertices\n");
2404   printf(
2405 "  and edges are associated with which PSLG segment, and to identify which\n");
2406   printf(
2407 "  vertices and edges occur on a boundary of the triangulation.  A common\n");
2408   printf(
2409 "  use is to determine where boundary conditions should be applied to a\n");
2410   printf(
2411 "  finite element mesh.  You can prevent boundary markers from being written\n"
2412 );
2413   printf("  into files produced by Triangle by using the -B switch.\n\n");
2414   printf(
2415 "  The boundary marker associated with each segment in an output .poly file\n"
2416 );
2417   printf("  and each edge in an output .edge file is chosen as follows:\n");
2418   printf(
2419 "    - If an output edge is part or all of a PSLG segment with a nonzero\n");
2420   printf(
2421 "      boundary marker, then the edge is assigned the same marker.\n");
2422   printf(
2423 "    - Otherwise, if the edge lies on a boundary of the triangulation\n");
2424   printf(
2425 "      (even the boundary of a hole), then the edge is assigned the marker\n");
2426   printf("      one (1).\n");
2427   printf("    - Otherwise, the edge is assigned the marker zero (0).\n");
2428   printf(
2429 "  The boundary marker associated with each vertex in an output .node file\n");
2430   printf("  is chosen as follows:\n");
2431   printf(
2432 "    - If a vertex is assigned a nonzero boundary marker in the input file,\n"
2433 );
2434   printf(
2435 "      then it is assigned the same marker in the output .node file.\n");
2436   printf(
2437 "    - Otherwise, if the vertex lies on a PSLG segment (even if it is an\n");
2438   printf(
2439 "      endpoint of the segment) with a nonzero boundary marker, then the\n");
2440   printf(
2441 "      vertex is assigned the same marker.  If the vertex lies on several\n");
2442   printf("      such segments, one of the markers is chosen arbitrarily.\n");
2443   printf(
2444 "    - Otherwise, if the vertex occurs on a boundary of the triangulation,\n");
2445   printf("      then the vertex is assigned the marker one (1).\n");
2446   printf("    - Otherwise, the vertex is assigned the marker zero (0).\n");
2447   printf("\n");
2448   printf(
2449 "  If you want Triangle to determine for you which vertices and edges are on\n"
2450 );
2451   printf(
2452 "  the boundary, assign them the boundary marker zero (or use no markers at\n"
2453 );
2454   printf(
2455 "  all) in your input files.  In the output files, all boundary vertices,\n");
2456   printf("  edges, and segments will be assigned the value one.\n\n");
2457   printf("Triangulation Iteration Numbers:\n\n");
2458   printf(
2459 "  Because Triangle can read and refine its own triangulations, input\n");
2460   printf(
2461 "  and output files have iteration numbers.  For instance, Triangle might\n");
2462   printf(
2463 "  read the files mesh.3.node, mesh.3.ele, and mesh.3.poly, refine the\n");
2464   printf(
2465 "  triangulation, and output the files mesh.4.node, mesh.4.ele, and\n");
2466   printf("  mesh.4.poly.  Files with no iteration number are treated as if\n");
2467   printf(
2468 "  their iteration number is zero; hence, Triangle might read the file\n");
2469   printf(
2470 "  points.node, triangulate it, and produce the files points.1.node and\n");
2471   printf("  points.1.ele.\n\n");
2472   printf(
2473 "  Iteration numbers allow you to create a sequence of successively finer\n");
2474   printf(
2475 "  meshes suitable for multigrid methods.  They also allow you to produce a\n"
2476 );
2477   printf(
2478 "  sequence of meshes using error estimate-driven mesh refinement.\n");
2479   printf("\n");
2480   printf(
2481 "  If you're not using refinement or quality meshing, and you don't like\n");
2482   printf(
2483 "  iteration numbers, use the -I switch to disable them.  This switch also\n");
2484   printf(
2485 "  disables output of .node and .poly files to prevent your input files from\n"
2486 );
2487   printf(
2488 "  being overwritten.  (If the input is a .poly file that contains its own\n");
2489   printf(
2490 "  points, a .node file is written.  This can be quite convenient for\n");
2491   printf("  computing CDTs or quality meshes.)\n\n");
2492   printf("Examples of How to Use Triangle:\n\n");
2493   printf(
2494 "  `triangle dots' reads vertices from dots.node, and writes their Delaunay\n"
2495 );
2496   printf(
2497 "  triangulation to dots.1.node and dots.1.ele.  (dots.1.node is identical\n");
2498   printf(
2499 "  to dots.node.)  `triangle -I dots' writes the triangulation to dots.ele\n");
2500   printf(
2501 "  instead.  (No additional .node file is needed, so none is written.)\n");
2502   printf("\n");
2503   printf(
2504 "  `triangle -pe object.1' reads a PSLG from object.1.poly (and possibly\n");
2505   printf(
2506 "  object.1.node, if the vertices are omitted from object.1.poly) and writes\n"
2507 );
2508   printf(
2509 "  its constrained Delaunay triangulation to object.2.node and object.2.ele.\n"
2510 );
2511   printf(
2512 "  The segments are copied to object.2.poly, and all edges are written to\n");
2513   printf("  object.2.edge.\n\n");
2514   printf(
2515 "  `triangle -pq31.5a.1 object' reads a PSLG from object.poly (and possibly\n"
2516 );
2517   printf(
2518 "  object.node), generates a mesh whose angles are all between 31.5 and 117\n"
2519 );
2520   printf(
2521 "  degrees and whose triangles all have areas of 0.1 or less, and writes the\n"
2522 );
2523   printf(
2524 "  mesh to object.1.node and object.1.ele.  Each segment may be broken up\n");
2525   printf("  into multiple subsegments; these are written to object.1.poly.\n");
2526   printf("\n");
2527   printf(
2528 "  Here is a sample file `box.poly' describing a square with a square hole:\n"
2529 );
2530   printf("\n");
2531   printf(
2532 "    # A box with eight vertices in 2D, no attributes, one boundary marker.\n"
2533 );
2534   printf("    8 2 0 1\n");
2535   printf("     # Outer box has these vertices:\n");
2536   printf("     1   0 0   0\n");
2537   printf("     2   0 3   0\n");
2538   printf("     3   3 0   0\n");
2539   printf("     4   3 3   33     # A special marker for this vertex.\n");
2540   printf("     # Inner square has these vertices:\n");
2541   printf("     5   1 1   0\n");
2542   printf("     6   1 2   0\n");
2543   printf("     7   2 1   0\n");
2544   printf("     8   2 2   0\n");
2545   printf("    # Five segments with boundary markers.\n");
2546   printf("    5 1\n");
2547   printf("     1   1 2   5      # Left side of outer box.\n");
2548   printf("     # Square hole has these segments:\n");
2549   printf("     2   5 7   0\n");
2550   printf("     3   7 8   0\n");
2551   printf("     4   8 6   10\n");
2552   printf("     5   6 5   0\n");
2553   printf("    # One hole in the middle of the inner square.\n");
2554   printf("    1\n");
2555   printf("     1   1.5 1.5\n");
2556   printf("\n");
2557   printf(
2558 "  Note that some segments are missing from the outer square, so you must\n");
2559   printf(
2560 "  use the `-c' switch.  After `triangle -pqc box.poly', here is the output\n"
2561 );
2562   printf(
2563 "  file `box.1.node', with twelve vertices.  The last four vertices were\n");
2564   printf(
2565 "  added to meet the angle constraint.  Vertices 1, 2, and 9 have markers\n");
2566   printf(
2567 "  from segment 1.  Vertices 6 and 8 have markers from segment 4.  All the\n");
2568   printf(
2569 "  other vertices but 4 have been marked to indicate that they lie on a\n");
2570   printf("  boundary.\n\n");
2571   printf("    12  2  0  1\n");
2572   printf("       1    0   0      5\n");
2573   printf("       2    0   3      5\n");
2574   printf("       3    3   0      1\n");
2575   printf("       4    3   3     33\n");
2576   printf("       5    1   1      1\n");
2577   printf("       6    1   2     10\n");
2578   printf("       7    2   1      1\n");
2579   printf("       8    2   2     10\n");
2580   printf("       9    0   1.5    5\n");
2581   printf("      10    1.5   0    1\n");
2582   printf("      11    3   1.5    1\n");
2583   printf("      12    1.5   3    1\n");
2584   printf("    # Generated by triangle -pqc box.poly\n");
2585   printf("\n");
2586   printf("  Here is the output file `box.1.ele', with twelve triangles.\n");
2587   printf("\n");
2588   printf("    12  3  0\n");
2589   printf("       1     5   6   9\n");
2590   printf("       2    10   3   7\n");
2591   printf("       3     6   8  12\n");
2592   printf("       4     9   1   5\n");
2593   printf("       5     6   2   9\n");
2594   printf("       6     7   3  11\n");
2595   printf("       7    11   4   8\n");
2596   printf("       8     7   5  10\n");
2597   printf("       9    12   2   6\n");
2598   printf("      10     8   7  11\n");
2599   printf("      11     5   1  10\n");
2600   printf("      12     8   4  12\n");
2601   printf("    # Generated by triangle -pqc box.poly\n\n");
2602   printf(
2603 "  Here is the output file `box.1.poly'.  Note that segments have been added\n"
2604 );
2605   printf(
2606 "  to represent the convex hull, and some segments have been subdivided by\n");
2607   printf(
2608 "  newly added vertices.  Note also that <# of vertices> is set to zero to\n");
2609   printf("  indicate that the vertices should be read from the .node file.\n");
2610   printf("\n");
2611   printf("    0  2  0  1\n");
2612   printf("    12  1\n");
2613   printf("       1     1   9     5\n");
2614   printf("       2     5   7     1\n");
2615   printf("       3     8   7     1\n");
2616   printf("       4     6   8    10\n");
2617   printf("       5     5   6     1\n");
2618   printf("       6     3  10     1\n");
2619   printf("       7     4  11     1\n");
2620   printf("       8     2  12     1\n");
2621   printf("       9     9   2     5\n");
2622   printf("      10    10   1     1\n");
2623   printf("      11    11   3     1\n");
2624   printf("      12    12   4     1\n");
2625   printf("    1\n");
2626   printf("       1   1.5 1.5\n");
2627   printf("    # Generated by triangle -pqc box.poly\n");
2628   printf("\n");
2629   printf("Refinement and Area Constraints:\n");
2630   printf("\n");
2631   printf(
2632 "  The -r switch causes a mesh (.node and .ele files) to be read and\n");
2633   printf(
2634 "  refined.  If the -p switch is also used, a .poly file is read and used to\n"
2635 );
2636   printf(
2637 "  specify edges that are constrained and cannot be eliminated (although\n");
2638   printf(
2639 "  they can be subdivided into smaller edges) by the refinement process.\n");
2640   printf("\n");
2641   printf(
2642 "  When you refine a mesh, you generally want to impose tighter constraints.\n"
2643 );
2644   printf(
2645 "  One way to accomplish this is to use -q with a larger angle, or -a\n");
2646   printf(
2647 "  followed by a smaller area than you used to generate the mesh you are\n");
2648   printf(
2649 "  refining.  Another way to do this is to create an .area file, which\n");
2650   printf(
2651 "  specifies a maximum area for each triangle, and use the -a switch\n");
2652   printf(
2653 "  (without a number following).  Each triangle's area constraint is applied\n"
2654 );
2655   printf(
2656 "  to that triangle.  Area constraints tend to diffuse as the mesh is\n");
2657   printf(
2658 "  refined, so if there are large variations in area constraint between\n");
2659   printf(
2660 "  adjacent triangles, you may not get the results you want.  In that case,\n"
2661 );
2662   printf(
2663 "  consider instead using the -u switch and writing a C procedure that\n");
2664   printf("  determines which triangles are too large.\n\n");
2665   printf(
2666 "  If you are refining a mesh composed of linear (three-node) elements, the\n"
2667 );
2668   printf(
2669 "  output mesh contains all the nodes present in the input mesh, in the same\n"
2670 );
2671   printf(
2672 "  order, with new nodes added at the end of the .node file.  However, the\n");
2673   printf(
2674 "  refinement is not hierarchical: there is no guarantee that each output\n");
2675   printf(
2676 "  element is contained in a single input element.  Often, an output element\n"
2677 );
2678   printf(
2679 "  can overlap two or three input elements, and some input edges are not\n");
2680   printf(
2681 "  present in the output mesh.  Hence, a sequence of refined meshes forms a\n"
2682 );
2683   printf(
2684 "  hierarchy of nodes, but not a hierarchy of elements.  If you refine a\n");
2685   printf(
2686 "  mesh of higher-order elements, the hierarchical property applies only to\n"
2687 );
2688   printf(
2689 "  the nodes at the corners of an element; the midpoint nodes on each edge\n");
2690   printf("  are discarded before the mesh is refined.\n\n");
2691   printf(
2692 "  Maximum area constraints in .poly files operate differently from those in\n"
2693 );
2694   printf(
2695 "  .area files.  A maximum area in a .poly file applies to the whole\n");
2696   printf(
2697 "  (segment-bounded) region in which a point falls, whereas a maximum area\n");
2698   printf(
2699 "  in an .area file applies to only one triangle.  Area constraints in .poly\n"
2700 );
2701   printf(
2702 "  files are used only when a mesh is first generated, whereas area\n");
2703   printf(
2704 "  constraints in .area files are used only to refine an existing mesh, and\n"
2705 );
2706   printf(
2707 "  are typically based on a posteriori error estimates resulting from a\n");
2708   printf("  finite element simulation on that mesh.\n\n");
2709   printf(
2710 "  `triangle -rq25 object.1' reads object.1.node and object.1.ele, then\n");
2711   printf(
2712 "  refines the triangulation to enforce a 25 degree minimum angle, and then\n"
2713 );
2714   printf(
2715 "  writes the refined triangulation to object.2.node and object.2.ele.\n");
2716   printf("\n");
2717   printf(
2718 "  `triangle -rpaa6.2 z.3' reads z.3.node, z.3.ele, z.3.poly, and z.3.area.\n"
2719 );
2720   printf(
2721 "  After reconstructing the mesh and its subsegments, Triangle refines the\n");
2722   printf(
2723 "  mesh so that no triangle has area greater than 6.2, and furthermore the\n");
2724   printf(
2725 "  triangles satisfy the maximum area constraints in z.3.area.  No angle\n");
2726   printf(
2727 "  bound is imposed at all.  The output is written to z.4.node, z.4.ele, and\n"
2728 );
2729   printf("  z.4.poly.\n\n");
2730   printf(
2731 "  The sequence `triangle -qa1 x', `triangle -rqa.3 x.1', `triangle -rqa.1\n");
2732   printf(
2733 "  x.2' creates a sequence of successively finer meshes x.1, x.2, and x.3,\n");
2734   printf("  suitable for multigrid.\n\n");
2735   printf("Convex Hulls and Mesh Boundaries:\n\n");
2736   printf(
2737 "  If the input is a vertex set (not a PSLG), Triangle produces its convex\n");
2738   printf(
2739 "  hull as a by-product in the output .poly file if you use the -c switch.\n");
2740   printf(
2741 "  There are faster algorithms for finding a two-dimensional convex hull\n");
2742   printf("  than triangulation, of course, but this one comes for free.\n\n");
2743   printf(
2744 "  If the input is an unconstrained mesh (you are using the -r switch but\n");
2745   printf(
2746 "  not the -p switch), Triangle produces a list of its boundary edges\n");
2747   printf(
2748 "  (including hole boundaries) as a by-product when you use the -c switch.\n");
2749   printf(
2750 "  If you also use the -p switch, the output .poly file contains all the\n");
2751   printf("  segments from the input .poly file as well.\n\n");
2752   printf("Voronoi Diagrams:\n\n");
2753   printf(
2754 "  The -v switch produces a Voronoi diagram, in files suffixed .v.node and\n");
2755   printf(
2756 "  .v.edge.  For example, `triangle -v points' reads points.node, produces\n");
2757   printf(
2758 "  its Delaunay triangulation in points.1.node and points.1.ele, and\n");
2759   printf(
2760 "  produces its Voronoi diagram in points.1.v.node and points.1.v.edge.  The\n"
2761 );
2762   printf(
2763 "  .v.node file contains a list of all Voronoi vertices, and the .v.edge\n");
2764   printf(
2765 "  file contains a list of all Voronoi edges, some of which may be infinite\n"
2766 );
2767   printf(
2768 "  rays.  (The choice of filenames makes it easy to run the set of Voronoi\n");
2769   printf("  vertices through Triangle, if so desired.)\n\n");
2770   printf(
2771 "  This implementation does not use exact arithmetic to compute the Voronoi\n"
2772 );
2773   printf(
2774 "  vertices, and does not check whether neighboring vertices are identical.\n"
2775 );
2776   printf(
2777 "  Be forewarned that if the Delaunay triangulation is degenerate or\n");
2778   printf(
2779 "  near-degenerate, the Voronoi diagram may have duplicate vertices or\n");
2780   printf("  crossing edges.\n\n");
2781   printf(
2782 "  The result is a valid Voronoi diagram only if Triangle's output is a true\n"
2783 );
2784   printf(
2785 "  Delaunay triangulation.  The Voronoi output is usually meaningless (and\n");
2786   printf(
2787 "  may contain crossing edges and other pathology) if the output is a CDT or\n"
2788 );
2789   printf(
2790 "  CCDT, or if it has holes or concavities.  If the triangulated domain is\n");
2791   printf(
2792 "  convex and has no holes, you can use -D switch to force Triangle to\n");
2793   printf(
2794 "  construct a conforming Delaunay triangulation instead of a CCDT, so the\n");
2795   printf("  Voronoi diagram will be valid.\n\n");
2796   printf("Mesh Topology:\n\n");
2797   printf(
2798 "  You may wish to know which triangles are adjacent to a certain Delaunay\n");
2799   printf(
2800 "  edge in an .edge file, which Voronoi cells are adjacent to a certain\n");
2801   printf(
2802 "  Voronoi edge in a .v.edge file, or which Voronoi cells are adjacent to\n");
2803   printf(
2804 "  each other.  All of this information can be found by cross-referencing\n");
2805   printf(
2806 "  output files with the recollection that the Delaunay triangulation and\n");
2807   printf("  the Voronoi diagram are planar duals.\n\n");
2808   printf(
2809 "  Specifically, edge i of an .edge file is the dual of Voronoi edge i of\n");
2810   printf(
2811 "  the corresponding .v.edge file, and is rotated 90 degrees counterclock-\n");
2812   printf(
2813 "  wise from the Voronoi edge.  Triangle j of an .ele file is the dual of\n");
2814   printf(
2815 "  vertex j of the corresponding .v.node file.  Voronoi cell k is the dual\n");
2816   printf("  of vertex k of the corresponding .node file.\n\n");
2817   printf(
2818 "  Hence, to find the triangles adjacent to a Delaunay edge, look at the\n");
2819   printf(
2820 "  vertices of the corresponding Voronoi edge.  If the endpoints of a\n");
2821   printf(
2822 "  Voronoi edge are Voronoi vertices 2 and 6 respectively, then triangles 2\n"
2823 );
2824   printf(
2825 "  and 6 adjoin the left and right sides of the corresponding Delaunay edge,\n"
2826 );
2827   printf(
2828 "  respectively.  To find the Voronoi cells adjacent to a Voronoi edge, look\n"
2829 );
2830   printf(
2831 "  at the endpoints of the corresponding Delaunay edge.  If the endpoints of\n"
2832 );
2833   printf(
2834 "  a Delaunay edge are input vertices 7 and 12, then Voronoi cells 7 and 12\n"
2835 );
2836   printf(
2837 "  adjoin the right and left sides of the corresponding Voronoi edge,\n");
2838   printf(
2839 "  respectively.  To find which Voronoi cells are adjacent to each other,\n");
2840   printf("  just read the list of Delaunay edges.\n\n");
2841   printf(
2842 "  Triangle does not write a list of the edges adjoining each Voronoi cell,\n"
2843 );
2844   printf(
2845 "  but you can reconstructed it straightforwardly.  For instance, to find\n");
2846   printf(
2847 "  all the edges of Voronoi cell 1, search the output .edge file for every\n");
2848   printf(
2849 "  edge that has input vertex 1 as an endpoint.  The corresponding dual\n");
2850   printf(
2851 "  edges in the output .v.edge file form the boundary of Voronoi cell 1.\n");
2852   printf("\n");
2853   printf(
2854 "  For each Voronoi vertex, the .neigh file gives a list of the three\n");
2855   printf(
2856 "  Voronoi vertices attached to it.  You might find this more convenient\n");
2857   printf("  than the .v.edge file.\n\n");
2858   printf("Quadratic Elements:\n\n");
2859   printf(
2860 "  Triangle generates meshes with subparametric quadratic elements if the\n");
2861   printf(
2862 "  -o2 switch is specified.  Quadratic elements have six nodes per element,\n"
2863 );
2864   printf(
2865 "  rather than three.  `Subparametric' means that the edges of the triangles\n"
2866 );
2867   printf(
2868 "  are always straight, so that subparametric quadratic elements are\n");
2869   printf(
2870 "  geometrically identical to linear elements, even though they can be used\n"
2871 );
2872   printf(
2873 "  with quadratic interpolating functions.  The three extra nodes of an\n");
2874   printf(
2875 "  element fall at the midpoints of the three edges, with the fourth, fifth,\n"
2876 );
2877   printf(
2878 "  and sixth nodes appearing opposite the first, second, and third corners\n");
2879   printf("  respectively.\n\n");
2880   printf("Domains with Small Angles:\n\n");
2881   printf(
2882 "  If two input segments adjoin each other at a small angle, clearly the -q\n"
2883 );
2884   printf(
2885 "  switch cannot remove the small angle.  Moreover, Triangle may have no\n");
2886   printf(
2887 "  choice but to generate additional triangles whose smallest angles are\n");
2888   printf(
2889 "  smaller than the specified bound.  However, these triangles only appear\n");
2890   printf(
2891 "  between input segments separated by small angles.  Moreover, if you\n");
2892   printf(
2893 "  request a minimum angle of theta degrees, Triangle will generally produce\n"
2894 );
2895   printf(
2896 "  no angle larger than 180 - 2 theta, even if it is forced to compromise on\n"
2897 );
2898   printf("  the minimum angle.\n\n");
2899   printf("Statistics:\n\n");
2900   printf(
2901 "  After generating a mesh, Triangle prints a count of entities in the\n");
2902   printf(
2903 "  output mesh, including the number of vertices, triangles, edges, exterior\n"
2904 );
2905   printf(
2906 "  boundary edges (i.e. subsegments on the boundary of the triangulation,\n");
2907   printf(
2908 "  including hole boundaries), interior boundary edges (i.e. subsegments of\n"
2909 );
2910   printf(
2911 "  input segments not on the boundary), and total subsegments.  If you've\n");
2912   printf(
2913 "  forgotten the statistics for an existing mesh, run Triangle on that mesh\n"
2914 );
2915   printf(
2916 "  with the -rNEP switches to read the mesh and print the statistics without\n"
2917 );
2918   printf(
2919 "  writing any files.  Use -rpNEP if you've got a .poly file for the mesh.\n");
2920   printf("\n");
2921   printf(
2922 "  The -V switch produces extended statistics, including a rough estimate\n");
2923   printf(
2924 "  of memory use, the number of calls to geometric predicates, and\n");
2925   printf(
2926 "  histograms of the angles and the aspect ratios of the triangles in the\n");
2927   printf("  mesh.\n\n");
2928   printf("Exact Arithmetic:\n\n");
2929   printf(
2930 "  Triangle uses adaptive exact arithmetic to perform what computational\n");
2931   printf(
2932 "  geometers call the `orientation' and `incircle' tests.  If the floating-\n"
2933 );
2934   printf(
2935 "  point arithmetic of your machine conforms to the IEEE 754 standard (as\n");
2936   printf(
2937 "  most workstations do), and does not use extended precision internal\n");
2938   printf(
2939 "  floating-point registers, then your output is guaranteed to be an\n");
2940   printf(
2941 "  absolutely true Delaunay or constrained Delaunay triangulation, roundoff\n"
2942 );
2943   printf(
2944 "  error notwithstanding.  The word `adaptive' implies that these arithmetic\n"
2945 );
2946   printf(
2947 "  routines compute the result only to the precision necessary to guarantee\n"
2948 );
2949   printf(
2950 "  correctness, so they are usually nearly as fast as their approximate\n");
2951   printf("  counterparts.\n\n");
2952   printf(
2953 "  May CPUs, including Intel x86 processors, have extended precision\n");
2954   printf(
2955 "  floating-point registers.  These must be reconfigured so their precision\n"
2956 );
2957   printf(
2958 "  is reduced to memory precision.  Triangle does this if it is compiled\n");
2959   printf("  correctly.  See the makefile for details.\n\n");
2960   printf(
2961 "  The exact tests can be disabled with the -X switch.  On most inputs, this\n"
2962 );
2963   printf(
2964 "  switch reduces the computation time by about eight percent--it's not\n");
2965   printf(
2966 "  worth the risk.  There are rare difficult inputs (having many collinear\n");
2967   printf(
2968 "  and cocircular vertices), however, for which the difference in speed\n");
2969   printf(
2970 "  could be a factor of two.  Be forewarned that these are precisely the\n");
2971   printf(
2972 "  inputs most likely to cause errors if you use the -X switch.  Hence, the\n"
2973 );
2974   printf("  -X switch is not recommended.\n\n");
2975   printf(
2976 "  Unfortunately, the exact tests don't solve every numerical problem.\n");
2977   printf(
2978 "  Exact arithmetic is not used to compute the positions of new vertices,\n");
2979   printf(
2980 "  because the bit complexity of vertex coordinates would grow without\n");
2981   printf(
2982 "  bound.  Hence, segment intersections aren't computed exactly; in very\n");
2983   printf(
2984 "  unusual cases, roundoff error in computing an intersection point might\n");
2985   printf(
2986 "  actually lead to an inverted triangle and an invalid triangulation.\n");
2987   printf(
2988 "  (This is one reason to specify your own intersection points in your .poly\n"
2989 );
2990   printf(
2991 "  files.)  Similarly, exact arithmetic is not used to compute the vertices\n"
2992 );
2993   printf("  of the Voronoi diagram.\n\n");
2994   printf(
2995 "  Another pair of problems not solved by the exact arithmetic routines is\n");
2996   printf(
2997 "  underflow and overflow.  If Triangle is compiled for double precision\n");
2998   printf(
2999 "  arithmetic, I believe that Triangle's geometric predicates work correctly\n"
3000 );
3001   printf(
3002 "  if the exponent of every input coordinate falls in the range [-148, 201].\n"
3003 );
3004   printf(
3005 "  Underflow can silently prevent the orientation and incircle tests from\n");
3006   printf(
3007 "  being performed exactly, while overflow typically causes a floating\n");
3008   printf("  exception.\n\n");
3009   printf("Calling Triangle from Another Program:\n\n");
3010   printf("  Read the file triangle.h for details.\n\n");
3011   printf("Troubleshooting:\n\n");
3012   printf("  Please read this section before mailing me bugs.\n\n");
3013   printf("  `My output mesh has no triangles!'\n\n");
3014   printf(
3015 "    If you're using a PSLG, you've probably failed to specify a proper set\n"
3016 );
3017   printf(
3018 "    of bounding segments, or forgotten to use the -c switch.  Or you may\n");
3019   printf(
3020 "    have placed a hole badly, thereby eating all your triangles.  To test\n");
3021   printf("    these possibilities, try again with the -c and -O switches.\n");
3022   printf(
3023 "    Alternatively, all your input vertices may be collinear, in which case\n"
3024 );
3025   printf("    you can hardly expect to triangulate them.\n\n");
3026   printf("  `Triangle doesn't terminate, or just crashes.'\n\n");
3027   printf(
3028 "    Bad things can happen when triangles get so small that the distance\n");
3029   printf(
3030 "    between their vertices isn't much larger than the precision of your\n");
3031   printf(
3032 "    machine's arithmetic.  If you've compiled Triangle for single-precision\n"
3033 );
3034   printf(
3035 "    arithmetic, you might do better by recompiling it for double-precision.\n"
3036 );
3037   printf(
3038 "    Then again, you might just have to settle for more lenient constraints\n"
3039 );
3040   printf(
3041 "    on the minimum angle and the maximum area than you had planned.\n");
3042   printf("\n");
3043   printf(
3044 "    You can minimize precision problems by ensuring that the origin lies\n");
3045   printf(
3046 "    inside your vertex set, or even inside the densest part of your\n");
3047   printf(
3048 "    mesh.  If you're triangulating an object whose x-coordinates all fall\n");
3049   printf(
3050 "    between 6247133 and 6247134, you're not leaving much floating-point\n");
3051   printf("    precision for Triangle to work with.\n\n");
3052   printf(
3053 "    Precision problems can occur covertly if the input PSLG contains two\n");
3054   printf(
3055 "    segments that meet (or intersect) at an extremely small angle, or if\n");
3056   printf(
3057 "    such an angle is introduced by the -c switch.  If you don't realize\n");
3058   printf(
3059 "    that a tiny angle is being formed, you might never discover why\n");
3060   printf(
3061 "    Triangle is crashing.  To check for this possibility, use the -S switch\n"
3062 );
3063   printf(
3064 "    (with an appropriate limit on the number of Steiner points, found by\n");
3065   printf(
3066 "    trial-and-error) to stop Triangle early, and view the output .poly file\n"
3067 );
3068   printf(
3069 "    with Show Me (described below).  Look carefully for regions where dense\n"
3070 );
3071   printf(
3072 "    clusters of vertices are forming and for small angles between segments.\n"
3073 );
3074   printf(
3075 "    Zoom in closely, as such segments might look like a single segment from\n"
3076 );
3077   printf("    a distance.\n\n");
3078   printf(
3079 "    If some of the input values are too large, Triangle may suffer a\n");
3080   printf(
3081 "    floating exception due to overflow when attempting to perform an\n");
3082   printf(
3083 "    orientation or incircle test.  (Read the section on exact arithmetic\n");
3084   printf(
3085 "    above.)  Again, I recommend compiling Triangle for double (rather\n");
3086   printf("    than single) precision arithmetic.\n\n");
3087   printf(
3088 "    Unexpected problems can arise if you use quality meshing (-q, -a, or\n");
3089   printf(
3090 "    -u) with an input that is not segment-bounded--that is, if your input\n");
3091   printf(
3092 "    is a vertex set, or you're using the -c switch.  If the convex hull of\n"
3093 );
3094   printf(
3095 "    your input vertices has collinear vertices on its boundary, an input\n");
3096   printf(
3097 "    vertex that you think lies on the convex hull might actually lie just\n");
3098   printf(
3099 "    inside the convex hull.  If so, the vertex and the nearby convex hull\n");
3100   printf(
3101 "    edge form an extremely thin triangle.  When Triangle tries to refine\n");
3102   printf(
3103 "    the mesh to enforce angle and area constraints, Triangle might generate\n"
3104 );
3105   printf(
3106 "    extremely tiny triangles, or it might fail because of insufficient\n");
3107   printf("    floating-point precision.\n\n");
3108   printf(
3109 "  `The numbering of the output vertices doesn't match the input vertices.'\n"
3110 );
3111   printf("\n");
3112   printf(
3113 "    You may have had duplicate input vertices, or you may have eaten some\n");
3114   printf(
3115 "    of your input vertices with a hole, or by placing them outside the area\n"
3116 );
3117   printf(
3118 "    enclosed by segments.  In any case, you can solve the problem by not\n");
3119   printf("    using the -j switch.\n\n");
3120   printf(
3121 "  `Triangle executes without incident, but when I look at the resulting\n");
3122   printf(
3123 "  mesh, it has overlapping triangles or other geometric inconsistencies.'\n");
3124   printf("\n");
3125   printf(
3126 "    If you select the -X switch, Triangle occasionally makes mistakes due\n");
3127   printf(
3128 "    to floating-point roundoff error.  Although these errors are rare,\n");
3129   printf(
3130 "    don't use the -X switch.  If you still have problems, please report the\n"
3131 );
3132   printf("    bug.\n\n");
3133   printf(
3134 "  `Triangle executes without incident, but when I look at the resulting\n");
3135   printf("  Voronoi diagram, it has overlapping edges or other geometric\n");
3136   printf("  inconsistencies.'\n");
3137   printf("\n");
3138   printf(
3139 "    If your input is a PSLG (-p), you can only expect a meaningful Voronoi\n"
3140 );
3141   printf(
3142 "    diagram if the domain you are triangulating is convex and free of\n");
3143   printf(
3144 "    holes, and you use the -D switch to construct a conforming Delaunay\n");
3145   printf("    triangulation (instead of a CDT or CCDT).\n\n");
3146   printf(
3147 "  Strange things can happen if you've taken liberties with your PSLG.  Do\n");
3148   printf(
3149 "  you have a vertex lying in the middle of a segment?  Triangle sometimes\n");
3150   printf(
3151 "  copes poorly with that sort of thing.  Do you want to lay out a collinear\n"
3152 );
3153   printf(
3154 "  row of evenly spaced, segment-connected vertices?  Have you simply\n");
3155   printf(
3156 "  defined one long segment connecting the leftmost vertex to the rightmost\n"
3157 );
3158   printf(
3159 "  vertex, and a bunch of vertices lying along it?  This method occasionally\n"
3160 );
3161   printf(
3162 "  works, especially with horizontal and vertical lines, but often it\n");
3163   printf(
3164 "  doesn't, and you'll have to connect each adjacent pair of vertices with a\n"
3165 );
3166   printf("  separate segment.  If you don't like it, tough.\n\n");
3167   printf(
3168 "  Furthermore, if you have segments that intersect other than at their\n");
3169   printf(
3170 "  endpoints, try not to let the intersections fall extremely close to PSLG\n"
3171 );
3172   printf("  vertices or each other.\n\n");
3173   printf(
3174 "  If you have problems refining a triangulation not produced by Triangle:\n");
3175   printf(
3176 "  Are you sure the triangulation is geometrically valid?  Is it formatted\n");
3177   printf(
3178 "  correctly for Triangle?  Are the triangles all listed so the first three\n"
3179 );
3180   printf(
3181 "  vertices are their corners in counterclockwise order?  Are all of the\n");
3182   printf(
3183 "  triangles constrained Delaunay?  Triangle's Delaunay refinement algorithm\n"
3184 );
3185   printf("  assumes that it starts with a CDT.\n\n");
3186   printf("Show Me:\n\n");
3187   printf(
3188 "  Triangle comes with a separate program named `Show Me', whose primary\n");
3189   printf(
3190 "  purpose is to draw meshes on your screen or in PostScript.  Its secondary\n"
3191 );
3192   printf(
3193 "  purpose is to check the validity of your input files, and do so more\n");
3194   printf(
3195 "  thoroughly than Triangle does.  Unlike Triangle, Show Me requires that\n");
3196   printf(
3197 "  you have the X Windows system.  Sorry, Microsoft Windows users.\n");
3198   printf("\n");
3199   printf("Triangle on the Web:\n");
3200   printf("\n");
3201   printf("  To see an illustrated version of these instructions, check out\n");
3202   printf("\n");
3203   printf("    http://www.cs.cmu.edu/~quake/triangle.html\n");
3204   printf("\n");
3205   printf("A Brief Plea:\n");
3206   printf("\n");
3207   printf(
3208 "  If you use Triangle, and especially if you use it to accomplish real\n");
3209   printf(
3210 "  work, I would like very much to hear from you.  A short letter or email\n");
3211   printf(
3212 "  (to jrs@cs.berkeley.edu) describing how you use Triangle will mean a lot\n"
3213 );
3214   printf(
3215 "  to me.  The more people I know are using this program, the more easily I\n"
3216 );
3217   printf(
3218 "  can justify spending time on improvements, which in turn will benefit\n");
3219   printf(
3220 "  you.  Also, I can put you on a list to receive email whenever a new\n");
3221   printf("  version of Triangle is available.\n\n");
3222   printf(
3223 "  If you use a mesh generated by Triangle in a publication, please include\n"
3224 );
3225   printf(
3226 "  an acknowledgment as well.  And please spell Triangle with a capital `T'!\n"
3227 );
3228   printf(
3229 "  If you want to include a citation, use `Jonathan Richard Shewchuk,\n");
3230   printf(
3231 "  ``Triangle: Engineering a 2D Quality Mesh Generator and Delaunay\n");
3232   printf(
3233 "  Triangulator,'' in Applied Computational Geometry:  Towards Geometric\n");
3234   printf(
3235 "  Engineering (Ming C. Lin and Dinesh Manocha, editors), volume 1148 of\n");
3236   printf(
3237 "  Lecture Notes in Computer Science, pages 203-222, Springer-Verlag,\n");
3238   printf(
3239 "  Berlin, May 1996.  (From the First ACM Workshop on Applied Computational\n"
3240 );
3241   printf("  Geometry.)'\n\n");
3242   printf("Research credit:\n\n");
3243   printf(
3244 "  Of course, I can take credit for only a fraction of the ideas that made\n");
3245   printf(
3246 "  this mesh generator possible.  Triangle owes its existence to the efforts\n"
3247 );
3248   printf(
3249 "  of many fine computational geometers and other researchers, including\n");
3250   printf(
3251 "  Marshall Bern, L. Paul Chew, Kenneth L. Clarkson, Boris Delaunay, Rex A.\n"
3252 );
3253   printf(
3254 "  Dwyer, David Eppstein, Steven Fortune, Leonidas J. Guibas, Donald E.\n");
3255   printf(
3256 "  Knuth, Charles L. Lawson, Der-Tsai Lee, Gary L. Miller, Ernst P. Mucke,\n");
3257   printf(
3258 "  Steven E. Pav, Douglas M. Priest, Jim Ruppert, Isaac Saias, Bruce J.\n");
3259   printf(
3260 "  Schachter, Micha Sharir, Peter W. Shor, Daniel D. Sleator, Jorge Stolfi,\n"
3261 );
3262   printf("  Robert E. Tarjan, Alper Ungor, Christopher J. Van Wyk, Noel J.\n");
3263   printf(
3264 "  Walkington, and Binhai Zhu.  See the comments at the beginning of the\n");
3265   printf("  source code for references.\n\n");
3266   triexit(0);
3267 }
3268 
3269 #endif /* not TRILIBRARY */
3270 
3271 /*****************************************************************************/
3272 /*                                                                           */
3273 /*  internalerror()   Ask the user to send me the defective product.  Exit.  */
3274 /*                                                                           */
3275 /*****************************************************************************/
3276 
internalerror()3277 void internalerror()
3278 {
3279   printf("  Please report this bug to jrs@cs.berkeley.edu\n");
3280   printf("  Include the message above, your input data set, and the exact\n");
3281   printf("    command line you used to run Triangle.\n");
3282   triexit(1);
3283 }
3284 
3285 /*****************************************************************************/
3286 /*                                                                           */
3287 /*  parsecommandline()   Read the command line, identify switches, and set   */
3288 /*                       up options and file names.                          */
3289 /*                                                                           */
3290 /*****************************************************************************/
3291 
3292 #ifdef ANSI_DECLARATORS
3293 void parsecommandline(int argc, char **argv, struct behavior *b)
3294 #else /* not ANSI_DECLARATORS */
3295 void parsecommandline(argc, argv, b)
3296 int argc;
3297 char **argv;
3298 struct behavior *b;
3299 #endif /* not ANSI_DECLARATORS */
3300 
3301 {
3302 #ifdef TRILIBRARY
3303 #define STARTINDEX 0
3304 #else /* not TRILIBRARY */
3305 #define STARTINDEX 1
3306   int increment;
3307   int meshnumber;
3308 #endif /* not TRILIBRARY */
3309   int i, j, k;
3310   char workstring[FILENAMESIZE];
3311 
3312   b->poly = b->refine = b->quality = 0;
3313   b->vararea = b->fixedarea = b->usertest = 0;
3314   b->regionattrib = b->convex = b->weighted = b->jettison = 0;
3315   b->firstnumber = 1;
3316   b->edgesout = b->voronoi = b->neighbors = b->geomview = 0;
3317   b->nobound = b->nopolywritten = b->nonodewritten = b->noelewritten = 0;
3318   b->noiterationnum = 0;
3319   b->noholes = b->noexact = 0;
3320   b->incremental = b->sweepline = 0;
3321   b->dwyer = 1;
3322   b->splitseg = 0;
3323   b->docheck = 0;
3324   b->nobisect = 0;
3325   b->conformdel = 0;
3326   b->steiner = -1;
3327   b->order = 1;
3328   b->minangle = 0.0;
3329   b->maxarea = -1.0;
3330   b->quiet = b->verbose = 0;
3331 #ifndef TRILIBRARY
3332   b->innodefilename[0] = '\0';
3333 #endif /* not TRILIBRARY */
3334 
3335   for (i = STARTINDEX; i < argc; i++) {
3336 #ifndef TRILIBRARY
3337     if (argv[i][0] == '-') {
3338 #endif /* not TRILIBRARY */
3339       for (j = STARTINDEX; argv[i][j] != '\0'; j++) {
3340         if (argv[i][j] == 'p') {
3341           b->poly = 1;
3342 	}
3343 #ifndef CDT_ONLY
3344         if (argv[i][j] == 'r') {
3345           b->refine = 1;
3346 	}
3347         if (argv[i][j] == 'q') {
3348           b->quality = 1;
3349           if (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) ||
3350               (argv[i][j + 1] == '.')) {
3351             k = 0;
3352             while (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) ||
3353                    (argv[i][j + 1] == '.')) {
3354               j++;
3355               workstring[k] = argv[i][j];
3356               k++;
3357             }
3358             workstring[k] = '\0';
3359             b->minangle = (REAL) strtod(workstring, (char **) NULL);
3360 	  } else {
3361             b->minangle = 20.0;
3362 	  }
3363 	}
3364         if (argv[i][j] == 'a') {
3365           b->quality = 1;
3366           if (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) ||
3367               (argv[i][j + 1] == '.')) {
3368             b->fixedarea = 1;
3369             k = 0;
3370             while (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) ||
3371                    (argv[i][j + 1] == '.')) {
3372               j++;
3373               workstring[k] = argv[i][j];
3374               k++;
3375             }
3376             workstring[k] = '\0';
3377             b->maxarea = (REAL) strtod(workstring, (char **) NULL);
3378             if (b->maxarea <= 0.0) {
3379               printf("Error:  Maximum area must be greater than zero.\n");
3380               triexit(1);
3381 	    }
3382 	  } else {
3383             b->vararea = 1;
3384 	  }
3385 	}
3386         if (argv[i][j] == 'u') {
3387           b->quality = 1;
3388           b->usertest = 1;
3389         }
3390 #endif /* not CDT_ONLY */
3391         if (argv[i][j] == 'A') {
3392           b->regionattrib = 1;
3393         }
3394         if (argv[i][j] == 'c') {
3395           b->convex = 1;
3396         }
3397         if (argv[i][j] == 'w') {
3398           b->weighted = 1;
3399         }
3400         if (argv[i][j] == 'W') {
3401           b->weighted = 2;
3402         }
3403         if (argv[i][j] == 'j') {
3404           b->jettison = 1;
3405         }
3406         if (argv[i][j] == 'z') {
3407           b->firstnumber = 0;
3408         }
3409         if (argv[i][j] == 'e') {
3410           b->edgesout = 1;
3411 	}
3412         if (argv[i][j] == 'v') {
3413           b->voronoi = 1;
3414 	}
3415         if (argv[i][j] == 'n') {
3416           b->neighbors = 1;
3417 	}
3418         if (argv[i][j] == 'g') {
3419           b->geomview = 1;
3420 	}
3421         if (argv[i][j] == 'B') {
3422           b->nobound = 1;
3423 	}
3424         if (argv[i][j] == 'P') {
3425           b->nopolywritten = 1;
3426 	}
3427         if (argv[i][j] == 'N') {
3428           b->nonodewritten = 1;
3429 	}
3430         if (argv[i][j] == 'E') {
3431           b->noelewritten = 1;
3432 	}
3433 #ifndef TRILIBRARY
3434         if (argv[i][j] == 'I') {
3435           b->noiterationnum = 1;
3436 	}
3437 #endif /* not TRILIBRARY */
3438         if (argv[i][j] == 'O') {
3439           b->noholes = 1;
3440 	}
3441         if (argv[i][j] == 'X') {
3442           b->noexact = 1;
3443 	}
3444         if (argv[i][j] == 'o') {
3445           if (argv[i][j + 1] == '2') {
3446             j++;
3447             b->order = 2;
3448           }
3449 	}
3450 #ifndef CDT_ONLY
3451         if (argv[i][j] == 'Y') {
3452           b->nobisect++;
3453 	}
3454         if (argv[i][j] == 'S') {
3455           b->steiner = 0;
3456           while ((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) {
3457             j++;
3458             b->steiner = b->steiner * 10 + (int) (argv[i][j] - '0');
3459           }
3460         }
3461 #endif /* not CDT_ONLY */
3462 #ifndef REDUCED
3463         if (argv[i][j] == 'i') {
3464           b->incremental = 1;
3465         }
3466         if (argv[i][j] == 'F') {
3467           b->sweepline = 1;
3468         }
3469 #endif /* not REDUCED */
3470         if (argv[i][j] == 'l') {
3471           b->dwyer = 0;
3472         }
3473 #ifndef REDUCED
3474 #ifndef CDT_ONLY
3475         if (argv[i][j] == 's') {
3476           b->splitseg = 1;
3477         }
3478         if ((argv[i][j] == 'D') || (argv[i][j] == 'L')) {
3479           b->quality = 1;
3480           b->conformdel = 1;
3481         }
3482 #endif /* not CDT_ONLY */
3483         if (argv[i][j] == 'C') {
3484           b->docheck = 1;
3485         }
3486 #endif /* not REDUCED */
3487         if (argv[i][j] == 'Q') {
3488           b->quiet = 1;
3489         }
3490         if (argv[i][j] == 'V') {
3491           b->verbose++;
3492         }
3493 #ifndef TRILIBRARY
3494         if ((argv[i][j] == 'h') || (argv[i][j] == 'H') ||
3495             (argv[i][j] == '?')) {
3496           info();
3497 	}
3498 #endif /* not TRILIBRARY */
3499       }
3500 #ifndef TRILIBRARY
3501     } else {
3502       strncpy(b->innodefilename, argv[i], FILENAMESIZE - 1);
3503       b->innodefilename[FILENAMESIZE - 1] = '\0';
3504     }
3505 #endif /* not TRILIBRARY */
3506   }
3507 #ifndef TRILIBRARY
3508   if (b->innodefilename[0] == '\0') {
3509     syntax();
3510   }
3511   if (!strcmp(&b->innodefilename[strlen(b->innodefilename) - 5], ".node")) {
3512     b->innodefilename[strlen(b->innodefilename) - 5] = '\0';
3513   }
3514   if (!strcmp(&b->innodefilename[strlen(b->innodefilename) - 5], ".poly")) {
3515     b->innodefilename[strlen(b->innodefilename) - 5] = '\0';
3516     b->poly = 1;
3517   }
3518 #ifndef CDT_ONLY
3519   if (!strcmp(&b->innodefilename[strlen(b->innodefilename) - 4], ".ele")) {
3520     b->innodefilename[strlen(b->innodefilename) - 4] = '\0';
3521     b->refine = 1;
3522   }
3523   if (!strcmp(&b->innodefilename[strlen(b->innodefilename) - 5], ".area")) {
3524     b->innodefilename[strlen(b->innodefilename) - 5] = '\0';
3525     b->refine = 1;
3526     b->quality = 1;
3527     b->vararea = 1;
3528   }
3529 #endif /* not CDT_ONLY */
3530 #endif /* not TRILIBRARY */
3531   b->usesegments = b->poly || b->refine || b->quality || b->convex;
3532   b->goodangle = cos(b->minangle * PI / 180.0);
3533   if (b->goodangle == 1.0) {
3534     b->offconstant = 0.0;
3535   } else {
3536     b->offconstant = 0.475 * sqrt((1.0 + b->goodangle) / (1.0 - b->goodangle));
3537   }
3538   b->goodangle *= b->goodangle;
3539   if (b->refine && b->noiterationnum) {
3540     printf(
3541       "Error:  You cannot use the -I switch when refining a triangulation.\n");
3542     triexit(1);
3543   }
3544   /* Be careful not to allocate space for element area constraints that */
3545   /*   will never be assigned any value (other than the default -1.0).  */
3546   if (!b->refine && !b->poly) {
3547     b->vararea = 0;
3548   }
3549   /* Be careful not to add an extra attribute to each element unless the */
3550   /*   input supports it (PSLG in, but not refining a preexisting mesh). */
3551   if (b->refine || !b->poly) {
3552     b->regionattrib = 0;
3553   }
3554   /* Regular/weighted triangulations are incompatible with PSLGs */
3555   /*   and meshing.                                              */
3556   if (b->weighted && (b->poly || b->quality)) {
3557     b->weighted = 0;
3558     if (!b->quiet) {
3559       printf("Warning:  weighted triangulations (-w, -W) are incompatible\n");
3560       printf("  with PSLGs (-p) and meshing (-q, -a, -u).  Weights ignored.\n"
3561              );
3562     }
3563   }
3564   if (b->jettison && b->nonodewritten && !b->quiet) {
3565     printf("Warning:  -j and -N switches are somewhat incompatible.\n");
3566     printf("  If any vertices are jettisoned, you will need the output\n");
3567     printf("  .node file to reconstruct the new node indices.");
3568   }
3569 
3570 #ifndef TRILIBRARY
3571   strcpy(b->inpolyfilename, b->innodefilename);
3572   strcpy(b->inelefilename, b->innodefilename);
3573   strcpy(b->areafilename, b->innodefilename);
3574   increment = 0;
3575   strcpy(workstring, b->innodefilename);
3576   j = 1;
3577   while (workstring[j] != '\0') {
3578     if ((workstring[j] == '.') && (workstring[j + 1] != '\0')) {
3579       increment = j + 1;
3580     }
3581     j++;
3582   }
3583   meshnumber = 0;
3584   if (increment > 0) {
3585     j = increment;
3586     do {
3587       if ((workstring[j] >= '0') && (workstring[j] <= '9')) {
3588         meshnumber = meshnumber * 10 + (int) (workstring[j] - '0');
3589       } else {
3590         increment = 0;
3591       }
3592       j++;
3593     } while (workstring[j] != '\0');
3594   }
3595   if (b->noiterationnum) {
3596     strcpy(b->outnodefilename, b->innodefilename);
3597     strcpy(b->outelefilename, b->innodefilename);
3598     strcpy(b->edgefilename, b->innodefilename);
3599     strcpy(b->vnodefilename, b->innodefilename);
3600     strcpy(b->vedgefilename, b->innodefilename);
3601     strcpy(b->neighborfilename, b->innodefilename);
3602     strcpy(b->offfilename, b->innodefilename);
3603     strcat(b->outnodefilename, ".node");
3604     strcat(b->outelefilename, ".ele");
3605     strcat(b->edgefilename, ".edge");
3606     strcat(b->vnodefilename, ".v.node");
3607     strcat(b->vedgefilename, ".v.edge");
3608     strcat(b->neighborfilename, ".neigh");
3609     strcat(b->offfilename, ".off");
3610   } else if (increment == 0) {
3611     strcpy(b->outnodefilename, b->innodefilename);
3612     strcpy(b->outpolyfilename, b->innodefilename);
3613     strcpy(b->outelefilename, b->innodefilename);
3614     strcpy(b->edgefilename, b->innodefilename);
3615     strcpy(b->vnodefilename, b->innodefilename);
3616     strcpy(b->vedgefilename, b->innodefilename);
3617     strcpy(b->neighborfilename, b->innodefilename);
3618     strcpy(b->offfilename, b->innodefilename);
3619     strcat(b->outnodefilename, ".1.node");
3620     strcat(b->outpolyfilename, ".1.poly");
3621     strcat(b->outelefilename, ".1.ele");
3622     strcat(b->edgefilename, ".1.edge");
3623     strcat(b->vnodefilename, ".1.v.node");
3624     strcat(b->vedgefilename, ".1.v.edge");
3625     strcat(b->neighborfilename, ".1.neigh");
3626     strcat(b->offfilename, ".1.off");
3627   } else {
3628     workstring[increment] = '%';
3629     workstring[increment + 1] = 'd';
3630     workstring[increment + 2] = '\0';
3631     sprintf(b->outnodefilename, workstring, meshnumber + 1);
3632     strcpy(b->outpolyfilename, b->outnodefilename);
3633     strcpy(b->outelefilename, b->outnodefilename);
3634     strcpy(b->edgefilename, b->outnodefilename);
3635     strcpy(b->vnodefilename, b->outnodefilename);
3636     strcpy(b->vedgefilename, b->outnodefilename);
3637     strcpy(b->neighborfilename, b->outnodefilename);
3638     strcpy(b->offfilename, b->outnodefilename);
3639     strcat(b->outnodefilename, ".node");
3640     strcat(b->outpolyfilename, ".poly");
3641     strcat(b->outelefilename, ".ele");
3642     strcat(b->edgefilename, ".edge");
3643     strcat(b->vnodefilename, ".v.node");
3644     strcat(b->vedgefilename, ".v.edge");
3645     strcat(b->neighborfilename, ".neigh");
3646     strcat(b->offfilename, ".off");
3647   }
3648   strcat(b->innodefilename, ".node");
3649   strcat(b->inpolyfilename, ".poly");
3650   strcat(b->inelefilename, ".ele");
3651   strcat(b->areafilename, ".area");
3652 #endif /* not TRILIBRARY */
3653 }
3654 
3655 /**                                                                         **/
3656 /**                                                                         **/
3657 /********* User interaction routines begin here                      *********/
3658 
3659 /********* Debugging routines begin here                             *********/
3660 /**                                                                         **/
3661 /**                                                                         **/
3662 
3663 /*****************************************************************************/
3664 /*                                                                           */
3665 /*  printtriangle()   Print out the details of an oriented triangle.         */
3666 /*                                                                           */
3667 /*  I originally wrote this procedure to simplify debugging; it can be       */
3668 /*  called directly from the debugger, and presents information about an     */
3669 /*  oriented triangle in digestible form.  It's also used when the           */
3670 /*  highest level of verbosity (`-VVV') is specified.                        */
3671 /*                                                                           */
3672 /*****************************************************************************/
3673 
3674 #ifdef ANSI_DECLARATORS
3675 void printtriangle(struct mesh *m, struct behavior *b, struct otri *t)
3676 #else /* not ANSI_DECLARATORS */
3677 void printtriangle(m, b, t)
3678 struct mesh *m;
3679 struct behavior *b;
3680 struct otri *t;
3681 #endif /* not ANSI_DECLARATORS */
3682 
3683 {
3684   struct otri printtri;
3685   struct osub printsh;
3686   vertex printvertex;
3687 
3688   printf("triangle x%lx with orientation %d:\n", (unsigned long) t->tri,
3689          t->orient);
3690   decode(t->tri[0], printtri);
3691   if (printtri.tri == m->dummytri) {
3692     printf("    [0] = Outer space\n");
3693   } else {
3694     printf("    [0] = x%lx  %d\n", (unsigned long) printtri.tri,
3695            printtri.orient);
3696   }
3697   decode(t->tri[1], printtri);
3698   if (printtri.tri == m->dummytri) {
3699     printf("    [1] = Outer space\n");
3700   } else {
3701     printf("    [1] = x%lx  %d\n", (unsigned long) printtri.tri,
3702            printtri.orient);
3703   }
3704   decode(t->tri[2], printtri);
3705   if (printtri.tri == m->dummytri) {
3706     printf("    [2] = Outer space\n");
3707   } else {
3708     printf("    [2] = x%lx  %d\n", (unsigned long) printtri.tri,
3709            printtri.orient);
3710   }
3711 
3712   org(*t, printvertex);
3713   if (printvertex == (vertex) NULL)
3714     printf("    Origin[%d] = NULL\n", (t->orient + 1) % 3 + 3);
3715   else
3716     printf("    Origin[%d] = x%lx  (%.12g, %.12g)\n",
3717            (t->orient + 1) % 3 + 3, (unsigned long) printvertex,
3718            (double)printvertex[0], (double)printvertex[1]);
3719   dest(*t, printvertex);
3720   if (printvertex == (vertex) NULL)
3721     printf("    Dest  [%d] = NULL\n", (t->orient + 2) % 3 + 3);
3722   else
3723     printf("    Dest  [%d] = x%lx  (%.12g, %.12g)\n",
3724            (t->orient + 2) % 3 + 3, (unsigned long) printvertex,
3725            (double)printvertex[0], (double)printvertex[1]);
3726   apex(*t, printvertex);
3727   if (printvertex == (vertex) NULL)
3728     printf("    Apex  [%d] = NULL\n", t->orient + 3);
3729   else
3730     printf("    Apex  [%d] = x%lx  (%.12g, %.12g)\n",
3731            t->orient + 3, (unsigned long) printvertex,
3732            (double)printvertex[0], (double)printvertex[1]);
3733 
3734   if (b->usesegments) {
3735     sdecode(t->tri[6], printsh);
3736     if (printsh.ss != m->dummysub) {
3737       printf("    [6] = x%lx  %d\n", (unsigned long) printsh.ss,
3738              printsh.ssorient);
3739     }
3740     sdecode(t->tri[7], printsh);
3741     if (printsh.ss != m->dummysub) {
3742       printf("    [7] = x%lx  %d\n", (unsigned long) printsh.ss,
3743              printsh.ssorient);
3744     }
3745     sdecode(t->tri[8], printsh);
3746     if (printsh.ss != m->dummysub) {
3747       printf("    [8] = x%lx  %d\n", (unsigned long) printsh.ss,
3748              printsh.ssorient);
3749     }
3750   }
3751 
3752   if (b->vararea) {
3753     printf("    Area constraint:  %.4g\n", (double)areabound(*t));
3754   }
3755 }
3756 
3757 /*****************************************************************************/
3758 /*                                                                           */
3759 /*  printsubseg()   Print out the details of an oriented subsegment.         */
3760 /*                                                                           */
3761 /*  I originally wrote this procedure to simplify debugging; it can be       */
3762 /*  called directly from the debugger, and presents information about an     */
3763 /*  oriented subsegment in digestible form.  It's also used when the highest */
3764 /*  level of verbosity (`-VVV') is specified.                                */
3765 /*                                                                           */
3766 /*****************************************************************************/
3767 
3768 #ifdef ANSI_DECLARATORS
3769 void printsubseg(struct mesh *m, struct behavior *b, struct osub *s)
3770 #else /* not ANSI_DECLARATORS */
3771 void printsubseg(m, b, s)
3772 struct mesh *m;
3773 struct behavior *b;
3774 struct osub *s;
3775 #endif /* not ANSI_DECLARATORS */
3776 
3777 {
3778   struct osub printsh;
3779   struct otri printtri;
3780   vertex printvertex;
3781 
3782   printf("subsegment x%lx with orientation %d and mark %d:\n",
3783          (unsigned long) s->ss, s->ssorient, mark(*s));
3784   sdecode(s->ss[0], printsh);
3785   if (printsh.ss == m->dummysub) {
3786     printf("    [0] = No subsegment\n");
3787   } else {
3788     printf("    [0] = x%lx  %d\n", (unsigned long) printsh.ss,
3789            printsh.ssorient);
3790   }
3791   sdecode(s->ss[1], printsh);
3792   if (printsh.ss == m->dummysub) {
3793     printf("    [1] = No subsegment\n");
3794   } else {
3795     printf("    [1] = x%lx  %d\n", (unsigned long) printsh.ss,
3796            printsh.ssorient);
3797   }
3798 
3799   sorg(*s, printvertex);
3800   if (printvertex == (vertex) NULL)
3801     printf("    Origin[%d] = NULL\n", 2 + s->ssorient);
3802   else
3803     printf("    Origin[%d] = x%lx  (%.12g, %.12g)\n",
3804            2 + s->ssorient, (unsigned long) printvertex,
3805            (double)printvertex[0], (double)printvertex[1]);
3806   sdest(*s, printvertex);
3807   if (printvertex == (vertex) NULL)
3808     printf("    Dest  [%d] = NULL\n", 3 - s->ssorient);
3809   else
3810     printf("    Dest  [%d] = x%lx  (%.12g, %.12g)\n",
3811            3 - s->ssorient, (unsigned long) printvertex,
3812            (double)printvertex[0], (double)printvertex[1]);
3813 
3814   decode(s->ss[6], printtri);
3815   if (printtri.tri == m->dummytri) {
3816     printf("    [6] = Outer space\n");
3817   } else {
3818     printf("    [6] = x%lx  %d\n", (unsigned long) printtri.tri,
3819            printtri.orient);
3820   }
3821   decode(s->ss[7], printtri);
3822   if (printtri.tri == m->dummytri) {
3823     printf("    [7] = Outer space\n");
3824   } else {
3825     printf("    [7] = x%lx  %d\n", (unsigned long) printtri.tri,
3826            printtri.orient);
3827   }
3828 
3829   segorg(*s, printvertex);
3830   if (printvertex == (vertex) NULL)
3831     printf("    Segment origin[%d] = NULL\n", 4 + s->ssorient);
3832   else
3833     printf("    Segment origin[%d] = x%lx  (%.12g, %.12g)\n",
3834            4 + s->ssorient, (unsigned long) printvertex,
3835            (double)printvertex[0], (double)printvertex[1]);
3836   segdest(*s, printvertex);
3837   if (printvertex == (vertex) NULL)
3838     printf("    Segment dest  [%d] = NULL\n", 5 - s->ssorient);
3839   else
3840     printf("    Segment dest  [%d] = x%lx  (%.12g, %.12g)\n",
3841            5 - s->ssorient, (unsigned long) printvertex,
3842            (double)printvertex[0], (double)printvertex[1]);
3843 }
3844 
3845 /**                                                                         **/
3846 /**                                                                         **/
3847 /********* Debugging routines end here                               *********/
3848 
3849 /********* Memory management routines begin here                     *********/
3850 /**                                                                         **/
3851 /**                                                                         **/
3852 
3853 /*****************************************************************************/
3854 /*                                                                           */
3855 /*  poolzero()   Set all of a pool's fields to zero.                         */
3856 /*                                                                           */
3857 /*  This procedure should never be called on a pool that has any memory      */
3858 /*  allocated to it, as that memory would leak.                              */
3859 /*                                                                           */
3860 /*****************************************************************************/
3861 
3862 #ifdef ANSI_DECLARATORS
3863 void poolzero(struct memorypool *pool)
3864 #else /* not ANSI_DECLARATORS */
3865 void poolzero(pool)
3866 struct memorypool *pool;
3867 #endif /* not ANSI_DECLARATORS */
3868 
3869 {
3870   pool->firstblock = (VOID **) NULL;
3871   pool->nowblock = (VOID **) NULL;
3872   pool->nextitem = (VOID *) NULL;
3873   pool->deaditemstack = (VOID *) NULL;
3874   pool->pathblock = (VOID **) NULL;
3875   pool->pathitem = (VOID *) NULL;
3876   pool->alignbytes = 0;
3877   pool->itembytes = 0;
3878   pool->itemsperblock = 0;
3879   pool->itemsfirstblock = 0;
3880   pool->items = 0;
3881   pool->maxitems = 0;
3882   pool->unallocateditems = 0;
3883   pool->pathitemsleft = 0;
3884 }
3885 
3886 /*****************************************************************************/
3887 /*                                                                           */
3888 /*  poolrestart()   Deallocate all items in a pool.                          */
3889 /*                                                                           */
3890 /*  The pool is returned to its starting state, except that no memory is     */
3891 /*  freed to the operating system.  Rather, the previously allocated blocks  */
3892 /*  are ready to be reused.                                                  */
3893 /*                                                                           */
3894 /*****************************************************************************/
3895 
3896 #ifdef ANSI_DECLARATORS
3897 void poolrestart(struct memorypool *pool)
3898 #else /* not ANSI_DECLARATORS */
3899 void poolrestart(pool)
3900 struct memorypool *pool;
3901 #endif /* not ANSI_DECLARATORS */
3902 
3903 {
3904   unsigned long alignptr;
3905 
3906   pool->items = 0;
3907   pool->maxitems = 0;
3908 
3909   /* Set the currently active block. */
3910   pool->nowblock = pool->firstblock;
3911   /* Find the first item in the pool.  Increment by the size of (VOID *). */
3912   alignptr = (unsigned long) (pool->nowblock + 1);
3913   /* Align the item on an `alignbytes'-byte boundary. */
3914   pool->nextitem = (VOID *)
3915     (alignptr + (unsigned long) pool->alignbytes -
3916      (alignptr % (unsigned long) pool->alignbytes));
3917   /* There are lots of unallocated items left in this block. */
3918   pool->unallocateditems = pool->itemsfirstblock;
3919   /* The stack of deallocated items is empty. */
3920   pool->deaditemstack = (VOID *) NULL;
3921 }
3922 
3923 /*****************************************************************************/
3924 /*                                                                           */
3925 /*  poolinit()   Initialize a pool of memory for allocation of items.        */
3926 /*                                                                           */
3927 /*  This routine initializes the machinery for allocating items.  A `pool'   */
3928 /*  is created whose records have size at least `bytecount'.  Items will be  */
3929 /*  allocated in `itemcount'-item blocks.  Each item is assumed to be a      */
3930 /*  collection of words, and either pointers or floating-point values are    */
3931 /*  assumed to be the "primary" word type.  (The "primary" word type is used */
3932 /*  to determine alignment of items.)  If `alignment' isn't zero, all items  */
3933 /*  will be `alignment'-byte aligned in memory.  `alignment' must be either  */
3934 /*  a multiple or a factor of the primary word size; powers of two are safe. */
3935 /*  `alignment' is normally used to create a few unused bits at the bottom   */
3936 /*  of each item's pointer, in which information may be stored.              */
3937 /*                                                                           */
3938 /*  Don't change this routine unless you understand it.                      */
3939 /*                                                                           */
3940 /*****************************************************************************/
3941 
3942 #ifdef ANSI_DECLARATORS
3943 void poolinit(struct memorypool *pool, int bytecount, int itemcount,
3944               int firstitemcount, int alignment)
3945 #else /* not ANSI_DECLARATORS */
3946 void poolinit(pool, bytecount, itemcount, firstitemcount, alignment)
3947 struct memorypool *pool;
3948 int bytecount;
3949 int itemcount;
3950 int firstitemcount;
3951 int alignment;
3952 #endif /* not ANSI_DECLARATORS */
3953 
3954 {
3955   /* Find the proper alignment, which must be at least as large as:   */
3956   /*   - The parameter `alignment'.                                   */
3957   /*   - sizeof(VOID *), so the stack of dead items can be maintained */
3958   /*       without unaligned accesses.                                */
3959   if (alignment > sizeof(VOID *)) {
3960     pool->alignbytes = alignment;
3961   } else {
3962     pool->alignbytes = sizeof(VOID *);
3963   }
3964   pool->itembytes = ((bytecount - 1) / pool->alignbytes + 1) *
3965                     pool->alignbytes;
3966   pool->itemsperblock = itemcount;
3967   if (firstitemcount == 0) {
3968     pool->itemsfirstblock = itemcount;
3969   } else {
3970     pool->itemsfirstblock = firstitemcount;
3971   }
3972 
3973   /* Allocate a block of items.  Space for `itemsfirstblock' items and one  */
3974   /*   pointer (to point to the next block) are allocated, as well as space */
3975   /*   to ensure alignment of the items.                                    */
3976   pool->firstblock = (VOID **)
3977     trimalloc(pool->itemsfirstblock * pool->itembytes + (int) sizeof(VOID *) +
3978               pool->alignbytes);
3979   /* Set the next block pointer to NULL. */
3980   *(pool->firstblock) = (VOID *) NULL;
3981   poolrestart(pool);
3982 }
3983 
3984 /*****************************************************************************/
3985 /*                                                                           */
3986 /*  pooldeinit()   Free to the operating system all memory taken by a pool.  */
3987 /*                                                                           */
3988 /*****************************************************************************/
3989 
3990 #ifdef ANSI_DECLARATORS
3991 void pooldeinit(struct memorypool *pool)
3992 #else /* not ANSI_DECLARATORS */
3993 void pooldeinit(pool)
3994 struct memorypool *pool;
3995 #endif /* not ANSI_DECLARATORS */
3996 
3997 {
3998   while (pool->firstblock != (VOID **) NULL) {
3999     pool->nowblock = (VOID **) *(pool->firstblock);
4000     trifree((VOID *) pool->firstblock);
4001     pool->firstblock = pool->nowblock;
4002   }
4003 }
4004 
4005 /*****************************************************************************/
4006 /*                                                                           */
4007 /*  poolalloc()   Allocate space for an item.                                */
4008 /*                                                                           */
4009 /*****************************************************************************/
4010 
4011 #ifdef ANSI_DECLARATORS
4012 VOID *poolalloc(struct memorypool *pool)
4013 #else /* not ANSI_DECLARATORS */
4014 VOID *poolalloc(pool)
4015 struct memorypool *pool;
4016 #endif /* not ANSI_DECLARATORS */
4017 
4018 {
4019   VOID *newitem;
4020   VOID **newblock;
4021   unsigned long alignptr;
4022 
4023   /* First check the linked list of dead items.  If the list is not   */
4024   /*   empty, allocate an item from the list rather than a fresh one. */
4025   if (pool->deaditemstack != (VOID *) NULL) {
4026     newitem = pool->deaditemstack;               /* Take first item in list. */
4027     pool->deaditemstack = * (VOID **) pool->deaditemstack;
4028   } else {
4029     /* Check if there are any free items left in the current block. */
4030     if (pool->unallocateditems == 0) {
4031       /* Check if another block must be allocated. */
4032       if (*(pool->nowblock) == (VOID *) NULL) {
4033         /* Allocate a new block of items, pointed to by the previous block. */
4034         newblock = (VOID **) trimalloc(pool->itemsperblock * pool->itembytes +
4035                                        (int) sizeof(VOID *) +
4036                                        pool->alignbytes);
4037         *(pool->nowblock) = (VOID *) newblock;
4038         /* The next block pointer is NULL. */
4039         *newblock = (VOID *) NULL;
4040       }
4041 
4042       /* Move to the new block. */
4043       pool->nowblock = (VOID **) *(pool->nowblock);
4044       /* Find the first item in the block.    */
4045       /*   Increment by the size of (VOID *). */
4046       alignptr = (unsigned long) (pool->nowblock + 1);
4047       /* Align the item on an `alignbytes'-byte boundary. */
4048       pool->nextitem = (VOID *)
4049         (alignptr + (unsigned long) pool->alignbytes -
4050          (alignptr % (unsigned long) pool->alignbytes));
4051       /* There are lots of unallocated items left in this block. */
4052       pool->unallocateditems = pool->itemsperblock;
4053     }
4054 
4055     /* Allocate a new item. */
4056     newitem = pool->nextitem;
4057     /* Advance `nextitem' pointer to next free item in block. */
4058     pool->nextitem = (VOID *) ((char *) pool->nextitem + pool->itembytes);
4059     pool->unallocateditems--;
4060     pool->maxitems++;
4061   }
4062   pool->items++;
4063   return newitem;
4064 }
4065 
4066 /*****************************************************************************/
4067 /*                                                                           */
4068 /*  pooldealloc()   Deallocate space for an item.                            */
4069 /*                                                                           */
4070 /*  The deallocated space is stored in a queue for later reuse.              */
4071 /*                                                                           */
4072 /*****************************************************************************/
4073 
4074 #ifdef ANSI_DECLARATORS
4075 void pooldealloc(struct memorypool *pool, VOID *dyingitem)
4076 #else /* not ANSI_DECLARATORS */
4077 void pooldealloc(pool, dyingitem)
4078 struct memorypool *pool;
4079 VOID *dyingitem;
4080 #endif /* not ANSI_DECLARATORS */
4081 
4082 {
4083   /* Push freshly killed item onto stack. */
4084   *((VOID **) dyingitem) = pool->deaditemstack;
4085   pool->deaditemstack = dyingitem;
4086   pool->items--;
4087 }
4088 
4089 /*****************************************************************************/
4090 /*                                                                           */
4091 /*  traversalinit()   Prepare to traverse the entire list of items.          */
4092 /*                                                                           */
4093 /*  This routine is used in conjunction with traverse().                     */
4094 /*                                                                           */
4095 /*****************************************************************************/
4096 
4097 #ifdef ANSI_DECLARATORS
4098 void traversalinit(struct memorypool *pool)
4099 #else /* not ANSI_DECLARATORS */
4100 void traversalinit(pool)
4101 struct memorypool *pool;
4102 #endif /* not ANSI_DECLARATORS */
4103 
4104 {
4105   unsigned long alignptr;
4106 
4107   /* Begin the traversal in the first block. */
4108   pool->pathblock = pool->firstblock;
4109   /* Find the first item in the block.  Increment by the size of (VOID *). */
4110   alignptr = (unsigned long) (pool->pathblock + 1);
4111   /* Align with item on an `alignbytes'-byte boundary. */
4112   pool->pathitem = (VOID *)
4113     (alignptr + (unsigned long) pool->alignbytes -
4114      (alignptr % (unsigned long) pool->alignbytes));
4115   /* Set the number of items left in the current block. */
4116   pool->pathitemsleft = pool->itemsfirstblock;
4117 }
4118 
4119 /*****************************************************************************/
4120 /*                                                                           */
4121 /*  traverse()   Find the next item in the list.                             */
4122 /*                                                                           */
4123 /*  This routine is used in conjunction with traversalinit().  Be forewarned */
4124 /*  that this routine successively returns all items in the list, including  */
4125 /*  deallocated ones on the deaditemqueue.  It's up to you to figure out     */
4126 /*  which ones are actually dead.  Why?  I don't want to allocate extra      */
4127 /*  space just to demarcate dead items.  It can usually be done more         */
4128 /*  space-efficiently by a routine that knows something about the structure  */
4129 /*  of the item.                                                             */
4130 /*                                                                           */
4131 /*****************************************************************************/
4132 
4133 #ifdef ANSI_DECLARATORS
4134 VOID *traverse(struct memorypool *pool)
4135 #else /* not ANSI_DECLARATORS */
4136 VOID *traverse(pool)
4137 struct memorypool *pool;
4138 #endif /* not ANSI_DECLARATORS */
4139 
4140 {
4141   VOID *newitem;
4142   unsigned long alignptr;
4143 
4144   /* Stop upon exhausting the list of items. */
4145   if (pool->pathitem == pool->nextitem) {
4146     return (VOID *) NULL;
4147   }
4148 
4149   /* Check whether any untraversed items remain in the current block. */
4150   if (pool->pathitemsleft == 0) {
4151     /* Find the next block. */
4152     pool->pathblock = (VOID **) *(pool->pathblock);
4153     /* Find the first item in the block.  Increment by the size of (VOID *). */
4154     alignptr = (unsigned long) (pool->pathblock + 1);
4155     /* Align with item on an `alignbytes'-byte boundary. */
4156     pool->pathitem = (VOID *)
4157       (alignptr + (unsigned long) pool->alignbytes -
4158        (alignptr % (unsigned long) pool->alignbytes));
4159     /* Set the number of items left in the current block. */
4160     pool->pathitemsleft = pool->itemsperblock;
4161   }
4162 
4163   newitem = pool->pathitem;
4164   /* Find the next item in the block. */
4165   pool->pathitem = (VOID *) ((char *) pool->pathitem + pool->itembytes);
4166   pool->pathitemsleft--;
4167   return newitem;
4168 }
4169 
4170 /*****************************************************************************/
4171 /*                                                                           */
4172 /*  dummyinit()   Initialize the triangle that fills "outer space" and the   */
4173 /*                omnipresent subsegment.                                    */
4174 /*                                                                           */
4175 /*  The triangle that fills "outer space," called `dummytri', is pointed to  */
4176 /*  by every triangle and subsegment on a boundary (be it outer or inner) of */
4177 /*  the triangulation.  Also, `dummytri' points to one of the triangles on   */
4178 /*  the convex hull (until the holes and concavities are carved), making it  */
4179 /*  possible to find a starting triangle for point location.                 */
4180 /*                                                                           */
4181 /*  The omnipresent subsegment, `dummysub', is pointed to by every triangle  */
4182 /*  or subsegment that doesn't have a full complement of real subsegments    */
4183 /*  to point to.                                                             */
4184 /*                                                                           */
4185 /*  `dummytri' and `dummysub' are generally required to fulfill only a few   */
4186 /*  invariants:  their vertices must remain NULL and `dummytri' must always  */
4187 /*  be bonded (at offset zero) to some triangle on the convex hull of the    */
4188 /*  mesh, via a boundary edge.  Otherwise, the connections of `dummytri' and */
4189 /*  `dummysub' may change willy-nilly.  This makes it possible to avoid      */
4190 /*  writing a good deal of special-case code (in the edge flip, for example) */
4191 /*  for dealing with the boundary of the mesh, places where no subsegment is */
4192 /*  present, and so forth.  Other entities are frequently bonded to          */
4193 /*  `dummytri' and `dummysub' as if they were real mesh entities, with no    */
4194 /*  harm done.                                                               */
4195 /*                                                                           */
4196 /*****************************************************************************/
4197 
4198 #ifdef ANSI_DECLARATORS
4199 void dummyinit(struct mesh *m, struct behavior *b, int trianglebytes,
4200                int subsegbytes)
4201 #else /* not ANSI_DECLARATORS */
4202 void dummyinit(m, b, trianglebytes, subsegbytes)
4203 struct mesh *m;
4204 struct behavior *b;
4205 int trianglebytes;
4206 int subsegbytes;
4207 #endif /* not ANSI_DECLARATORS */
4208 
4209 {
4210   unsigned long alignptr;
4211 
4212   /* Set up `dummytri', the `triangle' that occupies "outer space." */
4213   m->dummytribase = (triangle *) trimalloc(trianglebytes +
4214                                            m->triangles.alignbytes);
4215   /* Align `dummytri' on a `triangles.alignbytes'-byte boundary. */
4216   alignptr = (unsigned long) m->dummytribase;
4217   m->dummytri = (triangle *)
4218     (alignptr + (unsigned long) m->triangles.alignbytes -
4219      (alignptr % (unsigned long) m->triangles.alignbytes));
4220   /* Initialize the three adjoining triangles to be "outer space."  These  */
4221   /*   will eventually be changed by various bonding operations, but their */
4222   /*   values don't really matter, as long as they can legally be          */
4223   /*   dereferenced.                                                       */
4224   m->dummytri[0] = (triangle) m->dummytri;
4225   m->dummytri[1] = (triangle) m->dummytri;
4226   m->dummytri[2] = (triangle) m->dummytri;
4227   /* Three NULL vertices. */
4228   m->dummytri[3] = (triangle) NULL;
4229   m->dummytri[4] = (triangle) NULL;
4230   m->dummytri[5] = (triangle) NULL;
4231 
4232   if (b->usesegments) {
4233     /* Set up `dummysub', the omnipresent subsegment pointed to by any */
4234     /*   triangle side or subsegment end that isn't attached to a real */
4235     /*   subsegment.                                                   */
4236     m->dummysubbase = (subseg *) trimalloc(subsegbytes +
4237                                            m->subsegs.alignbytes);
4238     /* Align `dummysub' on a `subsegs.alignbytes'-byte boundary. */
4239     alignptr = (unsigned long) m->dummysubbase;
4240     m->dummysub = (subseg *)
4241       (alignptr + (unsigned long) m->subsegs.alignbytes -
4242        (alignptr % (unsigned long) m->subsegs.alignbytes));
4243     /* Initialize the two adjoining subsegments to be the omnipresent      */
4244     /*   subsegment.  These will eventually be changed by various bonding  */
4245     /*   operations, but their values don't really matter, as long as they */
4246     /*   can legally be dereferenced.                                      */
4247     m->dummysub[0] = (subseg) m->dummysub;
4248     m->dummysub[1] = (subseg) m->dummysub;
4249     /* Four NULL vertices. */
4250     m->dummysub[2] = (subseg) NULL;
4251     m->dummysub[3] = (subseg) NULL;
4252     m->dummysub[4] = (subseg) NULL;
4253     m->dummysub[5] = (subseg) NULL;
4254     /* Initialize the two adjoining triangles to be "outer space." */
4255     m->dummysub[6] = (subseg) m->dummytri;
4256     m->dummysub[7] = (subseg) m->dummytri;
4257     /* Set the boundary marker to zero. */
4258     * (int *) (m->dummysub + 8) = 0;
4259 
4260     /* Initialize the three adjoining subsegments of `dummytri' to be */
4261     /*   the omnipresent subsegment.                                  */
4262     m->dummytri[6] = (triangle) m->dummysub;
4263     m->dummytri[7] = (triangle) m->dummysub;
4264     m->dummytri[8] = (triangle) m->dummysub;
4265   }
4266 }
4267 
4268 /*****************************************************************************/
4269 /*                                                                           */
4270 /*  initializevertexpool()   Calculate the size of the vertex data structure */
4271 /*                           and initialize its memory pool.                 */
4272 /*                                                                           */
4273 /*  This routine also computes the `vertexmarkindex' and `vertex2triindex'   */
4274 /*  indices used to find values within each vertex.                          */
4275 /*                                                                           */
4276 /*****************************************************************************/
4277 
4278 #ifdef ANSI_DECLARATORS
4279 void initializevertexpool(struct mesh *m, struct behavior *b)
4280 #else /* not ANSI_DECLARATORS */
4281 void initializevertexpool(m, b)
4282 struct mesh *m;
4283 struct behavior *b;
4284 #endif /* not ANSI_DECLARATORS */
4285 
4286 {
4287   int vertexsize;
4288 
4289   /* The index within each vertex at which the boundary marker is found,    */
4290   /*   followed by the vertex type.  Ensure the vertex marker is aligned to */
4291   /*   a sizeof(int)-byte address.                                          */
4292   m->vertexmarkindex = ((m->mesh_dim + m->nextras) * sizeof(REAL) +
4293                         sizeof(int) - 1) /
4294                        sizeof(int);
4295   vertexsize = (m->vertexmarkindex + 2) * sizeof(int);
4296   if (b->poly) {
4297     /* The index within each vertex at which a triangle pointer is found.  */
4298     /*   Ensure the pointer is aligned to a sizeof(triangle)-byte address. */
4299     m->vertex2triindex = (vertexsize + sizeof(triangle) - 1) /
4300                          sizeof(triangle);
4301     vertexsize = (m->vertex2triindex + 1) * sizeof(triangle);
4302   }
4303 
4304   /* Initialize the pool of vertices. */
4305   poolinit(&m->vertices, vertexsize, VERTEXPERBLOCK,
4306            m->invertices > VERTEXPERBLOCK ? m->invertices : VERTEXPERBLOCK,
4307            sizeof(REAL));
4308 }
4309 
4310 /*****************************************************************************/
4311 /*                                                                           */
4312 /*  initializetrisubpools()   Calculate the sizes of the triangle and        */
4313 /*                            subsegment data structures and initialize      */
4314 /*                            their memory pools.                            */
4315 /*                                                                           */
4316 /*  This routine also computes the `highorderindex', `elemattribindex', and  */
4317 /*  `areaboundindex' indices used to find values within each triangle.       */
4318 /*                                                                           */
4319 /*****************************************************************************/
4320 
4321 #ifdef ANSI_DECLARATORS
4322 void initializetrisubpools(struct mesh *m, struct behavior *b)
4323 #else /* not ANSI_DECLARATORS */
4324 void initializetrisubpools(m, b)
4325 struct mesh *m;
4326 struct behavior *b;
4327 #endif /* not ANSI_DECLARATORS */
4328 
4329 {
4330   int trisize;
4331 
4332   /* The index within each triangle at which the extra nodes (above three)  */
4333   /*   associated with high order elements are found.  There are three      */
4334   /*   pointers to other triangles, three pointers to corners, and possibly */
4335   /*   three pointers to subsegments before the extra nodes.                */
4336   m->highorderindex = 6 + (b->usesegments * 3);
4337   /* The number of bytes occupied by a triangle. */
4338   trisize = ((b->order + 1) * (b->order + 2) / 2 + (m->highorderindex - 3)) *
4339             sizeof(triangle);
4340   /* The index within each triangle at which its attributes are found, */
4341   /*   where the index is measured in REALs.                           */
4342   m->elemattribindex = (trisize + sizeof(REAL) - 1) / sizeof(REAL);
4343   /* The index within each triangle at which the maximum area constraint  */
4344   /*   is found, where the index is measured in REALs.  Note that if the  */
4345   /*   `regionattrib' flag is set, an additional attribute will be added. */
4346   m->areaboundindex = m->elemattribindex + m->eextras + b->regionattrib;
4347   /* If triangle attributes or an area bound are needed, increase the number */
4348   /*   of bytes occupied by a triangle.                                      */
4349   if (b->vararea) {
4350     trisize = (m->areaboundindex + 1) * sizeof(REAL);
4351   } else if (m->eextras + b->regionattrib > 0) {
4352     trisize = m->areaboundindex * sizeof(REAL);
4353   }
4354   /* If a Voronoi diagram or triangle neighbor graph is requested, make    */
4355   /*   sure there's room to store an integer index in each triangle.  This */
4356   /*   integer index can occupy the same space as the subsegment pointers  */
4357   /*   or attributes or area constraint or extra nodes.                    */
4358   if ((b->voronoi || b->neighbors) &&
4359       (trisize < 6 * sizeof(triangle) + sizeof(int))) {
4360     trisize = 6 * sizeof(triangle) + sizeof(int);
4361   }
4362 
4363   /* Having determined the memory size of a triangle, initialize the pool. */
4364   poolinit(&m->triangles, trisize, TRIPERBLOCK,
4365            (2 * m->invertices - 2) > TRIPERBLOCK ? (2 * m->invertices - 2) :
4366            TRIPERBLOCK, 4);
4367 
4368   if (b->usesegments) {
4369     /* Initialize the pool of subsegments.  Take into account all eight */
4370     /*   pointers and one boundary marker.                              */
4371     poolinit(&m->subsegs, 8 * sizeof(triangle) + sizeof(int),
4372              SUBSEGPERBLOCK, SUBSEGPERBLOCK, 4);
4373 
4374     /* Initialize the "outer space" triangle and omnipresent subsegment. */
4375     dummyinit(m, b, m->triangles.itembytes, m->subsegs.itembytes);
4376   } else {
4377     /* Initialize the "outer space" triangle. */
4378     dummyinit(m, b, m->triangles.itembytes, 0);
4379   }
4380 }
4381 
4382 /*****************************************************************************/
4383 /*                                                                           */
4384 /*  triangledealloc()   Deallocate space for a triangle, marking it dead.    */
4385 /*                                                                           */
4386 /*****************************************************************************/
4387 
4388 #ifdef ANSI_DECLARATORS
4389 void triangledealloc(struct mesh *m, triangle *dyingtriangle)
4390 #else /* not ANSI_DECLARATORS */
4391 void triangledealloc(m, dyingtriangle)
4392 struct mesh *m;
4393 triangle *dyingtriangle;
4394 #endif /* not ANSI_DECLARATORS */
4395 
4396 {
4397   /* Mark the triangle as dead.  This makes it possible to detect dead */
4398   /*   triangles when traversing the list of all triangles.            */
4399   killtri(dyingtriangle);
4400   pooldealloc(&m->triangles, (VOID *) dyingtriangle);
4401 }
4402 
4403 /*****************************************************************************/
4404 /*                                                                           */
4405 /*  triangletraverse()   Traverse the triangles, skipping dead ones.         */
4406 /*                                                                           */
4407 /*****************************************************************************/
4408 
4409 #ifdef ANSI_DECLARATORS
4410 triangle *triangletraverse(struct mesh *m)
4411 #else /* not ANSI_DECLARATORS */
4412 triangle *triangletraverse(m)
4413 struct mesh *m;
4414 #endif /* not ANSI_DECLARATORS */
4415 
4416 {
4417   triangle *newtriangle;
4418 
4419   do {
4420     newtriangle = (triangle *) traverse(&m->triangles);
4421     if (newtriangle == (triangle *) NULL) {
4422       return (triangle *) NULL;
4423     }
4424   } while (deadtri(newtriangle));                         /* Skip dead ones. */
4425   return newtriangle;
4426 }
4427 
4428 /*****************************************************************************/
4429 /*                                                                           */
4430 /*  subsegdealloc()   Deallocate space for a subsegment, marking it dead.    */
4431 /*                                                                           */
4432 /*****************************************************************************/
4433 
4434 #ifdef ANSI_DECLARATORS
4435 void subsegdealloc(struct mesh *m, subseg *dyingsubseg)
4436 #else /* not ANSI_DECLARATORS */
4437 void subsegdealloc(m, dyingsubseg)
4438 struct mesh *m;
4439 subseg *dyingsubseg;
4440 #endif /* not ANSI_DECLARATORS */
4441 
4442 {
4443   /* Mark the subsegment as dead.  This makes it possible to detect dead */
4444   /*   subsegments when traversing the list of all subsegments.          */
4445   killsubseg(dyingsubseg);
4446   pooldealloc(&m->subsegs, (VOID *) dyingsubseg);
4447 }
4448 
4449 /*****************************************************************************/
4450 /*                                                                           */
4451 /*  subsegtraverse()   Traverse the subsegments, skipping dead ones.         */
4452 /*                                                                           */
4453 /*****************************************************************************/
4454 
4455 #ifdef ANSI_DECLARATORS
4456 subseg *subsegtraverse(struct mesh *m)
4457 #else /* not ANSI_DECLARATORS */
4458 subseg *subsegtraverse(m)
4459 struct mesh *m;
4460 #endif /* not ANSI_DECLARATORS */
4461 
4462 {
4463   subseg *newsubseg;
4464 
4465   do {
4466     newsubseg = (subseg *) traverse(&m->subsegs);
4467     if (newsubseg == (subseg *) NULL) {
4468       return (subseg *) NULL;
4469     }
4470   } while (deadsubseg(newsubseg));                        /* Skip dead ones. */
4471   return newsubseg;
4472 }
4473 
4474 /*****************************************************************************/
4475 /*                                                                           */
4476 /*  vertexdealloc()   Deallocate space for a vertex, marking it dead.        */
4477 /*                                                                           */
4478 /*****************************************************************************/
4479 
4480 #ifdef ANSI_DECLARATORS
4481 void vertexdealloc(struct mesh *m, vertex dyingvertex)
4482 #else /* not ANSI_DECLARATORS */
4483 void vertexdealloc(m, dyingvertex)
4484 struct mesh *m;
4485 vertex dyingvertex;
4486 #endif /* not ANSI_DECLARATORS */
4487 
4488 {
4489   /* Mark the vertex as dead.  This makes it possible to detect dead */
4490   /*   vertices when traversing the list of all vertices.            */
4491   setvertextype(dyingvertex, DEADVERTEX);
4492   pooldealloc(&m->vertices, (VOID *) dyingvertex);
4493 }
4494 
4495 /*****************************************************************************/
4496 /*                                                                           */
4497 /*  vertextraverse()   Traverse the vertices, skipping dead ones.            */
4498 /*                                                                           */
4499 /*****************************************************************************/
4500 
4501 #ifdef ANSI_DECLARATORS
4502 vertex vertextraverse(struct mesh *m)
4503 #else /* not ANSI_DECLARATORS */
4504 vertex vertextraverse(m)
4505 struct mesh *m;
4506 #endif /* not ANSI_DECLARATORS */
4507 
4508 {
4509   vertex newvertex;
4510 
4511   do {
4512     newvertex = (vertex) traverse(&m->vertices);
4513     if (newvertex == (vertex) NULL) {
4514       return (vertex) NULL;
4515     }
4516   } while (vertextype(newvertex) == DEADVERTEX);          /* Skip dead ones. */
4517   return newvertex;
4518 }
4519 
4520 /*****************************************************************************/
4521 /*                                                                           */
4522 /*  badsubsegdealloc()   Deallocate space for a bad subsegment, marking it   */
4523 /*                       dead.                                               */
4524 /*                                                                           */
4525 /*****************************************************************************/
4526 
4527 #ifndef CDT_ONLY
4528 
4529 #ifdef ANSI_DECLARATORS
4530 void badsubsegdealloc(struct mesh *m, struct badsubseg *dyingseg)
4531 #else /* not ANSI_DECLARATORS */
4532 void badsubsegdealloc(m, dyingseg)
4533 struct mesh *m;
4534 struct badsubseg *dyingseg;
4535 #endif /* not ANSI_DECLARATORS */
4536 
4537 {
4538   /* Set subsegment's origin to NULL.  This makes it possible to detect dead */
4539   /*   badsubsegs when traversing the list of all badsubsegs             .   */
4540   dyingseg->subsegorg = (vertex) NULL;
4541   pooldealloc(&m->badsubsegs, (VOID *) dyingseg);
4542 }
4543 
4544 #endif /* not CDT_ONLY */
4545 
4546 /*****************************************************************************/
4547 /*                                                                           */
4548 /*  badsubsegtraverse()   Traverse the bad subsegments, skipping dead ones.  */
4549 /*                                                                           */
4550 /*****************************************************************************/
4551 
4552 #ifndef CDT_ONLY
4553 
4554 #ifdef ANSI_DECLARATORS
4555 struct badsubseg *badsubsegtraverse(struct mesh *m)
4556 #else /* not ANSI_DECLARATORS */
4557 struct badsubseg *badsubsegtraverse(m)
4558 struct mesh *m;
4559 #endif /* not ANSI_DECLARATORS */
4560 
4561 {
4562   struct badsubseg *newseg;
4563 
4564   do {
4565     newseg = (struct badsubseg *) traverse(&m->badsubsegs);
4566     if (newseg == (struct badsubseg *) NULL) {
4567       return (struct badsubseg *) NULL;
4568     }
4569   } while (newseg->subsegorg == (vertex) NULL);           /* Skip dead ones. */
4570   return newseg;
4571 }
4572 
4573 #endif /* not CDT_ONLY */
4574 
4575 /*****************************************************************************/
4576 /*                                                                           */
4577 /*  getvertex()   Get a specific vertex, by number, from the list.           */
4578 /*                                                                           */
4579 /*  The first vertex is number 'firstnumber'.                                */
4580 /*                                                                           */
4581 /*  Note that this takes O(n) time (with a small constant, if VERTEXPERBLOCK */
4582 /*  is large).  I don't care to take the trouble to make it work in constant */
4583 /*  time.                                                                    */
4584 /*                                                                           */
4585 /*****************************************************************************/
4586 
4587 #ifdef ANSI_DECLARATORS
4588 vertex getvertex(struct mesh *m, struct behavior *b, int number)
4589 #else /* not ANSI_DECLARATORS */
4590 vertex getvertex(m, b, number)
4591 struct mesh *m;
4592 struct behavior *b;
4593 int number;
4594 #endif /* not ANSI_DECLARATORS */
4595 
4596 {
4597   VOID **getblock;
4598   char *foundvertex;
4599   unsigned long alignptr;
4600   int current;
4601 
4602   getblock = m->vertices.firstblock;
4603   current = b->firstnumber;
4604 
4605   /* Find the right block. */
4606   if (current + m->vertices.itemsfirstblock <= number) {
4607     getblock = (VOID **) *getblock;
4608     current += m->vertices.itemsfirstblock;
4609     while (current + m->vertices.itemsperblock <= number) {
4610       getblock = (VOID **) *getblock;
4611       current += m->vertices.itemsperblock;
4612     }
4613   }
4614 
4615   /* Now find the right vertex. */
4616   alignptr = (unsigned long) (getblock + 1);
4617   foundvertex = (char *) (alignptr + (unsigned long) m->vertices.alignbytes -
4618                           (alignptr % (unsigned long) m->vertices.alignbytes));
4619   return (vertex) (foundvertex + m->vertices.itembytes * (number - current));
4620 }
4621 
4622 /*****************************************************************************/
4623 /*                                                                           */
4624 /*  triangledeinit()   Free all remaining allocated memory.                  */
4625 /*                                                                           */
4626 /*****************************************************************************/
4627 
4628 #ifdef ANSI_DECLARATORS
4629 void triangledeinit(struct mesh *m, struct behavior *b)
4630 #else /* not ANSI_DECLARATORS */
4631 void triangledeinit(m, b)
4632 struct mesh *m;
4633 struct behavior *b;
4634 #endif /* not ANSI_DECLARATORS */
4635 
4636 {
4637   pooldeinit(&m->triangles);
4638   trifree((VOID *) m->dummytribase);
4639   if (b->usesegments) {
4640     pooldeinit(&m->subsegs);
4641     trifree((VOID *) m->dummysubbase);
4642   }
4643   pooldeinit(&m->vertices);
4644 #ifndef CDT_ONLY
4645   if (b->quality) {
4646     pooldeinit(&m->badsubsegs);
4647     if ((b->minangle > 0.0) || b->vararea || b->fixedarea || b->usertest) {
4648       pooldeinit(&m->badtriangles);
4649       pooldeinit(&m->flipstackers);
4650     }
4651   }
4652 #endif /* not CDT_ONLY */
4653 }
4654 
4655 /**                                                                         **/
4656 /**                                                                         **/
4657 /********* Memory management routines end here                       *********/
4658 
4659 /********* Constructors begin here                                   *********/
4660 /**                                                                         **/
4661 /**                                                                         **/
4662 
4663 /*****************************************************************************/
4664 /*                                                                           */
4665 /*  maketriangle()   Create a new triangle with orientation zero.            */
4666 /*                                                                           */
4667 /*****************************************************************************/
4668 
4669 #ifdef ANSI_DECLARATORS
4670 void maketriangle(struct mesh *m, struct behavior *b, struct otri *newotri)
4671 #else /* not ANSI_DECLARATORS */
4672 void maketriangle(m, b, newotri)
4673 struct mesh *m;
4674 struct behavior *b;
4675 struct otri *newotri;
4676 #endif /* not ANSI_DECLARATORS */
4677 
4678 {
4679   int i;
4680 
4681   newotri->tri = (triangle *) poolalloc(&m->triangles);
4682   /* Initialize the three adjoining triangles to be "outer space". */
4683   newotri->tri[0] = (triangle) m->dummytri;
4684   newotri->tri[1] = (triangle) m->dummytri;
4685   newotri->tri[2] = (triangle) m->dummytri;
4686   /* Three NULL vertices. */
4687   newotri->tri[3] = (triangle) NULL;
4688   newotri->tri[4] = (triangle) NULL;
4689   newotri->tri[5] = (triangle) NULL;
4690   if (b->usesegments) {
4691     /* Initialize the three adjoining subsegments to be the omnipresent */
4692     /*   subsegment.                                                    */
4693     newotri->tri[6] = (triangle) m->dummysub;
4694     newotri->tri[7] = (triangle) m->dummysub;
4695     newotri->tri[8] = (triangle) m->dummysub;
4696   }
4697   for (i = 0; i < m->eextras; i++) {
4698     setelemattribute(*newotri, i, 0.0);
4699   }
4700   if (b->vararea) {
4701     setareabound(*newotri, -1.0);
4702   }
4703 
4704   newotri->orient = 0;
4705 }
4706 
4707 /*****************************************************************************/
4708 /*                                                                           */
4709 /*  makesubseg()   Create a new subsegment with orientation zero.            */
4710 /*                                                                           */
4711 /*****************************************************************************/
4712 
4713 #ifdef ANSI_DECLARATORS
4714 void makesubseg(struct mesh *m, struct osub *newsubseg)
4715 #else /* not ANSI_DECLARATORS */
4716 void makesubseg(m, newsubseg)
4717 struct mesh *m;
4718 struct osub *newsubseg;
4719 #endif /* not ANSI_DECLARATORS */
4720 
4721 {
4722   newsubseg->ss = (subseg *) poolalloc(&m->subsegs);
4723   /* Initialize the two adjoining subsegments to be the omnipresent */
4724   /*   subsegment.                                                  */
4725   newsubseg->ss[0] = (subseg) m->dummysub;
4726   newsubseg->ss[1] = (subseg) m->dummysub;
4727   /* Four NULL vertices. */
4728   newsubseg->ss[2] = (subseg) NULL;
4729   newsubseg->ss[3] = (subseg) NULL;
4730   newsubseg->ss[4] = (subseg) NULL;
4731   newsubseg->ss[5] = (subseg) NULL;
4732   /* Initialize the two adjoining triangles to be "outer space." */
4733   newsubseg->ss[6] = (subseg) m->dummytri;
4734   newsubseg->ss[7] = (subseg) m->dummytri;
4735   /* Set the boundary marker to zero. */
4736   setmark(*newsubseg, 0);
4737 
4738   newsubseg->ssorient = 0;
4739 }
4740 
4741 /**                                                                         **/
4742 /**                                                                         **/
4743 /********* Constructors end here                                     *********/
4744 
4745 /********* Geometric primitives begin here                           *********/
4746 /**                                                                         **/
4747 /**                                                                         **/
4748 
4749 /* The adaptive exact arithmetic geometric predicates implemented herein are */
4750 /*   described in detail in my paper, "Adaptive Precision Floating-Point     */
4751 /*   Arithmetic and Fast Robust Geometric Predicates."  See the header for a */
4752 /*   full citation.                                                          */
4753 
4754 /* Which of the following two methods of finding the absolute values is      */
4755 /*   fastest is compiler-dependent.  A few compilers can inline and optimize */
4756 /*   the fabs() call; but most will incur the overhead of a function call,   */
4757 /*   which is disastrously slow.  A faster way on IEEE machines might be to  */
4758 /*   mask the appropriate bit, but that's difficult to do in C without       */
4759 /*   forcing the value to be stored to memory (rather than be kept in the    */
4760 /*   register to which the optimizer assigned it).                           */
4761 
4762 #define Absolute(a)  ((a) >= 0.0 ? (a) : -(a))
4763 /* #define Absolute(a)  fabs(a) */
4764 
4765 /* Many of the operations are broken up into two pieces, a main part that    */
4766 /*   performs an approximate operation, and a "tail" that computes the       */
4767 /*   roundoff error of that operation.                                       */
4768 /*                                                                           */
4769 /* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(),    */
4770 /*   Split(), and Two_Product() are all implemented as described in the      */
4771 /*   reference.  Each of these macros requires certain variables to be       */
4772 /*   defined in the calling routine.  The variables `bvirt', `c', `abig',    */
4773 /*   `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because   */
4774 /*   they store the result of an operation that may incur roundoff error.    */
4775 /*   The input parameter `x' (or the highest numbered `x_' parameter) must   */
4776 /*   also be declared `INEXACT'.                                             */
4777 
4778 #define Fast_Two_Sum_Tail(a, b, x, y) \
4779   bvirt = x - a; \
4780   y = b - bvirt
4781 
4782 #define Fast_Two_Sum(a, b, x, y) \
4783   x = (REAL) (a + b); \
4784   Fast_Two_Sum_Tail(a, b, x, y)
4785 
4786 #define Two_Sum_Tail(a, b, x, y) \
4787   bvirt = (REAL) (x - a); \
4788   avirt = x - bvirt; \
4789   bround = b - bvirt; \
4790   around = a - avirt; \
4791   y = around + bround
4792 
4793 #define Two_Sum(a, b, x, y) \
4794   x = (REAL) (a + b); \
4795   Two_Sum_Tail(a, b, x, y)
4796 
4797 #define Two_Diff_Tail(a, b, x, y) \
4798   bvirt = (REAL) (a - x); \
4799   avirt = x + bvirt; \
4800   bround = bvirt - b; \
4801   around = a - avirt; \
4802   y = around + bround
4803 
4804 #define Two_Diff(a, b, x, y) \
4805   x = (REAL) (a - b); \
4806   Two_Diff_Tail(a, b, x, y)
4807 
4808 #define Split(a, ahi, alo) \
4809   c = (REAL) (splitter * a); \
4810   abig = (REAL) (c - a); \
4811   ahi = c - abig; \
4812   alo = a - ahi
4813 
4814 #define Two_Product_Tail(a, b, x, y) \
4815   Split(a, ahi, alo); \
4816   Split(b, bhi, blo); \
4817   err1 = x - (ahi * bhi); \
4818   err2 = err1 - (alo * bhi); \
4819   err3 = err2 - (ahi * blo); \
4820   y = (alo * blo) - err3
4821 
4822 #define Two_Product(a, b, x, y) \
4823   x = (REAL) (a * b); \
4824   Two_Product_Tail(a, b, x, y)
4825 
4826 /* Two_Product_Presplit() is Two_Product() where one of the inputs has       */
4827 /*   already been split.  Avoids redundant splitting.                        */
4828 
4829 #define Two_Product_Presplit(a, b, bhi, blo, x, y) \
4830   x = (REAL) (a * b); \
4831   Split(a, ahi, alo); \
4832   err1 = x - (ahi * bhi); \
4833   err2 = err1 - (alo * bhi); \
4834   err3 = err2 - (ahi * blo); \
4835   y = (alo * blo) - err3
4836 
4837 /* Square() can be done more quickly than Two_Product().                     */
4838 
4839 #define Square_Tail(a, x, y) \
4840   Split(a, ahi, alo); \
4841   err1 = x - (ahi * ahi); \
4842   err3 = err1 - ((ahi + ahi) * alo); \
4843   y = (alo * alo) - err3
4844 
4845 #define Square(a, x, y) \
4846   x = (REAL) (a * a); \
4847   Square_Tail(a, x, y)
4848 
4849 /* Macros for summing expansions of various fixed lengths.  These are all    */
4850 /*   unrolled versions of Expansion_Sum().                                   */
4851 
4852 #define Two_One_Sum(a1, a0, b, x2, x1, x0) \
4853   Two_Sum(a0, b , _i, x0); \
4854   Two_Sum(a1, _i, x2, x1)
4855 
4856 #define Two_One_Diff(a1, a0, b, x2, x1, x0) \
4857   Two_Diff(a0, b , _i, x0); \
4858   Two_Sum( a1, _i, x2, x1)
4859 
4860 #define Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0) \
4861   Two_One_Sum(a1, a0, b0, _j, _0, x0); \
4862   Two_One_Sum(_j, _0, b1, x3, x2, x1)
4863 
4864 #define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0) \
4865   Two_One_Diff(a1, a0, b0, _j, _0, x0); \
4866   Two_One_Diff(_j, _0, b1, x3, x2, x1)
4867 
4868 /* Macro for multiplying a two-component expansion by a single component.    */
4869 
4870 #define Two_One_Product(a1, a0, b, x3, x2, x1, x0) \
4871   Split(b, bhi, blo); \
4872   Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \
4873   Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \
4874   Two_Sum(_i, _0, _k, x1); \
4875   Fast_Two_Sum(_j, _k, x3, x2)
4876 
4877 /*****************************************************************************/
4878 /*                                                                           */
4879 /*  exactinit()   Initialize the variables used for exact arithmetic.        */
4880 /*                                                                           */
4881 /*  `epsilon' is the largest power of two such that 1.0 + epsilon = 1.0 in   */
4882 /*  floating-point arithmetic.  `epsilon' bounds the relative roundoff       */
4883 /*  error.  It is used for floating-point error analysis.                    */
4884 /*                                                                           */
4885 /*  `splitter' is used to split floating-point numbers into two half-        */
4886 /*  length significands for exact multiplication.                            */
4887 /*                                                                           */
4888 /*  I imagine that a highly optimizing compiler might be too smart for its   */
4889 /*  own good, and somehow cause this routine to fail, if it pretends that    */
4890 /*  floating-point arithmetic is too much like real arithmetic.              */
4891 /*                                                                           */
4892 /*  Don't change this routine unless you fully understand it.                */
4893 /*                                                                           */
4894 /*****************************************************************************/
4895 
exactinit()4896 void exactinit()
4897 {
4898   REAL half;
4899   REAL check, lastcheck;
4900   int every_other;
4901 #ifdef LINUX
4902   int cword;
4903 #endif /* LINUX */
4904 
4905 #ifdef CPU86
4906 #ifdef SINGLE
4907   _control87(_PC_24, _MCW_PC); /* Set FPU control word for single precision. */
4908 #else /* not SINGLE */
4909   _control87(_PC_53, _MCW_PC); /* Set FPU control word for double precision. */
4910 #endif /* not SINGLE */
4911 #endif /* CPU86 */
4912 #ifdef LINUX
4913 #ifdef SINGLE
4914   /*  cword = 4223; */
4915   cword = 4210;                 /* set FPU control word for single precision */
4916 #else /* not SINGLE */
4917   /*  cword = 4735; */
4918   cword = 4722;                 /* set FPU control word for double precision */
4919 #endif /* not SINGLE */
4920   _FPU_SETCW(cword);
4921 #endif /* LINUX */
4922 
4923   every_other = 1;
4924   half = 0.5;
4925   epsilon = 1.0;
4926   splitter = 1.0;
4927   check = 1.0;
4928   /* Repeatedly divide `epsilon' by two until it is too small to add to      */
4929   /*   one without causing roundoff.  (Also check if the sum is equal to     */
4930   /*   the previous sum, for machines that round up instead of using exact   */
4931   /*   rounding.  Not that these routines will work on such machines.)       */
4932   do {
4933     lastcheck = check;
4934     epsilon *= half;
4935     if (every_other) {
4936       splitter *= 2.0;
4937     }
4938     every_other = !every_other;
4939     check = 1.0 + epsilon;
4940   } while ((check != 1.0) && (check != lastcheck));
4941   splitter += 1.0;
4942   /* Error bounds for orientation and incircle tests. */
4943   resulterrbound = (3.0 + 8.0 * epsilon) * epsilon;
4944   ccwerrboundA = (3.0 + 16.0 * epsilon) * epsilon;
4945   ccwerrboundB = (2.0 + 12.0 * epsilon) * epsilon;
4946   ccwerrboundC = (9.0 + 64.0 * epsilon) * epsilon * epsilon;
4947   iccerrboundA = (10.0 + 96.0 * epsilon) * epsilon;
4948   iccerrboundB = (4.0 + 48.0 * epsilon) * epsilon;
4949   iccerrboundC = (44.0 + 576.0 * epsilon) * epsilon * epsilon;
4950   o3derrboundA = (7.0 + 56.0 * epsilon) * epsilon;
4951   o3derrboundB = (3.0 + 28.0 * epsilon) * epsilon;
4952   o3derrboundC = (26.0 + 288.0 * epsilon) * epsilon * epsilon;
4953 }
4954 
4955 /*****************************************************************************/
4956 /*                                                                           */
4957 /*  fast_expansion_sum_zeroelim()   Sum two expansions, eliminating zero     */
4958 /*                                  components from the output expansion.    */
4959 /*                                                                           */
4960 /*  Sets h = e + f.  See my Robust Predicates paper for details.             */
4961 /*                                                                           */
4962 /*  If round-to-even is used (as with IEEE 754), maintains the strongly      */
4963 /*  nonoverlapping property.  (That is, if e is strongly nonoverlapping, h   */
4964 /*  will be also.)  Does NOT maintain the nonoverlapping or nonadjacent      */
4965 /*  properties.                                                              */
4966 /*                                                                           */
4967 /*****************************************************************************/
4968 
4969 #ifdef ANSI_DECLARATORS
4970 int fast_expansion_sum_zeroelim(int elen, REAL *e, int flen, REAL *f, REAL *h)
4971 #else /* not ANSI_DECLARATORS */
4972 int fast_expansion_sum_zeroelim(elen, e, flen, f, h)  /* h cannot be e or f. */
4973 int elen;
4974 REAL *e;
4975 int flen;
4976 REAL *f;
4977 REAL *h;
4978 #endif /* not ANSI_DECLARATORS */
4979 
4980 {
4981   REAL Q;
4982   INEXACT REAL Qnew;
4983   INEXACT REAL hh;
4984   INEXACT REAL bvirt;
4985   REAL avirt, bround, around;
4986   int eindex, findex, hindex;
4987   REAL enow, fnow;
4988 
4989   enow = e[0];
4990   fnow = f[0];
4991   eindex = findex = 0;
4992   if ((fnow > enow) == (fnow > -enow)) {
4993     Q = enow;
4994     enow = e[++eindex];
4995   } else {
4996     Q = fnow;
4997     fnow = f[++findex];
4998   }
4999   hindex = 0;
5000   if ((eindex < elen) && (findex < flen)) {
5001     if ((fnow > enow) == (fnow > -enow)) {
5002       Fast_Two_Sum(enow, Q, Qnew, hh);
5003       enow = e[++eindex];
5004     } else {
5005       Fast_Two_Sum(fnow, Q, Qnew, hh);
5006       fnow = f[++findex];
5007     }
5008     Q = Qnew;
5009     if (hh != 0.0) {
5010       h[hindex++] = hh;
5011     }
5012     while ((eindex < elen) && (findex < flen)) {
5013       if ((fnow > enow) == (fnow > -enow)) {
5014         Two_Sum(Q, enow, Qnew, hh);
5015         enow = e[++eindex];
5016       } else {
5017         Two_Sum(Q, fnow, Qnew, hh);
5018         fnow = f[++findex];
5019       }
5020       Q = Qnew;
5021       if (hh != 0.0) {
5022         h[hindex++] = hh;
5023       }
5024     }
5025   }
5026   while (eindex < elen) {
5027     Two_Sum(Q, enow, Qnew, hh);
5028     enow = e[++eindex];
5029     Q = Qnew;
5030     if (hh != 0.0) {
5031       h[hindex++] = hh;
5032     }
5033   }
5034   while (findex < flen) {
5035     Two_Sum(Q, fnow, Qnew, hh);
5036     fnow = f[++findex];
5037     Q = Qnew;
5038     if (hh != 0.0) {
5039       h[hindex++] = hh;
5040     }
5041   }
5042   if ((Q != 0.0) || (hindex == 0)) {
5043     h[hindex++] = Q;
5044   }
5045   return hindex;
5046 }
5047 
5048 /*****************************************************************************/
5049 /*                                                                           */
5050 /*  scale_expansion_zeroelim()   Multiply an expansion by a scalar,          */
5051 /*                               eliminating zero components from the        */
5052 /*                               output expansion.                           */
5053 /*                                                                           */
5054 /*  Sets h = be.  See my Robust Predicates paper for details.                */
5055 /*                                                                           */
5056 /*  Maintains the nonoverlapping property.  If round-to-even is used (as     */
5057 /*  with IEEE 754), maintains the strongly nonoverlapping and nonadjacent    */
5058 /*  properties as well.  (That is, if e has one of these properties, so      */
5059 /*  will h.)                                                                 */
5060 /*                                                                           */
5061 /*****************************************************************************/
5062 
5063 #ifdef ANSI_DECLARATORS
5064 int scale_expansion_zeroelim(int elen, REAL *e, REAL b, REAL *h)
5065 #else /* not ANSI_DECLARATORS */
5066 int scale_expansion_zeroelim(elen, e, b, h)   /* e and h cannot be the same. */
5067 int elen;
5068 REAL *e;
5069 REAL b;
5070 REAL *h;
5071 #endif /* not ANSI_DECLARATORS */
5072 
5073 {
5074   INEXACT REAL Q, sum;
5075   REAL hh;
5076   INEXACT REAL product1;
5077   REAL product0;
5078   int eindex, hindex;
5079   REAL enow;
5080   INEXACT REAL bvirt;
5081   REAL avirt, bround, around;
5082   INEXACT REAL c;
5083   INEXACT REAL abig;
5084   REAL ahi, alo, bhi, blo;
5085   REAL err1, err2, err3;
5086 
5087   Split(b, bhi, blo);
5088   Two_Product_Presplit(e[0], b, bhi, blo, Q, hh);
5089   hindex = 0;
5090   if (hh != 0) {
5091     h[hindex++] = hh;
5092   }
5093   for (eindex = 1; eindex < elen; eindex++) {
5094     enow = e[eindex];
5095     Two_Product_Presplit(enow, b, bhi, blo, product1, product0);
5096     Two_Sum(Q, product0, sum, hh);
5097     if (hh != 0) {
5098       h[hindex++] = hh;
5099     }
5100     Fast_Two_Sum(product1, sum, Q, hh);
5101     if (hh != 0) {
5102       h[hindex++] = hh;
5103     }
5104   }
5105   if ((Q != 0.0) || (hindex == 0)) {
5106     h[hindex++] = Q;
5107   }
5108   return hindex;
5109 }
5110 
5111 /*****************************************************************************/
5112 /*                                                                           */
5113 /*  estimate()   Produce a one-word estimate of an expansion's value.        */
5114 /*                                                                           */
5115 /*  See my Robust Predicates paper for details.                              */
5116 /*                                                                           */
5117 /*****************************************************************************/
5118 
5119 #ifdef ANSI_DECLARATORS
5120 REAL estimate(int elen, REAL *e)
5121 #else /* not ANSI_DECLARATORS */
5122 REAL estimate(elen, e)
5123 int elen;
5124 REAL *e;
5125 #endif /* not ANSI_DECLARATORS */
5126 
5127 {
5128   REAL Q;
5129   int eindex;
5130 
5131   Q = e[0];
5132   for (eindex = 1; eindex < elen; eindex++) {
5133     Q += e[eindex];
5134   }
5135   return Q;
5136 }
5137 
5138 /*****************************************************************************/
5139 /*                                                                           */
5140 /*  counterclockwise()   Return a positive value if the points pa, pb, and   */
5141 /*                       pc occur in counterclockwise order; a negative      */
5142 /*                       value if they occur in clockwise order; and zero    */
5143 /*                       if they are collinear.  The result is also a rough  */
5144 /*                       approximation of twice the signed area of the       */
5145 /*                       triangle defined by the three points.               */
5146 /*                                                                           */
5147 /*  Uses exact arithmetic if necessary to ensure a correct answer.  The      */
5148 /*  result returned is the determinant of a matrix.  This determinant is     */
5149 /*  computed adaptively, in the sense that exact arithmetic is used only to  */
5150 /*  the degree it is needed to ensure that the returned value has the        */
5151 /*  correct sign.  Hence, this function is usually quite fast, but will run  */
5152 /*  more slowly when the input points are collinear or nearly so.            */
5153 /*                                                                           */
5154 /*  See my Robust Predicates paper for details.                              */
5155 /*                                                                           */
5156 /*****************************************************************************/
5157 
5158 #ifdef ANSI_DECLARATORS
5159 REAL counterclockwiseadapt(vertex pa, vertex pb, vertex pc, REAL detsum)
5160 #else /* not ANSI_DECLARATORS */
5161 REAL counterclockwiseadapt(pa, pb, pc, detsum)
5162 vertex pa;
5163 vertex pb;
5164 vertex pc;
5165 REAL detsum;
5166 #endif /* not ANSI_DECLARATORS */
5167 
5168 {
5169   INEXACT REAL acx, acy, bcx, bcy;
5170   REAL acxtail, acytail, bcxtail, bcytail;
5171   INEXACT REAL detleft, detright;
5172   REAL detlefttail, detrighttail;
5173   REAL det, errbound;
5174   REAL B[4], C1[8], C2[12], D[16];
5175   INEXACT REAL B3;
5176   int C1length, C2length, Dlength;
5177   REAL u[4];
5178   INEXACT REAL u3;
5179   INEXACT REAL s1, t1;
5180   REAL s0, t0;
5181 
5182   INEXACT REAL bvirt;
5183   REAL avirt, bround, around;
5184   INEXACT REAL c;
5185   INEXACT REAL abig;
5186   REAL ahi, alo, bhi, blo;
5187   REAL err1, err2, err3;
5188   INEXACT REAL _i, _j;
5189   REAL _0;
5190 
5191   acx = (REAL) (pa[0] - pc[0]);
5192   bcx = (REAL) (pb[0] - pc[0]);
5193   acy = (REAL) (pa[1] - pc[1]);
5194   bcy = (REAL) (pb[1] - pc[1]);
5195 
5196   Two_Product(acx, bcy, detleft, detlefttail);
5197   Two_Product(acy, bcx, detright, detrighttail);
5198 
5199   Two_Two_Diff(detleft, detlefttail, detright, detrighttail,
5200                B3, B[2], B[1], B[0]);
5201   B[3] = B3;
5202 
5203   det = estimate(4, B);
5204   errbound = ccwerrboundB * detsum;
5205   if ((det >= errbound) || (-det >= errbound)) {
5206     return det;
5207   }
5208 
5209   Two_Diff_Tail(pa[0], pc[0], acx, acxtail);
5210   Two_Diff_Tail(pb[0], pc[0], bcx, bcxtail);
5211   Two_Diff_Tail(pa[1], pc[1], acy, acytail);
5212   Two_Diff_Tail(pb[1], pc[1], bcy, bcytail);
5213 
5214   if ((acxtail == 0.0) && (acytail == 0.0)
5215       && (bcxtail == 0.0) && (bcytail == 0.0)) {
5216     return det;
5217   }
5218 
5219   errbound = ccwerrboundC * detsum + resulterrbound * Absolute(det);
5220   det += (acx * bcytail + bcy * acxtail)
5221        - (acy * bcxtail + bcx * acytail);
5222   if ((det >= errbound) || (-det >= errbound)) {
5223     return det;
5224   }
5225 
5226   Two_Product(acxtail, bcy, s1, s0);
5227   Two_Product(acytail, bcx, t1, t0);
5228   Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
5229   u[3] = u3;
5230   C1length = fast_expansion_sum_zeroelim(4, B, 4, u, C1);
5231 
5232   Two_Product(acx, bcytail, s1, s0);
5233   Two_Product(acy, bcxtail, t1, t0);
5234   Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
5235   u[3] = u3;
5236   C2length = fast_expansion_sum_zeroelim(C1length, C1, 4, u, C2);
5237 
5238   Two_Product(acxtail, bcytail, s1, s0);
5239   Two_Product(acytail, bcxtail, t1, t0);
5240   Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
5241   u[3] = u3;
5242   Dlength = fast_expansion_sum_zeroelim(C2length, C2, 4, u, D);
5243 
5244   return(D[Dlength - 1]);
5245 }
5246 
5247 #ifdef ANSI_DECLARATORS
5248 REAL counterclockwise(struct mesh *m, struct behavior *b,
5249                       vertex pa, vertex pb, vertex pc)
5250 #else /* not ANSI_DECLARATORS */
5251 REAL counterclockwise(m, b, pa, pb, pc)
5252 struct mesh *m;
5253 struct behavior *b;
5254 vertex pa;
5255 vertex pb;
5256 vertex pc;
5257 #endif /* not ANSI_DECLARATORS */
5258 
5259 {
5260   REAL detleft, detright, det;
5261   REAL detsum, errbound;
5262 
5263   m->counterclockcount++;
5264 
5265   detleft = (pa[0] - pc[0]) * (pb[1] - pc[1]);
5266   detright = (pa[1] - pc[1]) * (pb[0] - pc[0]);
5267   det = detleft - detright;
5268 
5269   if (b->noexact) {
5270     return det;
5271   }
5272 
5273   if (detleft > 0.0) {
5274     if (detright <= 0.0) {
5275       return det;
5276     } else {
5277       detsum = detleft + detright;
5278     }
5279   } else if (detleft < 0.0) {
5280     if (detright >= 0.0) {
5281       return det;
5282     } else {
5283       detsum = -detleft - detright;
5284     }
5285   } else {
5286     return det;
5287   }
5288 
5289   errbound = ccwerrboundA * detsum;
5290   if ((det >= errbound) || (-det >= errbound)) {
5291     return det;
5292   }
5293 
5294   return counterclockwiseadapt(pa, pb, pc, detsum);
5295 }
5296 
5297 /*****************************************************************************/
5298 /*                                                                           */
5299 /*  incircle()   Return a positive value if the point pd lies inside the     */
5300 /*               circle passing through pa, pb, and pc; a negative value if  */
5301 /*               it lies outside; and zero if the four points are cocircular.*/
5302 /*               The points pa, pb, and pc must be in counterclockwise       */
5303 /*               order, or the sign of the result will be reversed.          */
5304 /*                                                                           */
5305 /*  Uses exact arithmetic if necessary to ensure a correct answer.  The      */
5306 /*  result returned is the determinant of a matrix.  This determinant is     */
5307 /*  computed adaptively, in the sense that exact arithmetic is used only to  */
5308 /*  the degree it is needed to ensure that the returned value has the        */
5309 /*  correct sign.  Hence, this function is usually quite fast, but will run  */
5310 /*  more slowly when the input points are cocircular or nearly so.           */
5311 /*                                                                           */
5312 /*  See my Robust Predicates paper for details.                              */
5313 /*                                                                           */
5314 /*****************************************************************************/
5315 
5316 #ifdef ANSI_DECLARATORS
5317 REAL incircleadapt(vertex pa, vertex pb, vertex pc, vertex pd, REAL permanent)
5318 #else /* not ANSI_DECLARATORS */
5319 REAL incircleadapt(pa, pb, pc, pd, permanent)
5320 vertex pa;
5321 vertex pb;
5322 vertex pc;
5323 vertex pd;
5324 REAL permanent;
5325 #endif /* not ANSI_DECLARATORS */
5326 
5327 {
5328   INEXACT REAL adx, bdx, cdx, ady, bdy, cdy;
5329   REAL det, errbound;
5330 
5331   INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1;
5332   REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0;
5333   REAL bc[4], ca[4], ab[4];
5334   INEXACT REAL bc3, ca3, ab3;
5335   REAL axbc[8], axxbc[16], aybc[8], ayybc[16], adet[32];
5336   int axbclen, axxbclen, aybclen, ayybclen, alen;
5337   REAL bxca[8], bxxca[16], byca[8], byyca[16], bdet[32];
5338   int bxcalen, bxxcalen, bycalen, byycalen, blen;
5339   REAL cxab[8], cxxab[16], cyab[8], cyyab[16], cdet[32];
5340   int cxablen, cxxablen, cyablen, cyyablen, clen;
5341   REAL abdet[64];
5342   int ablen;
5343   REAL fin1[1152], fin2[1152];
5344   REAL *finnow, *finother, *finswap;
5345   int finlength;
5346 
5347   REAL adxtail, bdxtail, cdxtail, adytail, bdytail, cdytail;
5348   INEXACT REAL adxadx1, adyady1, bdxbdx1, bdybdy1, cdxcdx1, cdycdy1;
5349   REAL adxadx0, adyady0, bdxbdx0, bdybdy0, cdxcdx0, cdycdy0;
5350   REAL aa[4], bb[4], cc[4];
5351   INEXACT REAL aa3, bb3, cc3;
5352   INEXACT REAL ti1, tj1;
5353   REAL ti0, tj0;
5354   REAL u[4], v[4];
5355   INEXACT REAL u3, v3;
5356   REAL temp8[8], temp16a[16], temp16b[16], temp16c[16];
5357   REAL temp32a[32], temp32b[32], temp48[48], temp64[64];
5358   int temp8len, temp16alen, temp16blen, temp16clen;
5359   int temp32alen, temp32blen, temp48len, temp64len;
5360   REAL axtbb[8], axtcc[8], aytbb[8], aytcc[8];
5361   int axtbblen, axtcclen, aytbblen, aytcclen;
5362   REAL bxtaa[8], bxtcc[8], bytaa[8], bytcc[8];
5363   int bxtaalen, bxtcclen, bytaalen, bytcclen;
5364   REAL cxtaa[8], cxtbb[8], cytaa[8], cytbb[8];
5365   int cxtaalen, cxtbblen, cytaalen, cytbblen;
5366   REAL axtbc[8], aytbc[8], bxtca[8], bytca[8], cxtab[8], cytab[8];
5367   int axtbclen=0, aytbclen=0, bxtcalen=0, bytcalen=0, cxtablen=0, cytablen=0;
5368   REAL axtbct[16], aytbct[16], bxtcat[16], bytcat[16], cxtabt[16], cytabt[16];
5369   int axtbctlen, aytbctlen, bxtcatlen, bytcatlen, cxtabtlen, cytabtlen;
5370   REAL axtbctt[8], aytbctt[8], bxtcatt[8];
5371   REAL bytcatt[8], cxtabtt[8], cytabtt[8];
5372   int axtbcttlen, aytbcttlen, bxtcattlen, bytcattlen, cxtabttlen, cytabttlen;
5373   REAL abt[8], bct[8], cat[8];
5374   int abtlen, bctlen, catlen;
5375   REAL abtt[4], bctt[4], catt[4];
5376   int abttlen, bcttlen, cattlen;
5377   INEXACT REAL abtt3, bctt3, catt3;
5378   REAL negate;
5379 
5380   INEXACT REAL bvirt;
5381   REAL avirt, bround, around;
5382   INEXACT REAL c;
5383   INEXACT REAL abig;
5384   REAL ahi, alo, bhi, blo;
5385   REAL err1, err2, err3;
5386   INEXACT REAL _i, _j;
5387   REAL _0;
5388 
5389   adx = (REAL) (pa[0] - pd[0]);
5390   bdx = (REAL) (pb[0] - pd[0]);
5391   cdx = (REAL) (pc[0] - pd[0]);
5392   ady = (REAL) (pa[1] - pd[1]);
5393   bdy = (REAL) (pb[1] - pd[1]);
5394   cdy = (REAL) (pc[1] - pd[1]);
5395 
5396   Two_Product(bdx, cdy, bdxcdy1, bdxcdy0);
5397   Two_Product(cdx, bdy, cdxbdy1, cdxbdy0);
5398   Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]);
5399   bc[3] = bc3;
5400   axbclen = scale_expansion_zeroelim(4, bc, adx, axbc);
5401   axxbclen = scale_expansion_zeroelim(axbclen, axbc, adx, axxbc);
5402   aybclen = scale_expansion_zeroelim(4, bc, ady, aybc);
5403   ayybclen = scale_expansion_zeroelim(aybclen, aybc, ady, ayybc);
5404   alen = fast_expansion_sum_zeroelim(axxbclen, axxbc, ayybclen, ayybc, adet);
5405 
5406   Two_Product(cdx, ady, cdxady1, cdxady0);
5407   Two_Product(adx, cdy, adxcdy1, adxcdy0);
5408   Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]);
5409   ca[3] = ca3;
5410   bxcalen = scale_expansion_zeroelim(4, ca, bdx, bxca);
5411   bxxcalen = scale_expansion_zeroelim(bxcalen, bxca, bdx, bxxca);
5412   bycalen = scale_expansion_zeroelim(4, ca, bdy, byca);
5413   byycalen = scale_expansion_zeroelim(bycalen, byca, bdy, byyca);
5414   blen = fast_expansion_sum_zeroelim(bxxcalen, bxxca, byycalen, byyca, bdet);
5415 
5416   Two_Product(adx, bdy, adxbdy1, adxbdy0);
5417   Two_Product(bdx, ady, bdxady1, bdxady0);
5418   Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]);
5419   ab[3] = ab3;
5420   cxablen = scale_expansion_zeroelim(4, ab, cdx, cxab);
5421   cxxablen = scale_expansion_zeroelim(cxablen, cxab, cdx, cxxab);
5422   cyablen = scale_expansion_zeroelim(4, ab, cdy, cyab);
5423   cyyablen = scale_expansion_zeroelim(cyablen, cyab, cdy, cyyab);
5424   clen = fast_expansion_sum_zeroelim(cxxablen, cxxab, cyyablen, cyyab, cdet);
5425 
5426   ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
5427   finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1);
5428 
5429   det = estimate(finlength, fin1);
5430   errbound = iccerrboundB * permanent;
5431   if ((det >= errbound) || (-det >= errbound)) {
5432     return det;
5433   }
5434 
5435   Two_Diff_Tail(pa[0], pd[0], adx, adxtail);
5436   Two_Diff_Tail(pa[1], pd[1], ady, adytail);
5437   Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail);
5438   Two_Diff_Tail(pb[1], pd[1], bdy, bdytail);
5439   Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail);
5440   Two_Diff_Tail(pc[1], pd[1], cdy, cdytail);
5441   if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0)
5442       && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0)) {
5443     return det;
5444   }
5445 
5446   errbound = iccerrboundC * permanent + resulterrbound * Absolute(det);
5447   det += ((adx * adx + ady * ady) * ((bdx * cdytail + cdy * bdxtail)
5448                                      - (bdy * cdxtail + cdx * bdytail))
5449           + 2.0 * (adx * adxtail + ady * adytail) * (bdx * cdy - bdy * cdx))
5450        + ((bdx * bdx + bdy * bdy) * ((cdx * adytail + ady * cdxtail)
5451                                      - (cdy * adxtail + adx * cdytail))
5452           + 2.0 * (bdx * bdxtail + bdy * bdytail) * (cdx * ady - cdy * adx))
5453        + ((cdx * cdx + cdy * cdy) * ((adx * bdytail + bdy * adxtail)
5454                                      - (ady * bdxtail + bdx * adytail))
5455           + 2.0 * (cdx * cdxtail + cdy * cdytail) * (adx * bdy - ady * bdx));
5456   if ((det >= errbound) || (-det >= errbound)) {
5457     return det;
5458   }
5459 
5460   finnow = fin1;
5461   finother = fin2;
5462 
5463   if ((bdxtail != 0.0) || (bdytail != 0.0)
5464       || (cdxtail != 0.0) || (cdytail != 0.0)) {
5465     Square(adx, adxadx1, adxadx0);
5466     Square(ady, adyady1, adyady0);
5467     Two_Two_Sum(adxadx1, adxadx0, adyady1, adyady0, aa3, aa[2], aa[1], aa[0]);
5468     aa[3] = aa3;
5469   }
5470   if ((cdxtail != 0.0) || (cdytail != 0.0)
5471       || (adxtail != 0.0) || (adytail != 0.0)) {
5472     Square(bdx, bdxbdx1, bdxbdx0);
5473     Square(bdy, bdybdy1, bdybdy0);
5474     Two_Two_Sum(bdxbdx1, bdxbdx0, bdybdy1, bdybdy0, bb3, bb[2], bb[1], bb[0]);
5475     bb[3] = bb3;
5476   }
5477   if ((adxtail != 0.0) || (adytail != 0.0)
5478       || (bdxtail != 0.0) || (bdytail != 0.0)) {
5479     Square(cdx, cdxcdx1, cdxcdx0);
5480     Square(cdy, cdycdy1, cdycdy0);
5481     Two_Two_Sum(cdxcdx1, cdxcdx0, cdycdy1, cdycdy0, cc3, cc[2], cc[1], cc[0]);
5482     cc[3] = cc3;
5483   }
5484 
5485   if (adxtail != 0.0) {
5486     axtbclen = scale_expansion_zeroelim(4, bc, adxtail, axtbc);
5487     temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, 2.0 * adx,
5488                                           temp16a);
5489 
5490     axtcclen = scale_expansion_zeroelim(4, cc, adxtail, axtcc);
5491     temp16blen = scale_expansion_zeroelim(axtcclen, axtcc, bdy, temp16b);
5492 
5493     axtbblen = scale_expansion_zeroelim(4, bb, adxtail, axtbb);
5494     temp16clen = scale_expansion_zeroelim(axtbblen, axtbb, -cdy, temp16c);
5495 
5496     temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5497                                             temp16blen, temp16b, temp32a);
5498     temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
5499                                             temp32alen, temp32a, temp48);
5500     finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5501                                             temp48, finother);
5502     finswap = finnow; finnow = finother; finother = finswap;
5503   }
5504   if (adytail != 0.0) {
5505     aytbclen = scale_expansion_zeroelim(4, bc, adytail, aytbc);
5506     temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, 2.0 * ady,
5507                                           temp16a);
5508 
5509     aytbblen = scale_expansion_zeroelim(4, bb, adytail, aytbb);
5510     temp16blen = scale_expansion_zeroelim(aytbblen, aytbb, cdx, temp16b);
5511 
5512     aytcclen = scale_expansion_zeroelim(4, cc, adytail, aytcc);
5513     temp16clen = scale_expansion_zeroelim(aytcclen, aytcc, -bdx, 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 (bdxtail != 0.0) {
5524     bxtcalen = scale_expansion_zeroelim(4, ca, bdxtail, bxtca);
5525     temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, 2.0 * bdx,
5526                                           temp16a);
5527 
5528     bxtaalen = scale_expansion_zeroelim(4, aa, bdxtail, bxtaa);
5529     temp16blen = scale_expansion_zeroelim(bxtaalen, bxtaa, cdy, temp16b);
5530 
5531     bxtcclen = scale_expansion_zeroelim(4, cc, bdxtail, bxtcc);
5532     temp16clen = scale_expansion_zeroelim(bxtcclen, bxtcc, -ady, 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 (bdytail != 0.0) {
5543     bytcalen = scale_expansion_zeroelim(4, ca, bdytail, bytca);
5544     temp16alen = scale_expansion_zeroelim(bytcalen, bytca, 2.0 * bdy,
5545                                           temp16a);
5546 
5547     bytcclen = scale_expansion_zeroelim(4, cc, bdytail, bytcc);
5548     temp16blen = scale_expansion_zeroelim(bytcclen, bytcc, adx, temp16b);
5549 
5550     bytaalen = scale_expansion_zeroelim(4, aa, bdytail, bytaa);
5551     temp16clen = scale_expansion_zeroelim(bytaalen, bytaa, -cdx, 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 (cdxtail != 0.0) {
5562     cxtablen = scale_expansion_zeroelim(4, ab, cdxtail, cxtab);
5563     temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, 2.0 * cdx,
5564                                           temp16a);
5565 
5566     cxtbblen = scale_expansion_zeroelim(4, bb, cdxtail, cxtbb);
5567     temp16blen = scale_expansion_zeroelim(cxtbblen, cxtbb, ady, temp16b);
5568 
5569     cxtaalen = scale_expansion_zeroelim(4, aa, cdxtail, cxtaa);
5570     temp16clen = scale_expansion_zeroelim(cxtaalen, cxtaa, -bdy, 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 (cdytail != 0.0) {
5581     cytablen = scale_expansion_zeroelim(4, ab, cdytail, cytab);
5582     temp16alen = scale_expansion_zeroelim(cytablen, cytab, 2.0 * cdy,
5583                                           temp16a);
5584 
5585     cytaalen = scale_expansion_zeroelim(4, aa, cdytail, cytaa);
5586     temp16blen = scale_expansion_zeroelim(cytaalen, cytaa, bdx, temp16b);
5587 
5588     cytbblen = scale_expansion_zeroelim(4, bb, cdytail, cytbb);
5589     temp16clen = scale_expansion_zeroelim(cytbblen, cytbb, -adx, 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 
5600   if ((adxtail != 0.0) || (adytail != 0.0)) {
5601     if ((bdxtail != 0.0) || (bdytail != 0.0)
5602         || (cdxtail != 0.0) || (cdytail != 0.0)) {
5603       Two_Product(bdxtail, cdy, ti1, ti0);
5604       Two_Product(bdx, cdytail, tj1, tj0);
5605       Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
5606       u[3] = u3;
5607       negate = -bdy;
5608       Two_Product(cdxtail, negate, ti1, ti0);
5609       negate = -bdytail;
5610       Two_Product(cdx, negate, tj1, tj0);
5611       Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
5612       v[3] = v3;
5613       bctlen = fast_expansion_sum_zeroelim(4, u, 4, v, bct);
5614 
5615       Two_Product(bdxtail, cdytail, ti1, ti0);
5616       Two_Product(cdxtail, bdytail, tj1, tj0);
5617       Two_Two_Diff(ti1, ti0, tj1, tj0, bctt3, bctt[2], bctt[1], bctt[0]);
5618       bctt[3] = bctt3;
5619       bcttlen = 4;
5620     } else {
5621       bct[0] = 0.0;
5622       bctlen = 1;
5623       bctt[0] = 0.0;
5624       bcttlen = 1;
5625     }
5626 
5627     if (adxtail != 0.0) {
5628       temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, adxtail, temp16a);
5629       axtbctlen = scale_expansion_zeroelim(bctlen, bct, adxtail, axtbct);
5630       temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, 2.0 * adx,
5631                                             temp32a);
5632       temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5633                                               temp32alen, temp32a, temp48);
5634       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5635                                               temp48, finother);
5636       finswap = finnow; finnow = finother; finother = finswap;
5637       if (bdytail != 0.0) {
5638         temp8len = scale_expansion_zeroelim(4, cc, adxtail, temp8);
5639         temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail,
5640                                               temp16a);
5641         finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
5642                                                 temp16a, finother);
5643         finswap = finnow; finnow = finother; finother = finswap;
5644       }
5645       if (cdytail != 0.0) {
5646         temp8len = scale_expansion_zeroelim(4, bb, -adxtail, temp8);
5647         temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail,
5648                                               temp16a);
5649         finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
5650                                                 temp16a, finother);
5651         finswap = finnow; finnow = finother; finother = finswap;
5652       }
5653 
5654       temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, adxtail,
5655                                             temp32a);
5656       axtbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adxtail, axtbctt);
5657       temp16alen = scale_expansion_zeroelim(axtbcttlen, axtbctt, 2.0 * adx,
5658                                             temp16a);
5659       temp16blen = scale_expansion_zeroelim(axtbcttlen, axtbctt, adxtail,
5660                                             temp16b);
5661       temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5662                                               temp16blen, temp16b, temp32b);
5663       temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
5664                                               temp32blen, temp32b, temp64);
5665       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
5666                                               temp64, finother);
5667       finswap = finnow; finnow = finother; finother = finswap;
5668     }
5669     if (adytail != 0.0) {
5670       temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, adytail, temp16a);
5671       aytbctlen = scale_expansion_zeroelim(bctlen, bct, adytail, aytbct);
5672       temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, 2.0 * ady,
5673                                             temp32a);
5674       temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5675                                               temp32alen, temp32a, temp48);
5676       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5677                                               temp48, finother);
5678       finswap = finnow; finnow = finother; finother = finswap;
5679 
5680 
5681       temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, adytail,
5682                                             temp32a);
5683       aytbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adytail, aytbctt);
5684       temp16alen = scale_expansion_zeroelim(aytbcttlen, aytbctt, 2.0 * ady,
5685                                             temp16a);
5686       temp16blen = scale_expansion_zeroelim(aytbcttlen, aytbctt, adytail,
5687                                             temp16b);
5688       temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5689                                               temp16blen, temp16b, temp32b);
5690       temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
5691                                               temp32blen, temp32b, temp64);
5692       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
5693                                               temp64, finother);
5694       finswap = finnow; finnow = finother; finother = finswap;
5695     }
5696   }
5697   if ((bdxtail != 0.0) || (bdytail != 0.0)) {
5698     if ((cdxtail != 0.0) || (cdytail != 0.0)
5699         || (adxtail != 0.0) || (adytail != 0.0)) {
5700       Two_Product(cdxtail, ady, ti1, ti0);
5701       Two_Product(cdx, adytail, tj1, tj0);
5702       Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
5703       u[3] = u3;
5704       negate = -cdy;
5705       Two_Product(adxtail, negate, ti1, ti0);
5706       negate = -cdytail;
5707       Two_Product(adx, negate, tj1, tj0);
5708       Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
5709       v[3] = v3;
5710       catlen = fast_expansion_sum_zeroelim(4, u, 4, v, cat);
5711 
5712       Two_Product(cdxtail, adytail, ti1, ti0);
5713       Two_Product(adxtail, cdytail, tj1, tj0);
5714       Two_Two_Diff(ti1, ti0, tj1, tj0, catt3, catt[2], catt[1], catt[0]);
5715       catt[3] = catt3;
5716       cattlen = 4;
5717     } else {
5718       cat[0] = 0.0;
5719       catlen = 1;
5720       catt[0] = 0.0;
5721       cattlen = 1;
5722     }
5723 
5724     if (bdxtail != 0.0) {
5725       temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, bdxtail, temp16a);
5726       bxtcatlen = scale_expansion_zeroelim(catlen, cat, bdxtail, bxtcat);
5727       temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, 2.0 * bdx,
5728                                             temp32a);
5729       temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5730                                               temp32alen, temp32a, temp48);
5731       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5732                                               temp48, finother);
5733       finswap = finnow; finnow = finother; finother = finswap;
5734       if (cdytail != 0.0) {
5735         temp8len = scale_expansion_zeroelim(4, aa, bdxtail, temp8);
5736         temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail,
5737                                               temp16a);
5738         finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
5739                                                 temp16a, finother);
5740         finswap = finnow; finnow = finother; finother = finswap;
5741       }
5742       if (adytail != 0.0) {
5743         temp8len = scale_expansion_zeroelim(4, cc, -bdxtail, temp8);
5744         temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail,
5745                                               temp16a);
5746         finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
5747                                                 temp16a, finother);
5748         finswap = finnow; finnow = finother; finother = finswap;
5749       }
5750 
5751       temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, bdxtail,
5752                                             temp32a);
5753       bxtcattlen = scale_expansion_zeroelim(cattlen, catt, bdxtail, bxtcatt);
5754       temp16alen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, 2.0 * bdx,
5755                                             temp16a);
5756       temp16blen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, bdxtail,
5757                                             temp16b);
5758       temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5759                                               temp16blen, temp16b, temp32b);
5760       temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
5761                                               temp32blen, temp32b, temp64);
5762       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
5763                                               temp64, finother);
5764       finswap = finnow; finnow = finother; finother = finswap;
5765     }
5766     if (bdytail != 0.0) {
5767       temp16alen = scale_expansion_zeroelim(bytcalen, bytca, bdytail, temp16a);
5768       bytcatlen = scale_expansion_zeroelim(catlen, cat, bdytail, bytcat);
5769       temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, 2.0 * bdy,
5770                                             temp32a);
5771       temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5772                                               temp32alen, temp32a, temp48);
5773       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5774                                               temp48, finother);
5775       finswap = finnow; finnow = finother; finother = finswap;
5776 
5777 
5778       temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, bdytail,
5779                                             temp32a);
5780       bytcattlen = scale_expansion_zeroelim(cattlen, catt, bdytail, bytcatt);
5781       temp16alen = scale_expansion_zeroelim(bytcattlen, bytcatt, 2.0 * bdy,
5782                                             temp16a);
5783       temp16blen = scale_expansion_zeroelim(bytcattlen, bytcatt, bdytail,
5784                                             temp16b);
5785       temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5786                                               temp16blen, temp16b, temp32b);
5787       temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
5788                                               temp32blen, temp32b, temp64);
5789       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
5790                                               temp64, finother);
5791       finswap = finnow; finnow = finother; finother = finswap;
5792     }
5793   }
5794   if ((cdxtail != 0.0) || (cdytail != 0.0)) {
5795     if ((adxtail != 0.0) || (adytail != 0.0)
5796         || (bdxtail != 0.0) || (bdytail != 0.0)) {
5797       Two_Product(adxtail, bdy, ti1, ti0);
5798       Two_Product(adx, bdytail, tj1, tj0);
5799       Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
5800       u[3] = u3;
5801       negate = -ady;
5802       Two_Product(bdxtail, negate, ti1, ti0);
5803       negate = -adytail;
5804       Two_Product(bdx, negate, tj1, tj0);
5805       Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
5806       v[3] = v3;
5807       abtlen = fast_expansion_sum_zeroelim(4, u, 4, v, abt);
5808 
5809       Two_Product(adxtail, bdytail, ti1, ti0);
5810       Two_Product(bdxtail, adytail, tj1, tj0);
5811       Two_Two_Diff(ti1, ti0, tj1, tj0, abtt3, abtt[2], abtt[1], abtt[0]);
5812       abtt[3] = abtt3;
5813       abttlen = 4;
5814     } else {
5815       abt[0] = 0.0;
5816       abtlen = 1;
5817       abtt[0] = 0.0;
5818       abttlen = 1;
5819     }
5820 
5821     if (cdxtail != 0.0) {
5822       temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, cdxtail, temp16a);
5823       cxtabtlen = scale_expansion_zeroelim(abtlen, abt, cdxtail, cxtabt);
5824       temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, 2.0 * cdx,
5825                                             temp32a);
5826       temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5827                                               temp32alen, temp32a, temp48);
5828       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5829                                               temp48, finother);
5830       finswap = finnow; finnow = finother; finother = finswap;
5831       if (adytail != 0.0) {
5832         temp8len = scale_expansion_zeroelim(4, bb, cdxtail, temp8);
5833         temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail,
5834                                               temp16a);
5835         finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
5836                                                 temp16a, finother);
5837         finswap = finnow; finnow = finother; finother = finswap;
5838       }
5839       if (bdytail != 0.0) {
5840         temp8len = scale_expansion_zeroelim(4, aa, -cdxtail, temp8);
5841         temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail,
5842                                               temp16a);
5843         finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
5844                                                 temp16a, finother);
5845         finswap = finnow; finnow = finother; finother = finswap;
5846       }
5847 
5848       temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, cdxtail,
5849                                             temp32a);
5850       cxtabttlen = scale_expansion_zeroelim(abttlen, abtt, cdxtail, cxtabtt);
5851       temp16alen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, 2.0 * cdx,
5852                                             temp16a);
5853       temp16blen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, cdxtail,
5854                                             temp16b);
5855       temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5856                                               temp16blen, temp16b, temp32b);
5857       temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
5858                                               temp32blen, temp32b, temp64);
5859       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
5860                                               temp64, finother);
5861       finswap = finnow; finnow = finother; finother = finswap;
5862     }
5863     if (cdytail != 0.0) {
5864       temp16alen = scale_expansion_zeroelim(cytablen, cytab, cdytail, temp16a);
5865       cytabtlen = scale_expansion_zeroelim(abtlen, abt, cdytail, cytabt);
5866       temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, 2.0 * cdy,
5867                                             temp32a);
5868       temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5869                                               temp32alen, temp32a, temp48);
5870       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5871                                               temp48, finother);
5872       finswap = finnow; finnow = finother; finother = finswap;
5873 
5874 
5875       temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, cdytail,
5876                                             temp32a);
5877       cytabttlen = scale_expansion_zeroelim(abttlen, abtt, cdytail, cytabtt);
5878       temp16alen = scale_expansion_zeroelim(cytabttlen, cytabtt, 2.0 * cdy,
5879                                             temp16a);
5880       temp16blen = scale_expansion_zeroelim(cytabttlen, cytabtt, cdytail,
5881                                             temp16b);
5882       temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5883                                               temp16blen, temp16b, temp32b);
5884       temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
5885                                               temp32blen, temp32b, temp64);
5886       finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
5887                                               temp64, finother);
5888       finswap = finnow; finnow = finother; finother = finswap;
5889     }
5890   }
5891 
5892   return finnow[finlength - 1];
5893 }
5894 
5895 #ifdef ANSI_DECLARATORS
5896 REAL incircle(struct mesh *m, struct behavior *b,
5897               vertex pa, vertex pb, vertex pc, vertex pd)
5898 #else /* not ANSI_DECLARATORS */
5899 REAL incircle(m, b, pa, pb, pc, pd)
5900 struct mesh *m;
5901 struct behavior *b;
5902 vertex pa;
5903 vertex pb;
5904 vertex pc;
5905 vertex pd;
5906 #endif /* not ANSI_DECLARATORS */
5907 
5908 {
5909   REAL adx, bdx, cdx, ady, bdy, cdy;
5910   REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
5911   REAL alift, blift, clift;
5912   REAL det;
5913   REAL permanent, errbound;
5914 
5915   m->incirclecount++;
5916 
5917   adx = pa[0] - pd[0];
5918   bdx = pb[0] - pd[0];
5919   cdx = pc[0] - pd[0];
5920   ady = pa[1] - pd[1];
5921   bdy = pb[1] - pd[1];
5922   cdy = pc[1] - pd[1];
5923 
5924   bdxcdy = bdx * cdy;
5925   cdxbdy = cdx * bdy;
5926   alift = adx * adx + ady * ady;
5927 
5928   cdxady = cdx * ady;
5929   adxcdy = adx * cdy;
5930   blift = bdx * bdx + bdy * bdy;
5931 
5932   adxbdy = adx * bdy;
5933   bdxady = bdx * ady;
5934   clift = cdx * cdx + cdy * cdy;
5935 
5936   det = alift * (bdxcdy - cdxbdy)
5937       + blift * (cdxady - adxcdy)
5938       + clift * (adxbdy - bdxady);
5939 
5940   if (b->noexact) {
5941     return det;
5942   }
5943 
5944   permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * alift
5945             + (Absolute(cdxady) + Absolute(adxcdy)) * blift
5946             + (Absolute(adxbdy) + Absolute(bdxady)) * clift;
5947   errbound = iccerrboundA * permanent;
5948   if ((det > errbound) || (-det > errbound)) {
5949     return det;
5950   }
5951 
5952   return incircleadapt(pa, pb, pc, pd, permanent);
5953 }
5954 
5955 /*****************************************************************************/
5956 /*                                                                           */
5957 /*  orient3d()   Return a positive value if the point pd lies below the      */
5958 /*               plane passing through pa, pb, and pc; "below" is defined so */
5959 /*               that pa, pb, and pc appear in counterclockwise order when   */
5960 /*               viewed from above the plane.  Returns a negative value if   */
5961 /*               pd lies above the plane.  Returns zero if the points are    */
5962 /*               coplanar.  The result is also a rough approximation of six  */
5963 /*               times the signed volume of the tetrahedron defined by the   */
5964 /*               four points.                                                */
5965 /*                                                                           */
5966 /*  Uses exact arithmetic if necessary to ensure a correct answer.  The      */
5967 /*  result returned is the determinant of a matrix.  This determinant is     */
5968 /*  computed adaptively, in the sense that exact arithmetic is used only to  */
5969 /*  the degree it is needed to ensure that the returned value has the        */
5970 /*  correct sign.  Hence, this function is usually quite fast, but will run  */
5971 /*  more slowly when the input points are coplanar or nearly so.             */
5972 /*                                                                           */
5973 /*  See my Robust Predicates paper for details.                              */
5974 /*                                                                           */
5975 /*****************************************************************************/
5976 
5977 #ifdef ANSI_DECLARATORS
5978 REAL orient3dadapt(vertex pa, vertex pb, vertex pc, vertex pd,
5979                    REAL aheight, REAL bheight, REAL cheight, REAL dheight,
5980                    REAL permanent)
5981 #else /* not ANSI_DECLARATORS */
5982 REAL orient3dadapt(pa, pb, pc, pd,
5983                    aheight, bheight, cheight, dheight, permanent)
5984 vertex pa;
5985 vertex pb;
5986 vertex pc;
5987 vertex pd;
5988 REAL aheight;
5989 REAL bheight;
5990 REAL cheight;
5991 REAL dheight;
5992 REAL permanent;
5993 #endif /* not ANSI_DECLARATORS */
5994 
5995 {
5996   INEXACT REAL adx, bdx, cdx, ady, bdy, cdy, adheight, bdheight, cdheight;
5997   REAL det, errbound;
5998 
5999   INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1;
6000   REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0;
6001   REAL bc[4], ca[4], ab[4];
6002   INEXACT REAL bc3, ca3, ab3;
6003   REAL adet[8], bdet[8], cdet[8];
6004   int alen, blen, clen;
6005   REAL abdet[16];
6006   int ablen;
6007   REAL *finnow, *finother, *finswap;
6008   REAL fin1[192], fin2[192];
6009   int finlength;
6010 
6011   REAL adxtail, bdxtail, cdxtail;
6012   REAL adytail, bdytail, cdytail;
6013   REAL adheighttail, bdheighttail, cdheighttail;
6014   INEXACT REAL at_blarge, at_clarge;
6015   INEXACT REAL bt_clarge, bt_alarge;
6016   INEXACT REAL ct_alarge, ct_blarge;
6017   REAL at_b[4], at_c[4], bt_c[4], bt_a[4], ct_a[4], ct_b[4];
6018   int at_blen, at_clen, bt_clen, bt_alen, ct_alen, ct_blen;
6019   INEXACT REAL bdxt_cdy1, cdxt_bdy1, cdxt_ady1;
6020   INEXACT REAL adxt_cdy1, adxt_bdy1, bdxt_ady1;
6021   REAL bdxt_cdy0, cdxt_bdy0, cdxt_ady0;
6022   REAL adxt_cdy0, adxt_bdy0, bdxt_ady0;
6023   INEXACT REAL bdyt_cdx1, cdyt_bdx1, cdyt_adx1;
6024   INEXACT REAL adyt_cdx1, adyt_bdx1, bdyt_adx1;
6025   REAL bdyt_cdx0, cdyt_bdx0, cdyt_adx0;
6026   REAL adyt_cdx0, adyt_bdx0, bdyt_adx0;
6027   REAL bct[8], cat[8], abt[8];
6028   int bctlen, catlen, abtlen;
6029   INEXACT REAL bdxt_cdyt1, cdxt_bdyt1, cdxt_adyt1;
6030   INEXACT REAL adxt_cdyt1, adxt_bdyt1, bdxt_adyt1;
6031   REAL bdxt_cdyt0, cdxt_bdyt0, cdxt_adyt0;
6032   REAL adxt_cdyt0, adxt_bdyt0, bdxt_adyt0;
6033   REAL u[4], v[12], w[16];
6034   INEXACT REAL u3;
6035   int vlength, wlength;
6036   REAL negate;
6037 
6038   INEXACT REAL bvirt;
6039   REAL avirt, bround, around;
6040   INEXACT REAL c;
6041   INEXACT REAL abig;
6042   REAL ahi, alo, bhi, blo;
6043   REAL err1, err2, err3;
6044   INEXACT REAL _i, _j, _k;
6045   REAL _0;
6046 
6047   adx = (REAL) (pa[0] - pd[0]);
6048   bdx = (REAL) (pb[0] - pd[0]);
6049   cdx = (REAL) (pc[0] - pd[0]);
6050   ady = (REAL) (pa[1] - pd[1]);
6051   bdy = (REAL) (pb[1] - pd[1]);
6052   cdy = (REAL) (pc[1] - pd[1]);
6053   adheight = (REAL) (aheight - dheight);
6054   bdheight = (REAL) (bheight - dheight);
6055   cdheight = (REAL) (cheight - dheight);
6056 
6057   Two_Product(bdx, cdy, bdxcdy1, bdxcdy0);
6058   Two_Product(cdx, bdy, cdxbdy1, cdxbdy0);
6059   Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]);
6060   bc[3] = bc3;
6061   alen = scale_expansion_zeroelim(4, bc, adheight, adet);
6062 
6063   Two_Product(cdx, ady, cdxady1, cdxady0);
6064   Two_Product(adx, cdy, adxcdy1, adxcdy0);
6065   Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]);
6066   ca[3] = ca3;
6067   blen = scale_expansion_zeroelim(4, ca, bdheight, bdet);
6068 
6069   Two_Product(adx, bdy, adxbdy1, adxbdy0);
6070   Two_Product(bdx, ady, bdxady1, bdxady0);
6071   Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]);
6072   ab[3] = ab3;
6073   clen = scale_expansion_zeroelim(4, ab, cdheight, cdet);
6074 
6075   ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
6076   finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1);
6077 
6078   det = estimate(finlength, fin1);
6079   errbound = o3derrboundB * permanent;
6080   if ((det >= errbound) || (-det >= errbound)) {
6081     return det;
6082   }
6083 
6084   Two_Diff_Tail(pa[0], pd[0], adx, adxtail);
6085   Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail);
6086   Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail);
6087   Two_Diff_Tail(pa[1], pd[1], ady, adytail);
6088   Two_Diff_Tail(pb[1], pd[1], bdy, bdytail);
6089   Two_Diff_Tail(pc[1], pd[1], cdy, cdytail);
6090   Two_Diff_Tail(aheight, dheight, adheight, adheighttail);
6091   Two_Diff_Tail(bheight, dheight, bdheight, bdheighttail);
6092   Two_Diff_Tail(cheight, dheight, cdheight, cdheighttail);
6093 
6094   if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0) &&
6095       (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0) &&
6096       (adheighttail == 0.0) &&
6097       (bdheighttail == 0.0) &&
6098       (cdheighttail == 0.0)) {
6099     return det;
6100   }
6101 
6102   errbound = o3derrboundC * permanent + resulterrbound * Absolute(det);
6103   det += (adheight * ((bdx * cdytail + cdy * bdxtail) -
6104                       (bdy * cdxtail + cdx * bdytail)) +
6105           adheighttail * (bdx * cdy - bdy * cdx)) +
6106          (bdheight * ((cdx * adytail + ady * cdxtail) -
6107                       (cdy * adxtail + adx * cdytail)) +
6108           bdheighttail * (cdx * ady - cdy * adx)) +
6109          (cdheight * ((adx * bdytail + bdy * adxtail) -
6110                       (ady * bdxtail + bdx * adytail)) +
6111           cdheighttail * (adx * bdy - ady * bdx));
6112   if ((det >= errbound) || (-det >= errbound)) {
6113     return det;
6114   }
6115 
6116   finnow = fin1;
6117   finother = fin2;
6118 
6119   if (adxtail == 0.0) {
6120     if (adytail == 0.0) {
6121       at_b[0] = 0.0;
6122       at_blen = 1;
6123       at_c[0] = 0.0;
6124       at_clen = 1;
6125     } else {
6126       negate = -adytail;
6127       Two_Product(negate, bdx, at_blarge, at_b[0]);
6128       at_b[1] = at_blarge;
6129       at_blen = 2;
6130       Two_Product(adytail, cdx, at_clarge, at_c[0]);
6131       at_c[1] = at_clarge;
6132       at_clen = 2;
6133     }
6134   } else {
6135     if (adytail == 0.0) {
6136       Two_Product(adxtail, bdy, at_blarge, at_b[0]);
6137       at_b[1] = at_blarge;
6138       at_blen = 2;
6139       negate = -adxtail;
6140       Two_Product(negate, cdy, at_clarge, at_c[0]);
6141       at_c[1] = at_clarge;
6142       at_clen = 2;
6143     } else {
6144       Two_Product(adxtail, bdy, adxt_bdy1, adxt_bdy0);
6145       Two_Product(adytail, bdx, adyt_bdx1, adyt_bdx0);
6146       Two_Two_Diff(adxt_bdy1, adxt_bdy0, adyt_bdx1, adyt_bdx0,
6147                    at_blarge, at_b[2], at_b[1], at_b[0]);
6148       at_b[3] = at_blarge;
6149       at_blen = 4;
6150       Two_Product(adytail, cdx, adyt_cdx1, adyt_cdx0);
6151       Two_Product(adxtail, cdy, adxt_cdy1, adxt_cdy0);
6152       Two_Two_Diff(adyt_cdx1, adyt_cdx0, adxt_cdy1, adxt_cdy0,
6153                    at_clarge, at_c[2], at_c[1], at_c[0]);
6154       at_c[3] = at_clarge;
6155       at_clen = 4;
6156     }
6157   }
6158   if (bdxtail == 0.0) {
6159     if (bdytail == 0.0) {
6160       bt_c[0] = 0.0;
6161       bt_clen = 1;
6162       bt_a[0] = 0.0;
6163       bt_alen = 1;
6164     } else {
6165       negate = -bdytail;
6166       Two_Product(negate, cdx, bt_clarge, bt_c[0]);
6167       bt_c[1] = bt_clarge;
6168       bt_clen = 2;
6169       Two_Product(bdytail, adx, bt_alarge, bt_a[0]);
6170       bt_a[1] = bt_alarge;
6171       bt_alen = 2;
6172     }
6173   } else {
6174     if (bdytail == 0.0) {
6175       Two_Product(bdxtail, cdy, bt_clarge, bt_c[0]);
6176       bt_c[1] = bt_clarge;
6177       bt_clen = 2;
6178       negate = -bdxtail;
6179       Two_Product(negate, ady, bt_alarge, bt_a[0]);
6180       bt_a[1] = bt_alarge;
6181       bt_alen = 2;
6182     } else {
6183       Two_Product(bdxtail, cdy, bdxt_cdy1, bdxt_cdy0);
6184       Two_Product(bdytail, cdx, bdyt_cdx1, bdyt_cdx0);
6185       Two_Two_Diff(bdxt_cdy1, bdxt_cdy0, bdyt_cdx1, bdyt_cdx0,
6186                    bt_clarge, bt_c[2], bt_c[1], bt_c[0]);
6187       bt_c[3] = bt_clarge;
6188       bt_clen = 4;
6189       Two_Product(bdytail, adx, bdyt_adx1, bdyt_adx0);
6190       Two_Product(bdxtail, ady, bdxt_ady1, bdxt_ady0);
6191       Two_Two_Diff(bdyt_adx1, bdyt_adx0, bdxt_ady1, bdxt_ady0,
6192                   bt_alarge, bt_a[2], bt_a[1], bt_a[0]);
6193       bt_a[3] = bt_alarge;
6194       bt_alen = 4;
6195     }
6196   }
6197   if (cdxtail == 0.0) {
6198     if (cdytail == 0.0) {
6199       ct_a[0] = 0.0;
6200       ct_alen = 1;
6201       ct_b[0] = 0.0;
6202       ct_blen = 1;
6203     } else {
6204       negate = -cdytail;
6205       Two_Product(negate, adx, ct_alarge, ct_a[0]);
6206       ct_a[1] = ct_alarge;
6207       ct_alen = 2;
6208       Two_Product(cdytail, bdx, ct_blarge, ct_b[0]);
6209       ct_b[1] = ct_blarge;
6210       ct_blen = 2;
6211     }
6212   } else {
6213     if (cdytail == 0.0) {
6214       Two_Product(cdxtail, ady, ct_alarge, ct_a[0]);
6215       ct_a[1] = ct_alarge;
6216       ct_alen = 2;
6217       negate = -cdxtail;
6218       Two_Product(negate, bdy, ct_blarge, ct_b[0]);
6219       ct_b[1] = ct_blarge;
6220       ct_blen = 2;
6221     } else {
6222       Two_Product(cdxtail, ady, cdxt_ady1, cdxt_ady0);
6223       Two_Product(cdytail, adx, cdyt_adx1, cdyt_adx0);
6224       Two_Two_Diff(cdxt_ady1, cdxt_ady0, cdyt_adx1, cdyt_adx0,
6225                    ct_alarge, ct_a[2], ct_a[1], ct_a[0]);
6226       ct_a[3] = ct_alarge;
6227       ct_alen = 4;
6228       Two_Product(cdytail, bdx, cdyt_bdx1, cdyt_bdx0);
6229       Two_Product(cdxtail, bdy, cdxt_bdy1, cdxt_bdy0);
6230       Two_Two_Diff(cdyt_bdx1, cdyt_bdx0, cdxt_bdy1, cdxt_bdy0,
6231                    ct_blarge, ct_b[2], ct_b[1], ct_b[0]);
6232       ct_b[3] = ct_blarge;
6233       ct_blen = 4;
6234     }
6235   }
6236 
6237   bctlen = fast_expansion_sum_zeroelim(bt_clen, bt_c, ct_blen, ct_b, bct);
6238   wlength = scale_expansion_zeroelim(bctlen, bct, adheight, w);
6239   finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
6240                                           finother);
6241   finswap = finnow; finnow = finother; finother = finswap;
6242 
6243   catlen = fast_expansion_sum_zeroelim(ct_alen, ct_a, at_clen, at_c, cat);
6244   wlength = scale_expansion_zeroelim(catlen, cat, bdheight, w);
6245   finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
6246                                           finother);
6247   finswap = finnow; finnow = finother; finother = finswap;
6248 
6249   abtlen = fast_expansion_sum_zeroelim(at_blen, at_b, bt_alen, bt_a, abt);
6250   wlength = scale_expansion_zeroelim(abtlen, abt, cdheight, w);
6251   finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
6252                                           finother);
6253   finswap = finnow; finnow = finother; finother = finswap;
6254 
6255   if (adheighttail != 0.0) {
6256     vlength = scale_expansion_zeroelim(4, bc, adheighttail, v);
6257     finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
6258                                             finother);
6259     finswap = finnow; finnow = finother; finother = finswap;
6260   }
6261   if (bdheighttail != 0.0) {
6262     vlength = scale_expansion_zeroelim(4, ca, bdheighttail, v);
6263     finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
6264                                             finother);
6265     finswap = finnow; finnow = finother; finother = finswap;
6266   }
6267   if (cdheighttail != 0.0) {
6268     vlength = scale_expansion_zeroelim(4, ab, cdheighttail, v);
6269     finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
6270                                             finother);
6271     finswap = finnow; finnow = finother; finother = finswap;
6272   }
6273 
6274   if (adxtail != 0.0) {
6275     if (bdytail != 0.0) {
6276       Two_Product(adxtail, bdytail, adxt_bdyt1, adxt_bdyt0);
6277       Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdheight, u3, u[2], u[1], u[0]);
6278       u[3] = u3;
6279       finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6280                                               finother);
6281       finswap = finnow; finnow = finother; finother = finswap;
6282       if (cdheighttail != 0.0) {
6283         Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdheighttail,
6284                         u3, u[2], u[1], u[0]);
6285         u[3] = u3;
6286         finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6287                                                 finother);
6288         finswap = finnow; finnow = finother; finother = finswap;
6289       }
6290     }
6291     if (cdytail != 0.0) {
6292       negate = -adxtail;
6293       Two_Product(negate, cdytail, adxt_cdyt1, adxt_cdyt0);
6294       Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdheight, u3, u[2], u[1], u[0]);
6295       u[3] = u3;
6296       finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6297                                               finother);
6298       finswap = finnow; finnow = finother; finother = finswap;
6299       if (bdheighttail != 0.0) {
6300         Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdheighttail,
6301                         u3, u[2], u[1], u[0]);
6302         u[3] = u3;
6303         finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6304                                                 finother);
6305         finswap = finnow; finnow = finother; finother = finswap;
6306       }
6307     }
6308   }
6309   if (bdxtail != 0.0) {
6310     if (cdytail != 0.0) {
6311       Two_Product(bdxtail, cdytail, bdxt_cdyt1, bdxt_cdyt0);
6312       Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adheight, u3, u[2], u[1], u[0]);
6313       u[3] = u3;
6314       finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6315                                               finother);
6316       finswap = finnow; finnow = finother; finother = finswap;
6317       if (adheighttail != 0.0) {
6318         Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adheighttail,
6319                         u3, u[2], u[1], u[0]);
6320         u[3] = u3;
6321         finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6322                                                 finother);
6323         finswap = finnow; finnow = finother; finother = finswap;
6324       }
6325     }
6326     if (adytail != 0.0) {
6327       negate = -bdxtail;
6328       Two_Product(negate, adytail, bdxt_adyt1, bdxt_adyt0);
6329       Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdheight, u3, u[2], u[1], u[0]);
6330       u[3] = u3;
6331       finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6332                                               finother);
6333       finswap = finnow; finnow = finother; finother = finswap;
6334       if (cdheighttail != 0.0) {
6335         Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdheighttail,
6336                         u3, u[2], u[1], u[0]);
6337         u[3] = u3;
6338         finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6339                                                 finother);
6340         finswap = finnow; finnow = finother; finother = finswap;
6341       }
6342     }
6343   }
6344   if (cdxtail != 0.0) {
6345     if (adytail != 0.0) {
6346       Two_Product(cdxtail, adytail, cdxt_adyt1, cdxt_adyt0);
6347       Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdheight, u3, u[2], u[1], u[0]);
6348       u[3] = u3;
6349       finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6350                                               finother);
6351       finswap = finnow; finnow = finother; finother = finswap;
6352       if (bdheighttail != 0.0) {
6353         Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdheighttail,
6354                         u3, u[2], u[1], u[0]);
6355         u[3] = u3;
6356         finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6357                                                 finother);
6358         finswap = finnow; finnow = finother; finother = finswap;
6359       }
6360     }
6361     if (bdytail != 0.0) {
6362       negate = -cdxtail;
6363       Two_Product(negate, bdytail, cdxt_bdyt1, cdxt_bdyt0);
6364       Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adheight, u3, u[2], u[1], u[0]);
6365       u[3] = u3;
6366       finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6367                                               finother);
6368       finswap = finnow; finnow = finother; finother = finswap;
6369       if (adheighttail != 0.0) {
6370         Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adheighttail,
6371                         u3, u[2], u[1], u[0]);
6372         u[3] = u3;
6373         finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6374                                                 finother);
6375         finswap = finnow; finnow = finother; finother = finswap;
6376       }
6377     }
6378   }
6379 
6380   if (adheighttail != 0.0) {
6381     wlength = scale_expansion_zeroelim(bctlen, bct, adheighttail, w);
6382     finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
6383                                             finother);
6384     finswap = finnow; finnow = finother; finother = finswap;
6385   }
6386   if (bdheighttail != 0.0) {
6387     wlength = scale_expansion_zeroelim(catlen, cat, bdheighttail, w);
6388     finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
6389                                             finother);
6390     finswap = finnow; finnow = finother; finother = finswap;
6391   }
6392   if (cdheighttail != 0.0) {
6393     wlength = scale_expansion_zeroelim(abtlen, abt, cdheighttail, w);
6394     finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
6395                                             finother);
6396     finswap = finnow; finnow = finother; finother = finswap;
6397   }
6398 
6399   return finnow[finlength - 1];
6400 }
6401 
6402 #ifdef ANSI_DECLARATORS
6403 REAL orient3d(struct mesh *m, struct behavior *b,
6404               vertex pa, vertex pb, vertex pc, vertex pd,
6405               REAL aheight, REAL bheight, REAL cheight, REAL dheight)
6406 #else /* not ANSI_DECLARATORS */
6407 REAL orient3d(m, b, pa, pb, pc, pd, aheight, bheight, cheight, dheight)
6408 struct mesh *m;
6409 struct behavior *b;
6410 vertex pa;
6411 vertex pb;
6412 vertex pc;
6413 vertex pd;
6414 REAL aheight;
6415 REAL bheight;
6416 REAL cheight;
6417 REAL dheight;
6418 #endif /* not ANSI_DECLARATORS */
6419 
6420 {
6421   REAL adx, bdx, cdx, ady, bdy, cdy, adheight, bdheight, cdheight;
6422   REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
6423   REAL det;
6424   REAL permanent, errbound;
6425 
6426   m->orient3dcount++;
6427 
6428   adx = pa[0] - pd[0];
6429   bdx = pb[0] - pd[0];
6430   cdx = pc[0] - pd[0];
6431   ady = pa[1] - pd[1];
6432   bdy = pb[1] - pd[1];
6433   cdy = pc[1] - pd[1];
6434   adheight = aheight - dheight;
6435   bdheight = bheight - dheight;
6436   cdheight = cheight - dheight;
6437 
6438   bdxcdy = bdx * cdy;
6439   cdxbdy = cdx * bdy;
6440 
6441   cdxady = cdx * ady;
6442   adxcdy = adx * cdy;
6443 
6444   adxbdy = adx * bdy;
6445   bdxady = bdx * ady;
6446 
6447   det = adheight * (bdxcdy - cdxbdy)
6448       + bdheight * (cdxady - adxcdy)
6449       + cdheight * (adxbdy - bdxady);
6450 
6451   if (b->noexact) {
6452     return det;
6453   }
6454 
6455   permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * Absolute(adheight)
6456             + (Absolute(cdxady) + Absolute(adxcdy)) * Absolute(bdheight)
6457             + (Absolute(adxbdy) + Absolute(bdxady)) * Absolute(cdheight);
6458   errbound = o3derrboundA * permanent;
6459   if ((det > errbound) || (-det > errbound)) {
6460     return det;
6461   }
6462 
6463   return orient3dadapt(pa, pb, pc, pd, aheight, bheight, cheight, dheight,
6464                        permanent);
6465 }
6466 
6467 /*****************************************************************************/
6468 /*                                                                           */
6469 /*  nonregular()   Return a positive value if the point pd is incompatible   */
6470 /*                 with the circle or plane passing through pa, pb, and pc   */
6471 /*                 (meaning that pd is inside the circle or below the        */
6472 /*                 plane); a negative value if it is compatible; and zero if */
6473 /*                 the four points are cocircular/coplanar.  The points pa,  */
6474 /*                 pb, and pc must be in counterclockwise order, or the sign */
6475 /*                 of the result will be reversed.                           */
6476 /*                                                                           */
6477 /*  If the -w switch is used, the points are lifted onto the parabolic       */
6478 /*  lifting map, then they are dropped according to their weights, then the  */
6479 /*  3D orientation test is applied.  If the -W switch is used, the points'   */
6480 /*  heights are already provided, so the 3D orientation test is applied      */
6481 /*  directly.  If neither switch is used, the incircle test is applied.      */
6482 /*                                                                           */
6483 /*****************************************************************************/
6484 
6485 #ifdef ANSI_DECLARATORS
6486 REAL nonregular(struct mesh *m, struct behavior *b,
6487                 vertex pa, vertex pb, vertex pc, vertex pd)
6488 #else /* not ANSI_DECLARATORS */
6489 REAL nonregular(m, b, pa, pb, pc, pd)
6490 struct mesh *m;
6491 struct behavior *b;
6492 vertex pa;
6493 vertex pb;
6494 vertex pc;
6495 vertex pd;
6496 #endif /* not ANSI_DECLARATORS */
6497 
6498 {
6499   if (b->weighted == 0) {
6500     return incircle(m, b, pa, pb, pc, pd);
6501   } else if (b->weighted == 1) {
6502     return orient3d(m, b, pa, pb, pc, pd,
6503                     pa[0] * pa[0] + pa[1] * pa[1] - pa[2],
6504                     pb[0] * pb[0] + pb[1] * pb[1] - pb[2],
6505                     pc[0] * pc[0] + pc[1] * pc[1] - pc[2],
6506                     pd[0] * pd[0] + pd[1] * pd[1] - pd[2]);
6507   } else {
6508     return orient3d(m, b, pa, pb, pc, pd, pa[2], pb[2], pc[2], pd[2]);
6509   }
6510 }
6511 
6512 /*****************************************************************************/
6513 /*                                                                           */
6514 /*  findcircumcenter()   Find the circumcenter of a triangle.                */
6515 /*                                                                           */
6516 /*  The result is returned both in terms of x-y coordinates and xi-eta       */
6517 /*  (barycentric) coordinates.  The xi-eta coordinate system is defined in   */
6518 /*  terms of the triangle:  the origin of the triangle is the origin of the  */
6519 /*  coordinate system; the destination of the triangle is one unit along the */
6520 /*  xi axis; and the apex of the triangle is one unit along the eta axis.    */
6521 /*  This procedure also returns the square of the length of the triangle's   */
6522 /*  shortest edge.                                                           */
6523 /*                                                                           */
6524 /*****************************************************************************/
6525 
6526 #ifdef ANSI_DECLARATORS
6527 void findcircumcenter(struct mesh *m, struct behavior *b,
6528                       vertex torg, vertex tdest, vertex tapex,
6529                       vertex circumcenter, REAL *xi, REAL *eta, int offcenter)
6530 #else /* not ANSI_DECLARATORS */
6531 void findcircumcenter(m, b, torg, tdest, tapex, circumcenter, xi, eta,
6532                       offcenter)
6533 struct mesh *m;
6534 struct behavior *b;
6535 vertex torg;
6536 vertex tdest;
6537 vertex tapex;
6538 vertex circumcenter;
6539 REAL *xi;
6540 REAL *eta;
6541 int offcenter;
6542 #endif /* not ANSI_DECLARATORS */
6543 
6544 {
6545   REAL xdo, ydo, xao, yao;
6546   REAL dodist, aodist, dadist;
6547   REAL denominator;
6548   REAL dx, dy, dxoff, dyoff;
6549 
6550   m->circumcentercount++;
6551 
6552   /* Compute the circumcenter of the triangle. */
6553   xdo = tdest[0] - torg[0];
6554   ydo = tdest[1] - torg[1];
6555   xao = tapex[0] - torg[0];
6556   yao = tapex[1] - torg[1];
6557   dodist = xdo * xdo + ydo * ydo;
6558   aodist = xao * xao + yao * yao;
6559   dadist = (tdest[0] - tapex[0]) * (tdest[0] - tapex[0]) +
6560            (tdest[1] - tapex[1]) * (tdest[1] - tapex[1]);
6561   if (b->noexact) {
6562     denominator = 0.5 / (xdo * yao - xao * ydo);
6563   } else {
6564     /* Use the counterclockwise() routine to ensure a positive (and */
6565     /*   reasonably accurate) result, avoiding any possibility of   */
6566     /*   division by zero.                                          */
6567     denominator = 0.5 / counterclockwise(m, b, tdest, tapex, torg);
6568     /* Don't count the above as an orientation test. */
6569     m->counterclockcount--;
6570   }
6571   dx = (yao * dodist - ydo * aodist) * denominator;
6572   dy = (xdo * aodist - xao * dodist) * denominator;
6573 
6574   /* Find the (squared) length of the triangle's shortest edge.  This   */
6575   /*   serves as a conservative estimate of the insertion radius of the */
6576   /*   circumcenter's parent.  The estimate is used to ensure that      */
6577   /*   the algorithm terminates even if very small angles appear in     */
6578   /*   the input PSLG.                                                  */
6579   if ((dodist < aodist) && (dodist < dadist)) {
6580     if (offcenter && (b->offconstant > 0.0)) {
6581       /* Find the position of the off-center, as described by Alper Ungor. */
6582       dxoff = 0.5 * xdo - b->offconstant * ydo;
6583       dyoff = 0.5 * ydo + b->offconstant * xdo;
6584       /* If the off-center is closer to the origin than the */
6585       /*   circumcenter, use the off-center instead.        */
6586       if (dxoff * dxoff + dyoff * dyoff < dx * dx + dy * dy) {
6587         dx = dxoff;
6588         dy = dyoff;
6589       }
6590     }
6591   } else if (aodist < dadist) {
6592     if (offcenter && (b->offconstant > 0.0)) {
6593       dxoff = 0.5 * xao + b->offconstant * yao;
6594       dyoff = 0.5 * yao - b->offconstant * xao;
6595       /* If the off-center is closer to the origin than the */
6596       /*   circumcenter, use the off-center instead.        */
6597       if (dxoff * dxoff + dyoff * dyoff < dx * dx + dy * dy) {
6598         dx = dxoff;
6599         dy = dyoff;
6600       }
6601     }
6602   } else {
6603     if (offcenter && (b->offconstant > 0.0)) {
6604       dxoff = 0.5 * (tapex[0] - tdest[0]) -
6605               b->offconstant * (tapex[1] - tdest[1]);
6606       dyoff = 0.5 * (tapex[1] - tdest[1]) +
6607               b->offconstant * (tapex[0] - tdest[0]);
6608       /* If the off-center is closer to the destination than the */
6609       /*   circumcenter, use the off-center instead.             */
6610       if (dxoff * dxoff + dyoff * dyoff <
6611           (dx - xdo) * (dx - xdo) + (dy - ydo) * (dy - ydo)) {
6612         dx = xdo + dxoff;
6613         dy = ydo + dyoff;
6614       }
6615     }
6616   }
6617 
6618   circumcenter[0] = torg[0] + dx;
6619   circumcenter[1] = torg[1] + dy;
6620 
6621   /* To interpolate vertex attributes for the new vertex inserted at */
6622   /*   the circumcenter, define a coordinate system with a xi-axis,  */
6623   /*   directed from the triangle's origin to its destination, and   */
6624   /*   an eta-axis, directed from its origin to its apex.            */
6625   /*   Calculate the xi and eta coordinates of the circumcenter.     */
6626   *xi = (yao * dx - xao * dy) * (2.0 * denominator);
6627   *eta = (xdo * dy - ydo * dx) * (2.0 * denominator);
6628 }
6629 
6630 /**                                                                         **/
6631 /**                                                                         **/
6632 /********* Geometric primitives end here                             *********/
6633 
6634 /*****************************************************************************/
6635 /*                                                                           */
6636 /*  triangleinit()   Initialize some variables.                              */
6637 /*                                                                           */
6638 /*****************************************************************************/
6639 
6640 #ifdef ANSI_DECLARATORS
6641 void triangleinit(struct mesh *m)
6642 #else /* not ANSI_DECLARATORS */
6643 void triangleinit(m)
6644 struct mesh *m;
6645 #endif /* not ANSI_DECLARATORS */
6646 
6647 {
6648   poolzero(&m->vertices);
6649   poolzero(&m->triangles);
6650   poolzero(&m->subsegs);
6651   poolzero(&m->viri);
6652   poolzero(&m->badsubsegs);
6653   poolzero(&m->badtriangles);
6654   poolzero(&m->flipstackers);
6655   poolzero(&m->splaynodes);
6656 
6657   m->recenttri.tri = (triangle *) NULL; /* No triangle has been visited yet. */
6658   m->undeads = 0;                       /* No eliminated input vertices yet. */
6659   m->samples = 1;         /* Point location should take at least one sample. */
6660   m->checksegments = 0;   /* There are no segments in the triangulation yet. */
6661   m->checkquality = 0;     /* The quality triangulation stage has not begun. */
6662   m->incirclecount = m->counterclockcount = m->orient3dcount = 0;
6663   m->hyperbolacount = m->circletopcount = m->circumcentercount = 0;
6664   randomseed = 1;
6665 
6666   exactinit();                     /* Initialize exact arithmetic constants. */
6667 }
6668 
6669 /*****************************************************************************/
6670 /*                                                                           */
6671 /*  randomnation()   Generate a random number between 0 and `choices' - 1.   */
6672 /*                                                                           */
6673 /*  This is a simple linear congruential random number generator.  Hence, it */
6674 /*  is a bad random number generator, but good enough for most randomized    */
6675 /*  geometric algorithms.                                                    */
6676 /*                                                                           */
6677 /*****************************************************************************/
6678 
6679 #ifdef ANSI_DECLARATORS
6680 unsigned long randomnation(unsigned int choices)
6681 #else /* not ANSI_DECLARATORS */
6682 unsigned long randomnation(choices)
6683 unsigned int choices;
6684 #endif /* not ANSI_DECLARATORS */
6685 
6686 {
6687   randomseed = (randomseed * 1366l + 150889l) % 714025l;
6688   return randomseed / (714025l / choices + 1);
6689 }
6690 
6691 /********* Mesh quality testing routines begin here                  *********/
6692 /**                                                                         **/
6693 /**                                                                         **/
6694 
6695 /*****************************************************************************/
6696 /*                                                                           */
6697 /*  checkmesh()   Test the mesh for topological consistency.                 */
6698 /*                                                                           */
6699 /*****************************************************************************/
6700 
6701 #ifndef REDUCED
6702 
6703 #ifdef ANSI_DECLARATORS
6704 void checkmesh(struct mesh *m, struct behavior *b)
6705 #else /* not ANSI_DECLARATORS */
6706 void checkmesh(m, b)
6707 struct mesh *m;
6708 struct behavior *b;
6709 #endif /* not ANSI_DECLARATORS */
6710 
6711 {
6712   struct otri triangleloop;
6713   struct otri oppotri, oppooppotri;
6714   vertex triorg, tridest, triapex;
6715   vertex oppoorg, oppodest;
6716   int horrors;
6717   int saveexact;
6718   triangle ptr;                         /* Temporary variable used by sym(). */
6719 
6720   /* Temporarily turn on exact arithmetic if it's off. */
6721   saveexact = b->noexact;
6722   b->noexact = 0;
6723   if (!b->quiet) {
6724     printf("  Checking consistency of mesh...\n");
6725   }
6726   horrors = 0;
6727   /* Run through the list of triangles, checking each one. */
6728   traversalinit(&m->triangles);
6729   triangleloop.tri = triangletraverse(m);
6730   while (triangleloop.tri != (triangle *) NULL) {
6731     /* Check all three edges of the triangle. */
6732     for (triangleloop.orient = 0; triangleloop.orient < 3;
6733          triangleloop.orient++) {
6734       org(triangleloop, triorg);
6735       dest(triangleloop, tridest);
6736       if (triangleloop.orient == 0) {       /* Only test for inversion once. */
6737         /* Test if the triangle is flat or inverted. */
6738         apex(triangleloop, triapex);
6739         if (counterclockwise(m, b, triorg, tridest, triapex) <= 0.0) {
6740           printf("  !! !! Inverted ");
6741           printtriangle(m, b, &triangleloop);
6742           horrors++;
6743         }
6744       }
6745       /* Find the neighboring triangle on this edge. */
6746       sym(triangleloop, oppotri);
6747       if (oppotri.tri != m->dummytri) {
6748         /* Check that the triangle's neighbor knows it's a neighbor. */
6749         sym(oppotri, oppooppotri);
6750         if ((triangleloop.tri != oppooppotri.tri)
6751             || (triangleloop.orient != oppooppotri.orient)) {
6752           printf("  !! !! Asymmetric triangle-triangle bond:\n");
6753           if (triangleloop.tri == oppooppotri.tri) {
6754             printf("   (Right triangle, wrong orientation)\n");
6755           }
6756           printf("    First ");
6757           printtriangle(m, b, &triangleloop);
6758           printf("    Second (nonreciprocating) ");
6759           printtriangle(m, b, &oppotri);
6760           horrors++;
6761         }
6762         /* Check that both triangles agree on the identities */
6763         /*   of their shared vertices.                       */
6764         org(oppotri, oppoorg);
6765         dest(oppotri, oppodest);
6766         if ((triorg != oppodest) || (tridest != oppoorg)) {
6767           printf("  !! !! Mismatched edge coordinates between two triangles:\n"
6768                  );
6769           printf("    First mismatched ");
6770           printtriangle(m, b, &triangleloop);
6771           printf("    Second mismatched ");
6772           printtriangle(m, b, &oppotri);
6773           horrors++;
6774         }
6775       }
6776     }
6777     triangleloop.tri = triangletraverse(m);
6778   }
6779   if (horrors == 0) {
6780     if (!b->quiet) {
6781       printf("  In my studied opinion, the mesh appears to be consistent.\n");
6782     }
6783   } else if (horrors == 1) {
6784     printf("  !! !! !! !! Precisely one festering wound discovered.\n");
6785   } else {
6786     printf("  !! !! !! !! %d abominations witnessed.\n", horrors);
6787   }
6788   /* Restore the status of exact arithmetic. */
6789   b->noexact = saveexact;
6790 }
6791 
6792 #endif /* not REDUCED */
6793 
6794 /*****************************************************************************/
6795 /*                                                                           */
6796 /*  checkdelaunay()   Ensure that the mesh is (constrained) Delaunay.        */
6797 /*                                                                           */
6798 /*****************************************************************************/
6799 
6800 #ifndef REDUCED
6801 
6802 #ifdef ANSI_DECLARATORS
6803 void checkdelaunay(struct mesh *m, struct behavior *b)
6804 #else /* not ANSI_DECLARATORS */
6805 void checkdelaunay(m, b)
6806 struct mesh *m;
6807 struct behavior *b;
6808 #endif /* not ANSI_DECLARATORS */
6809 
6810 {
6811   struct otri triangleloop;
6812   struct otri oppotri;
6813   struct osub opposubseg;
6814   vertex triorg, tridest, triapex;
6815   vertex oppoapex;
6816   int shouldbedelaunay;
6817   int horrors;
6818   int saveexact;
6819   triangle ptr;                         /* Temporary variable used by sym(). */
6820   subseg sptr;                      /* Temporary variable used by tspivot(). */
6821 
6822   /* Temporarily turn on exact arithmetic if it's off. */
6823   saveexact = b->noexact;
6824   b->noexact = 0;
6825   if (!b->quiet) {
6826     printf("  Checking Delaunay property of mesh...\n");
6827   }
6828   horrors = 0;
6829   /* Run through the list of triangles, checking each one. */
6830   traversalinit(&m->triangles);
6831   triangleloop.tri = triangletraverse(m);
6832   while (triangleloop.tri != (triangle *) NULL) {
6833     /* Check all three edges of the triangle. */
6834     for (triangleloop.orient = 0; triangleloop.orient < 3;
6835          triangleloop.orient++) {
6836       org(triangleloop, triorg);
6837       dest(triangleloop, tridest);
6838       apex(triangleloop, triapex);
6839       sym(triangleloop, oppotri);
6840       apex(oppotri, oppoapex);
6841       /* Only test that the edge is locally Delaunay if there is an   */
6842       /*   adjoining triangle whose pointer is larger (to ensure that */
6843       /*   each pair isn't tested twice).                             */
6844       shouldbedelaunay = (oppotri.tri != m->dummytri) &&
6845             !deadtri(oppotri.tri) && (triangleloop.tri < oppotri.tri) &&
6846             (triorg != m->infvertex1) && (triorg != m->infvertex2) &&
6847             (triorg != m->infvertex3) &&
6848             (tridest != m->infvertex1) && (tridest != m->infvertex2) &&
6849             (tridest != m->infvertex3) &&
6850             (triapex != m->infvertex1) && (triapex != m->infvertex2) &&
6851             (triapex != m->infvertex3) &&
6852             (oppoapex != m->infvertex1) && (oppoapex != m->infvertex2) &&
6853             (oppoapex != m->infvertex3);
6854       if (m->checksegments && shouldbedelaunay) {
6855         /* If a subsegment separates the triangles, then the edge is */
6856         /*   constrained, so no local Delaunay test should be done.  */
6857         tspivot(triangleloop, opposubseg);
6858         if (opposubseg.ss != m->dummysub){
6859           shouldbedelaunay = 0;
6860         }
6861       }
6862       if (shouldbedelaunay) {
6863         if (nonregular(m, b, triorg, tridest, triapex, oppoapex) > 0.0) {
6864           if (!b->weighted) {
6865             printf("  !! !! Non-Delaunay pair of triangles:\n");
6866             printf("    First non-Delaunay ");
6867             printtriangle(m, b, &triangleloop);
6868             printf("    Second non-Delaunay ");
6869           } else {
6870             printf("  !! !! Non-regular pair of triangles:\n");
6871             printf("    First non-regular ");
6872             printtriangle(m, b, &triangleloop);
6873             printf("    Second non-regular ");
6874           }
6875           printtriangle(m, b, &oppotri);
6876           horrors++;
6877         }
6878       }
6879     }
6880     triangleloop.tri = triangletraverse(m);
6881   }
6882   if (horrors == 0) {
6883     if (!b->quiet) {
6884       printf(
6885   "  By virtue of my perceptive intelligence, I declare the mesh Delaunay.\n");
6886     }
6887   } else if (horrors == 1) {
6888     printf(
6889          "  !! !! !! !! Precisely one terrifying transgression identified.\n");
6890   } else {
6891     printf("  !! !! !! !! %d obscenities viewed with horror.\n", horrors);
6892   }
6893   /* Restore the status of exact arithmetic. */
6894   b->noexact = saveexact;
6895 }
6896 
6897 #endif /* not REDUCED */
6898 
6899 /*****************************************************************************/
6900 /*                                                                           */
6901 /*  enqueuebadtriang()   Add a bad triangle data structure to the end of a   */
6902 /*                       queue.                                              */
6903 /*                                                                           */
6904 /*  The queue is actually a set of 4096 queues.  I use multiple queues to    */
6905 /*  give priority to smaller angles.  I originally implemented a heap, but   */
6906 /*  the queues are faster by a larger margin than I'd suspected.             */
6907 /*                                                                           */
6908 /*****************************************************************************/
6909 
6910 #ifndef CDT_ONLY
6911 
6912 #ifdef ANSI_DECLARATORS
6913 void enqueuebadtriang(struct mesh *m, struct behavior *b,
6914                       struct badtriang *badtri)
6915 #else /* not ANSI_DECLARATORS */
6916 void enqueuebadtriang(m, b, badtri)
6917 struct mesh *m;
6918 struct behavior *b;
6919 struct badtriang *badtri;
6920 #endif /* not ANSI_DECLARATORS */
6921 
6922 {
6923   REAL length, multiplier;
6924   int exponent, expincrement;
6925   int queuenumber;
6926   int posexponent;
6927   int i;
6928 
6929   if (b->verbose > 2) {
6930     printf("  Queueing bad triangle:\n");
6931     printf("    (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
6932            (double)badtri->triangorg[0], (double)badtri->triangorg[1],
6933            (double)badtri->triangdest[0], (double)badtri->triangdest[1],
6934            (double)badtri->triangapex[0], (double)badtri->triangapex[1]);
6935   }
6936 
6937   /* Determine the appropriate queue to put the bad triangle into.    */
6938   /*   Recall that the key is the square of its shortest edge length. */
6939   if (badtri->key >= 1.0) {
6940     length = badtri->key;
6941     posexponent = 1;
6942   } else {
6943     /* `badtri->key' is 2.0 to a negative exponent, so we'll record that */
6944     /*   fact and use the reciprocal of `badtri->key', which is > 1.0.   */
6945     length = 1.0 / badtri->key;
6946     posexponent = 0;
6947   }
6948   /* `length' is approximately 2.0 to what exponent?  The following code */
6949   /*   determines the answer in time logarithmic in the exponent.        */
6950   exponent = 0;
6951   while (length > 2.0) {
6952     /* Find an approximation by repeated squaring of two. */
6953     expincrement = 1;
6954     multiplier = 0.5;
6955     while (length * multiplier * multiplier > 1.0) {
6956       expincrement *= 2;
6957       multiplier *= multiplier;
6958     }
6959     /* Reduce the value of `length', then iterate if necessary. */
6960     exponent += expincrement;
6961     length *= multiplier;
6962   }
6963   /* `length' is approximately squareroot(2.0) to what exponent? */
6964   exponent = 2.0 * exponent + (length > SQUAREROOTTWO);
6965   /* `exponent' is now in the range 0...2047 for IEEE double precision.   */
6966   /*   Choose a queue in the range 0...4095.  The shortest edges have the */
6967   /*   highest priority (queue 4095).                                     */
6968   if (posexponent) {
6969     queuenumber = 2047 - exponent;
6970   } else {
6971     queuenumber = 2048 + exponent;
6972   }
6973 
6974   /* Are we inserting into an empty queue? */
6975   if (m->queuefront[queuenumber] == (struct badtriang *) NULL) {
6976     /* Yes, we are inserting into an empty queue.     */
6977     /*   Will this become the highest-priority queue? */
6978     if (queuenumber > m->firstnonemptyq) {
6979       /* Yes, this is the highest-priority queue. */
6980       m->nextnonemptyq[queuenumber] = m->firstnonemptyq;
6981       m->firstnonemptyq = queuenumber;
6982     } else {
6983       /* No, this is not the highest-priority queue. */
6984       /*   Find the queue with next higher priority. */
6985       i = queuenumber + 1;
6986       while (m->queuefront[i] == (struct badtriang *) NULL) {
6987         i++;
6988       }
6989       /* Mark the newly nonempty queue as following a higher-priority queue. */
6990       m->nextnonemptyq[queuenumber] = m->nextnonemptyq[i];
6991       m->nextnonemptyq[i] = queuenumber;
6992     }
6993     /* Put the bad triangle at the beginning of the (empty) queue. */
6994     m->queuefront[queuenumber] = badtri;
6995   } else {
6996     /* Add the bad triangle to the end of an already nonempty queue. */
6997     m->queuetail[queuenumber]->nexttriang = badtri;
6998   }
6999   /* Maintain a pointer to the last triangle of the queue. */
7000   m->queuetail[queuenumber] = badtri;
7001   /* Newly enqueued bad triangle has no successor in the queue. */
7002   badtri->nexttriang = (struct badtriang *) NULL;
7003 }
7004 
7005 #endif /* not CDT_ONLY */
7006 
7007 /*****************************************************************************/
7008 /*                                                                           */
7009 /*  enqueuebadtri()   Add a bad triangle to the end of a queue.              */
7010 /*                                                                           */
7011 /*  Allocates a badtriang data structure for the triangle, then passes it to */
7012 /*  enqueuebadtriang().                                                      */
7013 /*                                                                           */
7014 /*****************************************************************************/
7015 
7016 #ifndef CDT_ONLY
7017 
7018 #ifdef ANSI_DECLARATORS
7019 void enqueuebadtri(struct mesh *m, struct behavior *b, struct otri *enqtri,
7020                    REAL minedge, vertex enqapex, vertex enqorg, vertex enqdest)
7021 #else /* not ANSI_DECLARATORS */
7022 void enqueuebadtri(m, b, enqtri, minedge, enqapex, enqorg, enqdest)
7023 struct mesh *m;
7024 struct behavior *b;
7025 struct otri *enqtri;
7026 REAL minedge;
7027 vertex enqapex;
7028 vertex enqorg;
7029 vertex enqdest;
7030 #endif /* not ANSI_DECLARATORS */
7031 
7032 {
7033   struct badtriang *newbad;
7034 
7035   /* Allocate space for the bad triangle. */
7036   newbad = (struct badtriang *) poolalloc(&m->badtriangles);
7037   newbad->poortri = encode(*enqtri);
7038   newbad->key = minedge;
7039   newbad->triangapex = enqapex;
7040   newbad->triangorg = enqorg;
7041   newbad->triangdest = enqdest;
7042   enqueuebadtriang(m, b, newbad);
7043 }
7044 
7045 #endif /* not CDT_ONLY */
7046 
7047 /*****************************************************************************/
7048 /*                                                                           */
7049 /*  dequeuebadtriang()   Remove a triangle from the front of the queue.      */
7050 /*                                                                           */
7051 /*****************************************************************************/
7052 
7053 #ifndef CDT_ONLY
7054 
7055 #ifdef ANSI_DECLARATORS
7056 struct badtriang *dequeuebadtriang(struct mesh *m)
7057 #else /* not ANSI_DECLARATORS */
7058 struct badtriang *dequeuebadtriang(m)
7059 struct mesh *m;
7060 #endif /* not ANSI_DECLARATORS */
7061 
7062 {
7063   struct badtriang *result;
7064 
7065   /* If no queues are nonempty, return NULL. */
7066   if (m->firstnonemptyq < 0) {
7067     return (struct badtriang *) NULL;
7068   }
7069   /* Find the first triangle of the highest-priority queue. */
7070   result = m->queuefront[m->firstnonemptyq];
7071   /* Remove the triangle from the queue. */
7072   m->queuefront[m->firstnonemptyq] = result->nexttriang;
7073   /* If this queue is now empty, note the new highest-priority */
7074   /*   nonempty queue.                                         */
7075   if (result == m->queuetail[m->firstnonemptyq]) {
7076     m->firstnonemptyq = m->nextnonemptyq[m->firstnonemptyq];
7077   }
7078   return result;
7079 }
7080 
7081 #endif /* not CDT_ONLY */
7082 
7083 /*****************************************************************************/
7084 /*                                                                           */
7085 /*  checkseg4encroach()   Check a subsegment to see if it is encroached; add */
7086 /*                        it to the list if it is.                           */
7087 /*                                                                           */
7088 /*  A subsegment is encroached if there is a vertex in its diametral lens.   */
7089 /*  For Ruppert's algorithm (-D switch), the "diametral lens" is the         */
7090 /*  diametral circle.  For Chew's algorithm (default), the diametral lens is */
7091 /*  just big enough to enclose two isosceles triangles whose bases are the   */
7092 /*  subsegment.  Each of the two isosceles triangles has two angles equal    */
7093 /*  to `b->minangle'.                                                        */
7094 /*                                                                           */
7095 /*  Chew's algorithm does not require diametral lenses at all--but they save */
7096 /*  time.  Any vertex inside a subsegment's diametral lens implies that the  */
7097 /*  triangle adjoining the subsegment will be too skinny, so it's only a     */
7098 /*  matter of time before the encroaching vertex is deleted by Chew's        */
7099 /*  algorithm.  It's faster to simply not insert the doomed vertex in the    */
7100 /*  first place, which is why I use diametral lenses with Chew's algorithm.  */
7101 /*                                                                           */
7102 /*  Returns a nonzero value if the subsegment is encroached.                 */
7103 /*                                                                           */
7104 /*****************************************************************************/
7105 
7106 #ifndef CDT_ONLY
7107 
7108 #ifdef ANSI_DECLARATORS
7109 int checkseg4encroach(struct mesh *m, struct behavior *b,
7110                       struct osub *testsubseg)
7111 #else /* not ANSI_DECLARATORS */
7112 int checkseg4encroach(m, b, testsubseg)
7113 struct mesh *m;
7114 struct behavior *b;
7115 struct osub *testsubseg;
7116 #endif /* not ANSI_DECLARATORS */
7117 
7118 {
7119   struct otri neighbortri;
7120   struct osub testsym;
7121   struct badsubseg *encroachedseg;
7122   REAL dotproduct;
7123   int encroached;
7124   int sides;
7125   vertex eorg, edest, eapex;
7126   triangle ptr;                     /* Temporary variable used by stpivot(). */
7127 
7128   encroached = 0;
7129   sides = 0;
7130 
7131   sorg(*testsubseg, eorg);
7132   sdest(*testsubseg, edest);
7133   /* Check one neighbor of the subsegment. */
7134   stpivot(*testsubseg, neighbortri);
7135   /* Does the neighbor exist, or is this a boundary edge? */
7136   if (neighbortri.tri != m->dummytri) {
7137     sides++;
7138     /* Find a vertex opposite this subsegment. */
7139     apex(neighbortri, eapex);
7140     /* Check whether the apex is in the diametral lens of the subsegment */
7141     /*   (the diametral circle if `conformdel' is set).  A dot product   */
7142     /*   of two sides of the triangle is used to check whether the angle */
7143     /*   at the apex is greater than (180 - 2 `minangle') degrees (for   */
7144     /*   lenses; 90 degrees for diametral circles).                      */
7145     dotproduct = (eorg[0] - eapex[0]) * (edest[0] - eapex[0]) +
7146                  (eorg[1] - eapex[1]) * (edest[1] - eapex[1]);
7147     if (dotproduct < 0.0) {
7148       if (b->conformdel ||
7149           (dotproduct * dotproduct >=
7150            (2.0 * b->goodangle - 1.0) * (2.0 * b->goodangle - 1.0) *
7151            ((eorg[0] - eapex[0]) * (eorg[0] - eapex[0]) +
7152             (eorg[1] - eapex[1]) * (eorg[1] - eapex[1])) *
7153            ((edest[0] - eapex[0]) * (edest[0] - eapex[0]) +
7154             (edest[1] - eapex[1]) * (edest[1] - eapex[1])))) {
7155         encroached = 1;
7156       }
7157     }
7158   }
7159   /* Check the other neighbor of the subsegment. */
7160   ssym(*testsubseg, testsym);
7161   stpivot(testsym, neighbortri);
7162   /* Does the neighbor exist, or is this a boundary edge? */
7163   if (neighbortri.tri != m->dummytri) {
7164     sides++;
7165     /* Find the other vertex opposite this subsegment. */
7166     apex(neighbortri, eapex);
7167     /* Check whether the apex is in the diametral lens of the subsegment */
7168     /*   (or the diametral circle, if `conformdel' is set).              */
7169     dotproduct = (eorg[0] - eapex[0]) * (edest[0] - eapex[0]) +
7170                  (eorg[1] - eapex[1]) * (edest[1] - eapex[1]);
7171     if (dotproduct < 0.0) {
7172       if (b->conformdel ||
7173           (dotproduct * dotproduct >=
7174            (2.0 * b->goodangle - 1.0) * (2.0 * b->goodangle - 1.0) *
7175            ((eorg[0] - eapex[0]) * (eorg[0] - eapex[0]) +
7176             (eorg[1] - eapex[1]) * (eorg[1] - eapex[1])) *
7177            ((edest[0] - eapex[0]) * (edest[0] - eapex[0]) +
7178             (edest[1] - eapex[1]) * (edest[1] - eapex[1])))) {
7179         encroached += 2;
7180       }
7181     }
7182   }
7183 
7184   if (encroached && (!b->nobisect || ((b->nobisect == 1) && (sides == 2)))) {
7185     if (b->verbose > 2) {
7186       printf(
7187         "  Queueing encroached subsegment (%.12g, %.12g) (%.12g, %.12g).\n",
7188         (double)eorg[0], (double)eorg[1], (double)edest[0], (double)edest[1]);
7189     }
7190     /* Add the subsegment to the list of encroached subsegments. */
7191     /*   Be sure to get the orientation right.                   */
7192     encroachedseg = (struct badsubseg *) poolalloc(&m->badsubsegs);
7193     if (encroached == 1) {
7194       encroachedseg->encsubseg = sencode(*testsubseg);
7195       encroachedseg->subsegorg = eorg;
7196       encroachedseg->subsegdest = edest;
7197     } else {
7198       encroachedseg->encsubseg = sencode(testsym);
7199       encroachedseg->subsegorg = edest;
7200       encroachedseg->subsegdest = eorg;
7201     }
7202   }
7203 
7204   return encroached;
7205 }
7206 
7207 #endif /* not CDT_ONLY */
7208 
7209 /*****************************************************************************/
7210 /*                                                                           */
7211 /*  testtriangle()   Test a triangle for quality and size.                   */
7212 /*                                                                           */
7213 /*  Tests a triangle to see if it satisfies the minimum angle condition and  */
7214 /*  the maximum area condition.  Triangles that aren't up to spec are added  */
7215 /*  to the bad triangle queue.                                               */
7216 /*                                                                           */
7217 /*****************************************************************************/
7218 
7219 #ifndef CDT_ONLY
7220 
7221 #ifdef ANSI_DECLARATORS
7222 void testtriangle(struct mesh *m, struct behavior *b, struct otri *testtri)
7223 #else /* not ANSI_DECLARATORS */
7224 void testtriangle(m, b, testtri)
7225 struct mesh *m;
7226 struct behavior *b;
7227 struct otri *testtri;
7228 #endif /* not ANSI_DECLARATORS */
7229 
7230 {
7231   struct otri tri1, tri2;
7232   struct osub testsub;
7233   vertex torg, tdest, tapex;
7234   vertex base1, base2;
7235   vertex org1, dest1, org2, dest2;
7236   vertex joinvertex;
7237   REAL dxod, dyod, dxda, dyda, dxao, dyao;
7238   REAL dxod2, dyod2, dxda2, dyda2, dxao2, dyao2;
7239   REAL apexlen, orglen, destlen, minedge;
7240   REAL angle;
7241   REAL area;
7242   REAL dist1, dist2;
7243   subseg sptr;                      /* Temporary variable used by tspivot(). */
7244   triangle ptr;           /* Temporary variable used by oprev() and dnext(). */
7245 
7246   org(*testtri, torg);
7247   dest(*testtri, tdest);
7248   apex(*testtri, tapex);
7249   dxod = torg[0] - tdest[0];
7250   dyod = torg[1] - tdest[1];
7251   dxda = tdest[0] - tapex[0];
7252   dyda = tdest[1] - tapex[1];
7253   dxao = tapex[0] - torg[0];
7254   dyao = tapex[1] - torg[1];
7255   dxod2 = dxod * dxod;
7256   dyod2 = dyod * dyod;
7257   dxda2 = dxda * dxda;
7258   dyda2 = dyda * dyda;
7259   dxao2 = dxao * dxao;
7260   dyao2 = dyao * dyao;
7261   /* Find the lengths of the triangle's three edges. */
7262   apexlen = dxod2 + dyod2;
7263   orglen = dxda2 + dyda2;
7264   destlen = dxao2 + dyao2;
7265 
7266   if ((apexlen < orglen) && (apexlen < destlen)) {
7267     /* The edge opposite the apex is shortest. */
7268     minedge = apexlen;
7269     /* Find the square of the cosine of the angle at the apex. */
7270     angle = dxda * dxao + dyda * dyao;
7271     angle = angle * angle / (orglen * destlen);
7272     base1 = torg;
7273     base2 = tdest;
7274     otricopy(*testtri, tri1);
7275   } else if (orglen < destlen) {
7276     /* The edge opposite the origin is shortest. */
7277     minedge = orglen;
7278     /* Find the square of the cosine of the angle at the origin. */
7279     angle = dxod * dxao + dyod * dyao;
7280     angle = angle * angle / (apexlen * destlen);
7281     base1 = tdest;
7282     base2 = tapex;
7283     lnext(*testtri, tri1);
7284   } else {
7285     /* The edge opposite the destination is shortest. */
7286     minedge = destlen;
7287     /* Find the square of the cosine of the angle at the destination. */
7288     angle = dxod * dxda + dyod * dyda;
7289     angle = angle * angle / (apexlen * orglen);
7290     base1 = tapex;
7291     base2 = torg;
7292     lprev(*testtri, tri1);
7293   }
7294 
7295   if (b->vararea || b->fixedarea || b->usertest) {
7296     /* Check whether the area is larger than permitted. */
7297     area = 0.5 * (dxod * dyda - dyod * dxda);
7298     if (b->fixedarea && (area > b->maxarea)) {
7299       /* Add this triangle to the list of bad triangles. */
7300       enqueuebadtri(m, b, testtri, minedge, tapex, torg, tdest);
7301       return;
7302     }
7303 
7304     /* Nonpositive area constraints are treated as unconstrained. */
7305     if ((b->vararea) && (area > areabound(*testtri)) &&
7306         (areabound(*testtri) > 0.0)) {
7307       /* Add this triangle to the list of bad triangles. */
7308       enqueuebadtri(m, b, testtri, minedge, tapex, torg, tdest);
7309       return;
7310     }
7311 
7312     if (b->usertest) {
7313       /* Check whether the user thinks this triangle is too large. */
7314       if (triunsuitable(torg, tdest, tapex, area)) {
7315         enqueuebadtri(m, b, testtri, minedge, tapex, torg, tdest);
7316         return;
7317       }
7318     }
7319   }
7320 
7321   /* Check whether the angle is smaller than permitted. */
7322   if (angle > b->goodangle) {
7323     /* Use the rules of Miller, Pav, and Walkington to decide that certain */
7324     /*   triangles should not be split, even if they have bad angles.      */
7325     /*   A skinny triangle is not split if its shortest edge subtends a    */
7326     /*   small input angle, and both endpoints of the edge lie on a        */
7327     /*   concentric circular shell.  For convenience, I make a small       */
7328     /*   adjustment to that rule:  I check if the endpoints of the edge    */
7329     /*   both lie in segment interiors, equidistant from the apex where    */
7330     /*   the two segments meet.                                            */
7331     /* First, check if both points lie in segment interiors.               */
7332     if ((vertextype(base1) == SEGMENTVERTEX) &&
7333         (vertextype(base2) == SEGMENTVERTEX)) {
7334       /* Check if both points lie in a common segment.  If they do, the */
7335       /*   skinny triangle is enqueued to be split as usual.            */
7336       tspivot(tri1, testsub);
7337       if (testsub.ss == m->dummysub) {
7338         /* No common segment.  Find a subsegment that contains `torg'. */
7339         otricopy(tri1, tri2);
7340         do {
7341           oprevself(tri1);
7342           tspivot(tri1, testsub);
7343         } while (testsub.ss == m->dummysub);
7344         /* Find the endpoints of the containing segment. */
7345         segorg(testsub, org1);
7346         segdest(testsub, dest1);
7347         /* Find a subsegment that contains `tdest'. */
7348         do {
7349           dnextself(tri2);
7350           tspivot(tri2, testsub);
7351         } while (testsub.ss == m->dummysub);
7352         /* Find the endpoints of the containing segment. */
7353         segorg(testsub, org2);
7354         segdest(testsub, dest2);
7355         /* Check if the two containing segments have an endpoint in common. */
7356         joinvertex = (vertex) NULL;
7357         if ((dest1[0] == org2[0]) && (dest1[1] == org2[1])) {
7358           joinvertex = dest1;
7359         } else if ((org1[0] == dest2[0]) && (org1[1] == dest2[1])) {
7360           joinvertex = org1;
7361         }
7362         if (joinvertex != (vertex) NULL) {
7363           /* Compute the distance from the common endpoint (of the two  */
7364           /*   segments) to each of the endpoints of the shortest edge. */
7365           dist1 = ((base1[0] - joinvertex[0]) * (base1[0] - joinvertex[0]) +
7366                    (base1[1] - joinvertex[1]) * (base1[1] - joinvertex[1]));
7367           dist2 = ((base2[0] - joinvertex[0]) * (base2[0] - joinvertex[0]) +
7368                    (base2[1] - joinvertex[1]) * (base2[1] - joinvertex[1]));
7369           /* If the two distances are equal, don't split the triangle. */
7370           if ((dist1 < 1.001 * dist2) && (dist1 > 0.999 * dist2)) {
7371             /* Return now to avoid enqueueing the bad triangle. */
7372             return;
7373           }
7374         }
7375       }
7376     }
7377 
7378     /* Add this triangle to the list of bad triangles. */
7379     enqueuebadtri(m, b, testtri, minedge, tapex, torg, tdest);
7380   }
7381 }
7382 
7383 #endif /* not CDT_ONLY */
7384 
7385 /**                                                                         **/
7386 /**                                                                         **/
7387 /********* Mesh quality testing routines end here                    *********/
7388 
7389 /********* Point location routines begin here                        *********/
7390 /**                                                                         **/
7391 /**                                                                         **/
7392 
7393 /*****************************************************************************/
7394 /*                                                                           */
7395 /*  makevertexmap()   Construct a mapping from vertices to triangles to      */
7396 /*                    improve the speed of point location for segment        */
7397 /*                    insertion.                                             */
7398 /*                                                                           */
7399 /*  Traverses all the triangles, and provides each corner of each triangle   */
7400 /*  with a pointer to that triangle.  Of course, pointers will be            */
7401 /*  overwritten by other pointers because (almost) each vertex is a corner   */
7402 /*  of several triangles, but in the end every vertex will point to some     */
7403 /*  triangle that contains it.                                               */
7404 /*                                                                           */
7405 /*****************************************************************************/
7406 
7407 #ifdef ANSI_DECLARATORS
7408 void makevertexmap(struct mesh *m, struct behavior *b)
7409 #else /* not ANSI_DECLARATORS */
7410 void makevertexmap(m, b)
7411 struct mesh *m;
7412 struct behavior *b;
7413 #endif /* not ANSI_DECLARATORS */
7414 
7415 {
7416   struct otri triangleloop;
7417   vertex triorg;
7418 
7419   if (b->verbose) {
7420     printf("    Constructing mapping from vertices to triangles.\n");
7421   }
7422   traversalinit(&m->triangles);
7423   triangleloop.tri = triangletraverse(m);
7424   while (triangleloop.tri != (triangle *) NULL) {
7425     /* Check all three vertices of the triangle. */
7426     for (triangleloop.orient = 0; triangleloop.orient < 3;
7427          triangleloop.orient++) {
7428       org(triangleloop, triorg);
7429       setvertex2tri(triorg, encode(triangleloop));
7430     }
7431     triangleloop.tri = triangletraverse(m);
7432   }
7433 }
7434 
7435 /*****************************************************************************/
7436 /*                                                                           */
7437 /*  preciselocate()   Find a triangle or edge containing a given point.      */
7438 /*                                                                           */
7439 /*  Begins its search from `searchtri'.  It is important that `searchtri'    */
7440 /*  be a handle with the property that `searchpoint' is strictly to the left */
7441 /*  of the edge denoted by `searchtri', or is collinear with that edge and   */
7442 /*  does not intersect that edge.  (In particular, `searchpoint' should not  */
7443 /*  be the origin or destination of that edge.)                              */
7444 /*                                                                           */
7445 /*  These conditions are imposed because preciselocate() is normally used in */
7446 /*  one of two situations:                                                   */
7447 /*                                                                           */
7448 /*  (1)  To try to find the location to insert a new point.  Normally, we    */
7449 /*       know an edge that the point is strictly to the left of.  In the     */
7450 /*       incremental Delaunay algorithm, that edge is a bounding box edge.   */
7451 /*       In Ruppert's Delaunay refinement algorithm for quality meshing,     */
7452 /*       that edge is the shortest edge of the triangle whose circumcenter   */
7453 /*       is being inserted.                                                  */
7454 /*                                                                           */
7455 /*  (2)  To try to find an existing point.  In this case, any edge on the    */
7456 /*       convex hull is a good starting edge.  You must screen out the       */
7457 /*       possibility that the vertex sought is an endpoint of the starting   */
7458 /*       edge before you call preciselocate().                               */
7459 /*                                                                           */
7460 /*  On completion, `searchtri' is a triangle that contains `searchpoint'.    */
7461 /*                                                                           */
7462 /*  This implementation differs from that given by Guibas and Stolfi.  It    */
7463 /*  walks from triangle to triangle, crossing an edge only if `searchpoint'  */
7464 /*  is on the other side of the line containing that edge.  After entering   */
7465 /*  a triangle, there are two edges by which one can leave that triangle.    */
7466 /*  If both edges are valid (`searchpoint' is on the other side of both      */
7467 /*  edges), one of the two is chosen by drawing a line perpendicular to      */
7468 /*  the entry edge (whose endpoints are `forg' and `fdest') passing through  */
7469 /*  `fapex'.  Depending on which side of this perpendicular `searchpoint'    */
7470 /*  falls on, an exit edge is chosen.                                        */
7471 /*                                                                           */
7472 /*  This implementation is empirically faster than the Guibas and Stolfi     */
7473 /*  point location routine (which I originally used), which tends to spiral  */
7474 /*  in toward its target.                                                    */
7475 /*                                                                           */
7476 /*  Returns ONVERTEX if the point lies on an existing vertex.  `searchtri'   */
7477 /*  is a handle whose origin is the existing vertex.                         */
7478 /*                                                                           */
7479 /*  Returns ONEDGE if the point lies on a mesh edge.  `searchtri' is a       */
7480 /*  handle whose primary edge is the edge on which the point lies.           */
7481 /*                                                                           */
7482 /*  Returns INTRIANGLE if the point lies strictly within a triangle.         */
7483 /*  `searchtri' is a handle on the triangle that contains the point.         */
7484 /*                                                                           */
7485 /*  Returns OUTSIDE if the point lies outside the mesh.  `searchtri' is a    */
7486 /*  handle whose primary edge the point is to the right of.  This might      */
7487 /*  occur when the circumcenter of a triangle falls just slightly outside    */
7488 /*  the mesh due to floating-point roundoff error.  It also occurs when      */
7489 /*  seeking a hole or region point that a foolish user has placed outside    */
7490 /*  the mesh.                                                                */
7491 /*                                                                           */
7492 /*  If `stopatsubsegment' is nonzero, the search will stop if it tries to    */
7493 /*  walk through a subsegment, and will return OUTSIDE.                      */
7494 /*                                                                           */
7495 /*  WARNING:  This routine is designed for convex triangulations, and will   */
7496 /*  not generally work after the holes and concavities have been carved.     */
7497 /*  However, it can still be used to find the circumcenter of a triangle, as */
7498 /*  long as the search is begun from the triangle in question.               */
7499 /*                                                                           */
7500 /*****************************************************************************/
7501 
7502 #ifdef ANSI_DECLARATORS
7503 enum locateresult preciselocate(struct mesh *m, struct behavior *b,
7504                                 vertex searchpoint, struct otri *searchtri,
7505                                 int stopatsubsegment)
7506 #else /* not ANSI_DECLARATORS */
7507 enum locateresult preciselocate(m, b, searchpoint, searchtri, stopatsubsegment)
7508 struct mesh *m;
7509 struct behavior *b;
7510 vertex searchpoint;
7511 struct otri *searchtri;
7512 int stopatsubsegment;
7513 #endif /* not ANSI_DECLARATORS */
7514 
7515 {
7516   struct otri backtracktri;
7517   struct osub checkedge;
7518   vertex forg, fdest, fapex;
7519   REAL orgorient, destorient;
7520   int moveleft;
7521   triangle ptr;                         /* Temporary variable used by sym(). */
7522   subseg sptr;                      /* Temporary variable used by tspivot(). */
7523 
7524   if (b->verbose > 2) {
7525     printf("  Searching for point (%.12g, %.12g).\n",
7526            (double)searchpoint[0], (double)searchpoint[1]);
7527   }
7528   /* Where are we? */
7529   org(*searchtri, forg);
7530   dest(*searchtri, fdest);
7531   apex(*searchtri, fapex);
7532   while (1) {
7533     if (b->verbose > 2) {
7534       printf("    At (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
7535              (double)forg[0], (double)forg[1],
7536              (double)fdest[0], (double)fdest[1],
7537              (double)fapex[0], (double)fapex[1]);
7538     }
7539     /* Check whether the apex is the point we seek. */
7540     if ((fapex[0] == searchpoint[0]) && (fapex[1] == searchpoint[1])) {
7541       lprevself(*searchtri);
7542       return ONVERTEX;
7543     }
7544     /* Does the point lie on the other side of the line defined by the */
7545     /*   triangle edge opposite the triangle's destination?            */
7546     destorient = counterclockwise(m, b, forg, fapex, searchpoint);
7547     /* Does the point lie on the other side of the line defined by the */
7548     /*   triangle edge opposite the triangle's origin?                 */
7549     orgorient = counterclockwise(m, b, fapex, fdest, searchpoint);
7550     if (destorient > 0.0) {
7551       if (orgorient > 0.0) {
7552         /* Move left if the inner product of (fapex - searchpoint) and  */
7553         /*   (fdest - forg) is positive.  This is equivalent to drawing */
7554         /*   a line perpendicular to the line (forg, fdest) and passing */
7555         /*   through `fapex', and determining which side of this line   */
7556         /*   `searchpoint' falls on.                                    */
7557         moveleft = (fapex[0] - searchpoint[0]) * (fdest[0] - forg[0]) +
7558                    (fapex[1] - searchpoint[1]) * (fdest[1] - forg[1]) > 0.0;
7559       } else {
7560         moveleft = 1;
7561       }
7562     } else {
7563       if (orgorient > 0.0) {
7564         moveleft = 0;
7565       } else {
7566         /* The point we seek must be on the boundary of or inside this */
7567         /*   triangle.                                                 */
7568         if (destorient == 0.0) {
7569           lprevself(*searchtri);
7570           return ONEDGE;
7571         }
7572         if (orgorient == 0.0) {
7573           lnextself(*searchtri);
7574           return ONEDGE;
7575         }
7576         return INTRIANGLE;
7577       }
7578     }
7579 
7580     /* Move to another triangle.  Leave a trace `backtracktri' in case */
7581     /*   floating-point roundoff or some such bogey causes us to walk  */
7582     /*   off a boundary of the triangulation.                          */
7583     if (moveleft) {
7584       lprev(*searchtri, backtracktri);
7585       fdest = fapex;
7586     } else {
7587       lnext(*searchtri, backtracktri);
7588       forg = fapex;
7589     }
7590     sym(backtracktri, *searchtri);
7591 
7592     if (m->checksegments && stopatsubsegment) {
7593       /* Check for walking through a subsegment. */
7594       tspivot(backtracktri, checkedge);
7595       if (checkedge.ss != m->dummysub) {
7596         /* Go back to the last triangle. */
7597         otricopy(backtracktri, *searchtri);
7598         return OUTSIDE;
7599       }
7600     }
7601     /* Check for walking right out of the triangulation. */
7602     if (searchtri->tri == m->dummytri) {
7603       /* Go back to the last triangle. */
7604       otricopy(backtracktri, *searchtri);
7605       return OUTSIDE;
7606     }
7607 
7608     apex(*searchtri, fapex);
7609   }
7610 }
7611 
7612 /*****************************************************************************/
7613 /*                                                                           */
7614 /*  locate()   Find a triangle or edge containing a given point.             */
7615 /*                                                                           */
7616 /*  Searching begins from one of:  the input `searchtri', a recently         */
7617 /*  encountered triangle `recenttri', or from a triangle chosen from a       */
7618 /*  random sample.  The choice is made by determining which triangle's       */
7619 /*  origin is closest to the point we are searching for.  Normally,          */
7620 /*  `searchtri' should be a handle on the convex hull of the triangulation.  */
7621 /*                                                                           */
7622 /*  Details on the random sampling method can be found in the Mucke, Saias,  */
7623 /*  and Zhu paper cited in the header of this code.                          */
7624 /*                                                                           */
7625 /*  On completion, `searchtri' is a triangle that contains `searchpoint'.    */
7626 /*                                                                           */
7627 /*  Returns ONVERTEX if the point lies on an existing vertex.  `searchtri'   */
7628 /*  is a handle whose origin is the existing vertex.                         */
7629 /*                                                                           */
7630 /*  Returns ONEDGE if the point lies on a mesh edge.  `searchtri' is a       */
7631 /*  handle whose primary edge is the edge on which the point lies.           */
7632 /*                                                                           */
7633 /*  Returns INTRIANGLE if the point lies strictly within a triangle.         */
7634 /*  `searchtri' is a handle on the triangle that contains the point.         */
7635 /*                                                                           */
7636 /*  Returns OUTSIDE if the point lies outside the mesh.  `searchtri' is a    */
7637 /*  handle whose primary edge the point is to the right of.  This might      */
7638 /*  occur when the circumcenter of a triangle falls just slightly outside    */
7639 /*  the mesh due to floating-point roundoff error.  It also occurs when      */
7640 /*  seeking a hole or region point that a foolish user has placed outside    */
7641 /*  the mesh.                                                                */
7642 /*                                                                           */
7643 /*  WARNING:  This routine is designed for convex triangulations, and will   */
7644 /*  not generally work after the holes and concavities have been carved.     */
7645 /*                                                                           */
7646 /*****************************************************************************/
7647 
7648 #ifdef ANSI_DECLARATORS
7649 enum locateresult locate(struct mesh *m, struct behavior *b,
7650                          vertex searchpoint, struct otri *searchtri)
7651 #else /* not ANSI_DECLARATORS */
7652 enum locateresult locate(m, b, searchpoint, searchtri)
7653 struct mesh *m;
7654 struct behavior *b;
7655 vertex searchpoint;
7656 struct otri *searchtri;
7657 #endif /* not ANSI_DECLARATORS */
7658 
7659 {
7660   VOID **sampleblock;
7661   char *firsttri;
7662   struct otri sampletri;
7663   vertex torg, tdest;
7664   unsigned long alignptr;
7665   REAL searchdist, dist;
7666   REAL ahead;
7667   long samplesperblock, totalsamplesleft, samplesleft;
7668   long population, totalpopulation;
7669   triangle ptr;                         /* Temporary variable used by sym(). */
7670 
7671   if (b->verbose > 2) {
7672     printf("  Randomly sampling for a triangle near point (%.12g, %.12g).\n",
7673            (double)searchpoint[0], (double)searchpoint[1]);
7674   }
7675   /* Record the distance from the suggested starting triangle to the */
7676   /*   point we seek.                                                */
7677   org(*searchtri, torg);
7678   searchdist = (searchpoint[0] - torg[0]) * (searchpoint[0] - torg[0]) +
7679                (searchpoint[1] - torg[1]) * (searchpoint[1] - torg[1]);
7680   if (b->verbose > 2) {
7681     printf("    Boundary triangle has origin (%.12g, %.12g).\n",
7682            (double)torg[0], (double)torg[1]);
7683   }
7684 
7685   /* If a recently encountered triangle has been recorded and has not been */
7686   /*   deallocated, test it as a good starting point.                      */
7687   if (m->recenttri.tri != (triangle *) NULL) {
7688     if (!deadtri(m->recenttri.tri)) {
7689       org(m->recenttri, torg);
7690       if ((torg[0] == searchpoint[0]) && (torg[1] == searchpoint[1])) {
7691         otricopy(m->recenttri, *searchtri);
7692         return ONVERTEX;
7693       }
7694       dist = (searchpoint[0] - torg[0]) * (searchpoint[0] - torg[0]) +
7695              (searchpoint[1] - torg[1]) * (searchpoint[1] - torg[1]);
7696       if (dist < searchdist) {
7697         otricopy(m->recenttri, *searchtri);
7698         searchdist = dist;
7699         if (b->verbose > 2) {
7700           printf("    Choosing recent triangle with origin (%.12g, %.12g).\n",
7701                  (double)torg[0], (double)torg[1]);
7702         }
7703       }
7704     }
7705   }
7706 
7707   /* The number of random samples taken is proportional to the cube root of */
7708   /*   the number of triangles in the mesh.  The next bit of code assumes   */
7709   /*   that the number of triangles increases monotonically (or at least    */
7710   /*   doesn't decrease enough to matter).                                  */
7711   while (SAMPLEFACTOR * m->samples * m->samples * m->samples <
7712          m->triangles.items) {
7713     m->samples++;
7714   }
7715 
7716   /* We'll draw ceiling(samples * TRIPERBLOCK / maxitems) random samples  */
7717   /*   from each block of triangles (except the first)--until we meet the */
7718   /*   sample quota.  The ceiling means that blocks at the end might be   */
7719   /*   neglected, but I don't care.                                       */
7720   samplesperblock = (m->samples * TRIPERBLOCK - 1) / m->triangles.maxitems + 1;
7721   /* We'll draw ceiling(samples * itemsfirstblock / maxitems) random samples */
7722   /*   from the first block of triangles.                                    */
7723   samplesleft = (m->samples * m->triangles.itemsfirstblock - 1) /
7724                 m->triangles.maxitems + 1;
7725   totalsamplesleft = m->samples;
7726   population = m->triangles.itemsfirstblock;
7727   totalpopulation = m->triangles.maxitems;
7728   sampleblock = m->triangles.firstblock;
7729   sampletri.orient = 0;
7730   while (totalsamplesleft > 0) {
7731     /* If we're in the last block, `population' needs to be corrected. */
7732     if (population > totalpopulation) {
7733       population = totalpopulation;
7734     }
7735     /* Find a pointer to the first triangle in the block. */
7736     alignptr = (unsigned long) (sampleblock + 1);
7737     firsttri = (char *) (alignptr +
7738                          (unsigned long) m->triangles.alignbytes -
7739                          (alignptr %
7740                           (unsigned long) m->triangles.alignbytes));
7741 
7742     /* Choose `samplesleft' randomly sampled triangles in this block. */
7743     do {
7744       sampletri.tri = (triangle *) (firsttri +
7745                                     (randomnation((unsigned int) population) *
7746                                      m->triangles.itembytes));
7747       if (!deadtri(sampletri.tri)) {
7748         org(sampletri, torg);
7749         dist = (searchpoint[0] - torg[0]) * (searchpoint[0] - torg[0]) +
7750                (searchpoint[1] - torg[1]) * (searchpoint[1] - torg[1]);
7751         if (dist < searchdist) {
7752           otricopy(sampletri, *searchtri);
7753           searchdist = dist;
7754           if (b->verbose > 2) {
7755             printf("    Choosing triangle with origin (%.12g, %.12g).\n",
7756                    (double)torg[0], (double)torg[1]);
7757           }
7758         }
7759       }
7760 
7761       samplesleft--;
7762       totalsamplesleft--;
7763     } while ((samplesleft > 0) && (totalsamplesleft > 0));
7764 
7765     if (totalsamplesleft > 0) {
7766       sampleblock = (VOID **) *sampleblock;
7767       samplesleft = samplesperblock;
7768       totalpopulation -= population;
7769       population = TRIPERBLOCK;
7770     }
7771   }
7772 
7773   /* Where are we? */
7774   org(*searchtri, torg);
7775   dest(*searchtri, tdest);
7776   /* Check the starting triangle's vertices. */
7777   if ((torg[0] == searchpoint[0]) && (torg[1] == searchpoint[1])) {
7778     return ONVERTEX;
7779   }
7780   if ((tdest[0] == searchpoint[0]) && (tdest[1] == searchpoint[1])) {
7781     lnextself(*searchtri);
7782     return ONVERTEX;
7783   }
7784   /* Orient `searchtri' to fit the preconditions of calling preciselocate(). */
7785   ahead = counterclockwise(m, b, torg, tdest, searchpoint);
7786   if (ahead < 0.0) {
7787     /* Turn around so that `searchpoint' is to the left of the */
7788     /*   edge specified by `searchtri'.                        */
7789     symself(*searchtri);
7790   } else if (ahead == 0.0) {
7791     /* Check if `searchpoint' is between `torg' and `tdest'. */
7792     if (((torg[0] < searchpoint[0]) == (searchpoint[0] < tdest[0])) &&
7793         ((torg[1] < searchpoint[1]) == (searchpoint[1] < tdest[1]))) {
7794       return ONEDGE;
7795     }
7796   }
7797   return preciselocate(m, b, searchpoint, searchtri, 0);
7798 }
7799 
7800 /**                                                                         **/
7801 /**                                                                         **/
7802 /********* Point location routines end here                          *********/
7803 
7804 /********* Mesh transformation routines begin here                   *********/
7805 /**                                                                         **/
7806 /**                                                                         **/
7807 
7808 /*****************************************************************************/
7809 /*                                                                           */
7810 /*  insertsubseg()   Create a new subsegment and insert it between two       */
7811 /*                   triangles.                                              */
7812 /*                                                                           */
7813 /*  The new subsegment is inserted at the edge described by the handle       */
7814 /*  `tri'.  Its vertices are properly initialized.  The marker `subsegmark'  */
7815 /*  is applied to the subsegment and, if appropriate, its vertices.          */
7816 /*                                                                           */
7817 /*****************************************************************************/
7818 
7819 #ifdef ANSI_DECLARATORS
7820 void insertsubseg(struct mesh *m, struct behavior *b, struct otri *tri,
7821                   int subsegmark)
7822 #else /* not ANSI_DECLARATORS */
7823 void insertsubseg(m, b, tri, subsegmark)
7824 struct mesh *m;
7825 struct behavior *b;
7826 struct otri *tri;             /* Edge at which to insert the new subsegment. */
7827 int subsegmark;                            /* Marker for the new subsegment. */
7828 #endif /* not ANSI_DECLARATORS */
7829 
7830 {
7831   struct otri oppotri;
7832   struct osub newsubseg;
7833   vertex triorg, tridest;
7834   triangle ptr;                         /* Temporary variable used by sym(). */
7835   subseg sptr;                      /* Temporary variable used by tspivot(). */
7836 
7837   org(*tri, triorg);
7838   dest(*tri, tridest);
7839   /* Mark vertices if possible. */
7840   if (vertexmark(triorg) == 0) {
7841     setvertexmark(triorg, subsegmark);
7842   }
7843   if (vertexmark(tridest) == 0) {
7844     setvertexmark(tridest, subsegmark);
7845   }
7846   /* Check if there's already a subsegment here. */
7847   tspivot(*tri, newsubseg);
7848   if (newsubseg.ss == m->dummysub) {
7849     /* Make new subsegment and initialize its vertices. */
7850     makesubseg(m, &newsubseg);
7851     setsorg(newsubseg, tridest);
7852     setsdest(newsubseg, triorg);
7853     setsegorg(newsubseg, tridest);
7854     setsegdest(newsubseg, triorg);
7855     /* Bond new subsegment to the two triangles it is sandwiched between. */
7856     /*   Note that the facing triangle `oppotri' might be equal to        */
7857     /*   `dummytri' (outer space), but the new subsegment is bonded to it */
7858     /*   all the same.                                                    */
7859     tsbond(*tri, newsubseg);
7860     sym(*tri, oppotri);
7861     ssymself(newsubseg);
7862     tsbond(oppotri, newsubseg);
7863     setmark(newsubseg, subsegmark);
7864     if (b->verbose > 2) {
7865       printf("  Inserting new ");
7866       printsubseg(m, b, &newsubseg);
7867     }
7868   } else {
7869     if (mark(newsubseg) == 0) {
7870       setmark(newsubseg, subsegmark);
7871     }
7872   }
7873 }
7874 
7875 /*****************************************************************************/
7876 /*                                                                           */
7877 /*  Terminology                                                              */
7878 /*                                                                           */
7879 /*  A "local transformation" replaces a small set of triangles with another  */
7880 /*  set of triangles.  This may or may not involve inserting or deleting a   */
7881 /*  vertex.                                                                  */
7882 /*                                                                           */
7883 /*  The term "casing" is used to describe the set of triangles that are      */
7884 /*  attached to the triangles being transformed, but are not transformed     */
7885 /*  themselves.  Think of the casing as a fixed hollow structure inside      */
7886 /*  which all the action happens.  A "casing" is only defined relative to    */
7887 /*  a single transformation; each occurrence of a transformation will        */
7888 /*  involve a different casing.                                              */
7889 /*                                                                           */
7890 /*****************************************************************************/
7891 
7892 /*****************************************************************************/
7893 /*                                                                           */
7894 /*  flip()   Transform two triangles to two different triangles by flipping  */
7895 /*           an edge counterclockwise within a quadrilateral.                */
7896 /*                                                                           */
7897 /*  Imagine the original triangles, abc and bad, oriented so that the        */
7898 /*  shared edge ab lies in a horizontal plane, with the vertex b on the left */
7899 /*  and the vertex a on the right.  The vertex c lies below the edge, and    */
7900 /*  the vertex d lies above the edge.  The `flipedge' handle holds the edge  */
7901 /*  ab of triangle abc, and is directed left, from vertex a to vertex b.     */
7902 /*                                                                           */
7903 /*  The triangles abc and bad are deleted and replaced by the triangles cdb  */
7904 /*  and dca.  The triangles that represent abc and bad are NOT deallocated;  */
7905 /*  they are reused for dca and cdb, respectively.  Hence, any handles that  */
7906 /*  may have held the original triangles are still valid, although not       */
7907 /*  directed as they were before.                                            */
7908 /*                                                                           */
7909 /*  Upon completion of this routine, the `flipedge' handle holds the edge    */
7910 /*  dc of triangle dca, and is directed down, from vertex d to vertex c.     */
7911 /*  (Hence, the two triangles have rotated counterclockwise.)                */
7912 /*                                                                           */
7913 /*  WARNING:  This transformation is geometrically valid only if the         */
7914 /*  quadrilateral adbc is convex.  Furthermore, this transformation is       */
7915 /*  valid only if there is not a subsegment between the triangles abc and    */
7916 /*  bad.  This routine does not check either of these preconditions, and     */
7917 /*  it is the responsibility of the calling routine to ensure that they are  */
7918 /*  met.  If they are not, the streets shall be filled with wailing and      */
7919 /*  gnashing of teeth.                                                       */
7920 /*                                                                           */
7921 /*****************************************************************************/
7922 
7923 #ifdef ANSI_DECLARATORS
7924 void flip(struct mesh *m, struct behavior *b, struct otri *flipedge)
7925 #else /* not ANSI_DECLARATORS */
7926 void flip(m, b, flipedge)
7927 struct mesh *m;
7928 struct behavior *b;
7929 struct otri *flipedge;                    /* Handle for the triangle abc. */
7930 #endif /* not ANSI_DECLARATORS */
7931 
7932 {
7933   struct otri botleft, botright;
7934   struct otri topleft, topright;
7935   struct otri top;
7936   struct otri botlcasing, botrcasing;
7937   struct otri toplcasing, toprcasing;
7938   struct osub botlsubseg, botrsubseg;
7939   struct osub toplsubseg, toprsubseg;
7940   vertex leftvertex, rightvertex, botvertex;
7941   vertex farvertex;
7942   triangle ptr;                         /* Temporary variable used by sym(). */
7943   subseg sptr;                      /* Temporary variable used by tspivot(). */
7944 
7945   /* Identify the vertices of the quadrilateral. */
7946   org(*flipedge, rightvertex);
7947   dest(*flipedge, leftvertex);
7948   apex(*flipedge, botvertex);
7949   sym(*flipedge, top);
7950 #ifdef SELF_CHECK
7951   if (top.tri == m->dummytri) {
7952     printf("Internal error in flip():  Attempt to flip on boundary.\n");
7953     lnextself(*flipedge);
7954     return;
7955   }
7956   if (m->checksegments) {
7957     tspivot(*flipedge, toplsubseg);
7958     if (toplsubseg.ss != m->dummysub) {
7959       printf("Internal error in flip():  Attempt to flip a segment.\n");
7960       lnextself(*flipedge);
7961       return;
7962     }
7963   }
7964 #endif /* SELF_CHECK */
7965   apex(top, farvertex);
7966 
7967   /* Identify the casing of the quadrilateral. */
7968   lprev(top, topleft);
7969   sym(topleft, toplcasing);
7970   lnext(top, topright);
7971   sym(topright, toprcasing);
7972   lnext(*flipedge, botleft);
7973   sym(botleft, botlcasing);
7974   lprev(*flipedge, botright);
7975   sym(botright, botrcasing);
7976   /* Rotate the quadrilateral one-quarter turn counterclockwise. */
7977   bond(topleft, botlcasing);
7978   bond(botleft, botrcasing);
7979   bond(botright, toprcasing);
7980   bond(topright, toplcasing);
7981 
7982   if (m->checksegments) {
7983     /* Check for subsegments and rebond them to the quadrilateral. */
7984     tspivot(topleft, toplsubseg);
7985     tspivot(botleft, botlsubseg);
7986     tspivot(botright, botrsubseg);
7987     tspivot(topright, toprsubseg);
7988     if (toplsubseg.ss == m->dummysub) {
7989       tsdissolve(topright);
7990     } else {
7991       tsbond(topright, toplsubseg);
7992     }
7993     if (botlsubseg.ss == m->dummysub) {
7994       tsdissolve(topleft);
7995     } else {
7996       tsbond(topleft, botlsubseg);
7997     }
7998     if (botrsubseg.ss == m->dummysub) {
7999       tsdissolve(botleft);
8000     } else {
8001       tsbond(botleft, botrsubseg);
8002     }
8003     if (toprsubseg.ss == m->dummysub) {
8004       tsdissolve(botright);
8005     } else {
8006       tsbond(botright, toprsubseg);
8007     }
8008   }
8009 
8010   /* New vertex assignments for the rotated quadrilateral. */
8011   setorg(*flipedge, farvertex);
8012   setdest(*flipedge, botvertex);
8013   setapex(*flipedge, rightvertex);
8014   setorg(top, botvertex);
8015   setdest(top, farvertex);
8016   setapex(top, leftvertex);
8017   if (b->verbose > 2) {
8018     printf("  Edge flip results in left ");
8019     printtriangle(m, b, &top);
8020     printf("  and right ");
8021     printtriangle(m, b, flipedge);
8022   }
8023 }
8024 
8025 /*****************************************************************************/
8026 /*                                                                           */
8027 /*  unflip()   Transform two triangles to two different triangles by         */
8028 /*             flipping an edge clockwise within a quadrilateral.  Reverses  */
8029 /*             the flip() operation so that the data structures representing */
8030 /*             the triangles are back where they were before the flip().     */
8031 /*                                                                           */
8032 /*  Imagine the original triangles, abc and bad, oriented so that the        */
8033 /*  shared edge ab lies in a horizontal plane, with the vertex b on the left */
8034 /*  and the vertex a on the right.  The vertex c lies below the edge, and    */
8035 /*  the vertex d lies above the edge.  The `flipedge' handle holds the edge  */
8036 /*  ab of triangle abc, and is directed left, from vertex a to vertex b.     */
8037 /*                                                                           */
8038 /*  The triangles abc and bad are deleted and replaced by the triangles cdb  */
8039 /*  and dca.  The triangles that represent abc and bad are NOT deallocated;  */
8040 /*  they are reused for cdb and dca, respectively.  Hence, any handles that  */
8041 /*  may have held the original triangles are still valid, although not       */
8042 /*  directed as they were before.                                            */
8043 /*                                                                           */
8044 /*  Upon completion of this routine, the `flipedge' handle holds the edge    */
8045 /*  cd of triangle cdb, and is directed up, from vertex c to vertex d.       */
8046 /*  (Hence, the two triangles have rotated clockwise.)                       */
8047 /*                                                                           */
8048 /*  WARNING:  This transformation is geometrically valid only if the         */
8049 /*  quadrilateral adbc is convex.  Furthermore, this transformation is       */
8050 /*  valid only if there is not a subsegment between the triangles abc and    */
8051 /*  bad.  This routine does not check either of these preconditions, and     */
8052 /*  it is the responsibility of the calling routine to ensure that they are  */
8053 /*  met.  If they are not, the streets shall be filled with wailing and      */
8054 /*  gnashing of teeth.                                                       */
8055 /*                                                                           */
8056 /*****************************************************************************/
8057 
8058 #ifdef ANSI_DECLARATORS
8059 void unflip(struct mesh *m, struct behavior *b, struct otri *flipedge)
8060 #else /* not ANSI_DECLARATORS */
8061 void unflip(m, b, flipedge)
8062 struct mesh *m;
8063 struct behavior *b;
8064 struct otri *flipedge;                    /* Handle for the triangle abc. */
8065 #endif /* not ANSI_DECLARATORS */
8066 
8067 {
8068   struct otri botleft, botright;
8069   struct otri topleft, topright;
8070   struct otri top;
8071   struct otri botlcasing, botrcasing;
8072   struct otri toplcasing, toprcasing;
8073   struct osub botlsubseg, botrsubseg;
8074   struct osub toplsubseg, toprsubseg;
8075   vertex leftvertex, rightvertex, botvertex;
8076   vertex farvertex;
8077   triangle ptr;                         /* Temporary variable used by sym(). */
8078   subseg sptr;                      /* Temporary variable used by tspivot(). */
8079 
8080   /* Identify the vertices of the quadrilateral. */
8081   org(*flipedge, rightvertex);
8082   dest(*flipedge, leftvertex);
8083   apex(*flipedge, botvertex);
8084   sym(*flipedge, top);
8085 #ifdef SELF_CHECK
8086   if (top.tri == m->dummytri) {
8087     printf("Internal error in unflip():  Attempt to flip on boundary.\n");
8088     lnextself(*flipedge);
8089     return;
8090   }
8091   if (m->checksegments) {
8092     tspivot(*flipedge, toplsubseg);
8093     if (toplsubseg.ss != m->dummysub) {
8094       printf("Internal error in unflip():  Attempt to flip a subsegment.\n");
8095       lnextself(*flipedge);
8096       return;
8097     }
8098   }
8099 #endif /* SELF_CHECK */
8100   apex(top, farvertex);
8101 
8102   /* Identify the casing of the quadrilateral. */
8103   lprev(top, topleft);
8104   sym(topleft, toplcasing);
8105   lnext(top, topright);
8106   sym(topright, toprcasing);
8107   lnext(*flipedge, botleft);
8108   sym(botleft, botlcasing);
8109   lprev(*flipedge, botright);
8110   sym(botright, botrcasing);
8111   /* Rotate the quadrilateral one-quarter turn clockwise. */
8112   bond(topleft, toprcasing);
8113   bond(botleft, toplcasing);
8114   bond(botright, botlcasing);
8115   bond(topright, botrcasing);
8116 
8117   if (m->checksegments) {
8118     /* Check for subsegments and rebond them to the quadrilateral. */
8119     tspivot(topleft, toplsubseg);
8120     tspivot(botleft, botlsubseg);
8121     tspivot(botright, botrsubseg);
8122     tspivot(topright, toprsubseg);
8123     if (toplsubseg.ss == m->dummysub) {
8124       tsdissolve(botleft);
8125     } else {
8126       tsbond(botleft, toplsubseg);
8127     }
8128     if (botlsubseg.ss == m->dummysub) {
8129       tsdissolve(botright);
8130     } else {
8131       tsbond(botright, botlsubseg);
8132     }
8133     if (botrsubseg.ss == m->dummysub) {
8134       tsdissolve(topright);
8135     } else {
8136       tsbond(topright, botrsubseg);
8137     }
8138     if (toprsubseg.ss == m->dummysub) {
8139       tsdissolve(topleft);
8140     } else {
8141       tsbond(topleft, toprsubseg);
8142     }
8143   }
8144 
8145   /* New vertex assignments for the rotated quadrilateral. */
8146   setorg(*flipedge, botvertex);
8147   setdest(*flipedge, farvertex);
8148   setapex(*flipedge, leftvertex);
8149   setorg(top, farvertex);
8150   setdest(top, botvertex);
8151   setapex(top, rightvertex);
8152   if (b->verbose > 2) {
8153     printf("  Edge unflip results in left ");
8154     printtriangle(m, b, flipedge);
8155     printf("  and right ");
8156     printtriangle(m, b, &top);
8157   }
8158 }
8159 
8160 /*****************************************************************************/
8161 /*                                                                           */
8162 /*  insertvertex()   Insert a vertex into a Delaunay triangulation,          */
8163 /*                   performing flips as necessary to maintain the Delaunay  */
8164 /*                   property.                                               */
8165 /*                                                                           */
8166 /*  The point `insertvertex' is located.  If `searchtri.tri' is not NULL,    */
8167 /*  the search for the containing triangle begins from `searchtri'.  If      */
8168 /*  `searchtri.tri' is NULL, a full point location procedure is called.      */
8169 /*  If `insertvertex' is found inside a triangle, the triangle is split into */
8170 /*  three; if `insertvertex' lies on an edge, the edge is split in two,      */
8171 /*  thereby splitting the two adjacent triangles into four.  Edge flips are  */
8172 /*  used to restore the Delaunay property.  If `insertvertex' lies on an     */
8173 /*  existing vertex, no action is taken, and the value DUPLICATEVERTEX is    */
8174 /*  returned.  On return, `searchtri' is set to a handle whose origin is the */
8175 /*  existing vertex.                                                         */
8176 /*                                                                           */
8177 /*  Normally, the parameter `splitseg' is set to NULL, implying that no      */
8178 /*  subsegment should be split.  In this case, if `insertvertex' is found to */
8179 /*  lie on a segment, no action is taken, and the value VIOLATINGVERTEX is   */
8180 /*  returned.  On return, `searchtri' is set to a handle whose primary edge  */
8181 /*  is the violated subsegment.                                              */
8182 /*                                                                           */
8183 /*  If the calling routine wishes to split a subsegment by inserting a       */
8184 /*  vertex in it, the parameter `splitseg' should be that subsegment.  In    */
8185 /*  this case, `searchtri' MUST be the triangle handle reached by pivoting   */
8186 /*  from that subsegment; no point location is done.                         */
8187 /*                                                                           */
8188 /*  `segmentflaws' and `triflaws' are flags that indicate whether or not     */
8189 /*  there should be checks for the creation of encroached subsegments or bad */
8190 /*  quality triangles.  If a newly inserted vertex encroaches upon           */
8191 /*  subsegments, these subsegments are added to the list of subsegments to   */
8192 /*  be split if `segmentflaws' is set.  If bad triangles are created, these  */
8193 /*  are added to the queue if `triflaws' is set.                             */
8194 /*                                                                           */
8195 /*  If a duplicate vertex or violated segment does not prevent the vertex    */
8196 /*  from being inserted, the return value will be ENCROACHINGVERTEX if the   */
8197 /*  vertex encroaches upon a subsegment (and checking is enabled), or        */
8198 /*  SUCCESSFULVERTEX otherwise.  In either case, `searchtri' is set to a     */
8199 /*  handle whose origin is the newly inserted vertex.                        */
8200 /*                                                                           */
8201 /*  insertvertex() does not use flip() for reasons of speed; some            */
8202 /*  information can be reused from edge flip to edge flip, like the          */
8203 /*  locations of subsegments.                                                */
8204 /*                                                                           */
8205 /*****************************************************************************/
8206 
8207 #ifdef ANSI_DECLARATORS
8208 enum insertvertexresult insertvertex(struct mesh *m, struct behavior *b,
8209                                      vertex newvertex, struct otri *searchtri,
8210                                      struct osub *splitseg,
8211                                      int segmentflaws, int triflaws)
8212 #else /* not ANSI_DECLARATORS */
8213 enum insertvertexresult insertvertex(m, b, newvertex, searchtri, splitseg,
8214                                      segmentflaws, triflaws)
8215 struct mesh *m;
8216 struct behavior *b;
8217 vertex newvertex;
8218 struct otri *searchtri;
8219 struct osub *splitseg;
8220 int segmentflaws;
8221 int triflaws;
8222 #endif /* not ANSI_DECLARATORS */
8223 
8224 {
8225   struct otri horiz;
8226   struct otri top;
8227   struct otri botleft, botright;
8228   struct otri topleft, topright;
8229   struct otri newbotleft, newbotright;
8230   struct otri newtopright;
8231   struct otri botlcasing, botrcasing;
8232   struct otri toplcasing, toprcasing;
8233   struct otri testtri;
8234   struct osub botlsubseg, botrsubseg;
8235   struct osub toplsubseg, toprsubseg;
8236   struct osub brokensubseg;
8237   struct osub checksubseg;
8238   struct osub rightsubseg;
8239   struct osub newsubseg;
8240   struct badsubseg *encroached;
8241   struct flipstacker *newflip;
8242   vertex first;
8243   vertex leftvertex, rightvertex, botvertex, topvertex, farvertex;
8244   vertex segmentorg, segmentdest;
8245   REAL attrib;
8246   REAL area;
8247   enum insertvertexresult success;
8248   enum locateresult intersect;
8249   int doflip;
8250   int mirrorflag;
8251   int enq;
8252   int i;
8253   triangle ptr;                         /* Temporary variable used by sym(). */
8254   subseg sptr;         /* Temporary variable used by spivot() and tspivot(). */
8255 
8256   /* Avoid compiler warnings about uninitialized variables */
8257   toprcasing.tri = NULL;
8258   toprcasing.orient = 0;
8259 
8260   if (b->verbose > 1) {
8261     printf("  Inserting (%.12g, %.12g).\n", (double)newvertex[0], (double)newvertex[1]);
8262   }
8263 
8264   if (splitseg == (struct osub *) NULL) {
8265     /* Find the location of the vertex to be inserted.  Check if a good */
8266     /*   starting triangle has already been provided by the caller.     */
8267     if (searchtri->tri == m->dummytri) {
8268       /* Find a boundary triangle. */
8269       horiz.tri = m->dummytri;
8270       horiz.orient = 0;
8271       symself(horiz);
8272       /* Search for a triangle containing `newvertex'. */
8273       intersect = locate(m, b, newvertex, &horiz);
8274     } else {
8275       /* Start searching from the triangle provided by the caller. */
8276       otricopy(*searchtri, horiz);
8277       intersect = preciselocate(m, b, newvertex, &horiz, 1);
8278     }
8279   } else {
8280     /* The calling routine provides the subsegment in which */
8281     /*   the vertex is inserted.                             */
8282     otricopy(*searchtri, horiz);
8283     intersect = ONEDGE;
8284   }
8285 
8286   if (intersect == ONVERTEX) {
8287     /* There's already a vertex there.  Return in `searchtri' a triangle */
8288     /*   whose origin is the existing vertex.                            */
8289     otricopy(horiz, *searchtri);
8290     otricopy(horiz, m->recenttri);
8291     return DUPLICATEVERTEX;
8292   }
8293   if ((intersect == ONEDGE) || (intersect == OUTSIDE)) {
8294     /* The vertex falls on an edge or boundary. */
8295     if (m->checksegments && (splitseg == (struct osub *) NULL)) {
8296       /* Check whether the vertex falls on a subsegment. */
8297       tspivot(horiz, brokensubseg);
8298       if (brokensubseg.ss != m->dummysub) {
8299         /* The vertex falls on a subsegment, and hence will not be inserted. */
8300         if (segmentflaws) {
8301           enq = b->nobisect != 2;
8302           if (enq && (b->nobisect == 1)) {
8303             /* This subsegment may be split only if it is an */
8304             /*   internal boundary.                          */
8305             sym(horiz, testtri);
8306             enq = testtri.tri != m->dummytri;
8307           }
8308           if (enq) {
8309             /* Add the subsegment to the list of encroached subsegments. */
8310             encroached = (struct badsubseg *) poolalloc(&m->badsubsegs);
8311             encroached->encsubseg = sencode(brokensubseg);
8312             sorg(brokensubseg, encroached->subsegorg);
8313             sdest(brokensubseg, encroached->subsegdest);
8314             if (b->verbose > 2) {
8315               printf(
8316           "  Queueing encroached subsegment (%.12g, %.12g) (%.12g, %.12g).\n",
8317                      (double)encroached->subsegorg[0], (double)encroached->subsegorg[1],
8318                      (double)encroached->subsegdest[0], (double)encroached->subsegdest[1]);
8319             }
8320           }
8321         }
8322         /* Return a handle whose primary edge contains the vertex, */
8323         /*   which has not been inserted.                          */
8324         otricopy(horiz, *searchtri);
8325         otricopy(horiz, m->recenttri);
8326         return VIOLATINGVERTEX;
8327       }
8328     }
8329 
8330     /* Insert the vertex on an edge, dividing one triangle into two (if */
8331     /*   the edge lies on a boundary) or two triangles into four.       */
8332     lprev(horiz, botright);
8333     sym(botright, botrcasing);
8334     sym(horiz, topright);
8335     /* Is there a second triangle?  (Or does this edge lie on a boundary?) */
8336     mirrorflag = topright.tri != m->dummytri;
8337     if (mirrorflag) {
8338       lnextself(topright);
8339       sym(topright, toprcasing);
8340       maketriangle(m, b, &newtopright);
8341     } else {
8342       /* Splitting a boundary edge increases the number of boundary edges. */
8343       m->hullsize++;
8344     }
8345     maketriangle(m, b, &newbotright);
8346 
8347     /* Set the vertices of changed and new triangles. */
8348     org(horiz, rightvertex);
8349     dest(horiz, leftvertex);
8350     apex(horiz, botvertex);
8351     setorg(newbotright, botvertex);
8352     setdest(newbotright, rightvertex);
8353     setapex(newbotright, newvertex);
8354     setorg(horiz, newvertex);
8355     for (i = 0; i < m->eextras; i++) {
8356       /* Set the element attributes of a new triangle. */
8357       setelemattribute(newbotright, i, elemattribute(botright, i));
8358     }
8359     if (b->vararea) {
8360       /* Set the area constraint of a new triangle. */
8361       setareabound(newbotright, areabound(botright));
8362     }
8363     if (mirrorflag) {
8364       dest(topright, topvertex);
8365       setorg(newtopright, rightvertex);
8366       setdest(newtopright, topvertex);
8367       setapex(newtopright, newvertex);
8368       setorg(topright, newvertex);
8369       for (i = 0; i < m->eextras; i++) {
8370         /* Set the element attributes of another new triangle. */
8371         setelemattribute(newtopright, i, elemattribute(topright, i));
8372       }
8373       if (b->vararea) {
8374         /* Set the area constraint of another new triangle. */
8375         setareabound(newtopright, areabound(topright));
8376       }
8377     }
8378 
8379     /* There may be subsegments that need to be bonded */
8380     /*   to the new triangle(s).                       */
8381     if (m->checksegments) {
8382       tspivot(botright, botrsubseg);
8383       if (botrsubseg.ss != m->dummysub) {
8384         tsdissolve(botright);
8385         tsbond(newbotright, botrsubseg);
8386       }
8387       if (mirrorflag) {
8388         tspivot(topright, toprsubseg);
8389         if (toprsubseg.ss != m->dummysub) {
8390           tsdissolve(topright);
8391           tsbond(newtopright, toprsubseg);
8392         }
8393       }
8394     }
8395 
8396     /* Bond the new triangle(s) to the surrounding triangles. */
8397     bond(newbotright, botrcasing);
8398     lprevself(newbotright);
8399     bond(newbotright, botright);
8400     lprevself(newbotright);
8401     if (mirrorflag) {
8402       bond(newtopright, toprcasing);
8403       lnextself(newtopright);
8404       bond(newtopright, topright);
8405       lnextself(newtopright);
8406       bond(newtopright, newbotright);
8407     }
8408 
8409     if (splitseg != (struct osub *) NULL) {
8410       /* Split the subsegment into two. */
8411       setsdest(*splitseg, newvertex);
8412       segorg(*splitseg, segmentorg);
8413       segdest(*splitseg, segmentdest);
8414       ssymself(*splitseg);
8415       spivot(*splitseg, rightsubseg);
8416       insertsubseg(m, b, &newbotright, mark(*splitseg));
8417       tspivot(newbotright, newsubseg);
8418       setsegorg(newsubseg, segmentorg);
8419       setsegdest(newsubseg, segmentdest);
8420       sbond(*splitseg, newsubseg);
8421       ssymself(newsubseg);
8422       sbond(newsubseg, rightsubseg);
8423       ssymself(*splitseg);
8424       /* Transfer the subsegment's boundary marker to the vertex */
8425       /*   if required.                                          */
8426       if (vertexmark(newvertex) == 0) {
8427         setvertexmark(newvertex, mark(*splitseg));
8428       }
8429     }
8430 
8431     if (m->checkquality) {
8432       poolrestart(&m->flipstackers);
8433       m->lastflip = (struct flipstacker *) poolalloc(&m->flipstackers);
8434       m->lastflip->flippedtri = encode(horiz);
8435       m->lastflip->prevflip = (struct flipstacker *) &insertvertex;
8436     }
8437 
8438 #ifdef SELF_CHECK
8439     if (counterclockwise(m, b, rightvertex, leftvertex, botvertex) < 0.0) {
8440       printf("Internal error in insertvertex():\n");
8441       printf(
8442             "  Clockwise triangle prior to edge vertex insertion (bottom).\n");
8443     }
8444     if (mirrorflag) {
8445       if (counterclockwise(m, b, leftvertex, rightvertex, topvertex) < 0.0) {
8446         printf("Internal error in insertvertex():\n");
8447         printf("  Clockwise triangle prior to edge vertex insertion (top).\n");
8448       }
8449       if (counterclockwise(m, b, rightvertex, topvertex, newvertex) < 0.0) {
8450         printf("Internal error in insertvertex():\n");
8451         printf(
8452             "  Clockwise triangle after edge vertex insertion (top right).\n");
8453       }
8454       if (counterclockwise(m, b, topvertex, leftvertex, newvertex) < 0.0) {
8455         printf("Internal error in insertvertex():\n");
8456         printf(
8457             "  Clockwise triangle after edge vertex insertion (top left).\n");
8458       }
8459     }
8460     if (counterclockwise(m, b, leftvertex, botvertex, newvertex) < 0.0) {
8461       printf("Internal error in insertvertex():\n");
8462       printf(
8463           "  Clockwise triangle after edge vertex insertion (bottom left).\n");
8464     }
8465     if (counterclockwise(m, b, botvertex, rightvertex, newvertex) < 0.0) {
8466       printf("Internal error in insertvertex():\n");
8467       printf(
8468         "  Clockwise triangle after edge vertex insertion (bottom right).\n");
8469     }
8470 #endif /* SELF_CHECK */
8471     if (b->verbose > 2) {
8472       printf("  Updating bottom left ");
8473       printtriangle(m, b, &botright);
8474       if (mirrorflag) {
8475         printf("  Updating top left ");
8476         printtriangle(m, b, &topright);
8477         printf("  Creating top right ");
8478         printtriangle(m, b, &newtopright);
8479       }
8480       printf("  Creating bottom right ");
8481       printtriangle(m, b, &newbotright);
8482     }
8483 
8484     /* Position `horiz' on the first edge to check for */
8485     /*   the Delaunay property.                        */
8486     lnextself(horiz);
8487   } else {
8488     /* Insert the vertex in a triangle, splitting it into three. */
8489     lnext(horiz, botleft);
8490     lprev(horiz, botright);
8491     sym(botleft, botlcasing);
8492     sym(botright, botrcasing);
8493     maketriangle(m, b, &newbotleft);
8494     maketriangle(m, b, &newbotright);
8495 
8496     /* Set the vertices of changed and new triangles. */
8497     org(horiz, rightvertex);
8498     dest(horiz, leftvertex);
8499     apex(horiz, botvertex);
8500     setorg(newbotleft, leftvertex);
8501     setdest(newbotleft, botvertex);
8502     setapex(newbotleft, newvertex);
8503     setorg(newbotright, botvertex);
8504     setdest(newbotright, rightvertex);
8505     setapex(newbotright, newvertex);
8506     setapex(horiz, newvertex);
8507     for (i = 0; i < m->eextras; i++) {
8508       /* Set the element attributes of the new triangles. */
8509       attrib = elemattribute(horiz, i);
8510       setelemattribute(newbotleft, i, attrib);
8511       setelemattribute(newbotright, i, attrib);
8512     }
8513     if (b->vararea) {
8514       /* Set the area constraint of the new triangles. */
8515       area = areabound(horiz);
8516       setareabound(newbotleft, area);
8517       setareabound(newbotright, area);
8518     }
8519 
8520     /* There may be subsegments that need to be bonded */
8521     /*   to the new triangles.                         */
8522     if (m->checksegments) {
8523       tspivot(botleft, botlsubseg);
8524       if (botlsubseg.ss != m->dummysub) {
8525         tsdissolve(botleft);
8526         tsbond(newbotleft, botlsubseg);
8527       }
8528       tspivot(botright, botrsubseg);
8529       if (botrsubseg.ss != m->dummysub) {
8530         tsdissolve(botright);
8531         tsbond(newbotright, botrsubseg);
8532       }
8533     }
8534 
8535     /* Bond the new triangles to the surrounding triangles. */
8536     bond(newbotleft, botlcasing);
8537     bond(newbotright, botrcasing);
8538     lnextself(newbotleft);
8539     lprevself(newbotright);
8540     bond(newbotleft, newbotright);
8541     lnextself(newbotleft);
8542     bond(botleft, newbotleft);
8543     lprevself(newbotright);
8544     bond(botright, newbotright);
8545 
8546     if (m->checkquality) {
8547       poolrestart(&m->flipstackers);
8548       m->lastflip = (struct flipstacker *) poolalloc(&m->flipstackers);
8549       m->lastflip->flippedtri = encode(horiz);
8550       m->lastflip->prevflip = (struct flipstacker *) NULL;
8551     }
8552 
8553 #ifdef SELF_CHECK
8554     if (counterclockwise(m, b, rightvertex, leftvertex, botvertex) < 0.0) {
8555       printf("Internal error in insertvertex():\n");
8556       printf("  Clockwise triangle prior to vertex insertion.\n");
8557     }
8558     if (counterclockwise(m, b, rightvertex, leftvertex, newvertex) < 0.0) {
8559       printf("Internal error in insertvertex():\n");
8560       printf("  Clockwise triangle after vertex insertion (top).\n");
8561     }
8562     if (counterclockwise(m, b, leftvertex, botvertex, newvertex) < 0.0) {
8563       printf("Internal error in insertvertex():\n");
8564       printf("  Clockwise triangle after vertex insertion (left).\n");
8565     }
8566     if (counterclockwise(m, b, botvertex, rightvertex, newvertex) < 0.0) {
8567       printf("Internal error in insertvertex():\n");
8568       printf("  Clockwise triangle after vertex insertion (right).\n");
8569     }
8570 #endif /* SELF_CHECK */
8571     if (b->verbose > 2) {
8572       printf("  Updating top ");
8573       printtriangle(m, b, &horiz);
8574       printf("  Creating left ");
8575       printtriangle(m, b, &newbotleft);
8576       printf("  Creating right ");
8577       printtriangle(m, b, &newbotright);
8578     }
8579   }
8580 
8581   /* The insertion is successful by default, unless an encroached */
8582   /*   subsegment is found.                                       */
8583   success = SUCCESSFULVERTEX;
8584   /* Circle around the newly inserted vertex, checking each edge opposite */
8585   /*   it for the Delaunay property.  Non-Delaunay edges are flipped.     */
8586   /*   `horiz' is always the edge being checked.  `first' marks where to  */
8587   /*   stop circling.                                                     */
8588   org(horiz, first);
8589   rightvertex = first;
8590   dest(horiz, leftvertex);
8591   /* Circle until finished. */
8592   while (1) {
8593     /* By default, the edge will be flipped. */
8594     doflip = 1;
8595 
8596     if (m->checksegments) {
8597       /* Check for a subsegment, which cannot be flipped. */
8598       tspivot(horiz, checksubseg);
8599       if (checksubseg.ss != m->dummysub) {
8600         /* The edge is a subsegment and cannot be flipped. */
8601         doflip = 0;
8602 #ifndef CDT_ONLY
8603         if (segmentflaws) {
8604           /* Does the new vertex encroach upon this subsegment? */
8605           if (checkseg4encroach(m, b, &checksubseg)) {
8606             success = ENCROACHINGVERTEX;
8607           }
8608         }
8609 #endif /* not CDT_ONLY */
8610       }
8611     }
8612 
8613     if (doflip) {
8614       /* Check if the edge is a boundary edge. */
8615       sym(horiz, top);
8616       if (top.tri == m->dummytri) {
8617         /* The edge is a boundary edge and cannot be flipped. */
8618         doflip = 0;
8619       } else {
8620         /* Find the vertex on the other side of the edge. */
8621         apex(top, farvertex);
8622         /* In the incremental Delaunay triangulation algorithm, any of      */
8623         /*   `leftvertex', `rightvertex', and `farvertex' could be vertices */
8624         /*   of the triangular bounding box.  These vertices must be        */
8625         /*   treated as if they are infinitely distant, even though their   */
8626         /*   "coordinates" are not.                                         */
8627         if ((leftvertex == m->infvertex1) || (leftvertex == m->infvertex2) ||
8628             (leftvertex == m->infvertex3)) {
8629           /* `leftvertex' is infinitely distant.  Check the convexity of  */
8630           /*   the boundary of the triangulation.  'farvertex' might be   */
8631           /*   infinite as well, but trust me, this same condition should */
8632           /*   be applied.                                                */
8633           doflip = counterclockwise(m, b, newvertex, rightvertex, farvertex)
8634                    > 0.0;
8635         } else if ((rightvertex == m->infvertex1) ||
8636                    (rightvertex == m->infvertex2) ||
8637                    (rightvertex == m->infvertex3)) {
8638           /* `rightvertex' is infinitely distant.  Check the convexity of */
8639           /*   the boundary of the triangulation.  'farvertex' might be   */
8640           /*   infinite as well, but trust me, this same condition should */
8641           /*   be applied.                                                */
8642           doflip = counterclockwise(m, b, farvertex, leftvertex, newvertex)
8643                    > 0.0;
8644         } else if ((farvertex == m->infvertex1) ||
8645                    (farvertex == m->infvertex2) ||
8646                    (farvertex == m->infvertex3)) {
8647           /* `farvertex' is infinitely distant and cannot be inside */
8648           /*   the circumcircle of the triangle `horiz'.            */
8649           doflip = 0;
8650         } else {
8651           /* Test whether the edge is locally Delaunay. */
8652           doflip = incircle(m, b, leftvertex, newvertex, rightvertex,
8653                             farvertex) > 0.0;
8654         }
8655         if (doflip) {
8656           /* We made it!  Flip the edge `horiz' by rotating its containing */
8657           /*   quadrilateral (the two triangles adjacent to `horiz').      */
8658           /* Identify the casing of the quadrilateral. */
8659           lprev(top, topleft);
8660           sym(topleft, toplcasing);
8661           lnext(top, topright);
8662           sym(topright, toprcasing);
8663           lnext(horiz, botleft);
8664           sym(botleft, botlcasing);
8665           lprev(horiz, botright);
8666           sym(botright, botrcasing);
8667           /* Rotate the quadrilateral one-quarter turn counterclockwise. */
8668           bond(topleft, botlcasing);
8669           bond(botleft, botrcasing);
8670           bond(botright, toprcasing);
8671           bond(topright, toplcasing);
8672           if (m->checksegments) {
8673             /* Check for subsegments and rebond them to the quadrilateral. */
8674             tspivot(topleft, toplsubseg);
8675             tspivot(botleft, botlsubseg);
8676             tspivot(botright, botrsubseg);
8677             tspivot(topright, toprsubseg);
8678             if (toplsubseg.ss == m->dummysub) {
8679               tsdissolve(topright);
8680             } else {
8681               tsbond(topright, toplsubseg);
8682             }
8683             if (botlsubseg.ss == m->dummysub) {
8684               tsdissolve(topleft);
8685             } else {
8686               tsbond(topleft, botlsubseg);
8687             }
8688             if (botrsubseg.ss == m->dummysub) {
8689               tsdissolve(botleft);
8690             } else {
8691               tsbond(botleft, botrsubseg);
8692             }
8693             if (toprsubseg.ss == m->dummysub) {
8694               tsdissolve(botright);
8695             } else {
8696               tsbond(botright, toprsubseg);
8697             }
8698           }
8699           /* New vertex assignments for the rotated quadrilateral. */
8700           setorg(horiz, farvertex);
8701           setdest(horiz, newvertex);
8702           setapex(horiz, rightvertex);
8703           setorg(top, newvertex);
8704           setdest(top, farvertex);
8705           setapex(top, leftvertex);
8706           for (i = 0; i < m->eextras; i++) {
8707             /* Take the average of the two triangles' attributes. */
8708             attrib = 0.5 * (elemattribute(top, i) + elemattribute(horiz, i));
8709             setelemattribute(top, i, attrib);
8710             setelemattribute(horiz, i, attrib);
8711           }
8712           if (b->vararea) {
8713             if ((areabound(top) <= 0.0) || (areabound(horiz) <= 0.0)) {
8714               area = -1.0;
8715             } else {
8716               /* Take the average of the two triangles' area constraints.    */
8717               /*   This prevents small area constraints from migrating a     */
8718               /*   long, long way from their original location due to flips. */
8719               area = 0.5 * (areabound(top) + areabound(horiz));
8720             }
8721             setareabound(top, area);
8722             setareabound(horiz, area);
8723           }
8724 
8725           if (m->checkquality) {
8726             newflip = (struct flipstacker *) poolalloc(&m->flipstackers);
8727             newflip->flippedtri = encode(horiz);
8728             newflip->prevflip = m->lastflip;
8729             m->lastflip = newflip;
8730           }
8731 
8732 #ifdef SELF_CHECK
8733           if (newvertex != (vertex) NULL) {
8734             if (counterclockwise(m, b, leftvertex, newvertex, rightvertex) <
8735                 0.0) {
8736               printf("Internal error in insertvertex():\n");
8737               printf("  Clockwise triangle prior to edge flip (bottom).\n");
8738             }
8739             /* The following test has been removed because constrainededge() */
8740             /*   sometimes generates inverted triangles that insertvertex()  */
8741             /*   removes.                                                    */
8742 /*
8743             if (counterclockwise(m, b, rightvertex, farvertex, leftvertex) <
8744                 0.0) {
8745               printf("Internal error in insertvertex():\n");
8746               printf("  Clockwise triangle prior to edge flip (top).\n");
8747             }
8748 */
8749             if (counterclockwise(m, b, farvertex, leftvertex, newvertex) <
8750                 0.0) {
8751               printf("Internal error in insertvertex():\n");
8752               printf("  Clockwise triangle after edge flip (left).\n");
8753             }
8754             if (counterclockwise(m, b, newvertex, rightvertex, farvertex) <
8755                 0.0) {
8756               printf("Internal error in insertvertex():\n");
8757               printf("  Clockwise triangle after edge flip (right).\n");
8758             }
8759           }
8760 #endif /* SELF_CHECK */
8761           if (b->verbose > 2) {
8762             printf("  Edge flip results in left ");
8763             lnextself(topleft);
8764             printtriangle(m, b, &topleft);
8765             printf("  and right ");
8766             printtriangle(m, b, &horiz);
8767           }
8768           /* On the next iterations, consider the two edges that were  */
8769           /*   exposed (this is, are now visible to the newly inserted */
8770           /*   vertex) by the edge flip.                               */
8771           lprevself(horiz);
8772           leftvertex = farvertex;
8773         }
8774       }
8775     }
8776     if (!doflip) {
8777       /* The handle `horiz' is accepted as locally Delaunay. */
8778 #ifndef CDT_ONLY
8779       if (triflaws) {
8780         /* Check the triangle `horiz' for quality. */
8781         testtriangle(m, b, &horiz);
8782       }
8783 #endif /* not CDT_ONLY */
8784       /* Look for the next edge around the newly inserted vertex. */
8785       lnextself(horiz);
8786       sym(horiz, testtri);
8787       /* Check for finishing a complete revolution about the new vertex, or */
8788       /*   falling outside  of the triangulation.  The latter will happen   */
8789       /*   when a vertex is inserted at a boundary.                         */
8790       if ((leftvertex == first) || (testtri.tri == m->dummytri)) {
8791         /* We're done.  Return a triangle whose origin is the new vertex. */
8792         lnext(horiz, *searchtri);
8793         lnext(horiz, m->recenttri);
8794         return success;
8795       }
8796       /* Finish finding the next edge around the newly inserted vertex. */
8797       lnext(testtri, horiz);
8798       rightvertex = leftvertex;
8799       dest(horiz, leftvertex);
8800     }
8801   }
8802 }
8803 
8804 /*****************************************************************************/
8805 /*                                                                           */
8806 /*  triangulatepolygon()   Find the Delaunay triangulation of a polygon that */
8807 /*                         has a certain "nice" shape.  This includes the    */
8808 /*                         polygons that result from deletion of a vertex or */
8809 /*                         insertion of a segment.                           */
8810 /*                                                                           */
8811 /*  This is a conceptually difficult routine.  The starting assumption is    */
8812 /*  that we have a polygon with n sides.  n - 1 of these sides are currently */
8813 /*  represented as edges in the mesh.  One side, called the "base", need not */
8814 /*  be.                                                                      */
8815 /*                                                                           */
8816 /*  Inside the polygon is a structure I call a "fan", consisting of n - 1    */
8817 /*  triangles that share a common origin.  For each of these triangles, the  */
8818 /*  edge opposite the origin is one of the sides of the polygon.  The        */
8819 /*  primary edge of each triangle is the edge directed from the origin to    */
8820 /*  the destination; note that this is not the same edge that is a side of   */
8821 /*  the polygon.  `firstedge' is the primary edge of the first triangle.     */
8822 /*  From there, the triangles follow in counterclockwise order about the     */
8823 /*  polygon, until `lastedge', the primary edge of the last triangle.        */
8824 /*  `firstedge' and `lastedge' are probably connected to other triangles     */
8825 /*  beyond the extremes of the fan, but their identity is not important, as  */
8826 /*  long as the fan remains connected to them.                               */
8827 /*                                                                           */
8828 /*  Imagine the polygon oriented so that its base is at the bottom.  This    */
8829 /*  puts `firstedge' on the far right, and `lastedge' on the far left.       */
8830 /*  The right vertex of the base is the destination of `firstedge', and the  */
8831 /*  left vertex of the base is the apex of `lastedge'.                       */
8832 /*                                                                           */
8833 /*  The challenge now is to find the right sequence of edge flips to         */
8834 /*  transform the fan into a Delaunay triangulation of the polygon.  Each    */
8835 /*  edge flip effectively removes one triangle from the fan, committing it   */
8836 /*  to the polygon.  The resulting polygon has one fewer edge.  If `doflip'  */
8837 /*  is set, the final flip will be performed, resulting in a fan of one      */
8838 /*  (useless?) triangle.  If `doflip' is not set, the final flip is not      */
8839 /*  performed, resulting in a fan of two triangles, and an unfinished        */
8840 /*  triangular polygon that is not yet filled out with a single triangle.    */
8841 /*  On completion of the routine, `lastedge' is the last remaining triangle, */
8842 /*  or the leftmost of the last two.                                         */
8843 /*                                                                           */
8844 /*  Although the flips are performed in the order described above, the       */
8845 /*  decisions about what flips to perform are made in precisely the reverse  */
8846 /*  order.  The recursive triangulatepolygon() procedure makes a decision,   */
8847 /*  uses up to two recursive calls to triangulate the "subproblems"          */
8848 /*  (polygons with fewer edges), and then performs an edge flip.             */
8849 /*                                                                           */
8850 /*  The "decision" it makes is which vertex of the polygon should be         */
8851 /*  connected to the base.  This decision is made by testing every possible  */
8852 /*  vertex.  Once the best vertex is found, the two edges that connect this  */
8853 /*  vertex to the base become the bases for two smaller polygons.  These     */
8854 /*  are triangulated recursively.  Unfortunately, this approach can take     */
8855 /*  O(n^2) time not only in the worst case, but in many common cases.  It's  */
8856 /*  rarely a big deal for vertex deletion, where n is rarely larger than     */
8857 /*  ten, but it could be a big deal for segment insertion, especially if     */
8858 /*  there's a lot of long segments that each cut many triangles.  I ought to */
8859 /*  code a faster algorithm some day.                                        */
8860 /*                                                                           */
8861 /*  The `edgecount' parameter is the number of sides of the polygon,         */
8862 /*  including its base.  `triflaws' is a flag that determines whether the    */
8863 /*  new triangles should be tested for quality, and enqueued if they are     */
8864 /*  bad.                                                                     */
8865 /*                                                                           */
8866 /*****************************************************************************/
8867 
8868 #ifdef ANSI_DECLARATORS
8869 void triangulatepolygon(struct mesh *m, struct behavior *b,
8870                         struct otri *firstedge, struct otri *lastedge,
8871                         int edgecount, int doflip, int triflaws)
8872 #else /* not ANSI_DECLARATORS */
8873 void triangulatepolygon(m, b, firstedge, lastedge, edgecount, doflip, triflaws)
8874 struct mesh *m;
8875 struct behavior *b;
8876 struct otri *firstedge;
8877 struct otri *lastedge;
8878 int edgecount;
8879 int doflip;
8880 int triflaws;
8881 #endif /* not ANSI_DECLARATORS */
8882 
8883 {
8884   struct otri testtri;
8885   struct otri besttri;
8886   struct otri tempedge;
8887   vertex leftbasevertex, rightbasevertex;
8888   vertex testvertex;
8889   vertex bestvertex;
8890   int bestnumber;
8891   int i;
8892   triangle ptr;   /* Temporary variable used by sym(), onext(), and oprev(). */
8893 
8894   /* Identify the base vertices. */
8895   apex(*lastedge, leftbasevertex);
8896   dest(*firstedge, rightbasevertex);
8897   if (b->verbose > 2) {
8898     printf("  Triangulating interior polygon at edge\n");
8899     printf("    (%.12g, %.12g) (%.12g, %.12g)\n", (double)leftbasevertex[0],
8900            (double)leftbasevertex[1], (double)rightbasevertex[0], (double)rightbasevertex[1]);
8901   }
8902   /* Find the best vertex to connect the base to. */
8903   onext(*firstedge, besttri);
8904   dest(besttri, bestvertex);
8905   otricopy(besttri, testtri);
8906   bestnumber = 1;
8907   for (i = 2; i <= edgecount - 2; i++) {
8908     onextself(testtri);
8909     dest(testtri, testvertex);
8910     /* Is this a better vertex? */
8911     if (incircle(m, b, leftbasevertex, rightbasevertex, bestvertex,
8912                  testvertex) > 0.0) {
8913       otricopy(testtri, besttri);
8914       bestvertex = testvertex;
8915       bestnumber = i;
8916     }
8917   }
8918   if (b->verbose > 2) {
8919     printf("    Connecting edge to (%.12g, %.12g)\n", (double)bestvertex[0],
8920            (double)bestvertex[1]);
8921   }
8922   if (bestnumber > 1) {
8923     /* Recursively triangulate the smaller polygon on the right. */
8924     oprev(besttri, tempedge);
8925     triangulatepolygon(m, b, firstedge, &tempedge, bestnumber + 1, 1,
8926                        triflaws);
8927   }
8928   if (bestnumber < edgecount - 2) {
8929     /* Recursively triangulate the smaller polygon on the left. */
8930     sym(besttri, tempedge);
8931     triangulatepolygon(m, b, &besttri, lastedge, edgecount - bestnumber, 1,
8932                        triflaws);
8933     /* Find `besttri' again; it may have been lost to edge flips. */
8934     sym(tempedge, besttri);
8935   }
8936   if (doflip) {
8937     /* Do one final edge flip. */
8938     flip(m, b, &besttri);
8939 #ifndef CDT_ONLY
8940     if (triflaws) {
8941       /* Check the quality of the newly committed triangle. */
8942       sym(besttri, testtri);
8943       testtriangle(m, b, &testtri);
8944     }
8945 #endif /* not CDT_ONLY */
8946   }
8947   /* Return the base triangle. */
8948   otricopy(besttri, *lastedge);
8949 }
8950 
8951 /*****************************************************************************/
8952 /*                                                                           */
8953 /*  deletevertex()   Delete a vertex from a Delaunay triangulation, ensuring */
8954 /*                   that the triangulation remains Delaunay.                */
8955 /*                                                                           */
8956 /*  The origin of `deltri' is deleted.  The union of the triangles adjacent  */
8957 /*  to this vertex is a polygon, for which the Delaunay triangulation is     */
8958 /*  found.  Two triangles are removed from the mesh.                         */
8959 /*                                                                           */
8960 /*  Only interior vertices that do not lie on segments or boundaries may be  */
8961 /*  deleted.                                                                 */
8962 /*                                                                           */
8963 /*****************************************************************************/
8964 
8965 #ifndef CDT_ONLY
8966 
8967 #ifdef ANSI_DECLARATORS
8968 void deletevertex(struct mesh *m, struct behavior *b, struct otri *deltri)
8969 #else /* not ANSI_DECLARATORS */
8970 void deletevertex(m, b, deltri)
8971 struct mesh *m;
8972 struct behavior *b;
8973 struct otri *deltri;
8974 #endif /* not ANSI_DECLARATORS */
8975 
8976 {
8977   struct otri countingtri;
8978   struct otri firstedge, lastedge;
8979   struct otri deltriright;
8980   struct otri lefttri, righttri;
8981   struct otri leftcasing, rightcasing;
8982   struct osub leftsubseg, rightsubseg;
8983   vertex delvertex;
8984   vertex neworg;
8985   int edgecount;
8986   triangle ptr;   /* Temporary variable used by sym(), onext(), and oprev(). */
8987   subseg sptr;                      /* Temporary variable used by tspivot(). */
8988 
8989   org(*deltri, delvertex);
8990   if (b->verbose > 1) {
8991     printf("  Deleting (%.12g, %.12g).\n", (double)delvertex[0], (double)delvertex[1]);
8992   }
8993   vertexdealloc(m, delvertex);
8994 
8995   /* Count the degree of the vertex being deleted. */
8996   onext(*deltri, countingtri);
8997   edgecount = 1;
8998   while (!otriequal(*deltri, countingtri)) {
8999 #ifdef SELF_CHECK
9000     if (countingtri.tri == m->dummytri) {
9001       printf("Internal error in deletevertex():\n");
9002       printf("  Attempt to delete boundary vertex.\n");
9003       internalerror();
9004     }
9005 #endif /* SELF_CHECK */
9006     edgecount++;
9007     onextself(countingtri);
9008   }
9009 
9010 #ifdef SELF_CHECK
9011   if (edgecount < 3) {
9012     printf("Internal error in deletevertex():\n  Vertex has degree %d.\n",
9013            edgecount);
9014     internalerror();
9015   }
9016 #endif /* SELF_CHECK */
9017   if (edgecount > 3) {
9018     /* Triangulate the polygon defined by the union of all triangles */
9019     /*   adjacent to the vertex being deleted.  Check the quality of */
9020     /*   the resulting triangles.                                    */
9021     onext(*deltri, firstedge);
9022     oprev(*deltri, lastedge);
9023     triangulatepolygon(m, b, &firstedge, &lastedge, edgecount, 0,
9024                        !b->nobisect);
9025   }
9026   /* Splice out two triangles. */
9027   lprev(*deltri, deltriright);
9028   dnext(*deltri, lefttri);
9029   sym(lefttri, leftcasing);
9030   oprev(deltriright, righttri);
9031   sym(righttri, rightcasing);
9032   bond(*deltri, leftcasing);
9033   bond(deltriright, rightcasing);
9034   tspivot(lefttri, leftsubseg);
9035   if (leftsubseg.ss != m->dummysub) {
9036     tsbond(*deltri, leftsubseg);
9037   }
9038   tspivot(righttri, rightsubseg);
9039   if (rightsubseg.ss != m->dummysub) {
9040     tsbond(deltriright, rightsubseg);
9041   }
9042 
9043   /* Set the new origin of `deltri' and check its quality. */
9044   org(lefttri, neworg);
9045   setorg(*deltri, neworg);
9046   if (!b->nobisect) {
9047     testtriangle(m, b, deltri);
9048   }
9049 
9050   /* Delete the two spliced-out triangles. */
9051   triangledealloc(m, lefttri.tri);
9052   triangledealloc(m, righttri.tri);
9053 }
9054 
9055 #endif /* not CDT_ONLY */
9056 
9057 /*****************************************************************************/
9058 /*                                                                           */
9059 /*  undovertex()   Undo the most recent vertex insertion.                    */
9060 /*                                                                           */
9061 /*  Walks through the list of transformations (flips and a vertex insertion) */
9062 /*  in the reverse of the order in which they were done, and undoes them.    */
9063 /*  The inserted vertex is removed from the triangulation and deallocated.   */
9064 /*  Two triangles (possibly just one) are also deallocated.                  */
9065 /*                                                                           */
9066 /*****************************************************************************/
9067 
9068 #ifndef CDT_ONLY
9069 
9070 #ifdef ANSI_DECLARATORS
9071 void undovertex(struct mesh *m, struct behavior *b)
9072 #else /* not ANSI_DECLARATORS */
9073 void undovertex(m, b)
9074 struct mesh *m;
9075 struct behavior *b;
9076 #endif /* not ANSI_DECLARATORS */
9077 
9078 {
9079   struct otri fliptri;
9080   struct otri botleft, botright, topright;
9081   struct otri botlcasing, botrcasing, toprcasing;
9082   struct otri gluetri;
9083   struct osub botlsubseg, botrsubseg, toprsubseg;
9084   vertex botvertex, rightvertex;
9085   triangle ptr;                         /* Temporary variable used by sym(). */
9086   subseg sptr;                      /* Temporary variable used by tspivot(). */
9087 
9088   /* Walk through the list of transformations (flips and a vertex insertion) */
9089   /*   in the reverse of the order in which they were done, and undo them.   */
9090   while (m->lastflip != (struct flipstacker *) NULL) {
9091     /* Find a triangle involved in the last unreversed transformation. */
9092     decode(m->lastflip->flippedtri, fliptri);
9093 
9094     /* We are reversing one of three transformations:  a trisection of one */
9095     /*   triangle into three (by inserting a vertex in the triangle), a    */
9096     /*   bisection of two triangles into four (by inserting a vertex in an */
9097     /*   edge), or an edge flip.                                           */
9098     if (m->lastflip->prevflip == (struct flipstacker *) NULL) {
9099       /* Restore a triangle that was split into three triangles, */
9100       /*   so it is again one triangle.                          */
9101       dprev(fliptri, botleft);
9102       lnextself(botleft);
9103       onext(fliptri, botright);
9104       lprevself(botright);
9105       sym(botleft, botlcasing);
9106       sym(botright, botrcasing);
9107       dest(botleft, botvertex);
9108 
9109       setapex(fliptri, botvertex);
9110       lnextself(fliptri);
9111       bond(fliptri, botlcasing);
9112       tspivot(botleft, botlsubseg);
9113       tsbond(fliptri, botlsubseg);
9114       lnextself(fliptri);
9115       bond(fliptri, botrcasing);
9116       tspivot(botright, botrsubseg);
9117       tsbond(fliptri, botrsubseg);
9118 
9119       /* Delete the two spliced-out triangles. */
9120       triangledealloc(m, botleft.tri);
9121       triangledealloc(m, botright.tri);
9122     } else if (m->lastflip->prevflip == (struct flipstacker *) &insertvertex) {
9123       /* Restore two triangles that were split into four triangles, */
9124       /*   so they are again two triangles.                         */
9125       lprev(fliptri, gluetri);
9126       sym(gluetri, botright);
9127       lnextself(botright);
9128       sym(botright, botrcasing);
9129       dest(botright, rightvertex);
9130 
9131       setorg(fliptri, rightvertex);
9132       bond(gluetri, botrcasing);
9133       tspivot(botright, botrsubseg);
9134       tsbond(gluetri, botrsubseg);
9135 
9136       /* Delete the spliced-out triangle. */
9137       triangledealloc(m, botright.tri);
9138 
9139       sym(fliptri, gluetri);
9140       if (gluetri.tri != m->dummytri) {
9141         lnextself(gluetri);
9142         dnext(gluetri, topright);
9143         sym(topright, toprcasing);
9144 
9145         setorg(gluetri, rightvertex);
9146         bond(gluetri, toprcasing);
9147         tspivot(topright, toprsubseg);
9148         tsbond(gluetri, toprsubseg);
9149 
9150         /* Delete the spliced-out triangle. */
9151         triangledealloc(m, topright.tri);
9152       }
9153 
9154       /* This is the end of the list, sneakily encoded. */
9155       m->lastflip->prevflip = (struct flipstacker *) NULL;
9156     } else {
9157       /* Undo an edge flip. */
9158       unflip(m, b, &fliptri);
9159     }
9160 
9161     /* Go on and process the next transformation. */
9162     m->lastflip = m->lastflip->prevflip;
9163   }
9164 }
9165 
9166 #endif /* not CDT_ONLY */
9167 
9168 /**                                                                         **/
9169 /**                                                                         **/
9170 /********* Mesh transformation routines end here                     *********/
9171 
9172 /********* Divide-and-conquer Delaunay triangulation begins here     *********/
9173 /**                                                                         **/
9174 /**                                                                         **/
9175 
9176 /*****************************************************************************/
9177 /*                                                                           */
9178 /*  The divide-and-conquer bounding box                                      */
9179 /*                                                                           */
9180 /*  I originally implemented the divide-and-conquer and incremental Delaunay */
9181 /*  triangulations using the edge-based data structure presented by Guibas   */
9182 /*  and Stolfi.  Switching to a triangle-based data structure doubled the    */
9183 /*  speed.  However, I had to think of a few extra tricks to maintain the    */
9184 /*  elegance of the original algorithms.                                     */
9185 /*                                                                           */
9186 /*  The "bounding box" used by my variant of the divide-and-conquer          */
9187 /*  algorithm uses one triangle for each edge of the convex hull of the      */
9188 /*  triangulation.  These bounding triangles all share a common apical       */
9189 /*  vertex, which is represented by NULL and which represents nothing.       */
9190 /*  The bounding triangles are linked in a circular fan about this NULL      */
9191 /*  vertex, and the edges on the convex hull of the triangulation appear     */
9192 /*  opposite the NULL vertex.  You might find it easiest to imagine that     */
9193 /*  the NULL vertex is a point in 3D space behind the center of the          */
9194 /*  triangulation, and that the bounding triangles form a sort of cone.      */
9195 /*                                                                           */
9196 /*  This bounding box makes it easy to represent degenerate cases.  For      */
9197 /*  instance, the triangulation of two vertices is a single edge.  This edge */
9198 /*  is represented by two bounding box triangles, one on each "side" of the  */
9199 /*  edge.  These triangles are also linked together in a fan about the NULL  */
9200 /*  vertex.                                                                  */
9201 /*                                                                           */
9202 /*  The bounding box also makes it easy to traverse the convex hull, as the  */
9203 /*  divide-and-conquer algorithm needs to do.                                */
9204 /*                                                                           */
9205 /*****************************************************************************/
9206 
9207 /*****************************************************************************/
9208 /*                                                                           */
9209 /*  vertexsort()   Sort an array of vertices by x-coordinate, using the      */
9210 /*                 y-coordinate as a secondary key.                          */
9211 /*                                                                           */
9212 /*  Uses quicksort.  Randomized O(n log n) time.  No, I did not make any of  */
9213 /*  the usual quicksort mistakes.                                            */
9214 /*                                                                           */
9215 /*****************************************************************************/
9216 
9217 #ifdef ANSI_DECLARATORS
9218 void vertexsort(vertex *sortarray, int arraysize)
9219 #else /* not ANSI_DECLARATORS */
9220 void vertexsort(sortarray, arraysize)
9221 vertex *sortarray;
9222 int arraysize;
9223 #endif /* not ANSI_DECLARATORS */
9224 
9225 {
9226   int left, right;
9227   int pivot;
9228   REAL pivotx, pivoty;
9229   vertex temp;
9230 
9231   if (arraysize == 2) {
9232     /* Recursive base case. */
9233     if ((sortarray[0][0] > sortarray[1][0]) ||
9234         ((sortarray[0][0] == sortarray[1][0]) &&
9235          (sortarray[0][1] > sortarray[1][1]))) {
9236       temp = sortarray[1];
9237       sortarray[1] = sortarray[0];
9238       sortarray[0] = temp;
9239     }
9240     return;
9241   }
9242   /* Choose a random pivot to split the array. */
9243   pivot = (int) randomnation((unsigned int) arraysize);
9244   pivotx = sortarray[pivot][0];
9245   pivoty = sortarray[pivot][1];
9246   /* Split the array. */
9247   left = -1;
9248   right = arraysize;
9249   while (left < right) {
9250     /* Search for a vertex whose x-coordinate is too large for the left. */
9251     do {
9252       left++;
9253     } while ((left <= right) && ((sortarray[left][0] < pivotx) ||
9254                                  ((sortarray[left][0] == pivotx) &&
9255                                   (sortarray[left][1] < pivoty))));
9256     /* Search for a vertex whose x-coordinate is too small for the right. */
9257     do {
9258       right--;
9259     } while ((left <= right) && ((sortarray[right][0] > pivotx) ||
9260                                  ((sortarray[right][0] == pivotx) &&
9261                                   (sortarray[right][1] > pivoty))));
9262     if (left < right) {
9263       /* Swap the left and right vertices. */
9264       temp = sortarray[left];
9265       sortarray[left] = sortarray[right];
9266       sortarray[right] = temp;
9267     }
9268   }
9269   if (left > 1) {
9270     /* Recursively sort the left subset. */
9271     vertexsort(sortarray, left);
9272   }
9273   if (right < arraysize - 2) {
9274     /* Recursively sort the right subset. */
9275     vertexsort(&sortarray[right + 1], arraysize - right - 1);
9276   }
9277 }
9278 
9279 /*****************************************************************************/
9280 /*                                                                           */
9281 /*  vertexmedian()   An order statistic algorithm, almost.  Shuffles an      */
9282 /*                   array of vertices so that the first `median' vertices   */
9283 /*                   occur lexicographically before the remaining vertices.  */
9284 /*                                                                           */
9285 /*  Uses the x-coordinate as the primary key if axis == 0; the y-coordinate  */
9286 /*  if axis == 1.  Very similar to the vertexsort() procedure, but runs in   */
9287 /*  randomized linear time.                                                  */
9288 /*                                                                           */
9289 /*****************************************************************************/
9290 
9291 #ifdef ANSI_DECLARATORS
9292 void vertexmedian(vertex *sortarray, int arraysize, int median, int axis)
9293 #else /* not ANSI_DECLARATORS */
9294 void vertexmedian(sortarray, arraysize, median, axis)
9295 vertex *sortarray;
9296 int arraysize;
9297 int median;
9298 int axis;
9299 #endif /* not ANSI_DECLARATORS */
9300 
9301 {
9302   int left, right;
9303   int pivot;
9304   REAL pivot1, pivot2;
9305   vertex temp;
9306 
9307   if (arraysize == 2) {
9308     /* Recursive base case. */
9309     if ((sortarray[0][axis] > sortarray[1][axis]) ||
9310         ((sortarray[0][axis] == sortarray[1][axis]) &&
9311          (sortarray[0][1 - axis] > sortarray[1][1 - axis]))) {
9312       temp = sortarray[1];
9313       sortarray[1] = sortarray[0];
9314       sortarray[0] = temp;
9315     }
9316     return;
9317   }
9318   /* Choose a random pivot to split the array. */
9319   pivot = (int) randomnation((unsigned int) arraysize);
9320   pivot1 = sortarray[pivot][axis];
9321   pivot2 = sortarray[pivot][1 - axis];
9322   /* Split the array. */
9323   left = -1;
9324   right = arraysize;
9325   while (left < right) {
9326     /* Search for a vertex whose x-coordinate is too large for the left. */
9327     do {
9328       left++;
9329     } while ((left <= right) && ((sortarray[left][axis] < pivot1) ||
9330                                  ((sortarray[left][axis] == pivot1) &&
9331                                   (sortarray[left][1 - axis] < pivot2))));
9332     /* Search for a vertex whose x-coordinate is too small for the right. */
9333     do {
9334       right--;
9335     } while ((left <= right) && ((sortarray[right][axis] > pivot1) ||
9336                                  ((sortarray[right][axis] == pivot1) &&
9337                                   (sortarray[right][1 - axis] > pivot2))));
9338     if (left < right) {
9339       /* Swap the left and right vertices. */
9340       temp = sortarray[left];
9341       sortarray[left] = sortarray[right];
9342       sortarray[right] = temp;
9343     }
9344   }
9345   /* Unlike in vertexsort(), at most one of the following */
9346   /*   conditionals is true.                             */
9347   if (left > median) {
9348     /* Recursively shuffle the left subset. */
9349     vertexmedian(sortarray, left, median, axis);
9350   }
9351   if (right < median - 1) {
9352     /* Recursively shuffle the right subset. */
9353     vertexmedian(&sortarray[right + 1], arraysize - right - 1,
9354                  median - right - 1, axis);
9355   }
9356 }
9357 
9358 /*****************************************************************************/
9359 /*                                                                           */
9360 /*  alternateaxes()   Sorts the vertices as appropriate for the divide-and-  */
9361 /*                    conquer algorithm with alternating cuts.               */
9362 /*                                                                           */
9363 /*  Partitions by x-coordinate if axis == 0; by y-coordinate if axis == 1.   */
9364 /*  For the base case, subsets containing only two or three vertices are     */
9365 /*  always sorted by x-coordinate.                                           */
9366 /*                                                                           */
9367 /*****************************************************************************/
9368 
9369 #ifdef ANSI_DECLARATORS
9370 void alternateaxes(vertex *sortarray, int arraysize, int axis)
9371 #else /* not ANSI_DECLARATORS */
9372 void alternateaxes(sortarray, arraysize, axis)
9373 vertex *sortarray;
9374 int arraysize;
9375 int axis;
9376 #endif /* not ANSI_DECLARATORS */
9377 
9378 {
9379   int divider;
9380 
9381   divider = arraysize >> 1;
9382   if (arraysize <= 3) {
9383     /* Recursive base case:  subsets of two or three vertices will be    */
9384     /*   handled specially, and should always be sorted by x-coordinate. */
9385     axis = 0;
9386   }
9387   /* Partition with a horizontal or vertical cut. */
9388   vertexmedian(sortarray, arraysize, divider, axis);
9389   /* Recursively partition the subsets with a cross cut. */
9390   if (arraysize - divider >= 2) {
9391     if (divider >= 2) {
9392       alternateaxes(sortarray, divider, 1 - axis);
9393     }
9394     alternateaxes(&sortarray[divider], arraysize - divider, 1 - axis);
9395   }
9396 }
9397 
9398 /*****************************************************************************/
9399 /*                                                                           */
9400 /*  mergehulls()   Merge two adjacent Delaunay triangulations into a         */
9401 /*                 single Delaunay triangulation.                            */
9402 /*                                                                           */
9403 /*  This is similar to the algorithm given by Guibas and Stolfi, but uses    */
9404 /*  a triangle-based, rather than edge-based, data structure.                */
9405 /*                                                                           */
9406 /*  The algorithm walks up the gap between the two triangulations, knitting  */
9407 /*  them together.  As they are merged, some of their bounding triangles     */
9408 /*  are converted into real triangles of the triangulation.  The procedure   */
9409 /*  pulls each hull's bounding triangles apart, then knits them together     */
9410 /*  like the teeth of two gears.  The Delaunay property determines, at each  */
9411 /*  step, whether the next "tooth" is a bounding triangle of the left hull   */
9412 /*  or the right.  When a bounding triangle becomes real, its apex is        */
9413 /*  changed from NULL to a real vertex.                                      */
9414 /*                                                                           */
9415 /*  Only two new triangles need to be allocated.  These become new bounding  */
9416 /*  triangles at the top and bottom of the seam.  They are used to connect   */
9417 /*  the remaining bounding triangles (those that have not been converted     */
9418 /*  into real triangles) into a single fan.                                  */
9419 /*                                                                           */
9420 /*  On entry, `farleft' and `innerleft' are bounding triangles of the left   */
9421 /*  triangulation.  The origin of `farleft' is the leftmost vertex, and      */
9422 /*  the destination of `innerleft' is the rightmost vertex of the            */
9423 /*  triangulation.  Similarly, `innerright' and `farright' are bounding      */
9424 /*  triangles of the right triangulation.  The origin of `innerright' and    */
9425 /*  destination of `farright' are the leftmost and rightmost vertices.       */
9426 /*                                                                           */
9427 /*  On completion, the origin of `farleft' is the leftmost vertex of the     */
9428 /*  merged triangulation, and the destination of `farright' is the rightmost */
9429 /*  vertex.                                                                  */
9430 /*                                                                           */
9431 /*****************************************************************************/
9432 
9433 #ifdef ANSI_DECLARATORS
9434 void mergehulls(struct mesh *m, struct behavior *b, struct otri *farleft,
9435                 struct otri *innerleft, struct otri *innerright,
9436                 struct otri *farright, int axis)
9437 #else /* not ANSI_DECLARATORS */
9438 void mergehulls(m, b, farleft, innerleft, innerright, farright, axis)
9439 struct mesh *m;
9440 struct behavior *b;
9441 struct otri *farleft;
9442 struct otri *innerleft;
9443 struct otri *innerright;
9444 struct otri *farright;
9445 int axis;
9446 #endif /* not ANSI_DECLARATORS */
9447 
9448 {
9449   struct otri leftcand, rightcand;
9450   struct otri baseedge;
9451   struct otri nextedge;
9452   struct otri sidecasing, topcasing, outercasing;
9453   struct otri checkedge;
9454   vertex innerleftdest;
9455   vertex innerrightorg;
9456   vertex innerleftapex, innerrightapex;
9457   vertex farleftpt, farrightpt;
9458   vertex farleftapex, farrightapex;
9459   vertex lowerleft, lowerright;
9460   vertex upperleft, upperright;
9461   vertex nextapex;
9462   vertex checkvertex;
9463   int changemade;
9464   int badedge;
9465   int leftfinished, rightfinished;
9466   triangle ptr;                         /* Temporary variable used by sym(). */
9467 
9468   dest(*innerleft, innerleftdest);
9469   apex(*innerleft, innerleftapex);
9470   org(*innerright, innerrightorg);
9471   apex(*innerright, innerrightapex);
9472   /* Special treatment for horizontal cuts. */
9473   if (b->dwyer && (axis == 1)) {
9474     org(*farleft, farleftpt);
9475     apex(*farleft, farleftapex);
9476     dest(*farright, farrightpt);
9477     apex(*farright, farrightapex);
9478     /* The pointers to the extremal vertices are shifted to point to the */
9479     /*   topmost and bottommost vertex of each hull, rather than the     */
9480     /*   leftmost and rightmost vertices.                                */
9481     while (farleftapex[1] < farleftpt[1]) {
9482       lnextself(*farleft);
9483       symself(*farleft);
9484       farleftpt = farleftapex;
9485       apex(*farleft, farleftapex);
9486     }
9487     sym(*innerleft, checkedge);
9488     apex(checkedge, checkvertex);
9489     while (checkvertex[1] > innerleftdest[1]) {
9490       lnext(checkedge, *innerleft);
9491       innerleftapex = innerleftdest;
9492       innerleftdest = checkvertex;
9493       sym(*innerleft, checkedge);
9494       apex(checkedge, checkvertex);
9495     }
9496     while (innerrightapex[1] < innerrightorg[1]) {
9497       lnextself(*innerright);
9498       symself(*innerright);
9499       innerrightorg = innerrightapex;
9500       apex(*innerright, innerrightapex);
9501     }
9502     sym(*farright, checkedge);
9503     apex(checkedge, checkvertex);
9504     while (checkvertex[1] > farrightpt[1]) {
9505       lnext(checkedge, *farright);
9506       farrightapex = farrightpt;
9507       farrightpt = checkvertex;
9508       sym(*farright, checkedge);
9509       apex(checkedge, checkvertex);
9510     }
9511   }
9512   /* Find a line tangent to and below both hulls. */
9513   do {
9514     changemade = 0;
9515     /* Make innerleftdest the "bottommost" vertex of the left hull. */
9516     if (counterclockwise(m, b, innerleftdest, innerleftapex, innerrightorg) >
9517         0.0) {
9518       lprevself(*innerleft);
9519       symself(*innerleft);
9520       innerleftdest = innerleftapex;
9521       apex(*innerleft, innerleftapex);
9522       changemade = 1;
9523     }
9524     /* Make innerrightorg the "bottommost" vertex of the right hull. */
9525     if (counterclockwise(m, b, innerrightapex, innerrightorg, innerleftdest) >
9526         0.0) {
9527       lnextself(*innerright);
9528       symself(*innerright);
9529       innerrightorg = innerrightapex;
9530       apex(*innerright, innerrightapex);
9531       changemade = 1;
9532     }
9533   } while (changemade);
9534   /* Find the two candidates to be the next "gear tooth." */
9535   sym(*innerleft, leftcand);
9536   sym(*innerright, rightcand);
9537   /* Create the bottom new bounding triangle. */
9538   maketriangle(m, b, &baseedge);
9539   /* Connect it to the bounding boxes of the left and right triangulations. */
9540   bond(baseedge, *innerleft);
9541   lnextself(baseedge);
9542   bond(baseedge, *innerright);
9543   lnextself(baseedge);
9544   setorg(baseedge, innerrightorg);
9545   setdest(baseedge, innerleftdest);
9546   /* Apex is intentionally left NULL. */
9547   if (b->verbose > 2) {
9548     printf("  Creating base bounding ");
9549     printtriangle(m, b, &baseedge);
9550   }
9551   /* Fix the extreme triangles if necessary. */
9552   org(*farleft, farleftpt);
9553   if (innerleftdest == farleftpt) {
9554     lnext(baseedge, *farleft);
9555   }
9556   dest(*farright, farrightpt);
9557   if (innerrightorg == farrightpt) {
9558     lprev(baseedge, *farright);
9559   }
9560   /* The vertices of the current knitting edge. */
9561   lowerleft = innerleftdest;
9562   lowerright = innerrightorg;
9563   /* The candidate vertices for knitting. */
9564   apex(leftcand, upperleft);
9565   apex(rightcand, upperright);
9566   /* Walk up the gap between the two triangulations, knitting them together. */
9567   while (1) {
9568     /* Have we reached the top?  (This isn't quite the right question,       */
9569     /*   because even though the left triangulation might seem finished now, */
9570     /*   moving up on the right triangulation might reveal a new vertex of   */
9571     /*   the left triangulation.  And vice-versa.)                           */
9572     leftfinished = counterclockwise(m, b, upperleft, lowerleft, lowerright) <=
9573                    0.0;
9574     rightfinished = counterclockwise(m, b, upperright, lowerleft, lowerright)
9575                  <= 0.0;
9576     if (leftfinished && rightfinished) {
9577       /* Create the top new bounding triangle. */
9578       maketriangle(m, b, &nextedge);
9579       setorg(nextedge, lowerleft);
9580       setdest(nextedge, lowerright);
9581       /* Apex is intentionally left NULL. */
9582       /* Connect it to the bounding boxes of the two triangulations. */
9583       bond(nextedge, baseedge);
9584       lnextself(nextedge);
9585       bond(nextedge, rightcand);
9586       lnextself(nextedge);
9587       bond(nextedge, leftcand);
9588       if (b->verbose > 2) {
9589         printf("  Creating top bounding ");
9590         printtriangle(m, b, &nextedge);
9591       }
9592       /* Special treatment for horizontal cuts. */
9593       if (b->dwyer && (axis == 1)) {
9594         org(*farleft, farleftpt);
9595         apex(*farleft, farleftapex);
9596         dest(*farright, farrightpt);
9597         apex(*farright, farrightapex);
9598         sym(*farleft, checkedge);
9599         apex(checkedge, checkvertex);
9600         /* The pointers to the extremal vertices are restored to the  */
9601         /*   leftmost and rightmost vertices (rather than topmost and */
9602         /*   bottommost).                                             */
9603         while (checkvertex[0] < farleftpt[0]) {
9604           lprev(checkedge, *farleft);
9605           farleftapex = farleftpt;
9606           farleftpt = checkvertex;
9607           sym(*farleft, checkedge);
9608           apex(checkedge, checkvertex);
9609         }
9610         while (farrightapex[0] > farrightpt[0]) {
9611           lprevself(*farright);
9612           symself(*farright);
9613           farrightpt = farrightapex;
9614           apex(*farright, farrightapex);
9615         }
9616       }
9617       return;
9618     }
9619     /* Consider eliminating edges from the left triangulation. */
9620     if (!leftfinished) {
9621       /* What vertex would be exposed if an edge were deleted? */
9622       lprev(leftcand, nextedge);
9623       symself(nextedge);
9624       apex(nextedge, nextapex);
9625       /* If nextapex is NULL, then no vertex would be exposed; the */
9626       /*   triangulation would have been eaten right through.      */
9627       if (nextapex != (vertex) NULL) {
9628         /* Check whether the edge is Delaunay. */
9629         badedge = incircle(m, b, lowerleft, lowerright, upperleft, nextapex) >
9630                   0.0;
9631         while (badedge) {
9632           /* Eliminate the edge with an edge flip.  As a result, the    */
9633           /*   left triangulation will have one more boundary triangle. */
9634           lnextself(nextedge);
9635           sym(nextedge, topcasing);
9636           lnextself(nextedge);
9637           sym(nextedge, sidecasing);
9638           bond(nextedge, topcasing);
9639           bond(leftcand, sidecasing);
9640           lnextself(leftcand);
9641           sym(leftcand, outercasing);
9642           lprevself(nextedge);
9643           bond(nextedge, outercasing);
9644           /* Correct the vertices to reflect the edge flip. */
9645           setorg(leftcand, lowerleft);
9646           setdest(leftcand, NULL);
9647           setapex(leftcand, nextapex);
9648           setorg(nextedge, NULL);
9649           setdest(nextedge, upperleft);
9650           setapex(nextedge, nextapex);
9651           /* Consider the newly exposed vertex. */
9652           upperleft = nextapex;
9653           /* What vertex would be exposed if another edge were deleted? */
9654           otricopy(sidecasing, nextedge);
9655           apex(nextedge, nextapex);
9656           if (nextapex != (vertex) NULL) {
9657             /* Check whether the edge is Delaunay. */
9658             badedge = incircle(m, b, lowerleft, lowerright, upperleft,
9659                                nextapex) > 0.0;
9660           } else {
9661             /* Avoid eating right through the triangulation. */
9662             badedge = 0;
9663           }
9664         }
9665       }
9666     }
9667     /* Consider eliminating edges from the right triangulation. */
9668     if (!rightfinished) {
9669       /* What vertex would be exposed if an edge were deleted? */
9670       lnext(rightcand, nextedge);
9671       symself(nextedge);
9672       apex(nextedge, nextapex);
9673       /* If nextapex is NULL, then no vertex would be exposed; the */
9674       /*   triangulation would have been eaten right through.      */
9675       if (nextapex != (vertex) NULL) {
9676         /* Check whether the edge is Delaunay. */
9677         badedge = incircle(m, b, lowerleft, lowerright, upperright, nextapex) >
9678                   0.0;
9679         while (badedge) {
9680           /* Eliminate the edge with an edge flip.  As a result, the     */
9681           /*   right triangulation will have one more boundary triangle. */
9682           lprevself(nextedge);
9683           sym(nextedge, topcasing);
9684           lprevself(nextedge);
9685           sym(nextedge, sidecasing);
9686           bond(nextedge, topcasing);
9687           bond(rightcand, sidecasing);
9688           lprevself(rightcand);
9689           sym(rightcand, outercasing);
9690           lnextself(nextedge);
9691           bond(nextedge, outercasing);
9692           /* Correct the vertices to reflect the edge flip. */
9693           setorg(rightcand, NULL);
9694           setdest(rightcand, lowerright);
9695           setapex(rightcand, nextapex);
9696           setorg(nextedge, upperright);
9697           setdest(nextedge, NULL);
9698           setapex(nextedge, nextapex);
9699           /* Consider the newly exposed vertex. */
9700           upperright = nextapex;
9701           /* What vertex would be exposed if another edge were deleted? */
9702           otricopy(sidecasing, nextedge);
9703           apex(nextedge, nextapex);
9704           if (nextapex != (vertex) NULL) {
9705             /* Check whether the edge is Delaunay. */
9706             badedge = incircle(m, b, lowerleft, lowerright, upperright,
9707                                nextapex) > 0.0;
9708           } else {
9709             /* Avoid eating right through the triangulation. */
9710             badedge = 0;
9711           }
9712         }
9713       }
9714     }
9715     if (leftfinished || (!rightfinished &&
9716            (incircle(m, b, upperleft, lowerleft, lowerright, upperright) >
9717             0.0))) {
9718       /* Knit the triangulations, adding an edge from `lowerleft' */
9719       /*   to `upperright'.                                       */
9720       bond(baseedge, rightcand);
9721       lprev(rightcand, baseedge);
9722       setdest(baseedge, lowerleft);
9723       lowerright = upperright;
9724       sym(baseedge, rightcand);
9725       apex(rightcand, upperright);
9726     } else {
9727       /* Knit the triangulations, adding an edge from `upperleft' */
9728       /*   to `lowerright'.                                       */
9729       bond(baseedge, leftcand);
9730       lnext(leftcand, baseedge);
9731       setorg(baseedge, lowerright);
9732       lowerleft = upperleft;
9733       sym(baseedge, leftcand);
9734       apex(leftcand, upperleft);
9735     }
9736     if (b->verbose > 2) {
9737       printf("  Connecting ");
9738       printtriangle(m, b, &baseedge);
9739     }
9740   }
9741 }
9742 
9743 /*****************************************************************************/
9744 /*                                                                           */
9745 /*  divconqrecurse()   Recursively form a Delaunay triangulation by the      */
9746 /*                     divide-and-conquer method.                            */
9747 /*                                                                           */
9748 /*  Recursively breaks down the problem into smaller pieces, which are       */
9749 /*  knitted together by mergehulls().  The base cases (problems of two or    */
9750 /*  three vertices) are handled specially here.                              */
9751 /*                                                                           */
9752 /*  On completion, `farleft' and `farright' are bounding triangles such that */
9753 /*  the origin of `farleft' is the leftmost vertex (breaking ties by         */
9754 /*  choosing the highest leftmost vertex), and the destination of            */
9755 /*  `farright' is the rightmost vertex (breaking ties by choosing the        */
9756 /*  lowest rightmost vertex).                                                */
9757 /*                                                                           */
9758 /*****************************************************************************/
9759 
9760 #ifdef ANSI_DECLARATORS
9761 void divconqrecurse(struct mesh *m, struct behavior *b, vertex *sortarray,
9762                     int vertices, int axis,
9763                     struct otri *farleft, struct otri *farright)
9764 #else /* not ANSI_DECLARATORS */
9765 void divconqrecurse(m, b, sortarray, vertices, axis, farleft, farright)
9766 struct mesh *m;
9767 struct behavior *b;
9768 vertex *sortarray;
9769 int vertices;
9770 int axis;
9771 struct otri *farleft;
9772 struct otri *farright;
9773 #endif /* not ANSI_DECLARATORS */
9774 
9775 {
9776   struct otri midtri, tri1, tri2, tri3;
9777   struct otri innerleft, innerright;
9778   REAL area;
9779   int divider;
9780 
9781   if (b->verbose > 2) {
9782     printf("  Triangulating %d vertices.\n", vertices);
9783   }
9784   if (vertices == 2) {
9785     /* The triangulation of two vertices is an edge.  An edge is */
9786     /*   represented by two bounding triangles.                  */
9787     maketriangle(m, b, farleft);
9788     setorg(*farleft, sortarray[0]);
9789     setdest(*farleft, sortarray[1]);
9790     /* The apex is intentionally left NULL. */
9791     maketriangle(m, b, farright);
9792     setorg(*farright, sortarray[1]);
9793     setdest(*farright, sortarray[0]);
9794     /* The apex is intentionally left NULL. */
9795     bond(*farleft, *farright);
9796     lprevself(*farleft);
9797     lnextself(*farright);
9798     bond(*farleft, *farright);
9799     lprevself(*farleft);
9800     lnextself(*farright);
9801     bond(*farleft, *farright);
9802     if (b->verbose > 2) {
9803       printf("  Creating ");
9804       printtriangle(m, b, farleft);
9805       printf("  Creating ");
9806       printtriangle(m, b, farright);
9807     }
9808     /* Ensure that the origin of `farleft' is sortarray[0]. */
9809     lprev(*farright, *farleft);
9810     return;
9811   } else if (vertices == 3) {
9812     /* The triangulation of three vertices is either a triangle (with */
9813     /*   three bounding triangles) or two edges (with four bounding   */
9814     /*   triangles).  In either case, four triangles are created.     */
9815     maketriangle(m, b, &midtri);
9816     maketriangle(m, b, &tri1);
9817     maketriangle(m, b, &tri2);
9818     maketriangle(m, b, &tri3);
9819     area = counterclockwise(m, b, sortarray[0], sortarray[1], sortarray[2]);
9820     if (area == 0.0) {
9821       /* Three collinear vertices; the triangulation is two edges. */
9822       setorg(midtri, sortarray[0]);
9823       setdest(midtri, sortarray[1]);
9824       setorg(tri1, sortarray[1]);
9825       setdest(tri1, sortarray[0]);
9826       setorg(tri2, sortarray[2]);
9827       setdest(tri2, sortarray[1]);
9828       setorg(tri3, sortarray[1]);
9829       setdest(tri3, sortarray[2]);
9830       /* All apices are intentionally left NULL. */
9831       bond(midtri, tri1);
9832       bond(tri2, tri3);
9833       lnextself(midtri);
9834       lprevself(tri1);
9835       lnextself(tri2);
9836       lprevself(tri3);
9837       bond(midtri, tri3);
9838       bond(tri1, tri2);
9839       lnextself(midtri);
9840       lprevself(tri1);
9841       lnextself(tri2);
9842       lprevself(tri3);
9843       bond(midtri, tri1);
9844       bond(tri2, tri3);
9845       /* Ensure that the origin of `farleft' is sortarray[0]. */
9846       otricopy(tri1, *farleft);
9847       /* Ensure that the destination of `farright' is sortarray[2]. */
9848       otricopy(tri2, *farright);
9849     } else {
9850       /* The three vertices are not collinear; the triangulation is one */
9851       /*   triangle, namely `midtri'.                                   */
9852       setorg(midtri, sortarray[0]);
9853       setdest(tri1, sortarray[0]);
9854       setorg(tri3, sortarray[0]);
9855       /* Apices of tri1, tri2, and tri3 are left NULL. */
9856       if (area > 0.0) {
9857         /* The vertices are in counterclockwise order. */
9858         setdest(midtri, sortarray[1]);
9859         setorg(tri1, sortarray[1]);
9860         setdest(tri2, sortarray[1]);
9861         setapex(midtri, sortarray[2]);
9862         setorg(tri2, sortarray[2]);
9863         setdest(tri3, sortarray[2]);
9864       } else {
9865         /* The vertices are in clockwise order. */
9866         setdest(midtri, sortarray[2]);
9867         setorg(tri1, sortarray[2]);
9868         setdest(tri2, sortarray[2]);
9869         setapex(midtri, sortarray[1]);
9870         setorg(tri2, sortarray[1]);
9871         setdest(tri3, sortarray[1]);
9872       }
9873       /* The topology does not depend on how the vertices are ordered. */
9874       bond(midtri, tri1);
9875       lnextself(midtri);
9876       bond(midtri, tri2);
9877       lnextself(midtri);
9878       bond(midtri, tri3);
9879       lprevself(tri1);
9880       lnextself(tri2);
9881       bond(tri1, tri2);
9882       lprevself(tri1);
9883       lprevself(tri3);
9884       bond(tri1, tri3);
9885       lnextself(tri2);
9886       lprevself(tri3);
9887       bond(tri2, tri3);
9888       /* Ensure that the origin of `farleft' is sortarray[0]. */
9889       otricopy(tri1, *farleft);
9890       /* Ensure that the destination of `farright' is sortarray[2]. */
9891       if (area > 0.0) {
9892         otricopy(tri2, *farright);
9893       } else {
9894         lnext(*farleft, *farright);
9895       }
9896     }
9897     if (b->verbose > 2) {
9898       printf("  Creating ");
9899       printtriangle(m, b, &midtri);
9900       printf("  Creating ");
9901       printtriangle(m, b, &tri1);
9902       printf("  Creating ");
9903       printtriangle(m, b, &tri2);
9904       printf("  Creating ");
9905       printtriangle(m, b, &tri3);
9906     }
9907     return;
9908   } else {
9909     /* Split the vertices in half. */
9910     divider = vertices >> 1;
9911     /* Recursively triangulate each half. */
9912     divconqrecurse(m, b, sortarray, divider, 1 - axis, farleft, &innerleft);
9913     divconqrecurse(m, b, &sortarray[divider], vertices - divider, 1 - axis,
9914                    &innerright, farright);
9915     if (b->verbose > 1) {
9916       printf("  Joining triangulations with %d and %d vertices.\n", divider,
9917              vertices - divider);
9918     }
9919     /* Merge the two triangulations into one. */
9920     mergehulls(m, b, farleft, &innerleft, &innerright, farright, axis);
9921   }
9922 }
9923 
9924 #ifdef ANSI_DECLARATORS
9925 long removeghosts(struct mesh *m, struct behavior *b, struct otri *startghost)
9926 #else /* not ANSI_DECLARATORS */
9927 long removeghosts(m, b, startghost)
9928 struct mesh *m;
9929 struct behavior *b;
9930 struct otri *startghost;
9931 #endif /* not ANSI_DECLARATORS */
9932 
9933 {
9934   struct otri searchedge;
9935   struct otri dissolveedge;
9936   struct otri deadtriangle;
9937   vertex markorg;
9938   long hullsize;
9939   triangle ptr;                         /* Temporary variable used by sym(). */
9940 
9941   if (b->verbose) {
9942     printf("  Removing ghost triangles.\n");
9943   }
9944   /* Find an edge on the convex hull to start point location from. */
9945   lprev(*startghost, searchedge);
9946   symself(searchedge);
9947   m->dummytri[0] = encode(searchedge);
9948   /* Remove the bounding box and count the convex hull edges. */
9949   otricopy(*startghost, dissolveedge);
9950   hullsize = 0;
9951   do {
9952     hullsize++;
9953     lnext(dissolveedge, deadtriangle);
9954     lprevself(dissolveedge);
9955     symself(dissolveedge);
9956     /* If no PSLG is involved, set the boundary markers of all the vertices */
9957     /*   on the convex hull.  If a PSLG is used, this step is done later.   */
9958     if (!b->poly) {
9959       /* Watch out for the case where all the input vertices are collinear. */
9960       if (dissolveedge.tri != m->dummytri) {
9961         org(dissolveedge, markorg);
9962         if (vertexmark(markorg) == 0) {
9963           setvertexmark(markorg, 1);
9964         }
9965       }
9966     }
9967     /* Remove a bounding triangle from a convex hull triangle. */
9968     dissolve(dissolveedge);
9969     /* Find the next bounding triangle. */
9970     sym(deadtriangle, dissolveedge);
9971     /* Delete the bounding triangle. */
9972     triangledealloc(m, deadtriangle.tri);
9973   } while (!otriequal(dissolveedge, *startghost));
9974   return hullsize;
9975 }
9976 
9977 /*****************************************************************************/
9978 /*                                                                           */
9979 /*  divconqdelaunay()   Form a Delaunay triangulation by the divide-and-     */
9980 /*                      conquer method.                                      */
9981 /*                                                                           */
9982 /*  Sorts the vertices, calls a recursive procedure to triangulate them, and */
9983 /*  removes the bounding box, setting boundary markers as appropriate.       */
9984 /*                                                                           */
9985 /*****************************************************************************/
9986 
9987 #ifdef ANSI_DECLARATORS
9988 long divconqdelaunay(struct mesh *m, struct behavior *b)
9989 #else /* not ANSI_DECLARATORS */
9990 long divconqdelaunay(m, b)
9991 struct mesh *m;
9992 struct behavior *b;
9993 #endif /* not ANSI_DECLARATORS */
9994 
9995 {
9996   vertex *sortarray;
9997   struct otri hullleft, hullright;
9998   int divider;
9999   int i, j;
10000 
10001   if (b->verbose) {
10002     printf("  Sorting vertices.\n");
10003   }
10004 
10005   /* Allocate an array of pointers to vertices for sorting. */
10006   sortarray = (vertex *) trimalloc(m->invertices * (int) sizeof(vertex));
10007   traversalinit(&m->vertices);
10008   for (i = 0; i < m->invertices; i++) {
10009     sortarray[i] = vertextraverse(m);
10010   }
10011   /* Sort the vertices. */
10012   vertexsort(sortarray, m->invertices);
10013   /* Discard duplicate vertices, which can really mess up the algorithm. */
10014   i = 0;
10015   for (j = 1; j < m->invertices; j++) {
10016     if ((sortarray[i][0] == sortarray[j][0])
10017         && (sortarray[i][1] == sortarray[j][1])) {
10018       if (!b->quiet) {
10019         printf(
10020 "Warning:  A duplicate vertex at (%.12g, %.12g) appeared and was ignored.\n",
10021                (double)sortarray[j][0], (double)sortarray[j][1]);
10022       }
10023       setvertextype(sortarray[j], UNDEADVERTEX);
10024       m->undeads++;
10025     } else {
10026       i++;
10027       sortarray[i] = sortarray[j];
10028     }
10029   }
10030   i++;
10031   if (b->dwyer) {
10032     /* Re-sort the array of vertices to accommodate alternating cuts. */
10033     divider = i >> 1;
10034     if (i - divider >= 2) {
10035       if (divider >= 2) {
10036         alternateaxes(sortarray, divider, 1);
10037       }
10038       alternateaxes(&sortarray[divider], i - divider, 1);
10039     }
10040   }
10041 
10042   if (b->verbose) {
10043     printf("  Forming triangulation.\n");
10044   }
10045 
10046   /* Form the Delaunay triangulation. */
10047   divconqrecurse(m, b, sortarray, i, 0, &hullleft, &hullright);
10048   trifree((VOID *) sortarray);
10049 
10050   return removeghosts(m, b, &hullleft);
10051 }
10052 
10053 /**                                                                         **/
10054 /**                                                                         **/
10055 /********* Divide-and-conquer Delaunay triangulation ends here       *********/
10056 
10057 /********* Incremental Delaunay triangulation begins here            *********/
10058 /**                                                                         **/
10059 /**                                                                         **/
10060 
10061 /*****************************************************************************/
10062 /*                                                                           */
10063 /*  boundingbox()   Form an "infinite" bounding triangle to insert vertices  */
10064 /*                  into.                                                    */
10065 /*                                                                           */
10066 /*  The vertices at "infinity" are assigned finite coordinates, which are    */
10067 /*  used by the point location routines, but (mostly) ignored by the         */
10068 /*  Delaunay edge flip routines.                                             */
10069 /*                                                                           */
10070 /*****************************************************************************/
10071 
10072 #ifndef REDUCED
10073 
10074 #ifdef ANSI_DECLARATORS
10075 void boundingbox(struct mesh *m, struct behavior *b)
10076 #else /* not ANSI_DECLARATORS */
10077 void boundingbox(m, b)
10078 struct mesh *m;
10079 struct behavior *b;
10080 #endif /* not ANSI_DECLARATORS */
10081 
10082 {
10083   struct otri inftri;          /* Handle for the triangular bounding box. */
10084   REAL width;
10085 
10086   if (b->verbose) {
10087     printf("  Creating triangular bounding box.\n");
10088   }
10089   /* Find the width (or height, whichever is larger) of the triangulation. */
10090   width = m->xmax - m->xmin;
10091   if (m->ymax - m->ymin > width) {
10092     width = m->ymax - m->ymin;
10093   }
10094   if (width == 0.0) {
10095     width = 1.0;
10096   }
10097   /* Create the vertices of the bounding box. */
10098   m->infvertex1 = (vertex) trimalloc(m->vertices.itembytes);
10099   m->infvertex2 = (vertex) trimalloc(m->vertices.itembytes);
10100   m->infvertex3 = (vertex) trimalloc(m->vertices.itembytes);
10101   m->infvertex1[0] = m->xmin - 50.0 * width;
10102   m->infvertex1[1] = m->ymin - 40.0 * width;
10103   m->infvertex2[0] = m->xmax + 50.0 * width;
10104   m->infvertex2[1] = m->ymin - 40.0 * width;
10105   m->infvertex3[0] = 0.5 * (m->xmin + m->xmax);
10106   m->infvertex3[1] = m->ymax + 60.0 * width;
10107 
10108   /* Create the bounding box. */
10109   maketriangle(m, b, &inftri);
10110   setorg(inftri, m->infvertex1);
10111   setdest(inftri, m->infvertex2);
10112   setapex(inftri, m->infvertex3);
10113   /* Link dummytri to the bounding box so we can always find an */
10114   /*   edge to begin searching (point location) from.           */
10115   m->dummytri[0] = (triangle) inftri.tri;
10116   if (b->verbose > 2) {
10117     printf("  Creating ");
10118     printtriangle(m, b, &inftri);
10119   }
10120 }
10121 
10122 #endif /* not REDUCED */
10123 
10124 /*****************************************************************************/
10125 /*                                                                           */
10126 /*  removebox()   Remove the "infinite" bounding triangle, setting boundary  */
10127 /*                markers as appropriate.                                    */
10128 /*                                                                           */
10129 /*  The triangular bounding box has three boundary triangles (one for each   */
10130 /*  side of the bounding box), and a bunch of triangles fanning out from     */
10131 /*  the three bounding box vertices (one triangle for each edge of the       */
10132 /*  convex hull of the inner mesh).  This routine removes these triangles.   */
10133 /*                                                                           */
10134 /*  Returns the number of edges on the convex hull of the triangulation.     */
10135 /*                                                                           */
10136 /*****************************************************************************/
10137 
10138 #ifndef REDUCED
10139 
10140 #ifdef ANSI_DECLARATORS
10141 long removebox(struct mesh *m, struct behavior *b)
10142 #else /* not ANSI_DECLARATORS */
10143 long removebox(m, b)
10144 struct mesh *m;
10145 struct behavior *b;
10146 #endif /* not ANSI_DECLARATORS */
10147 
10148 {
10149   struct otri deadtriangle;
10150   struct otri searchedge;
10151   struct otri checkedge;
10152   struct otri nextedge, finaledge, dissolveedge;
10153   vertex markorg;
10154   long hullsize;
10155   triangle ptr;                         /* Temporary variable used by sym(). */
10156 
10157   if (b->verbose) {
10158     printf("  Removing triangular bounding box.\n");
10159   }
10160   /* Find a boundary triangle. */
10161   nextedge.tri = m->dummytri;
10162   nextedge.orient = 0;
10163   symself(nextedge);
10164   /* Mark a place to stop. */
10165   lprev(nextedge, finaledge);
10166   lnextself(nextedge);
10167   symself(nextedge);
10168   /* Find a triangle (on the boundary of the vertex set) that isn't */
10169   /*   a bounding box triangle.                                     */
10170   lprev(nextedge, searchedge);
10171   symself(searchedge);
10172   /* Check whether nextedge is another boundary triangle */
10173   /*   adjacent to the first one.                        */
10174   lnext(nextedge, checkedge);
10175   symself(checkedge);
10176   if (checkedge.tri == m->dummytri) {
10177     /* Go on to the next triangle.  There are only three boundary   */
10178     /*   triangles, and this next triangle cannot be the third one, */
10179     /*   so it's safe to stop here.                                 */
10180     lprevself(searchedge);
10181     symself(searchedge);
10182   }
10183   /* Find a new boundary edge to search from, as the current search */
10184   /*   edge lies on a bounding box triangle and will be deleted.    */
10185   m->dummytri[0] = encode(searchedge);
10186   hullsize = -2l;
10187   while (!otriequal(nextedge, finaledge)) {
10188     hullsize++;
10189     lprev(nextedge, dissolveedge);
10190     symself(dissolveedge);
10191     /* If not using a PSLG, the vertices should be marked now. */
10192     /*   (If using a PSLG, markhull() will do the job.)        */
10193     if (!b->poly) {
10194       /* Be careful!  One must check for the case where all the input     */
10195       /*   vertices are collinear, and thus all the triangles are part of */
10196       /*   the bounding box.  Otherwise, the setvertexmark() call below   */
10197       /*   will cause a bad pointer reference.                            */
10198       if (dissolveedge.tri != m->dummytri) {
10199         org(dissolveedge, markorg);
10200         if (vertexmark(markorg) == 0) {
10201           setvertexmark(markorg, 1);
10202         }
10203       }
10204     }
10205     /* Disconnect the bounding box triangle from the mesh triangle. */
10206     dissolve(dissolveedge);
10207     lnext(nextedge, deadtriangle);
10208     sym(deadtriangle, nextedge);
10209     /* Get rid of the bounding box triangle. */
10210     triangledealloc(m, deadtriangle.tri);
10211     /* Do we need to turn the corner? */
10212     if (nextedge.tri == m->dummytri) {
10213       /* Turn the corner. */
10214       otricopy(dissolveedge, nextedge);
10215     }
10216   }
10217   triangledealloc(m, finaledge.tri);
10218 
10219   trifree((VOID *) m->infvertex1);  /* Deallocate the bounding box vertices. */
10220   trifree((VOID *) m->infvertex2);
10221   trifree((VOID *) m->infvertex3);
10222 
10223   return hullsize;
10224 }
10225 
10226 #endif /* not REDUCED */
10227 
10228 /*****************************************************************************/
10229 /*                                                                           */
10230 /*  incrementaldelaunay()   Form a Delaunay triangulation by incrementally   */
10231 /*                          inserting vertices.                              */
10232 /*                                                                           */
10233 /*  Returns the number of edges on the convex hull of the triangulation.     */
10234 /*                                                                           */
10235 /*****************************************************************************/
10236 
10237 #ifndef REDUCED
10238 
10239 #ifdef ANSI_DECLARATORS
10240 long incrementaldelaunay(struct mesh *m, struct behavior *b)
10241 #else /* not ANSI_DECLARATORS */
10242 long incrementaldelaunay(m, b)
10243 struct mesh *m;
10244 struct behavior *b;
10245 #endif /* not ANSI_DECLARATORS */
10246 
10247 {
10248   struct otri starttri;
10249   vertex vertexloop;
10250 
10251   /* Create a triangular bounding box. */
10252   boundingbox(m, b);
10253   if (b->verbose) {
10254     printf("  Incrementally inserting vertices.\n");
10255   }
10256   traversalinit(&m->vertices);
10257   vertexloop = vertextraverse(m);
10258   while (vertexloop != (vertex) NULL) {
10259     starttri.tri = m->dummytri;
10260     if (insertvertex(m, b, vertexloop, &starttri, (struct osub *) NULL, 0, 0)
10261         == DUPLICATEVERTEX) {
10262       if (!b->quiet) {
10263         printf(
10264 "Warning:  A duplicate vertex at (%.12g, %.12g) appeared and was ignored.\n",
10265                (double)vertexloop[0], (double)vertexloop[1]);
10266       }
10267       setvertextype(vertexloop, UNDEADVERTEX);
10268       m->undeads++;
10269     }
10270     vertexloop = vertextraverse(m);
10271   }
10272   /* Remove the bounding box. */
10273   return removebox(m, b);
10274 }
10275 
10276 #endif /* not REDUCED */
10277 
10278 /**                                                                         **/
10279 /**                                                                         **/
10280 /********* Incremental Delaunay triangulation ends here              *********/
10281 
10282 /********* Sweepline Delaunay triangulation begins here              *********/
10283 /**                                                                         **/
10284 /**                                                                         **/
10285 
10286 #ifndef REDUCED
10287 
10288 #ifdef ANSI_DECLARATORS
10289 void eventheapinsert(struct event **heap, int heapsize, struct event *newevent)
10290 #else /* not ANSI_DECLARATORS */
10291 void eventheapinsert(heap, heapsize, newevent)
10292 struct event **heap;
10293 int heapsize;
10294 struct event *newevent;
10295 #endif /* not ANSI_DECLARATORS */
10296 
10297 {
10298   REAL eventx, eventy;
10299   int eventnum;
10300   int parent;
10301   int notdone;
10302 
10303   eventx = newevent->xkey;
10304   eventy = newevent->ykey;
10305   eventnum = heapsize;
10306   notdone = eventnum > 0;
10307   while (notdone) {
10308     parent = (eventnum - 1) >> 1;
10309     if ((heap[parent]->ykey < eventy) ||
10310         ((heap[parent]->ykey == eventy)
10311          && (heap[parent]->xkey <= eventx))) {
10312       notdone = 0;
10313     } else {
10314       heap[eventnum] = heap[parent];
10315       heap[eventnum]->heapposition = eventnum;
10316 
10317       eventnum = parent;
10318       notdone = eventnum > 0;
10319     }
10320   }
10321   heap[eventnum] = newevent;
10322   newevent->heapposition = eventnum;
10323 }
10324 
10325 #endif /* not REDUCED */
10326 
10327 #ifndef REDUCED
10328 
10329 #ifdef ANSI_DECLARATORS
10330 void eventheapify(struct event **heap, int heapsize, int eventnum)
10331 #else /* not ANSI_DECLARATORS */
10332 void eventheapify(heap, heapsize, eventnum)
10333 struct event **heap;
10334 int heapsize;
10335 int eventnum;
10336 #endif /* not ANSI_DECLARATORS */
10337 
10338 {
10339   struct event *thisevent;
10340   REAL eventx, eventy;
10341   int leftchild, rightchild;
10342   int smallest;
10343   int notdone;
10344 
10345   thisevent = heap[eventnum];
10346   eventx = thisevent->xkey;
10347   eventy = thisevent->ykey;
10348   leftchild = 2 * eventnum + 1;
10349   notdone = leftchild < heapsize;
10350   while (notdone) {
10351     if ((heap[leftchild]->ykey < eventy) ||
10352         ((heap[leftchild]->ykey == eventy)
10353          && (heap[leftchild]->xkey < eventx))) {
10354       smallest = leftchild;
10355     } else {
10356       smallest = eventnum;
10357     }
10358     rightchild = leftchild + 1;
10359     if (rightchild < heapsize) {
10360       if ((heap[rightchild]->ykey < heap[smallest]->ykey) ||
10361           ((heap[rightchild]->ykey == heap[smallest]->ykey)
10362            && (heap[rightchild]->xkey < heap[smallest]->xkey))) {
10363         smallest = rightchild;
10364       }
10365     }
10366     if (smallest == eventnum) {
10367       notdone = 0;
10368     } else {
10369       heap[eventnum] = heap[smallest];
10370       heap[eventnum]->heapposition = eventnum;
10371       heap[smallest] = thisevent;
10372       thisevent->heapposition = smallest;
10373 
10374       eventnum = smallest;
10375       leftchild = 2 * eventnum + 1;
10376       notdone = leftchild < heapsize;
10377     }
10378   }
10379 }
10380 
10381 #endif /* not REDUCED */
10382 
10383 #ifndef REDUCED
10384 
10385 #ifdef ANSI_DECLARATORS
10386 void eventheapdelete(struct event **heap, int heapsize, int eventnum)
10387 #else /* not ANSI_DECLARATORS */
10388 void eventheapdelete(heap, heapsize, eventnum)
10389 struct event **heap;
10390 int heapsize;
10391 int eventnum;
10392 #endif /* not ANSI_DECLARATORS */
10393 
10394 {
10395   struct event *moveevent;
10396   REAL eventx, eventy;
10397   int parent;
10398   int notdone;
10399 
10400   moveevent = heap[heapsize - 1];
10401   if (eventnum > 0) {
10402     eventx = moveevent->xkey;
10403     eventy = moveevent->ykey;
10404     do {
10405       parent = (eventnum - 1) >> 1;
10406       if ((heap[parent]->ykey < eventy) ||
10407           ((heap[parent]->ykey == eventy)
10408            && (heap[parent]->xkey <= eventx))) {
10409         notdone = 0;
10410       } else {
10411         heap[eventnum] = heap[parent];
10412         heap[eventnum]->heapposition = eventnum;
10413 
10414         eventnum = parent;
10415         notdone = eventnum > 0;
10416       }
10417     } while (notdone);
10418   }
10419   heap[eventnum] = moveevent;
10420   moveevent->heapposition = eventnum;
10421   eventheapify(heap, heapsize - 1, eventnum);
10422 }
10423 
10424 #endif /* not REDUCED */
10425 
10426 #ifndef REDUCED
10427 
10428 #ifdef ANSI_DECLARATORS
10429 void createeventheap(struct mesh *m, struct event ***eventheap,
10430                      struct event **events, struct event **freeevents)
10431 #else /* not ANSI_DECLARATORS */
10432 void createeventheap(m, eventheap, events, freeevents)
10433 struct mesh *m;
10434 struct event ***eventheap;
10435 struct event **events;
10436 struct event **freeevents;
10437 #endif /* not ANSI_DECLARATORS */
10438 
10439 {
10440   vertex thisvertex;
10441   int maxevents;
10442   int i;
10443 
10444   maxevents = (3 * m->invertices) / 2;
10445   *eventheap = (struct event **) trimalloc(maxevents *
10446                                            (int) sizeof(struct event *));
10447   *events = (struct event *) trimalloc(maxevents * (int) sizeof(struct event));
10448   traversalinit(&m->vertices);
10449   for (i = 0; i < m->invertices; i++) {
10450     thisvertex = vertextraverse(m);
10451     (*events)[i].eventptr = (VOID *) thisvertex;
10452     (*events)[i].xkey = thisvertex[0];
10453     (*events)[i].ykey = thisvertex[1];
10454     eventheapinsert(*eventheap, i, *events + i);
10455   }
10456   *freeevents = (struct event *) NULL;
10457   for (i = maxevents - 1; i >= m->invertices; i--) {
10458     (*events)[i].eventptr = (VOID *) *freeevents;
10459     *freeevents = *events + i;
10460   }
10461 }
10462 
10463 #endif /* not REDUCED */
10464 
10465 #ifndef REDUCED
10466 
10467 #ifdef ANSI_DECLARATORS
10468 int rightofhyperbola(struct mesh *m, struct otri *fronttri, vertex newsite)
10469 #else /* not ANSI_DECLARATORS */
10470 int rightofhyperbola(m, fronttri, newsite)
10471 struct mesh *m;
10472 struct otri *fronttri;
10473 vertex newsite;
10474 #endif /* not ANSI_DECLARATORS */
10475 
10476 {
10477   vertex leftvertex, rightvertex;
10478   REAL dxa, dya, dxb, dyb;
10479 
10480   m->hyperbolacount++;
10481 
10482   dest(*fronttri, leftvertex);
10483   apex(*fronttri, rightvertex);
10484   if ((leftvertex[1] < rightvertex[1]) ||
10485       ((leftvertex[1] == rightvertex[1]) &&
10486        (leftvertex[0] < rightvertex[0]))) {
10487     if (newsite[0] >= rightvertex[0]) {
10488       return 1;
10489     }
10490   } else {
10491     if (newsite[0] <= leftvertex[0]) {
10492       return 0;
10493     }
10494   }
10495   dxa = leftvertex[0] - newsite[0];
10496   dya = leftvertex[1] - newsite[1];
10497   dxb = rightvertex[0] - newsite[0];
10498   dyb = rightvertex[1] - newsite[1];
10499   return dya * (dxb * dxb + dyb * dyb) > dyb * (dxa * dxa + dya * dya);
10500 }
10501 
10502 #endif /* not REDUCED */
10503 
10504 #ifndef REDUCED
10505 
10506 #ifdef ANSI_DECLARATORS
10507 REAL circletop(struct mesh *m, vertex pa, vertex pb, vertex pc, REAL ccwabc)
10508 #else /* not ANSI_DECLARATORS */
10509 REAL circletop(m, pa, pb, pc, ccwabc)
10510 struct mesh *m;
10511 vertex pa;
10512 vertex pb;
10513 vertex pc;
10514 REAL ccwabc;
10515 #endif /* not ANSI_DECLARATORS */
10516 
10517 {
10518   REAL xac, yac, xbc, ybc, xab, yab;
10519   REAL aclen2, bclen2, ablen2;
10520 
10521   m->circletopcount++;
10522 
10523   xac = pa[0] - pc[0];
10524   yac = pa[1] - pc[1];
10525   xbc = pb[0] - pc[0];
10526   ybc = pb[1] - pc[1];
10527   xab = pa[0] - pb[0];
10528   yab = pa[1] - pb[1];
10529   aclen2 = xac * xac + yac * yac;
10530   bclen2 = xbc * xbc + ybc * ybc;
10531   ablen2 = xab * xab + yab * yab;
10532   return pc[1] + (xac * bclen2 - xbc * aclen2 + sqrt(aclen2 * bclen2 * ablen2))
10533                / (2.0 * ccwabc);
10534 }
10535 
10536 #endif /* not REDUCED */
10537 
10538 #ifndef REDUCED
10539 
10540 #ifdef ANSI_DECLARATORS
10541 void check4deadevent(struct otri *checktri, struct event **freeevents,
10542                      struct event **eventheap, int *heapsize)
10543 #else /* not ANSI_DECLARATORS */
10544 void check4deadevent(checktri, freeevents, eventheap, heapsize)
10545 struct otri *checktri;
10546 struct event **freeevents;
10547 struct event **eventheap;
10548 int *heapsize;
10549 #endif /* not ANSI_DECLARATORS */
10550 
10551 {
10552   struct event *deadevent;
10553   vertex eventvertex;
10554   int eventnum;
10555 
10556   org(*checktri, eventvertex);
10557   if (eventvertex != (vertex) NULL) {
10558     deadevent = (struct event *) eventvertex;
10559     eventnum = deadevent->heapposition;
10560     deadevent->eventptr = (VOID *) *freeevents;
10561     *freeevents = deadevent;
10562     eventheapdelete(eventheap, *heapsize, eventnum);
10563     (*heapsize)--;
10564     setorg(*checktri, NULL);
10565   }
10566 }
10567 
10568 #endif /* not REDUCED */
10569 
10570 #ifndef REDUCED
10571 
10572 #ifdef ANSI_DECLARATORS
10573 struct splaynode *splay(struct mesh *m, struct splaynode *splaytree,
10574                         vertex searchpoint, struct otri *searchtri)
10575 #else /* not ANSI_DECLARATORS */
10576 struct splaynode *splay(m, splaytree, searchpoint, searchtri)
10577 struct mesh *m;
10578 struct splaynode *splaytree;
10579 vertex searchpoint;
10580 struct otri *searchtri;
10581 #endif /* not ANSI_DECLARATORS */
10582 
10583 {
10584   struct splaynode *child, *grandchild;
10585   struct splaynode *lefttree, *righttree;
10586   struct splaynode *leftright;
10587   vertex checkvertex;
10588   int rightofroot, rightofchild;
10589 
10590   if (splaytree == (struct splaynode *) NULL) {
10591     return (struct splaynode *) NULL;
10592   }
10593   dest(splaytree->keyedge, checkvertex);
10594   if (checkvertex == splaytree->keydest) {
10595     rightofroot = rightofhyperbola(m, &splaytree->keyedge, searchpoint);
10596     if (rightofroot) {
10597       otricopy(splaytree->keyedge, *searchtri);
10598       child = splaytree->rchild;
10599     } else {
10600       child = splaytree->lchild;
10601     }
10602     if (child == (struct splaynode *) NULL) {
10603       return splaytree;
10604     }
10605     dest(child->keyedge, checkvertex);
10606     if (checkvertex != child->keydest) {
10607       child = splay(m, child, searchpoint, searchtri);
10608       if (child == (struct splaynode *) NULL) {
10609         if (rightofroot) {
10610           splaytree->rchild = (struct splaynode *) NULL;
10611         } else {
10612           splaytree->lchild = (struct splaynode *) NULL;
10613         }
10614         return splaytree;
10615       }
10616     }
10617     rightofchild = rightofhyperbola(m, &child->keyedge, searchpoint);
10618     if (rightofchild) {
10619       otricopy(child->keyedge, *searchtri);
10620       grandchild = splay(m, child->rchild, searchpoint, searchtri);
10621       child->rchild = grandchild;
10622     } else {
10623       grandchild = splay(m, child->lchild, searchpoint, searchtri);
10624       child->lchild = grandchild;
10625     }
10626     if (grandchild == (struct splaynode *) NULL) {
10627       if (rightofroot) {
10628         splaytree->rchild = child->lchild;
10629         child->lchild = splaytree;
10630       } else {
10631         splaytree->lchild = child->rchild;
10632         child->rchild = splaytree;
10633       }
10634       return child;
10635     }
10636     if (rightofchild) {
10637       if (rightofroot) {
10638         splaytree->rchild = child->lchild;
10639         child->lchild = splaytree;
10640       } else {
10641         splaytree->lchild = grandchild->rchild;
10642         grandchild->rchild = splaytree;
10643       }
10644       child->rchild = grandchild->lchild;
10645       grandchild->lchild = child;
10646     } else {
10647       if (rightofroot) {
10648         splaytree->rchild = grandchild->lchild;
10649         grandchild->lchild = splaytree;
10650       } else {
10651         splaytree->lchild = child->rchild;
10652         child->rchild = splaytree;
10653       }
10654       child->lchild = grandchild->rchild;
10655       grandchild->rchild = child;
10656     }
10657     return grandchild;
10658   } else {
10659     lefttree = splay(m, splaytree->lchild, searchpoint, searchtri);
10660     righttree = splay(m, splaytree->rchild, searchpoint, searchtri);
10661 
10662     pooldealloc(&m->splaynodes, (VOID *) splaytree);
10663     if (lefttree == (struct splaynode *) NULL) {
10664       return righttree;
10665     } else if (righttree == (struct splaynode *) NULL) {
10666       return lefttree;
10667     } else if (lefttree->rchild == (struct splaynode *) NULL) {
10668       lefttree->rchild = righttree->lchild;
10669       righttree->lchild = lefttree;
10670       return righttree;
10671     } else if (righttree->lchild == (struct splaynode *) NULL) {
10672       righttree->lchild = lefttree->rchild;
10673       lefttree->rchild = righttree;
10674       return lefttree;
10675     } else {
10676 /*      printf("Holy Toledo!!!\n"); */
10677       leftright = lefttree->rchild;
10678       while (leftright->rchild != (struct splaynode *) NULL) {
10679         leftright = leftright->rchild;
10680       }
10681       leftright->rchild = righttree;
10682       return lefttree;
10683     }
10684   }
10685 }
10686 
10687 #endif /* not REDUCED */
10688 
10689 #ifndef REDUCED
10690 
10691 #ifdef ANSI_DECLARATORS
10692 struct splaynode *splayinsert(struct mesh *m, struct splaynode *splayroot,
10693                               struct otri *newkey, vertex searchpoint)
10694 #else /* not ANSI_DECLARATORS */
10695 struct splaynode *splayinsert(m, splayroot, newkey, searchpoint)
10696 struct mesh *m;
10697 struct splaynode *splayroot;
10698 struct otri *newkey;
10699 vertex searchpoint;
10700 #endif /* not ANSI_DECLARATORS */
10701 
10702 {
10703   struct splaynode *newsplaynode;
10704 
10705   newsplaynode = (struct splaynode *) poolalloc(&m->splaynodes);
10706   otricopy(*newkey, newsplaynode->keyedge);
10707   dest(*newkey, newsplaynode->keydest);
10708   if (splayroot == (struct splaynode *) NULL) {
10709     newsplaynode->lchild = (struct splaynode *) NULL;
10710     newsplaynode->rchild = (struct splaynode *) NULL;
10711   } else if (rightofhyperbola(m, &splayroot->keyedge, searchpoint)) {
10712     newsplaynode->lchild = splayroot;
10713     newsplaynode->rchild = splayroot->rchild;
10714     splayroot->rchild = (struct splaynode *) NULL;
10715   } else {
10716     newsplaynode->lchild = splayroot->lchild;
10717     newsplaynode->rchild = splayroot;
10718     splayroot->lchild = (struct splaynode *) NULL;
10719   }
10720   return newsplaynode;
10721 }
10722 
10723 #endif /* not REDUCED */
10724 
10725 #ifndef REDUCED
10726 
10727 #ifdef ANSI_DECLARATORS
10728 struct splaynode *circletopinsert(struct mesh *m, struct behavior *b,
10729                                   struct splaynode *splayroot,
10730                                   struct otri *newkey,
10731                                   vertex pa, vertex pb, vertex pc, REAL topy)
10732 #else /* not ANSI_DECLARATORS */
10733 struct splaynode *circletopinsert(m, b, splayroot, newkey, pa, pb, pc, topy)
10734 struct mesh *m;
10735 struct behavior *b;
10736 struct splaynode *splayroot;
10737 struct otri *newkey;
10738 vertex pa;
10739 vertex pb;
10740 vertex pc;
10741 REAL topy;
10742 #endif /* not ANSI_DECLARATORS */
10743 
10744 {
10745   REAL ccwabc;
10746   REAL xac, yac, xbc, ybc;
10747   REAL aclen2, bclen2;
10748   REAL searchpoint[2];
10749   struct otri dummytri;
10750 
10751   ccwabc = counterclockwise(m, b, pa, pb, pc);
10752   xac = pa[0] - pc[0];
10753   yac = pa[1] - pc[1];
10754   xbc = pb[0] - pc[0];
10755   ybc = pb[1] - pc[1];
10756   aclen2 = xac * xac + yac * yac;
10757   bclen2 = xbc * xbc + ybc * ybc;
10758   searchpoint[0] = pc[0] - (yac * bclen2 - ybc * aclen2) / (2.0 * ccwabc);
10759   searchpoint[1] = topy;
10760   return splayinsert(m, splay(m, splayroot, (vertex) searchpoint, &dummytri),
10761                      newkey, (vertex) searchpoint);
10762 }
10763 
10764 #endif /* not REDUCED */
10765 
10766 #ifndef REDUCED
10767 
10768 #ifdef ANSI_DECLARATORS
10769 struct splaynode *frontlocate(struct mesh *m, struct splaynode *splayroot,
10770                               struct otri *bottommost, vertex searchvertex,
10771                               struct otri *searchtri, int *farright)
10772 #else /* not ANSI_DECLARATORS */
10773 struct splaynode *frontlocate(m, splayroot, bottommost, searchvertex,
10774                               searchtri, farright)
10775 struct mesh *m;
10776 struct splaynode *splayroot;
10777 struct otri *bottommost;
10778 vertex searchvertex;
10779 struct otri *searchtri;
10780 int *farright;
10781 #endif /* not ANSI_DECLARATORS */
10782 
10783 {
10784   int farrightflag;
10785   triangle ptr;                       /* Temporary variable used by onext(). */
10786 
10787   otricopy(*bottommost, *searchtri);
10788   splayroot = splay(m, splayroot, searchvertex, searchtri);
10789 
10790   farrightflag = 0;
10791   while (!farrightflag && rightofhyperbola(m, searchtri, searchvertex)) {
10792     onextself(*searchtri);
10793     farrightflag = otriequal(*searchtri, *bottommost);
10794   }
10795   *farright = farrightflag;
10796   return splayroot;
10797 }
10798 
10799 #endif /* not REDUCED */
10800 
10801 #ifndef REDUCED
10802 
10803 #ifdef ANSI_DECLARATORS
10804 long sweeplinedelaunay(struct mesh *m, struct behavior *b)
10805 #else /* not ANSI_DECLARATORS */
10806 long sweeplinedelaunay(m, b)
10807 struct mesh *m;
10808 struct behavior *b;
10809 #endif /* not ANSI_DECLARATORS */
10810 
10811 {
10812   struct event **eventheap;
10813   struct event *events;
10814   struct event *freeevents;
10815   struct event *nextevent;
10816   struct event *newevent;
10817   struct splaynode *splayroot;
10818   struct otri bottommost;
10819   struct otri searchtri;
10820   struct otri fliptri;
10821   struct otri lefttri, righttri, farlefttri, farrighttri;
10822   struct otri inserttri;
10823   vertex firstvertex, secondvertex;
10824   vertex nextvertex, lastvertex;
10825   vertex connectvertex;
10826   vertex leftvertex, midvertex, rightvertex;
10827   REAL lefttest, righttest;
10828   int heapsize;
10829   int check4events, farrightflag;
10830   triangle ptr;   /* Temporary variable used by sym(), onext(), and oprev(). */
10831 
10832   poolinit(&m->splaynodes, sizeof(struct splaynode), SPLAYNODEPERBLOCK,
10833            SPLAYNODEPERBLOCK, 0);
10834   splayroot = (struct splaynode *) NULL;
10835 
10836   if (b->verbose) {
10837     printf("  Placing vertices in event heap.\n");
10838   }
10839   createeventheap(m, &eventheap, &events, &freeevents);
10840   heapsize = m->invertices;
10841 
10842   if (b->verbose) {
10843     printf("  Forming triangulation.\n");
10844   }
10845   maketriangle(m, b, &lefttri);
10846   maketriangle(m, b, &righttri);
10847   bond(lefttri, righttri);
10848   lnextself(lefttri);
10849   lprevself(righttri);
10850   bond(lefttri, righttri);
10851   lnextself(lefttri);
10852   lprevself(righttri);
10853   bond(lefttri, righttri);
10854   firstvertex = (vertex) eventheap[0]->eventptr;
10855   eventheap[0]->eventptr = (VOID *) freeevents;
10856   freeevents = eventheap[0];
10857   eventheapdelete(eventheap, heapsize, 0);
10858   heapsize--;
10859   do {
10860     if (heapsize == 0) {
10861       printf("Error:  Input vertices are all identical.\n");
10862       triexit(1);
10863     }
10864     secondvertex = (vertex) eventheap[0]->eventptr;
10865     eventheap[0]->eventptr = (VOID *) freeevents;
10866     freeevents = eventheap[0];
10867     eventheapdelete(eventheap, heapsize, 0);
10868     heapsize--;
10869     if ((firstvertex[0] == secondvertex[0]) &&
10870         (firstvertex[1] == secondvertex[1])) {
10871       if (!b->quiet) {
10872         printf(
10873 "Warning:  A duplicate vertex at (%.12g, %.12g) appeared and was ignored.\n",
10874                (double)secondvertex[0], (double)secondvertex[1]);
10875       }
10876       setvertextype(secondvertex, UNDEADVERTEX);
10877       m->undeads++;
10878     }
10879   } while ((firstvertex[0] == secondvertex[0]) &&
10880            (firstvertex[1] == secondvertex[1]));
10881   setorg(lefttri, firstvertex);
10882   setdest(lefttri, secondvertex);
10883   setorg(righttri, secondvertex);
10884   setdest(righttri, firstvertex);
10885   lprev(lefttri, bottommost);
10886   lastvertex = secondvertex;
10887   while (heapsize > 0) {
10888     nextevent = eventheap[0];
10889     eventheapdelete(eventheap, heapsize, 0);
10890     heapsize--;
10891     check4events = 1;
10892     if (nextevent->xkey < m->xmin) {
10893       decode(nextevent->eventptr, fliptri);
10894       oprev(fliptri, farlefttri);
10895       check4deadevent(&farlefttri, &freeevents, eventheap, &heapsize);
10896       onext(fliptri, farrighttri);
10897       check4deadevent(&farrighttri, &freeevents, eventheap, &heapsize);
10898 
10899       if (otriequal(farlefttri, bottommost)) {
10900         lprev(fliptri, bottommost);
10901       }
10902       flip(m, b, &fliptri);
10903       setapex(fliptri, NULL);
10904       lprev(fliptri, lefttri);
10905       lnext(fliptri, righttri);
10906       sym(lefttri, farlefttri);
10907 
10908       if (randomnation(SAMPLERATE) == 0) {
10909         symself(fliptri);
10910         dest(fliptri, leftvertex);
10911         apex(fliptri, midvertex);
10912         org(fliptri, rightvertex);
10913         splayroot = circletopinsert(m, b, splayroot, &lefttri, leftvertex,
10914                                     midvertex, rightvertex, nextevent->ykey);
10915       }
10916     } else {
10917       nextvertex = (vertex) nextevent->eventptr;
10918       if ((nextvertex[0] == lastvertex[0]) &&
10919           (nextvertex[1] == lastvertex[1])) {
10920         if (!b->quiet) {
10921           printf(
10922 "Warning:  A duplicate vertex at (%.12g, %.12g) appeared and was ignored.\n",
10923                  (double)nextvertex[0], (double)nextvertex[1]);
10924         }
10925         setvertextype(nextvertex, UNDEADVERTEX);
10926         m->undeads++;
10927         check4events = 0;
10928       } else {
10929         lastvertex = nextvertex;
10930 
10931         splayroot = frontlocate(m, splayroot, &bottommost, nextvertex,
10932                                 &searchtri, &farrightflag);
10933 /*
10934         otricopy(bottommost, searchtri);
10935         farrightflag = 0;
10936         while (!farrightflag && rightofhyperbola(m, &searchtri, nextvertex)) {
10937           onextself(searchtri);
10938           farrightflag = otriequal(searchtri, bottommost);
10939         }
10940 */
10941 
10942         check4deadevent(&searchtri, &freeevents, eventheap, &heapsize);
10943 
10944         otricopy(searchtri, farrighttri);
10945         sym(searchtri, farlefttri);
10946         maketriangle(m, b, &lefttri);
10947         maketriangle(m, b, &righttri);
10948         dest(farrighttri, connectvertex);
10949         setorg(lefttri, connectvertex);
10950         setdest(lefttri, nextvertex);
10951         setorg(righttri, nextvertex);
10952         setdest(righttri, connectvertex);
10953         bond(lefttri, righttri);
10954         lnextself(lefttri);
10955         lprevself(righttri);
10956         bond(lefttri, righttri);
10957         lnextself(lefttri);
10958         lprevself(righttri);
10959         bond(lefttri, farlefttri);
10960         bond(righttri, farrighttri);
10961         if (!farrightflag && otriequal(farrighttri, bottommost)) {
10962           otricopy(lefttri, bottommost);
10963         }
10964 
10965         if (randomnation(SAMPLERATE) == 0) {
10966           splayroot = splayinsert(m, splayroot, &lefttri, nextvertex);
10967         } else if (randomnation(SAMPLERATE) == 0) {
10968           lnext(righttri, inserttri);
10969           splayroot = splayinsert(m, splayroot, &inserttri, nextvertex);
10970         }
10971       }
10972     }
10973     nextevent->eventptr = (VOID *) freeevents;
10974     freeevents = nextevent;
10975 
10976     if (check4events) {
10977       apex(farlefttri, leftvertex);
10978       dest(lefttri, midvertex);
10979       apex(lefttri, rightvertex);
10980       lefttest = counterclockwise(m, b, leftvertex, midvertex, rightvertex);
10981       if (lefttest > 0.0) {
10982         newevent = freeevents;
10983         freeevents = (struct event *) freeevents->eventptr;
10984         newevent->xkey = m->xminextreme;
10985         newevent->ykey = circletop(m, leftvertex, midvertex, rightvertex,
10986                                    lefttest);
10987         newevent->eventptr = (VOID *) encode(lefttri);
10988         eventheapinsert(eventheap, heapsize, newevent);
10989         heapsize++;
10990         setorg(lefttri, newevent);
10991       }
10992       apex(righttri, leftvertex);
10993       org(righttri, midvertex);
10994       apex(farrighttri, rightvertex);
10995       righttest = counterclockwise(m, b, leftvertex, midvertex, rightvertex);
10996       if (righttest > 0.0) {
10997         newevent = freeevents;
10998         freeevents = (struct event *) freeevents->eventptr;
10999         newevent->xkey = m->xminextreme;
11000         newevent->ykey = circletop(m, leftvertex, midvertex, rightvertex,
11001                                    righttest);
11002         newevent->eventptr = (VOID *) encode(farrighttri);
11003         eventheapinsert(eventheap, heapsize, newevent);
11004         heapsize++;
11005         setorg(farrighttri, newevent);
11006       }
11007     }
11008   }
11009 
11010   pooldeinit(&m->splaynodes);
11011   lprevself(bottommost);
11012   return removeghosts(m, b, &bottommost);
11013 }
11014 
11015 #endif /* not REDUCED */
11016 
11017 /**                                                                         **/
11018 /**                                                                         **/
11019 /********* Sweepline Delaunay triangulation ends here                *********/
11020 
11021 /********* General mesh construction routines begin here             *********/
11022 /**                                                                         **/
11023 /**                                                                         **/
11024 
11025 /*****************************************************************************/
11026 /*                                                                           */
11027 /*  delaunay()   Form a Delaunay triangulation.                              */
11028 /*                                                                           */
11029 /*****************************************************************************/
11030 
11031 #ifdef ANSI_DECLARATORS
11032 long delaunay(struct mesh *m, struct behavior *b)
11033 #else /* not ANSI_DECLARATORS */
11034 long delaunay(m, b)
11035 struct mesh *m;
11036 struct behavior *b;
11037 #endif /* not ANSI_DECLARATORS */
11038 
11039 {
11040   long hulledges;
11041 
11042   m->eextras = 0;
11043   initializetrisubpools(m, b);
11044 
11045 #ifdef REDUCED
11046   if (!b->quiet) {
11047     printf(
11048       "Constructing Delaunay triangulation by divide-and-conquer method.\n");
11049   }
11050   hulledges = divconqdelaunay(m, b);
11051 #else /* not REDUCED */
11052   if (!b->quiet) {
11053     printf("Constructing Delaunay triangulation ");
11054     if (b->incremental) {
11055       printf("by incremental method.\n");
11056     } else if (b->sweepline) {
11057       printf("by sweepline method.\n");
11058     } else {
11059       printf("by divide-and-conquer method.\n");
11060     }
11061   }
11062   if (b->incremental) {
11063     hulledges = incrementaldelaunay(m, b);
11064   } else if (b->sweepline) {
11065     hulledges = sweeplinedelaunay(m, b);
11066   } else {
11067     hulledges = divconqdelaunay(m, b);
11068   }
11069 #endif /* not REDUCED */
11070 
11071   if (m->triangles.items == 0) {
11072     /* The input vertices were all collinear, so there are no triangles. */
11073     return 0l;
11074   } else {
11075     return hulledges;
11076   }
11077 }
11078 
11079 /*****************************************************************************/
11080 /*                                                                           */
11081 /*  reconstruct()   Reconstruct a triangulation from its .ele (and possibly  */
11082 /*                  .poly) file.  Used when the -r switch is used.           */
11083 /*                                                                           */
11084 /*  Reads an .ele file and reconstructs the original mesh.  If the -p switch */
11085 /*  is used, this procedure will also read a .poly file and reconstruct the  */
11086 /*  subsegments of the original mesh.  If the -a switch is used, this        */
11087 /*  procedure will also read an .area file and set a maximum area constraint */
11088 /*  on each triangle.                                                        */
11089 /*                                                                           */
11090 /*  Vertices that are not corners of triangles, such as nodes on edges of    */
11091 /*  subparametric elements, are discarded.                                   */
11092 /*                                                                           */
11093 /*  This routine finds the adjacencies between triangles (and subsegments)   */
11094 /*  by forming one stack of triangles for each vertex.  Each triangle is on  */
11095 /*  three different stacks simultaneously.  Each triangle's subsegment       */
11096 /*  pointers are used to link the items in each stack.  This memory-saving   */
11097 /*  feature makes the code harder to read.  The most important thing to keep */
11098 /*  in mind is that each triangle is removed from a stack precisely when     */
11099 /*  the corresponding pointer is adjusted to refer to a subsegment rather    */
11100 /*  than the next triangle of the stack.                                     */
11101 /*                                                                           */
11102 /*****************************************************************************/
11103 
11104 #ifndef CDT_ONLY
11105 
11106 #ifdef TRILIBRARY
11107 
11108 #ifdef ANSI_DECLARATORS
11109 int reconstruct(struct mesh *m, struct behavior *b, int *trianglelist,
11110                 REAL *triangleattriblist, REAL *trianglearealist,
11111                 int elements, int corners, int attribs,
11112                 int *segmentlist,int *segmentmarkerlist, int numberofsegments)
11113 #else /* not ANSI_DECLARATORS */
11114 int reconstruct(m, b, trianglelist, triangleattriblist, trianglearealist,
11115                 elements, corners, attribs, segmentlist, segmentmarkerlist,
11116                 numberofsegments)
11117 struct mesh *m;
11118 struct behavior *b;
11119 int *trianglelist;
11120 REAL *triangleattriblist;
11121 REAL *trianglearealist;
11122 int elements;
11123 int corners;
11124 int attribs;
11125 int *segmentlist;
11126 int *segmentmarkerlist;
11127 int numberofsegments;
11128 #endif /* not ANSI_DECLARATORS */
11129 
11130 #else /* not TRILIBRARY */
11131 
11132 #ifdef ANSI_DECLARATORS
11133 long reconstruct(struct mesh *m, struct behavior *b, char *elefilename,
11134                  char *areafilename, char *polyfilename, FILE *polyfile)
11135 #else /* not ANSI_DECLARATORS */
11136 long reconstruct(m, b, elefilename, areafilename, polyfilename, polyfile)
11137 struct mesh *m;
11138 struct behavior *b;
11139 char *elefilename;
11140 char *areafilename;
11141 char *polyfilename;
11142 FILE *polyfile;
11143 #endif /* not ANSI_DECLARATORS */
11144 
11145 #endif /* not TRILIBRARY */
11146 
11147 {
11148 #ifdef TRILIBRARY
11149   int vertexindex;
11150   int attribindex;
11151 #else /* not TRILIBRARY */
11152   FILE *elefile;
11153   FILE *areafile;
11154   char inputline[INPUTLINESIZE];
11155   char *stringptr;
11156   int areaelements;
11157 #endif /* not TRILIBRARY */
11158   struct otri triangleloop;
11159   struct otri triangleleft;
11160   struct otri checktri;
11161   struct otri checkleft;
11162   struct otri checkneighbor;
11163   struct osub subsegloop;
11164   triangle *vertexarray;
11165   triangle *prevlink;
11166   triangle nexttri;
11167   vertex tdest, tapex;
11168   vertex checkdest, checkapex;
11169   vertex shorg;
11170   vertex killvertex;
11171   vertex segmentorg, segmentdest;
11172   REAL area;
11173   int corner[3];
11174   int end[2];
11175   int killvertexindex;
11176   int incorners;
11177   int segmentmarkers;
11178   int boundmarker;
11179   int aroundvertex;
11180   long hullsize;
11181   int notfound;
11182   long elementnumber, segmentnumber;
11183   int i, j;
11184   triangle ptr;                         /* Temporary variable used by sym(). */
11185 
11186 #ifdef TRILIBRARY
11187   m->inelements = elements;
11188   incorners = corners;
11189   if (incorners < 3) {
11190     printf("Error:  Triangles must have at least 3 vertices.\n");
11191     triexit(1);
11192   }
11193   m->eextras = attribs;
11194 #else /* not TRILIBRARY */
11195   /* Read the triangles from an .ele file. */
11196   if (!b->quiet) {
11197     printf("Opening %s.\n", elefilename);
11198   }
11199   elefile = fopen(elefilename, "r");
11200   if (elefile == (FILE *) NULL) {
11201     printf("  Error:  Cannot access file %s.\n", elefilename);
11202     triexit(1);
11203   }
11204   /* Read number of triangles, number of vertices per triangle, and */
11205   /*   number of triangle attributes from .ele file.                */
11206   stringptr = readline(inputline, elefile, elefilename);
11207   m->inelements = (int) strtol(stringptr, &stringptr, 0);
11208   stringptr = findfield(stringptr);
11209   if (*stringptr == '\0') {
11210     incorners = 3;
11211   } else {
11212     incorners = (int) strtol(stringptr, &stringptr, 0);
11213     if (incorners < 3) {
11214       printf("Error:  Triangles in %s must have at least 3 vertices.\n",
11215              elefilename);
11216       triexit(1);
11217     }
11218   }
11219   stringptr = findfield(stringptr);
11220   if (*stringptr == '\0') {
11221     m->eextras = 0;
11222   } else {
11223     m->eextras = (int) strtol(stringptr, &stringptr, 0);
11224   }
11225 #endif /* not TRILIBRARY */
11226 
11227   initializetrisubpools(m, b);
11228 
11229   /* Create the triangles. */
11230   for (elementnumber = 1; elementnumber <= m->inelements; elementnumber++) {
11231     maketriangle(m, b, &triangleloop);
11232     /* Mark the triangle as living. */
11233     triangleloop.tri[3] = (triangle) triangleloop.tri;
11234   }
11235 
11236   segmentmarkers = 0;
11237   if (b->poly) {
11238 #ifdef TRILIBRARY
11239     m->insegments = numberofsegments;
11240     segmentmarkers = segmentmarkerlist != (int *) NULL;
11241 #else /* not TRILIBRARY */
11242     /* Read number of segments and number of segment */
11243     /*   boundary markers from .poly file.           */
11244     stringptr = readline(inputline, polyfile, b->inpolyfilename);
11245     m->insegments = (int) strtol(stringptr, &stringptr, 0);
11246     stringptr = findfield(stringptr);
11247     if (*stringptr != '\0') {
11248       segmentmarkers = (int) strtol(stringptr, &stringptr, 0);
11249     }
11250 #endif /* not TRILIBRARY */
11251 
11252     /* Create the subsegments. */
11253     for (segmentnumber = 1; segmentnumber <= m->insegments; segmentnumber++) {
11254       makesubseg(m, &subsegloop);
11255       /* Mark the subsegment as living. */
11256       subsegloop.ss[2] = (subseg) subsegloop.ss;
11257     }
11258   }
11259 
11260 #ifdef TRILIBRARY
11261   vertexindex = 0;
11262   attribindex = 0;
11263 #else /* not TRILIBRARY */
11264   if (b->vararea) {
11265     /* Open an .area file, check for consistency with the .ele file. */
11266     if (!b->quiet) {
11267       printf("Opening %s.\n", areafilename);
11268     }
11269     areafile = fopen(areafilename, "r");
11270     if (areafile == (FILE *) NULL) {
11271       printf("  Error:  Cannot access file %s.\n", areafilename);
11272       triexit(1);
11273     }
11274     stringptr = readline(inputline, areafile, areafilename);
11275     areaelements = (int) strtol(stringptr, &stringptr, 0);
11276     if (areaelements != m->inelements) {
11277       printf("Error:  %s and %s disagree on number of triangles.\n",
11278              elefilename, areafilename);
11279       triexit(1);
11280     }
11281   }
11282 #endif /* not TRILIBRARY */
11283 
11284   if (!b->quiet) {
11285     printf("Reconstructing mesh.\n");
11286   }
11287   /* Allocate a temporary array that maps each vertex to some adjacent */
11288   /*   triangle.  I took care to allocate all the permanent memory for */
11289   /*   triangles and subsegments first.                                */
11290   vertexarray = (triangle *) trimalloc(m->vertices.items *
11291                                        (int) sizeof(triangle));
11292   /* Each vertex is initially unrepresented. */
11293   for (i = 0; i < m->vertices.items; i++) {
11294     vertexarray[i] = (triangle) m->dummytri;
11295   }
11296 
11297   if (b->verbose) {
11298     printf("  Assembling triangles.\n");
11299   }
11300   /* Read the triangles from the .ele file, and link */
11301   /*   together those that share an edge.            */
11302   traversalinit(&m->triangles);
11303   triangleloop.tri = triangletraverse(m);
11304   elementnumber = b->firstnumber;
11305   while (triangleloop.tri != (triangle *) NULL) {
11306 #ifdef TRILIBRARY
11307     /* Copy the triangle's three corners. */
11308     for (j = 0; j < 3; j++) {
11309       corner[j] = trianglelist[vertexindex++];
11310       if ((corner[j] < b->firstnumber) ||
11311           (corner[j] >= b->firstnumber + m->invertices)) {
11312         printf("Error:  Triangle %ld has an invalid vertex index.\n",
11313                elementnumber);
11314         triexit(1);
11315       }
11316     }
11317 #else /* not TRILIBRARY */
11318     /* Read triangle number and the triangle's three corners. */
11319     stringptr = readline(inputline, elefile, elefilename);
11320     for (j = 0; j < 3; j++) {
11321       stringptr = findfield(stringptr);
11322       if (*stringptr == '\0') {
11323         printf("Error:  Triangle %ld is missing vertex %d in %s.\n",
11324                elementnumber, j + 1, elefilename);
11325         triexit(1);
11326       } else {
11327         corner[j] = (int) strtol(stringptr, &stringptr, 0);
11328         if ((corner[j] < b->firstnumber) ||
11329             (corner[j] >= b->firstnumber + m->invertices)) {
11330           printf("Error:  Triangle %ld has an invalid vertex index.\n",
11331                  elementnumber);
11332           triexit(1);
11333         }
11334       }
11335     }
11336 #endif /* not TRILIBRARY */
11337 
11338     /* Find out about (and throw away) extra nodes. */
11339     for (j = 3; j < incorners; j++) {
11340 #ifdef TRILIBRARY
11341       killvertexindex = trianglelist[vertexindex++];
11342 #else /* not TRILIBRARY */
11343       stringptr = findfield(stringptr);
11344       if (*stringptr != '\0') {
11345         killvertexindex = (int) strtol(stringptr, &stringptr, 0);
11346 #endif /* not TRILIBRARY */
11347         if ((killvertexindex >= b->firstnumber) &&
11348             (killvertexindex < b->firstnumber + m->invertices)) {
11349           /* Delete the non-corner vertex if it's not already deleted. */
11350           killvertex = getvertex(m, b, killvertexindex);
11351           if (vertextype(killvertex) != DEADVERTEX) {
11352             vertexdealloc(m, killvertex);
11353           }
11354         }
11355 #ifndef TRILIBRARY
11356       }
11357 #endif /* not TRILIBRARY */
11358     }
11359 
11360     /* Read the triangle's attributes. */
11361     for (j = 0; j < m->eextras; j++) {
11362 #ifdef TRILIBRARY
11363       setelemattribute(triangleloop, j, triangleattriblist[attribindex++]);
11364 #else /* not TRILIBRARY */
11365       stringptr = findfield(stringptr);
11366       if (*stringptr == '\0') {
11367         setelemattribute(triangleloop, j, 0);
11368       } else {
11369         setelemattribute(triangleloop, j,
11370                          (REAL) strtod(stringptr, &stringptr));
11371       }
11372 #endif /* not TRILIBRARY */
11373     }
11374 
11375     if (b->vararea) {
11376 #ifdef TRILIBRARY
11377       area = trianglearealist[elementnumber - b->firstnumber];
11378 #else /* not TRILIBRARY */
11379       /* Read an area constraint from the .area file. */
11380       stringptr = readline(inputline, areafile, areafilename);
11381       stringptr = findfield(stringptr);
11382       if (*stringptr == '\0') {
11383         area = -1.0;                      /* No constraint on this triangle. */
11384       } else {
11385         area = (REAL) strtod(stringptr, &stringptr);
11386       }
11387 #endif /* not TRILIBRARY */
11388       setareabound(triangleloop, area);
11389     }
11390 
11391     /* Set the triangle's vertices. */
11392     triangleloop.orient = 0;
11393     setorg(triangleloop, getvertex(m, b, corner[0]));
11394     setdest(triangleloop, getvertex(m, b, corner[1]));
11395     setapex(triangleloop, getvertex(m, b, corner[2]));
11396     /* Try linking the triangle to others that share these vertices. */
11397     for (triangleloop.orient = 0; triangleloop.orient < 3;
11398          triangleloop.orient++) {
11399       /* Take the number for the origin of triangleloop. */
11400       aroundvertex = corner[triangleloop.orient];
11401       /* Look for other triangles having this vertex. */
11402       nexttri = vertexarray[aroundvertex - b->firstnumber];
11403       /* Link the current triangle to the next one in the stack. */
11404       triangleloop.tri[6 + triangleloop.orient] = nexttri;
11405       /* Push the current triangle onto the stack. */
11406       vertexarray[aroundvertex - b->firstnumber] = encode(triangleloop);
11407       decode(nexttri, checktri);
11408       if (checktri.tri != m->dummytri) {
11409         dest(triangleloop, tdest);
11410         apex(triangleloop, tapex);
11411         /* Look for other triangles that share an edge. */
11412         do {
11413           dest(checktri, checkdest);
11414           apex(checktri, checkapex);
11415           if (tapex == checkdest) {
11416             /* The two triangles share an edge; bond them together. */
11417             lprev(triangleloop, triangleleft);
11418             bond(triangleleft, checktri);
11419           }
11420           if (tdest == checkapex) {
11421             /* The two triangles share an edge; bond them together. */
11422             lprev(checktri, checkleft);
11423             bond(triangleloop, checkleft);
11424           }
11425           /* Find the next triangle in the stack. */
11426           nexttri = checktri.tri[6 + checktri.orient];
11427           decode(nexttri, checktri);
11428         } while (checktri.tri != m->dummytri);
11429       }
11430     }
11431     triangleloop.tri = triangletraverse(m);
11432     elementnumber++;
11433   }
11434 
11435 #ifdef TRILIBRARY
11436   vertexindex = 0;
11437 #else /* not TRILIBRARY */
11438   fclose(elefile);
11439   if (b->vararea) {
11440     fclose(areafile);
11441   }
11442 #endif /* not TRILIBRARY */
11443 
11444   hullsize = 0;                      /* Prepare to count the boundary edges. */
11445   if (b->poly) {
11446     if (b->verbose) {
11447       printf("  Marking segments in triangulation.\n");
11448     }
11449     /* Read the segments from the .poly file, and link them */
11450     /*   to their neighboring triangles.                    */
11451     boundmarker = 0;
11452     traversalinit(&m->subsegs);
11453     subsegloop.ss = subsegtraverse(m);
11454     segmentnumber = b->firstnumber;
11455     while (subsegloop.ss != (subseg *) NULL) {
11456 #ifdef TRILIBRARY
11457       end[0] = segmentlist[vertexindex++];
11458       end[1] = segmentlist[vertexindex++];
11459       if (segmentmarkers) {
11460         boundmarker = segmentmarkerlist[segmentnumber - b->firstnumber];
11461       }
11462 #else /* not TRILIBRARY */
11463       /* Read the endpoints of each segment, and possibly a boundary marker. */
11464       stringptr = readline(inputline, polyfile, b->inpolyfilename);
11465       /* Skip the first (segment number) field. */
11466       stringptr = findfield(stringptr);
11467       if (*stringptr == '\0') {
11468         printf("Error:  Segment %ld has no endpoints in %s.\n", segmentnumber,
11469                polyfilename);
11470         triexit(1);
11471       } else {
11472         end[0] = (int) strtol(stringptr, &stringptr, 0);
11473       }
11474       stringptr = findfield(stringptr);
11475       if (*stringptr == '\0') {
11476         printf("Error:  Segment %ld is missing its second endpoint in %s.\n",
11477                segmentnumber, polyfilename);
11478         triexit(1);
11479       } else {
11480         end[1] = (int) strtol(stringptr, &stringptr, 0);
11481       }
11482       if (segmentmarkers) {
11483         stringptr = findfield(stringptr);
11484         if (*stringptr == '\0') {
11485           boundmarker = 0;
11486         } else {
11487           boundmarker = (int) strtol(stringptr, &stringptr, 0);
11488         }
11489       }
11490 #endif /* not TRILIBRARY */
11491       for (j = 0; j < 2; j++) {
11492         if ((end[j] < b->firstnumber) ||
11493             (end[j] >= b->firstnumber + m->invertices)) {
11494           printf("Error:  Segment %ld has an invalid vertex index.\n",
11495                  segmentnumber);
11496           triexit(1);
11497         }
11498       }
11499 
11500       /* set the subsegment's vertices. */
11501       subsegloop.ssorient = 0;
11502       segmentorg = getvertex(m, b, end[0]);
11503       segmentdest = getvertex(m, b, end[1]);
11504       setsorg(subsegloop, segmentorg);
11505       setsdest(subsegloop, segmentdest);
11506       setsegorg(subsegloop, segmentorg);
11507       setsegdest(subsegloop, segmentdest);
11508       setmark(subsegloop, boundmarker);
11509       /* Try linking the subsegment to triangles that share these vertices. */
11510       for (subsegloop.ssorient = 0; subsegloop.ssorient < 2;
11511            subsegloop.ssorient++) {
11512         /* Take the number for the destination of subsegloop. */
11513         aroundvertex = end[1 - subsegloop.ssorient];
11514         /* Look for triangles having this vertex. */
11515         prevlink = &vertexarray[aroundvertex - b->firstnumber];
11516         nexttri = vertexarray[aroundvertex - b->firstnumber];
11517         decode(nexttri, checktri);
11518         sorg(subsegloop, shorg);
11519         notfound = 1;
11520         /* Look for triangles having this edge.  Note that I'm only       */
11521         /*   comparing each triangle's destination with the subsegment;   */
11522         /*   each triangle's apex is handled through a different vertex.  */
11523         /*   Because each triangle appears on three vertices' lists, each */
11524         /*   occurrence of a triangle on a list can (and does) represent  */
11525         /*   an edge.  In this way, most edges are represented twice, and */
11526         /*   every triangle-subsegment bond is represented once.          */
11527         while (notfound && (checktri.tri != m->dummytri)) {
11528           dest(checktri, checkdest);
11529           if (shorg == checkdest) {
11530             /* We have a match.  Remove this triangle from the list. */
11531             *prevlink = checktri.tri[6 + checktri.orient];
11532             /* Bond the subsegment to the triangle. */
11533             tsbond(checktri, subsegloop);
11534             /* Check if this is a boundary edge. */
11535             sym(checktri, checkneighbor);
11536             if (checkneighbor.tri == m->dummytri) {
11537               /* The next line doesn't insert a subsegment (because there's */
11538               /*   already one there), but it sets the boundary markers of  */
11539               /*   the existing subsegment and its vertices.                */
11540               insertsubseg(m, b, &checktri, 1);
11541               hullsize++;
11542             }
11543             notfound = 0;
11544           }
11545           /* Find the next triangle in the stack. */
11546           prevlink = &checktri.tri[6 + checktri.orient];
11547           nexttri = checktri.tri[6 + checktri.orient];
11548           decode(nexttri, checktri);
11549         }
11550       }
11551       subsegloop.ss = subsegtraverse(m);
11552       segmentnumber++;
11553     }
11554   }
11555 
11556   /* Mark the remaining edges as not being attached to any subsegment. */
11557   /* Also, count the (yet uncounted) boundary edges.                   */
11558   for (i = 0; i < m->vertices.items; i++) {
11559     /* Search the stack of triangles adjacent to a vertex. */
11560     nexttri = vertexarray[i];
11561     decode(nexttri, checktri);
11562     while (checktri.tri != m->dummytri) {
11563       /* Find the next triangle in the stack before this */
11564       /*   information gets overwritten.                 */
11565       nexttri = checktri.tri[6 + checktri.orient];
11566       /* No adjacent subsegment.  (This overwrites the stack info.) */
11567       tsdissolve(checktri);
11568       sym(checktri, checkneighbor);
11569       if (checkneighbor.tri == m->dummytri) {
11570         insertsubseg(m, b, &checktri, 1);
11571         hullsize++;
11572       }
11573       decode(nexttri, checktri);
11574     }
11575   }
11576 
11577   trifree((VOID *) vertexarray);
11578   return hullsize;
11579 }
11580 
11581 #endif /* not CDT_ONLY */
11582 
11583 /**                                                                         **/
11584 /**                                                                         **/
11585 /********* General mesh construction routines end here               *********/
11586 
11587 /********* Segment insertion begins here                             *********/
11588 /**                                                                         **/
11589 /**                                                                         **/
11590 
11591 /*****************************************************************************/
11592 /*                                                                           */
11593 /*  finddirection()   Find the first triangle on the path from one point     */
11594 /*                    to another.                                            */
11595 /*                                                                           */
11596 /*  Finds the triangle that intersects a line segment drawn from the         */
11597 /*  origin of `searchtri' to the point `searchpoint', and returns the result */
11598 /*  in `searchtri'.  The origin of `searchtri' does not change, even though  */
11599 /*  the triangle returned may differ from the one passed in.  This routine   */
11600 /*  is used to find the direction to move in to get from one point to        */
11601 /*  another.                                                                 */
11602 /*                                                                           */
11603 /*  The return value notes whether the destination or apex of the found      */
11604 /*  triangle is collinear with the two points in question.                   */
11605 /*                                                                           */
11606 /*****************************************************************************/
11607 
11608 #ifdef ANSI_DECLARATORS
11609 enum finddirectionresult finddirection(struct mesh *m, struct behavior *b,
11610                                        struct otri *searchtri,
11611                                        vertex searchpoint)
11612 #else /* not ANSI_DECLARATORS */
11613 enum finddirectionresult finddirection(m, b, searchtri, searchpoint)
11614 struct mesh *m;
11615 struct behavior *b;
11616 struct otri *searchtri;
11617 vertex searchpoint;
11618 #endif /* not ANSI_DECLARATORS */
11619 
11620 {
11621   struct otri checktri;
11622   vertex startvertex;
11623   vertex leftvertex, rightvertex;
11624   REAL leftccw, rightccw;
11625   int leftflag, rightflag;
11626   triangle ptr;           /* Temporary variable used by onext() and oprev(). */
11627 
11628   org(*searchtri, startvertex);
11629   dest(*searchtri, rightvertex);
11630   apex(*searchtri, leftvertex);
11631   /* Is `searchpoint' to the left? */
11632   leftccw = counterclockwise(m, b, searchpoint, startvertex, leftvertex);
11633   leftflag = leftccw > 0.0;
11634   /* Is `searchpoint' to the right? */
11635   rightccw = counterclockwise(m, b, startvertex, searchpoint, rightvertex);
11636   rightflag = rightccw > 0.0;
11637   if (leftflag && rightflag) {
11638     /* `searchtri' faces directly away from `searchpoint'.  We could go left */
11639     /*   or right.  Ask whether it's a triangle or a boundary on the left.   */
11640     onext(*searchtri, checktri);
11641     if (checktri.tri == m->dummytri) {
11642       leftflag = 0;
11643     } else {
11644       rightflag = 0;
11645     }
11646   }
11647   while (leftflag) {
11648     /* Turn left until satisfied. */
11649     onextself(*searchtri);
11650     if (searchtri->tri == m->dummytri) {
11651       printf("Internal error in finddirection():  Unable to find a\n");
11652       printf("  triangle leading from (%.12g, %.12g) to", (double)startvertex[0],
11653              (double)startvertex[1]);
11654       printf("  (%.12g, %.12g).\n", (double)searchpoint[0], (double)searchpoint[1]);
11655       internalerror();
11656     }
11657     apex(*searchtri, leftvertex);
11658     rightccw = leftccw;
11659     leftccw = counterclockwise(m, b, searchpoint, startvertex, leftvertex);
11660     leftflag = leftccw > 0.0;
11661   }
11662   while (rightflag) {
11663     /* Turn right until satisfied. */
11664     oprevself(*searchtri);
11665     if (searchtri->tri == m->dummytri) {
11666       printf("Internal error in finddirection():  Unable to find a\n");
11667       printf("  triangle leading from (%.12g, %.12g) to", (double)startvertex[0],
11668              (double)startvertex[1]);
11669       printf("  (%.12g, %.12g).\n", (double)searchpoint[0], (double)searchpoint[1]);
11670       internalerror();
11671     }
11672     dest(*searchtri, rightvertex);
11673     leftccw = rightccw;
11674     rightccw = counterclockwise(m, b, startvertex, searchpoint, rightvertex);
11675     rightflag = rightccw > 0.0;
11676   }
11677   if (leftccw == 0.0) {
11678     return LEFTCOLLINEAR;
11679   } else if (rightccw == 0.0) {
11680     return RIGHTCOLLINEAR;
11681   } else {
11682     return WITHIN;
11683   }
11684 }
11685 
11686 /*****************************************************************************/
11687 /*                                                                           */
11688 /*  segmentintersection()   Find the intersection of an existing segment     */
11689 /*                          and a segment that is being inserted.  Insert    */
11690 /*                          a vertex at the intersection, splitting an       */
11691 /*                          existing subsegment.                             */
11692 /*                                                                           */
11693 /*  The segment being inserted connects the apex of splittri to endpoint2.   */
11694 /*  splitsubseg is the subsegment being split, and MUST adjoin splittri.     */
11695 /*  Hence, endpoints of the subsegment being split are the origin and        */
11696 /*  destination of splittri.                                                 */
11697 /*                                                                           */
11698 /*  On completion, splittri is a handle having the newly inserted            */
11699 /*  intersection point as its origin, and endpoint1 as its destination.      */
11700 /*                                                                           */
11701 /*****************************************************************************/
11702 
11703 #ifdef ANSI_DECLARATORS
11704 void segmentintersection(struct mesh *m, struct behavior *b,
11705                          struct otri *splittri, struct osub *splitsubseg,
11706                          vertex endpoint2)
11707 #else /* not ANSI_DECLARATORS */
11708 void segmentintersection(m, b, splittri, splitsubseg, endpoint2)
11709 struct mesh *m;
11710 struct behavior *b;
11711 struct otri *splittri;
11712 struct osub *splitsubseg;
11713 vertex endpoint2;
11714 #endif /* not ANSI_DECLARATORS */
11715 
11716 {
11717   struct osub opposubseg;
11718   vertex endpoint1;
11719   vertex torg, tdest;
11720   vertex leftvertex, rightvertex;
11721   vertex newvertex;
11722   enum insertvertexresult success;
11723   enum finddirectionresult collinear;
11724   REAL ex, ey;
11725   REAL tx, ty;
11726   REAL etx, ety;
11727   REAL split, denom;
11728   int i;
11729   triangle ptr;                       /* Temporary variable used by onext(). */
11730   subseg sptr;                        /* Temporary variable used by snext(). */
11731 
11732   /* Find the other three segment endpoints. */
11733   apex(*splittri, endpoint1);
11734   org(*splittri, torg);
11735   dest(*splittri, tdest);
11736   /* Segment intersection formulae; see the Antonio reference. */
11737   tx = tdest[0] - torg[0];
11738   ty = tdest[1] - torg[1];
11739   ex = endpoint2[0] - endpoint1[0];
11740   ey = endpoint2[1] - endpoint1[1];
11741   etx = torg[0] - endpoint2[0];
11742   ety = torg[1] - endpoint2[1];
11743   denom = ty * ex - tx * ey;
11744   if (denom == 0.0) {
11745     printf("Internal error in segmentintersection():");
11746     printf("  Attempt to find intersection of parallel segments.\n");
11747     internalerror();
11748   }
11749   split = (ey * etx - ex * ety) / denom;
11750   /* Create the new vertex. */
11751   newvertex = (vertex) poolalloc(&m->vertices);
11752   /* Interpolate its coordinate and attributes. */
11753   for (i = 0; i < 2 + m->nextras; i++) {
11754     newvertex[i] = torg[i] + split * (tdest[i] - torg[i]);
11755   }
11756   setvertexmark(newvertex, mark(*splitsubseg));
11757   setvertextype(newvertex, INPUTVERTEX);
11758   if (b->verbose > 1) {
11759     printf(
11760   "  Splitting subsegment (%.12g, %.12g) (%.12g, %.12g) at (%.12g, %.12g).\n",
11761            (double)torg[0], (double)torg[1], (double)tdest[0], (double)tdest[1], (double)newvertex[0], (double)newvertex[1]);
11762   }
11763   /* Insert the intersection vertex.  This should always succeed. */
11764   success = insertvertex(m, b, newvertex, splittri, splitsubseg, 0, 0);
11765   if (success != SUCCESSFULVERTEX) {
11766     printf("Internal error in segmentintersection():\n");
11767     printf("  Failure to split a segment.\n");
11768     internalerror();
11769   }
11770   /* Record a triangle whose origin is the new vertex. */
11771   setvertex2tri(newvertex, encode(*splittri));
11772   if (m->steinerleft > 0) {
11773     m->steinerleft--;
11774   }
11775 
11776   /* Divide the segment into two, and correct the segment endpoints. */
11777   ssymself(*splitsubseg);
11778   spivot(*splitsubseg, opposubseg);
11779   sdissolve(*splitsubseg);
11780   sdissolve(opposubseg);
11781   do {
11782     setsegorg(*splitsubseg, newvertex);
11783     snextself(*splitsubseg);
11784   } while (splitsubseg->ss != m->dummysub);
11785   do {
11786     setsegorg(opposubseg, newvertex);
11787     snextself(opposubseg);
11788   } while (opposubseg.ss != m->dummysub);
11789 
11790   /* Inserting the vertex may have caused edge flips.  We wish to rediscover */
11791   /*   the edge connecting endpoint1 to the new intersection vertex.         */
11792   collinear = finddirection(m, b, splittri, endpoint1);
11793   dest(*splittri, rightvertex);
11794   apex(*splittri, leftvertex);
11795   if ((leftvertex[0] == endpoint1[0]) && (leftvertex[1] == endpoint1[1])) {
11796     onextself(*splittri);
11797   } else if ((rightvertex[0] != endpoint1[0]) ||
11798              (rightvertex[1] != endpoint1[1])) {
11799     printf("Internal error in segmentintersection():\n");
11800     printf("  Topological inconsistency after splitting a segment.\n");
11801     internalerror();
11802   }
11803   /* `splittri' should have destination endpoint1. */
11804 }
11805 
11806 /*****************************************************************************/
11807 /*                                                                           */
11808 /*  scoutsegment()   Scout the first triangle on the path from one endpoint  */
11809 /*                   to another, and check for completion (reaching the      */
11810 /*                   second endpoint), a collinear vertex, or the            */
11811 /*                   intersection of two segments.                           */
11812 /*                                                                           */
11813 /*  Returns one if the entire segment is successfully inserted, and zero if  */
11814 /*  the job must be finished by conformingedge() or constrainededge().       */
11815 /*                                                                           */
11816 /*  If the first triangle on the path has the second endpoint as its         */
11817 /*  destination or apex, a subsegment is inserted and the job is done.       */
11818 /*                                                                           */
11819 /*  If the first triangle on the path has a destination or apex that lies on */
11820 /*  the segment, a subsegment is inserted connecting the first endpoint to   */
11821 /*  the collinear vertex, and the search is continued from the collinear     */
11822 /*  vertex.                                                                  */
11823 /*                                                                           */
11824 /*  If the first triangle on the path has a subsegment opposite its origin,  */
11825 /*  then there is a segment that intersects the segment being inserted.      */
11826 /*  Their intersection vertex is inserted, splitting the subsegment.         */
11827 /*                                                                           */
11828 /*****************************************************************************/
11829 
11830 #ifdef ANSI_DECLARATORS
11831 int scoutsegment(struct mesh *m, struct behavior *b, struct otri *searchtri,
11832                  vertex endpoint2, int newmark)
11833 #else /* not ANSI_DECLARATORS */
11834 int scoutsegment(m, b, searchtri, endpoint2, newmark)
11835 struct mesh *m;
11836 struct behavior *b;
11837 struct otri *searchtri;
11838 vertex endpoint2;
11839 int newmark;
11840 #endif /* not ANSI_DECLARATORS */
11841 
11842 {
11843   struct otri crosstri;
11844   struct osub crosssubseg;
11845   vertex leftvertex, rightvertex;
11846   enum finddirectionresult collinear;
11847   subseg sptr;                      /* Temporary variable used by tspivot(). */
11848 
11849   collinear = finddirection(m, b, searchtri, endpoint2);
11850   dest(*searchtri, rightvertex);
11851   apex(*searchtri, leftvertex);
11852   if (((leftvertex[0] == endpoint2[0]) && (leftvertex[1] == endpoint2[1])) ||
11853       ((rightvertex[0] == endpoint2[0]) && (rightvertex[1] == endpoint2[1]))) {
11854     /* The segment is already an edge in the mesh. */
11855     if ((leftvertex[0] == endpoint2[0]) && (leftvertex[1] == endpoint2[1])) {
11856       lprevself(*searchtri);
11857     }
11858     /* Insert a subsegment, if there isn't already one there. */
11859     insertsubseg(m, b, searchtri, newmark);
11860     return 1;
11861   } else if (collinear == LEFTCOLLINEAR) {
11862     /* We've collided with a vertex between the segment's endpoints. */
11863     /* Make the collinear vertex be the triangle's origin. */
11864     lprevself(*searchtri);
11865     insertsubseg(m, b, searchtri, newmark);
11866     /* Insert the remainder of the segment. */
11867     return scoutsegment(m, b, searchtri, endpoint2, newmark);
11868   } else if (collinear == RIGHTCOLLINEAR) {
11869     /* We've collided with a vertex between the segment's endpoints. */
11870     insertsubseg(m, b, searchtri, newmark);
11871     /* Make the collinear vertex be the triangle's origin. */
11872     lnextself(*searchtri);
11873     /* Insert the remainder of the segment. */
11874     return scoutsegment(m, b, searchtri, endpoint2, newmark);
11875   } else {
11876     lnext(*searchtri, crosstri);
11877     tspivot(crosstri, crosssubseg);
11878     /* Check for a crossing segment. */
11879     if (crosssubseg.ss == m->dummysub) {
11880       return 0;
11881     } else {
11882       /* Insert a vertex at the intersection. */
11883       segmentintersection(m, b, &crosstri, &crosssubseg, endpoint2);
11884       otricopy(crosstri, *searchtri);
11885       insertsubseg(m, b, searchtri, newmark);
11886       /* Insert the remainder of the segment. */
11887       return scoutsegment(m, b, searchtri, endpoint2, newmark);
11888     }
11889   }
11890 }
11891 
11892 /*****************************************************************************/
11893 /*                                                                           */
11894 /*  conformingedge()   Force a segment into a conforming Delaunay            */
11895 /*                     triangulation by inserting a vertex at its midpoint,  */
11896 /*                     and recursively forcing in the two half-segments if   */
11897 /*                     necessary.                                            */
11898 /*                                                                           */
11899 /*  Generates a sequence of subsegments connecting `endpoint1' to            */
11900 /*  `endpoint2'.  `newmark' is the boundary marker of the segment, assigned  */
11901 /*  to each new splitting vertex and subsegment.                             */
11902 /*                                                                           */
11903 /*  Note that conformingedge() does not always maintain the conforming       */
11904 /*  Delaunay property.  Once inserted, segments are locked into place;       */
11905 /*  vertices inserted later (to force other segments in) may render these    */
11906 /*  fixed segments non-Delaunay.  The conforming Delaunay property will be   */
11907 /*  restored by enforcequality() by splitting encroached subsegments.        */
11908 /*                                                                           */
11909 /*****************************************************************************/
11910 
11911 #ifndef REDUCED
11912 #ifndef CDT_ONLY
11913 
11914 #ifdef ANSI_DECLARATORS
11915 void conformingedge(struct mesh *m, struct behavior *b,
11916                     vertex endpoint1, vertex endpoint2, int newmark)
11917 #else /* not ANSI_DECLARATORS */
11918 void conformingedge(m, b, endpoint1, endpoint2, newmark)
11919 struct mesh *m;
11920 struct behavior *b;
11921 vertex endpoint1;
11922 vertex endpoint2;
11923 int newmark;
11924 #endif /* not ANSI_DECLARATORS */
11925 
11926 {
11927   struct otri searchtri1, searchtri2;
11928   struct osub brokensubseg;
11929   vertex newvertex;
11930   vertex midvertex1, midvertex2;
11931   enum insertvertexresult success;
11932   int i;
11933   subseg sptr;                      /* Temporary variable used by tspivot(). */
11934 
11935   if (b->verbose > 2) {
11936     printf("Forcing segment into triangulation by recursive splitting:\n");
11937     printf("  (%.12g, %.12g) (%.12g, %.12g)\n", (double)endpoint1[0], (double)endpoint1[1],
11938            (double)endpoint2[0], (double)endpoint2[1]);
11939   }
11940   /* Create a new vertex to insert in the middle of the segment. */
11941   newvertex = (vertex) poolalloc(&m->vertices);
11942   /* Interpolate coordinates and attributes. */
11943   for (i = 0; i < 2 + m->nextras; i++) {
11944     newvertex[i] = 0.5 * (endpoint1[i] + endpoint2[i]);
11945   }
11946   setvertexmark(newvertex, newmark);
11947   setvertextype(newvertex, SEGMENTVERTEX);
11948   /* No known triangle to search from. */
11949   searchtri1.tri = m->dummytri;
11950   /* Attempt to insert the new vertex. */
11951   success = insertvertex(m, b, newvertex, &searchtri1, (struct osub *) NULL,
11952                          0, 0);
11953   if (success == DUPLICATEVERTEX) {
11954     if (b->verbose > 2) {
11955       printf("  Segment intersects existing vertex (%.12g, %.12g).\n",
11956              (double)newvertex[0], (double)newvertex[1]);
11957     }
11958     /* Use the vertex that's already there. */
11959     vertexdealloc(m, newvertex);
11960     org(searchtri1, newvertex);
11961   } else {
11962     if (success == VIOLATINGVERTEX) {
11963       if (b->verbose > 2) {
11964         printf("  Two segments intersect at (%.12g, %.12g).\n",
11965                (double)newvertex[0], (double)newvertex[1]);
11966       }
11967       /* By fluke, we've landed right on another segment.  Split it. */
11968       tspivot(searchtri1, brokensubseg);
11969       success = insertvertex(m, b, newvertex, &searchtri1, &brokensubseg,
11970                              0, 0);
11971       if (success != SUCCESSFULVERTEX) {
11972         printf("Internal error in conformingedge():\n");
11973         printf("  Failure to split a segment.\n");
11974         internalerror();
11975       }
11976     }
11977     /* The vertex has been inserted successfully. */
11978     if (m->steinerleft > 0) {
11979       m->steinerleft--;
11980     }
11981   }
11982   otricopy(searchtri1, searchtri2);
11983   /* `searchtri1' and `searchtri2' are fastened at their origins to         */
11984   /*   `newvertex', and will be directed toward `endpoint1' and `endpoint2' */
11985   /*   respectively.  First, we must get `searchtri2' out of the way so it  */
11986   /*   won't be invalidated during the insertion of the first half of the   */
11987   /*   segment.                                                             */
11988   finddirection(m, b, &searchtri2, endpoint2);
11989   if (!scoutsegment(m, b, &searchtri1, endpoint1, newmark)) {
11990     /* The origin of searchtri1 may have changed if a collision with an */
11991     /*   intervening vertex on the segment occurred.                    */
11992     org(searchtri1, midvertex1);
11993     conformingedge(m, b, midvertex1, endpoint1, newmark);
11994   }
11995   if (!scoutsegment(m, b, &searchtri2, endpoint2, newmark)) {
11996     /* The origin of searchtri2 may have changed if a collision with an */
11997     /*   intervening vertex on the segment occurred.                    */
11998     org(searchtri2, midvertex2);
11999     conformingedge(m, b, midvertex2, endpoint2, newmark);
12000   }
12001 }
12002 
12003 #endif /* not CDT_ONLY */
12004 #endif /* not REDUCED */
12005 
12006 /*****************************************************************************/
12007 /*                                                                           */
12008 /*  delaunayfixup()   Enforce the Delaunay condition at an edge, fanning out */
12009 /*                    recursively from an existing vertex.  Pay special      */
12010 /*                    attention to stacking inverted triangles.              */
12011 /*                                                                           */
12012 /*  This is a support routine for inserting segments into a constrained      */
12013 /*  Delaunay triangulation.                                                  */
12014 /*                                                                           */
12015 /*  The origin of fixuptri is treated as if it has just been inserted, and   */
12016 /*  the local Delaunay condition needs to be enforced.  It is only enforced  */
12017 /*  in one sector, however, that being the angular range defined by          */
12018 /*  fixuptri.                                                                */
12019 /*                                                                           */
12020 /*  This routine also needs to make decisions regarding the "stacking" of    */
12021 /*  triangles.  (Read the description of constrainededge() below before      */
12022 /*  reading on here, so you understand the algorithm.)  If the position of   */
12023 /*  the new vertex (the origin of fixuptri) indicates that the vertex before */
12024 /*  it on the polygon is a reflex vertex, then "stack" the triangle by       */
12025 /*  doing nothing.  (fixuptri is an inverted triangle, which is how stacked  */
12026 /*  triangles are identified.)                                               */
12027 /*                                                                           */
12028 /*  Otherwise, check whether the vertex before that was a reflex vertex.     */
12029 /*  If so, perform an edge flip, thereby eliminating an inverted triangle    */
12030 /*  (popping it off the stack).  The edge flip may result in the creation    */
12031 /*  of a new inverted triangle, depending on whether or not the new vertex   */
12032 /*  is visible to the vertex three edges behind on the polygon.              */
12033 /*                                                                           */
12034 /*  If neither of the two vertices behind the new vertex are reflex          */
12035 /*  vertices, fixuptri and fartri, the triangle opposite it, are not         */
12036 /*  inverted; hence, ensure that the edge between them is locally Delaunay.  */
12037 /*                                                                           */
12038 /*  `leftside' indicates whether or not fixuptri is to the left of the       */
12039 /*  segment being inserted.  (Imagine that the segment is pointing up from   */
12040 /*  endpoint1 to endpoint2.)                                                 */
12041 /*                                                                           */
12042 /*****************************************************************************/
12043 
12044 #ifdef ANSI_DECLARATORS
12045 void delaunayfixup(struct mesh *m, struct behavior *b,
12046                    struct otri *fixuptri, int leftside)
12047 #else /* not ANSI_DECLARATORS */
12048 void delaunayfixup(m, b, fixuptri, leftside)
12049 struct mesh *m;
12050 struct behavior *b;
12051 struct otri *fixuptri;
12052 int leftside;
12053 #endif /* not ANSI_DECLARATORS */
12054 
12055 {
12056   struct otri neartri;
12057   struct otri fartri;
12058   struct osub faredge;
12059   vertex nearvertex, leftvertex, rightvertex, farvertex;
12060   triangle ptr;                         /* Temporary variable used by sym(). */
12061   subseg sptr;                      /* Temporary variable used by tspivot(). */
12062 
12063   lnext(*fixuptri, neartri);
12064   sym(neartri, fartri);
12065   /* Check if the edge opposite the origin of fixuptri can be flipped. */
12066   if (fartri.tri == m->dummytri) {
12067     return;
12068   }
12069   tspivot(neartri, faredge);
12070   if (faredge.ss != m->dummysub) {
12071     return;
12072   }
12073   /* Find all the relevant vertices. */
12074   apex(neartri, nearvertex);
12075   org(neartri, leftvertex);
12076   dest(neartri, rightvertex);
12077   apex(fartri, farvertex);
12078   /* Check whether the previous polygon vertex is a reflex vertex. */
12079   if (leftside) {
12080     if (counterclockwise(m, b, nearvertex, leftvertex, farvertex) <= 0.0) {
12081       /* leftvertex is a reflex vertex too.  Nothing can */
12082       /*   be done until a convex section is found.      */
12083       return;
12084     }
12085   } else {
12086     if (counterclockwise(m, b, farvertex, rightvertex, nearvertex) <= 0.0) {
12087       /* rightvertex is a reflex vertex too.  Nothing can */
12088       /*   be done until a convex section is found.       */
12089       return;
12090     }
12091   }
12092   if (counterclockwise(m, b, rightvertex, leftvertex, farvertex) > 0.0) {
12093     /* fartri is not an inverted triangle, and farvertex is not a reflex */
12094     /*   vertex.  As there are no reflex vertices, fixuptri isn't an     */
12095     /*   inverted triangle, either.  Hence, test the edge between the    */
12096     /*   triangles to ensure it is locally Delaunay.                     */
12097     if (incircle(m, b, leftvertex, farvertex, rightvertex, nearvertex) <=
12098         0.0) {
12099       return;
12100     }
12101     /* Not locally Delaunay; go on to an edge flip. */
12102   }        /* else fartri is inverted; remove it from the stack by flipping. */
12103   flip(m, b, &neartri);
12104   lprevself(*fixuptri);    /* Restore the origin of fixuptri after the flip. */
12105   /* Recursively process the two triangles that result from the flip. */
12106   delaunayfixup(m, b, fixuptri, leftside);
12107   delaunayfixup(m, b, &fartri, leftside);
12108 }
12109 
12110 /*****************************************************************************/
12111 /*                                                                           */
12112 /*  constrainededge()   Force a segment into a constrained Delaunay          */
12113 /*                      triangulation by deleting the triangles it           */
12114 /*                      intersects, and triangulating the polygons that      */
12115 /*                      form on each side of it.                             */
12116 /*                                                                           */
12117 /*  Generates a single subsegment connecting `endpoint1' to `endpoint2'.     */
12118 /*  The triangle `starttri' has `endpoint1' as its origin.  `newmark' is the */
12119 /*  boundary marker of the segment.                                          */
12120 /*                                                                           */
12121 /*  To insert a segment, every triangle whose interior intersects the        */
12122 /*  segment is deleted.  The union of these deleted triangles is a polygon   */
12123 /*  (which is not necessarily monotone, but is close enough), which is       */
12124 /*  divided into two polygons by the new segment.  This routine's task is    */
12125 /*  to generate the Delaunay triangulation of these two polygons.            */
12126 /*                                                                           */
12127 /*  You might think of this routine's behavior as a two-step process.  The   */
12128 /*  first step is to walk from endpoint1 to endpoint2, flipping each edge    */
12129 /*  encountered.  This step creates a fan of edges connected to endpoint1,   */
12130 /*  including the desired edge to endpoint2.  The second step enforces the   */
12131 /*  Delaunay condition on each side of the segment in an incremental manner: */
12132 /*  proceeding along the polygon from endpoint1 to endpoint2 (this is done   */
12133 /*  independently on each side of the segment), each vertex is "enforced"    */
12134 /*  as if it had just been inserted, but affecting only the previous         */
12135 /*  vertices.  The result is the same as if the vertices had been inserted   */
12136 /*  in the order they appear on the polygon, so the result is Delaunay.      */
12137 /*                                                                           */
12138 /*  In truth, constrainededge() interleaves these two steps.  The procedure  */
12139 /*  walks from endpoint1 to endpoint2, and each time an edge is encountered  */
12140 /*  and flipped, the newly exposed vertex (at the far end of the flipped     */
12141 /*  edge) is "enforced" upon the previously flipped edges, usually affecting */
12142 /*  only one side of the polygon (depending upon which side of the segment   */
12143 /*  the vertex falls on).                                                    */
12144 /*                                                                           */
12145 /*  The algorithm is complicated by the need to handle polygons that are not */
12146 /*  convex.  Although the polygon is not necessarily monotone, it can be     */
12147 /*  triangulated in a manner similar to the stack-based algorithms for       */
12148 /*  monotone polygons.  For each reflex vertex (local concavity) of the      */
12149 /*  polygon, there will be an inverted triangle formed by one of the edge    */
12150 /*  flips.  (An inverted triangle is one with negative area - that is, its   */
12151 /*  vertices are arranged in clockwise order - and is best thought of as a   */
12152 /*  wrinkle in the fabric of the mesh.)  Each inverted triangle can be       */
12153 /*  thought of as a reflex vertex pushed on the stack, waiting to be fixed   */
12154 /*  later.                                                                   */
12155 /*                                                                           */
12156 /*  A reflex vertex is popped from the stack when a vertex is inserted that  */
12157 /*  is visible to the reflex vertex.  (However, if the vertex behind the     */
12158 /*  reflex vertex is not visible to the reflex vertex, a new inverted        */
12159 /*  triangle will take its place on the stack.)  These details are handled   */
12160 /*  by the delaunayfixup() routine above.                                    */
12161 /*                                                                           */
12162 /*****************************************************************************/
12163 
12164 #ifdef ANSI_DECLARATORS
12165 void constrainededge(struct mesh *m, struct behavior *b,
12166                      struct otri *starttri, vertex endpoint2, int newmark)
12167 #else /* not ANSI_DECLARATORS */
12168 void constrainededge(m, b, starttri, endpoint2, newmark)
12169 struct mesh *m;
12170 struct behavior *b;
12171 struct otri *starttri;
12172 vertex endpoint2;
12173 int newmark;
12174 #endif /* not ANSI_DECLARATORS */
12175 
12176 {
12177   struct otri fixuptri, fixuptri2;
12178   struct osub crosssubseg;
12179   vertex endpoint1;
12180   vertex farvertex;
12181   REAL area;
12182   int collision;
12183   int done;
12184   triangle ptr;             /* Temporary variable used by sym() and oprev(). */
12185   subseg sptr;                      /* Temporary variable used by tspivot(). */
12186 
12187   org(*starttri, endpoint1);
12188   lnext(*starttri, fixuptri);
12189   flip(m, b, &fixuptri);
12190   /* `collision' indicates whether we have found a vertex directly */
12191   /*   between endpoint1 and endpoint2.                            */
12192   collision = 0;
12193   done = 0;
12194   do {
12195     org(fixuptri, farvertex);
12196     /* `farvertex' is the extreme point of the polygon we are "digging" */
12197     /*   to get from endpoint1 to endpoint2.                           */
12198     if ((farvertex[0] == endpoint2[0]) && (farvertex[1] == endpoint2[1])) {
12199       oprev(fixuptri, fixuptri2);
12200       /* Enforce the Delaunay condition around endpoint2. */
12201       delaunayfixup(m, b, &fixuptri, 0);
12202       delaunayfixup(m, b, &fixuptri2, 1);
12203       done = 1;
12204     } else {
12205       /* Check whether farvertex is to the left or right of the segment */
12206       /*   being inserted, to decide which edge of fixuptri to dig      */
12207       /*   through next.                                                */
12208       area = counterclockwise(m, b, endpoint1, endpoint2, farvertex);
12209       if (area == 0.0) {
12210         /* We've collided with a vertex between endpoint1 and endpoint2. */
12211         collision = 1;
12212         oprev(fixuptri, fixuptri2);
12213         /* Enforce the Delaunay condition around farvertex. */
12214         delaunayfixup(m, b, &fixuptri, 0);
12215         delaunayfixup(m, b, &fixuptri2, 1);
12216         done = 1;
12217       } else {
12218         if (area > 0.0) {        /* farvertex is to the left of the segment. */
12219           oprev(fixuptri, fixuptri2);
12220           /* Enforce the Delaunay condition around farvertex, on the */
12221           /*   left side of the segment only.                        */
12222           delaunayfixup(m, b, &fixuptri2, 1);
12223           /* Flip the edge that crosses the segment.  After the edge is */
12224           /*   flipped, one of its endpoints is the fan vertex, and the */
12225           /*   destination of fixuptri is the fan vertex.               */
12226           lprevself(fixuptri);
12227         } else {                /* farvertex is to the right of the segment. */
12228           delaunayfixup(m, b, &fixuptri, 0);
12229           /* Flip the edge that crosses the segment.  After the edge is */
12230           /*   flipped, one of its endpoints is the fan vertex, and the */
12231           /*   destination of fixuptri is the fan vertex.               */
12232           oprevself(fixuptri);
12233         }
12234         /* Check for two intersecting segments. */
12235         tspivot(fixuptri, crosssubseg);
12236         if (crosssubseg.ss == m->dummysub) {
12237           flip(m, b, &fixuptri);    /* May create inverted triangle at left. */
12238         } else {
12239           /* We've collided with a segment between endpoint1 and endpoint2. */
12240           collision = 1;
12241           /* Insert a vertex at the intersection. */
12242           segmentintersection(m, b, &fixuptri, &crosssubseg, endpoint2);
12243           done = 1;
12244         }
12245       }
12246     }
12247   } while (!done);
12248   /* Insert a subsegment to make the segment permanent. */
12249   insertsubseg(m, b, &fixuptri, newmark);
12250   /* If there was a collision with an interceding vertex, install another */
12251   /*   segment connecting that vertex with endpoint2.                     */
12252   if (collision) {
12253     /* Insert the remainder of the segment. */
12254     if (!scoutsegment(m, b, &fixuptri, endpoint2, newmark)) {
12255       constrainededge(m, b, &fixuptri, endpoint2, newmark);
12256     }
12257   }
12258 }
12259 
12260 /*****************************************************************************/
12261 /*                                                                           */
12262 /*  insertsegment()   Insert a PSLG segment into a triangulation.            */
12263 /*                                                                           */
12264 /*****************************************************************************/
12265 
12266 #ifdef ANSI_DECLARATORS
12267 void insertsegment(struct mesh *m, struct behavior *b,
12268                    vertex endpoint1, vertex endpoint2, int newmark)
12269 #else /* not ANSI_DECLARATORS */
12270 void insertsegment(m, b, endpoint1, endpoint2, newmark)
12271 struct mesh *m;
12272 struct behavior *b;
12273 vertex endpoint1;
12274 vertex endpoint2;
12275 int newmark;
12276 #endif /* not ANSI_DECLARATORS */
12277 
12278 {
12279   struct otri searchtri1, searchtri2;
12280   triangle encodedtri;
12281   vertex checkvertex;
12282   triangle ptr;                         /* Temporary variable used by sym(). */
12283 
12284   if (b->verbose > 1) {
12285     printf("  Connecting (%.12g, %.12g) to (%.12g, %.12g).\n",
12286            (double)endpoint1[0], (double)endpoint1[1], (double)endpoint2[0], (double)endpoint2[1]);
12287   }
12288 
12289   /* Find a triangle whose origin is the segment's first endpoint. */
12290   checkvertex = (vertex) NULL;
12291   encodedtri = vertex2tri(endpoint1);
12292   if (encodedtri != (triangle) NULL) {
12293     decode(encodedtri, searchtri1);
12294     org(searchtri1, checkvertex);
12295   }
12296   if (checkvertex != endpoint1) {
12297     /* Find a boundary triangle to search from. */
12298     searchtri1.tri = m->dummytri;
12299     searchtri1.orient = 0;
12300     symself(searchtri1);
12301     /* Search for the segment's first endpoint by point location. */
12302     if (locate(m, b, endpoint1, &searchtri1) != ONVERTEX) {
12303       printf(
12304         "Internal error in insertsegment():  Unable to locate PSLG vertex\n");
12305       printf("  (%.12g, %.12g) in triangulation.\n",
12306              (double)endpoint1[0], (double)endpoint1[1]);
12307       internalerror();
12308     }
12309   }
12310   /* Remember this triangle to improve subsequent point location. */
12311   otricopy(searchtri1, m->recenttri);
12312   /* Scout the beginnings of a path from the first endpoint */
12313   /*   toward the second.                                   */
12314   if (scoutsegment(m, b, &searchtri1, endpoint2, newmark)) {
12315     /* The segment was easily inserted. */
12316     return;
12317   }
12318   /* The first endpoint may have changed if a collision with an intervening */
12319   /*   vertex on the segment occurred.                                      */
12320   org(searchtri1, endpoint1);
12321 
12322   /* Find a triangle whose origin is the segment's second endpoint. */
12323   checkvertex = (vertex) NULL;
12324   encodedtri = vertex2tri(endpoint2);
12325   if (encodedtri != (triangle) NULL) {
12326     decode(encodedtri, searchtri2);
12327     org(searchtri2, checkvertex);
12328   }
12329   if (checkvertex != endpoint2) {
12330     /* Find a boundary triangle to search from. */
12331     searchtri2.tri = m->dummytri;
12332     searchtri2.orient = 0;
12333     symself(searchtri2);
12334     /* Search for the segment's second endpoint by point location. */
12335     if (locate(m, b, endpoint2, &searchtri2) != ONVERTEX) {
12336       printf(
12337         "Internal error in insertsegment():  Unable to locate PSLG vertex\n");
12338       printf("  (%.12g, %.12g) in triangulation.\n",
12339              (double)endpoint2[0], (double)endpoint2[1]);
12340       internalerror();
12341     }
12342   }
12343   /* Remember this triangle to improve subsequent point location. */
12344   otricopy(searchtri2, m->recenttri);
12345   /* Scout the beginnings of a path from the second endpoint */
12346   /*   toward the first.                                     */
12347   if (scoutsegment(m, b, &searchtri2, endpoint1, newmark)) {
12348     /* The segment was easily inserted. */
12349     return;
12350   }
12351   /* The second endpoint may have changed if a collision with an intervening */
12352   /*   vertex on the segment occurred.                                       */
12353   org(searchtri2, endpoint2);
12354 
12355 #ifndef REDUCED
12356 #ifndef CDT_ONLY
12357   if (b->splitseg) {
12358     /* Insert vertices to force the segment into the triangulation. */
12359     conformingedge(m, b, endpoint1, endpoint2, newmark);
12360   } else {
12361 #endif /* not CDT_ONLY */
12362 #endif /* not REDUCED */
12363     /* Insert the segment directly into the triangulation. */
12364     constrainededge(m, b, &searchtri1, endpoint2, newmark);
12365 #ifndef REDUCED
12366 #ifndef CDT_ONLY
12367   }
12368 #endif /* not CDT_ONLY */
12369 #endif /* not REDUCED */
12370 }
12371 
12372 /*****************************************************************************/
12373 /*                                                                           */
12374 /*  markhull()   Cover the convex hull of a triangulation with subsegments.  */
12375 /*                                                                           */
12376 /*****************************************************************************/
12377 
12378 #ifdef ANSI_DECLARATORS
12379 void markhull(struct mesh *m, struct behavior *b)
12380 #else /* not ANSI_DECLARATORS */
12381 void markhull(m, b)
12382 struct mesh *m;
12383 struct behavior *b;
12384 #endif /* not ANSI_DECLARATORS */
12385 
12386 {
12387   struct otri hulltri;
12388   struct otri nexttri;
12389   struct otri starttri;
12390   triangle ptr;             /* Temporary variable used by sym() and oprev(). */
12391 
12392   /* Find a triangle handle on the hull. */
12393   hulltri.tri = m->dummytri;
12394   hulltri.orient = 0;
12395   symself(hulltri);
12396   /* Remember where we started so we know when to stop. */
12397   otricopy(hulltri, starttri);
12398   /* Go once counterclockwise around the convex hull. */
12399   do {
12400     /* Create a subsegment if there isn't already one here. */
12401     insertsubseg(m, b, &hulltri, 1);
12402     /* To find the next hull edge, go clockwise around the next vertex. */
12403     lnextself(hulltri);
12404     oprev(hulltri, nexttri);
12405     while (nexttri.tri != m->dummytri) {
12406       otricopy(nexttri, hulltri);
12407       oprev(hulltri, nexttri);
12408     }
12409   } while (!otriequal(hulltri, starttri));
12410 }
12411 
12412 /*****************************************************************************/
12413 /*                                                                           */
12414 /*  formskeleton()   Create the segments of a triangulation, including PSLG  */
12415 /*                   segments and edges on the convex hull.                  */
12416 /*                                                                           */
12417 /*  The PSLG segments are read from a .poly file.  The return value is the   */
12418 /*  number of segments in the file.                                          */
12419 /*                                                                           */
12420 /*****************************************************************************/
12421 
12422 #ifdef TRILIBRARY
12423 
12424 #ifdef ANSI_DECLARATORS
12425 void formskeleton(struct mesh *m, struct behavior *b, int *segmentlist,
12426                   int *segmentmarkerlist, int numberofsegments)
12427 #else /* not ANSI_DECLARATORS */
12428 void formskeleton(m, b, segmentlist, segmentmarkerlist, numberofsegments)
12429 struct mesh *m;
12430 struct behavior *b;
12431 int *segmentlist;
12432 int *segmentmarkerlist;
12433 int numberofsegments;
12434 #endif /* not ANSI_DECLARATORS */
12435 
12436 #else /* not TRILIBRARY */
12437 
12438 #ifdef ANSI_DECLARATORS
12439 void formskeleton(struct mesh *m, struct behavior *b,
12440                   FILE *polyfile, char *polyfilename)
12441 #else /* not ANSI_DECLARATORS */
12442 void formskeleton(m, b, polyfile, polyfilename)
12443 struct mesh *m;
12444 struct behavior *b;
12445 FILE *polyfile;
12446 char *polyfilename;
12447 #endif /* not ANSI_DECLARATORS */
12448 
12449 #endif /* not TRILIBRARY */
12450 
12451 {
12452 #ifdef TRILIBRARY
12453   char polyfilename[6];
12454   int index;
12455 #else /* not TRILIBRARY */
12456   char inputline[INPUTLINESIZE];
12457   char *stringptr;
12458 #endif /* not TRILIBRARY */
12459   vertex endpoint1, endpoint2;
12460   int segmentmarkers;
12461   int end1, end2;
12462   int boundmarker;
12463   int i;
12464 
12465   if (b->poly) {
12466     if (!b->quiet) {
12467       printf("Recovering segments in Delaunay triangulation.\n");
12468     }
12469 #ifdef TRILIBRARY
12470     strcpy(polyfilename, "input");
12471     m->insegments = numberofsegments;
12472     segmentmarkers = segmentmarkerlist != (int *) NULL;
12473     index = 0;
12474 #else /* not TRILIBRARY */
12475     /* Read the segments from a .poly file. */
12476     /* Read number of segments and number of boundary markers. */
12477     stringptr = readline(inputline, polyfile, polyfilename);
12478     m->insegments = (int) strtol(stringptr, &stringptr, 0);
12479     stringptr = findfield(stringptr);
12480     if (*stringptr == '\0') {
12481       segmentmarkers = 0;
12482     } else {
12483       segmentmarkers = (int) strtol(stringptr, &stringptr, 0);
12484     }
12485 #endif /* not TRILIBRARY */
12486     /* If the input vertices are collinear, there is no triangulation, */
12487     /*   so don't try to insert segments.                              */
12488     if (m->triangles.items == 0) {
12489       return;
12490     }
12491 
12492     /* If segments are to be inserted, compute a mapping */
12493     /*   from vertices to triangles.                     */
12494     if (m->insegments > 0) {
12495       makevertexmap(m, b);
12496       if (b->verbose) {
12497         printf("  Recovering PSLG segments.\n");
12498       }
12499     }
12500 
12501     boundmarker = 0;
12502     /* Read and insert the segments. */
12503     for (i = 0; i < m->insegments; i++) {
12504 #ifdef TRILIBRARY
12505       end1 = segmentlist[index++];
12506       end2 = segmentlist[index++];
12507       if (segmentmarkers) {
12508         boundmarker = segmentmarkerlist[i];
12509       }
12510 #else /* not TRILIBRARY */
12511       stringptr = readline(inputline, polyfile, b->inpolyfilename);
12512       stringptr = findfield(stringptr);
12513       if (*stringptr == '\0') {
12514         printf("Error:  Segment %d has no endpoints in %s.\n",
12515                b->firstnumber + i, polyfilename);
12516         triexit(1);
12517       } else {
12518         end1 = (int) strtol(stringptr, &stringptr, 0);
12519       }
12520       stringptr = findfield(stringptr);
12521       if (*stringptr == '\0') {
12522         printf("Error:  Segment %d is missing its second endpoint in %s.\n",
12523                b->firstnumber + i, polyfilename);
12524         triexit(1);
12525       } else {
12526         end2 = (int) strtol(stringptr, &stringptr, 0);
12527       }
12528       if (segmentmarkers) {
12529         stringptr = findfield(stringptr);
12530         if (*stringptr == '\0') {
12531           boundmarker = 0;
12532         } else {
12533           boundmarker = (int) strtol(stringptr, &stringptr, 0);
12534         }
12535       }
12536 #endif /* not TRILIBRARY */
12537       if ((end1 < b->firstnumber) ||
12538           (end1 >= b->firstnumber + m->invertices)) {
12539         if (!b->quiet) {
12540           printf("Warning:  Invalid first endpoint of segment %d in %s.\n",
12541                  b->firstnumber + i, polyfilename);
12542         }
12543       } else if ((end2 < b->firstnumber) ||
12544                  (end2 >= b->firstnumber + m->invertices)) {
12545         if (!b->quiet) {
12546           printf("Warning:  Invalid second endpoint of segment %d in %s.\n",
12547                  b->firstnumber + i, polyfilename);
12548         }
12549       } else {
12550         /* Find the vertices numbered `end1' and `end2'. */
12551         endpoint1 = getvertex(m, b, end1);
12552         endpoint2 = getvertex(m, b, end2);
12553         if ((endpoint1[0] == endpoint2[0]) && (endpoint1[1] == endpoint2[1])) {
12554           if (!b->quiet) {
12555             printf("Warning:  Endpoints of segment %d are coincident in %s.\n",
12556                    b->firstnumber + i, polyfilename);
12557           }
12558         } else {
12559           insertsegment(m, b, endpoint1, endpoint2, boundmarker);
12560         }
12561       }
12562     }
12563   } else {
12564     m->insegments = 0;
12565   }
12566   if (b->convex || !b->poly) {
12567     /* Enclose the convex hull with subsegments. */
12568     if (b->verbose) {
12569       printf("  Enclosing convex hull with segments.\n");
12570     }
12571     markhull(m, b);
12572   }
12573 }
12574 
12575 /**                                                                         **/
12576 /**                                                                         **/
12577 /********* Segment insertion ends here                               *********/
12578 
12579 /********* Carving out holes and concavities begins here             *********/
12580 /**                                                                         **/
12581 /**                                                                         **/
12582 
12583 /*****************************************************************************/
12584 /*                                                                           */
12585 /*  infecthull()   Virally infect all of the triangles of the convex hull    */
12586 /*                 that are not protected by subsegments.  Where there are   */
12587 /*                 subsegments, set boundary markers as appropriate.         */
12588 /*                                                                           */
12589 /*****************************************************************************/
12590 
12591 #ifdef ANSI_DECLARATORS
12592 void infecthull(struct mesh *m, struct behavior *b)
12593 #else /* not ANSI_DECLARATORS */
12594 void infecthull(m, b)
12595 struct mesh *m;
12596 struct behavior *b;
12597 #endif /* not ANSI_DECLARATORS */
12598 
12599 {
12600   struct otri hulltri;
12601   struct otri nexttri;
12602   struct otri starttri;
12603   struct osub hullsubseg;
12604   triangle **deadtriangle;
12605   vertex horg, hdest;
12606   triangle ptr;                         /* Temporary variable used by sym(). */
12607   subseg sptr;                      /* Temporary variable used by tspivot(). */
12608 
12609   if (b->verbose) {
12610     printf("  Marking concavities (external triangles) for elimination.\n");
12611   }
12612   /* Find a triangle handle on the hull. */
12613   hulltri.tri = m->dummytri;
12614   hulltri.orient = 0;
12615   symself(hulltri);
12616   /* Remember where we started so we know when to stop. */
12617   otricopy(hulltri, starttri);
12618   /* Go once counterclockwise around the convex hull. */
12619   do {
12620     /* Ignore triangles that are already infected. */
12621     if (!infected(hulltri)) {
12622       /* Is the triangle protected by a subsegment? */
12623       tspivot(hulltri, hullsubseg);
12624       if (hullsubseg.ss == m->dummysub) {
12625         /* The triangle is not protected; infect it. */
12626         if (!infected(hulltri)) {
12627           infect(hulltri);
12628           deadtriangle = (triangle **) poolalloc(&m->viri);
12629           *deadtriangle = hulltri.tri;
12630         }
12631       } else {
12632         /* The triangle is protected; set boundary markers if appropriate. */
12633         if (mark(hullsubseg) == 0) {
12634           setmark(hullsubseg, 1);
12635           org(hulltri, horg);
12636           dest(hulltri, hdest);
12637           if (vertexmark(horg) == 0) {
12638             setvertexmark(horg, 1);
12639           }
12640           if (vertexmark(hdest) == 0) {
12641             setvertexmark(hdest, 1);
12642           }
12643         }
12644       }
12645     }
12646     /* To find the next hull edge, go clockwise around the next vertex. */
12647     lnextself(hulltri);
12648     oprev(hulltri, nexttri);
12649     while (nexttri.tri != m->dummytri) {
12650       otricopy(nexttri, hulltri);
12651       oprev(hulltri, nexttri);
12652     }
12653   } while (!otriequal(hulltri, starttri));
12654 }
12655 
12656 /*****************************************************************************/
12657 /*                                                                           */
12658 /*  plague()   Spread the virus from all infected triangles to any neighbors */
12659 /*             not protected by subsegments.  Delete all infected triangles. */
12660 /*                                                                           */
12661 /*  This is the procedure that actually creates holes and concavities.       */
12662 /*                                                                           */
12663 /*  This procedure operates in two phases.  The first phase identifies all   */
12664 /*  the triangles that will die, and marks them as infected.  They are       */
12665 /*  marked to ensure that each triangle is added to the virus pool only      */
12666 /*  once, so the procedure will terminate.                                   */
12667 /*                                                                           */
12668 /*  The second phase actually eliminates the infected triangles.  It also    */
12669 /*  eliminates orphaned vertices.                                            */
12670 /*                                                                           */
12671 /*****************************************************************************/
12672 
12673 #ifdef ANSI_DECLARATORS
12674 void plague(struct mesh *m, struct behavior *b)
12675 #else /* not ANSI_DECLARATORS */
12676 void plague(m, b)
12677 struct mesh *m;
12678 struct behavior *b;
12679 #endif /* not ANSI_DECLARATORS */
12680 
12681 {
12682   struct otri testtri;
12683   struct otri neighbor;
12684   triangle **virusloop;
12685   triangle **deadtriangle;
12686   struct osub neighborsubseg;
12687   vertex testvertex;
12688   vertex norg, ndest;
12689   vertex deadorg, deaddest, deadapex;
12690   int killorg;
12691   triangle ptr;             /* Temporary variable used by sym() and onext(). */
12692   subseg sptr;                      /* Temporary variable used by tspivot(). */
12693 
12694   if (b->verbose) {
12695     printf("  Marking neighbors of marked triangles.\n");
12696   }
12697   /* Loop through all the infected triangles, spreading the virus to */
12698   /*   their neighbors, then to their neighbors' neighbors.          */
12699   traversalinit(&m->viri);
12700   virusloop = (triangle **) traverse(&m->viri);
12701   while (virusloop != (triangle **) NULL) {
12702     testtri.tri = *virusloop;
12703     /* A triangle is marked as infected by messing with one of its pointers */
12704     /*   to subsegments, setting it to an illegal value.  Hence, we have to */
12705     /*   temporarily uninfect this triangle so that we can examine its      */
12706     /*   adjacent subsegments.                                              */
12707     uninfect(testtri);
12708     if (b->verbose > 2) {
12709       /* Assign the triangle an orientation for convenience in */
12710       /*   checking its vertices.                              */
12711       testtri.orient = 0;
12712       org(testtri, deadorg);
12713       dest(testtri, deaddest);
12714       apex(testtri, deadapex);
12715       printf("    Checking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
12716              (double)deadorg[0], (double)deadorg[1], (double)deaddest[0], (double)deaddest[1],
12717              (double)deadapex[0], (double)deadapex[1]);
12718     }
12719     /* Check each of the triangle's three neighbors. */
12720     for (testtri.orient = 0; testtri.orient < 3; testtri.orient++) {
12721       /* Find the neighbor. */
12722       sym(testtri, neighbor);
12723       /* Check for a subsegment between the triangle and its neighbor. */
12724       tspivot(testtri, neighborsubseg);
12725       /* Check if the neighbor is nonexistent or already infected. */
12726       if ((neighbor.tri == m->dummytri) || infected(neighbor)) {
12727         if (neighborsubseg.ss != m->dummysub) {
12728           /* There is a subsegment separating the triangle from its      */
12729           /*   neighbor, but both triangles are dying, so the subsegment */
12730           /*   dies too.                                                 */
12731           subsegdealloc(m, neighborsubseg.ss);
12732           if (neighbor.tri != m->dummytri) {
12733             /* Make sure the subsegment doesn't get deallocated again */
12734             /*   later when the infected neighbor is visited.         */
12735             uninfect(neighbor);
12736             tsdissolve(neighbor);
12737             infect(neighbor);
12738           }
12739         }
12740       } else {                   /* The neighbor exists and is not infected. */
12741         if (neighborsubseg.ss == m->dummysub) {
12742           /* There is no subsegment protecting the neighbor, so */
12743           /*   the neighbor becomes infected.                   */
12744           if (b->verbose > 2) {
12745             org(neighbor, deadorg);
12746             dest(neighbor, deaddest);
12747             apex(neighbor, deadapex);
12748             printf(
12749               "    Marking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
12750                    (double)deadorg[0], (double)deadorg[1], (double)deaddest[0], (double)deaddest[1],
12751                    (double)deadapex[0], (double)deadapex[1]);
12752           }
12753           infect(neighbor);
12754           /* Ensure that the neighbor's neighbors will be infected. */
12755           deadtriangle = (triangle **) poolalloc(&m->viri);
12756           *deadtriangle = neighbor.tri;
12757         } else {               /* The neighbor is protected by a subsegment. */
12758           /* Remove this triangle from the subsegment. */
12759           stdissolve(neighborsubseg);
12760           /* The subsegment becomes a boundary.  Set markers accordingly. */
12761           if (mark(neighborsubseg) == 0) {
12762             setmark(neighborsubseg, 1);
12763           }
12764           org(neighbor, norg);
12765           dest(neighbor, ndest);
12766           if (vertexmark(norg) == 0) {
12767             setvertexmark(norg, 1);
12768           }
12769           if (vertexmark(ndest) == 0) {
12770             setvertexmark(ndest, 1);
12771           }
12772         }
12773       }
12774     }
12775     /* Remark the triangle as infected, so it doesn't get added to the */
12776     /*   virus pool again.                                             */
12777     infect(testtri);
12778     virusloop = (triangle **) traverse(&m->viri);
12779   }
12780 
12781   if (b->verbose) {
12782     printf("  Deleting marked triangles.\n");
12783   }
12784 
12785   traversalinit(&m->viri);
12786   virusloop = (triangle **) traverse(&m->viri);
12787   while (virusloop != (triangle **) NULL) {
12788     testtri.tri = *virusloop;
12789 
12790     /* Check each of the three corners of the triangle for elimination. */
12791     /*   This is done by walking around each vertex, checking if it is  */
12792     /*   still connected to at least one live triangle.                 */
12793     for (testtri.orient = 0; testtri.orient < 3; testtri.orient++) {
12794       org(testtri, testvertex);
12795       /* Check if the vertex has already been tested. */
12796       if (testvertex != (vertex) NULL) {
12797         killorg = 1;
12798         /* Mark the corner of the triangle as having been tested. */
12799         setorg(testtri, NULL);
12800         /* Walk counterclockwise about the vertex. */
12801         onext(testtri, neighbor);
12802         /* Stop upon reaching a boundary or the starting triangle. */
12803         while ((neighbor.tri != m->dummytri) &&
12804                (!otriequal(neighbor, testtri))) {
12805           if (infected(neighbor)) {
12806             /* Mark the corner of this triangle as having been tested. */
12807             setorg(neighbor, NULL);
12808           } else {
12809             /* A live triangle.  The vertex survives. */
12810             killorg = 0;
12811           }
12812           /* Walk counterclockwise about the vertex. */
12813           onextself(neighbor);
12814         }
12815         /* If we reached a boundary, we must walk clockwise as well. */
12816         if (neighbor.tri == m->dummytri) {
12817           /* Walk clockwise about the vertex. */
12818           oprev(testtri, neighbor);
12819           /* Stop upon reaching a boundary. */
12820           while (neighbor.tri != m->dummytri) {
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 clockwise about the vertex. */
12829             oprevself(neighbor);
12830           }
12831         }
12832         if (killorg) {
12833           if (b->verbose > 1) {
12834             printf("    Deleting vertex (%.12g, %.12g)\n",
12835                    (double)testvertex[0], (double)testvertex[1]);
12836           }
12837           setvertextype(testvertex, UNDEADVERTEX);
12838           m->undeads++;
12839         }
12840       }
12841     }
12842 
12843     /* Record changes in the number of boundary edges, and disconnect */
12844     /*   dead triangles from their neighbors.                         */
12845     for (testtri.orient = 0; testtri.orient < 3; testtri.orient++) {
12846       sym(testtri, neighbor);
12847       if (neighbor.tri == m->dummytri) {
12848         /* There is no neighboring triangle on this edge, so this edge    */
12849         /*   is a boundary edge.  This triangle is being deleted, so this */
12850         /*   boundary edge is deleted.                                    */
12851         m->hullsize--;
12852       } else {
12853         /* Disconnect the triangle from its neighbor. */
12854         dissolve(neighbor);
12855         /* There is a neighboring triangle on this edge, so this edge */
12856         /*   becomes a boundary edge when this triangle is deleted.   */
12857         m->hullsize++;
12858       }
12859     }
12860     /* Return the dead triangle to the pool of triangles. */
12861     triangledealloc(m, testtri.tri);
12862     virusloop = (triangle **) traverse(&m->viri);
12863   }
12864   /* Empty the virus pool. */
12865   poolrestart(&m->viri);
12866 }
12867 
12868 /*****************************************************************************/
12869 /*                                                                           */
12870 /*  regionplague()   Spread regional attributes and/or area constraints      */
12871 /*                   (from a .poly file) throughout the mesh.                */
12872 /*                                                                           */
12873 /*  This procedure operates in two phases.  The first phase spreads an       */
12874 /*  attribute and/or an area constraint through a (segment-bounded) region.  */
12875 /*  The triangles are marked to ensure that each triangle is added to the    */
12876 /*  virus pool only once, so the procedure will terminate.                   */
12877 /*                                                                           */
12878 /*  The second phase uninfects all infected triangles, returning them to     */
12879 /*  normal.                                                                  */
12880 /*                                                                           */
12881 /*****************************************************************************/
12882 
12883 #ifdef ANSI_DECLARATORS
12884 void regionplague(struct mesh *m, struct behavior *b,
12885                   REAL attribute, REAL area)
12886 #else /* not ANSI_DECLARATORS */
12887 void regionplague(m, b, attribute, area)
12888 struct mesh *m;
12889 struct behavior *b;
12890 REAL attribute;
12891 REAL area;
12892 #endif /* not ANSI_DECLARATORS */
12893 
12894 {
12895   struct otri testtri;
12896   struct otri neighbor;
12897   triangle **virusloop;
12898   triangle **regiontri;
12899   struct osub neighborsubseg;
12900   vertex regionorg, regiondest, regionapex;
12901   triangle ptr;             /* Temporary variable used by sym() and onext(). */
12902   subseg sptr;                      /* Temporary variable used by tspivot(). */
12903 
12904   if (b->verbose > 1) {
12905     printf("  Marking neighbors of marked triangles.\n");
12906   }
12907   /* Loop through all the infected triangles, spreading the attribute      */
12908   /*   and/or area constraint to their neighbors, then to their neighbors' */
12909   /*   neighbors.                                                          */
12910   traversalinit(&m->viri);
12911   virusloop = (triangle **) traverse(&m->viri);
12912   while (virusloop != (triangle **) NULL) {
12913     testtri.tri = *virusloop;
12914     /* A triangle is marked as infected by messing with one of its pointers */
12915     /*   to subsegments, setting it to an illegal value.  Hence, we have to */
12916     /*   temporarily uninfect this triangle so that we can examine its      */
12917     /*   adjacent subsegments.                                              */
12918     uninfect(testtri);
12919     if (b->regionattrib) {
12920       /* Set an attribute. */
12921       setelemattribute(testtri, m->eextras, attribute);
12922     }
12923     if (b->vararea) {
12924       /* Set an area constraint. */
12925       setareabound(testtri, area);
12926     }
12927     if (b->verbose > 2) {
12928       /* Assign the triangle an orientation for convenience in */
12929       /*   checking its vertices.                              */
12930       testtri.orient = 0;
12931       org(testtri, regionorg);
12932       dest(testtri, regiondest);
12933       apex(testtri, regionapex);
12934       printf("    Checking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
12935              (double)regionorg[0], (double)regionorg[1], (double)regiondest[0], (double)regiondest[1],
12936              (double)regionapex[0], (double)regionapex[1]);
12937     }
12938     /* Check each of the triangle's three neighbors. */
12939     for (testtri.orient = 0; testtri.orient < 3; testtri.orient++) {
12940       /* Find the neighbor. */
12941       sym(testtri, neighbor);
12942       /* Check for a subsegment between the triangle and its neighbor. */
12943       tspivot(testtri, neighborsubseg);
12944       /* Make sure the neighbor exists, is not already infected, and */
12945       /*   isn't protected by a subsegment.                          */
12946       if ((neighbor.tri != m->dummytri) && !infected(neighbor)
12947           && (neighborsubseg.ss == m->dummysub)) {
12948         if (b->verbose > 2) {
12949           org(neighbor, regionorg);
12950           dest(neighbor, regiondest);
12951           apex(neighbor, regionapex);
12952           printf("    Marking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
12953                  (double)regionorg[0], (double)regionorg[1], (double)regiondest[0], (double)regiondest[1],
12954                  (double)regionapex[0], (double)regionapex[1]);
12955         }
12956         /* Infect the neighbor. */
12957         infect(neighbor);
12958         /* Ensure that the neighbor's neighbors will be infected. */
12959         regiontri = (triangle **) poolalloc(&m->viri);
12960         *regiontri = neighbor.tri;
12961       }
12962     }
12963     /* Remark the triangle as infected, so it doesn't get added to the */
12964     /*   virus pool again.                                             */
12965     infect(testtri);
12966     virusloop = (triangle **) traverse(&m->viri);
12967   }
12968 
12969   /* Uninfect all triangles. */
12970   if (b->verbose > 1) {
12971     printf("  Unmarking marked triangles.\n");
12972   }
12973   traversalinit(&m->viri);
12974   virusloop = (triangle **) traverse(&m->viri);
12975   while (virusloop != (triangle **) NULL) {
12976     testtri.tri = *virusloop;
12977     uninfect(testtri);
12978     virusloop = (triangle **) traverse(&m->viri);
12979   }
12980   /* Empty the virus pool. */
12981   poolrestart(&m->viri);
12982 }
12983 
12984 /*****************************************************************************/
12985 /*                                                                           */
12986 /*  carveholes()   Find the holes and infect them.  Find the area            */
12987 /*                 constraints and infect them.  Infect the convex hull.     */
12988 /*                 Spread the infection and kill triangles.  Spread the      */
12989 /*                 area constraints.                                         */
12990 /*                                                                           */
12991 /*  This routine mainly calls other routines to carry out all these          */
12992 /*  functions.                                                               */
12993 /*                                                                           */
12994 /*****************************************************************************/
12995 
12996 #ifdef ANSI_DECLARATORS
12997 void carveholes(struct mesh *m, struct behavior *b, REAL *holelist, int holes,
12998                 REAL *regionlist, int regions)
12999 #else /* not ANSI_DECLARATORS */
13000 void carveholes(m, b, holelist, holes, regionlist, regions)
13001 struct mesh *m;
13002 struct behavior *b;
13003 REAL *holelist;
13004 int holes;
13005 REAL *regionlist;
13006 int regions;
13007 #endif /* not ANSI_DECLARATORS */
13008 
13009 {
13010   struct otri searchtri;
13011   struct otri triangleloop;
13012   struct otri *regiontris;
13013   triangle **holetri;
13014   triangle **regiontri;
13015   vertex searchorg, searchdest;
13016   enum locateresult intersect;
13017   int i;
13018   triangle ptr;                         /* Temporary variable used by sym(). */
13019 
13020   if (!(b->quiet || (b->noholes && b->convex))) {
13021     printf("Removing unwanted triangles.\n");
13022     if (b->verbose && (holes > 0)) {
13023       printf("  Marking holes for elimination.\n");
13024     }
13025   }
13026 
13027   if (regions > 0) {
13028     /* Allocate storage for the triangles in which region points fall. */
13029     regiontris = (struct otri *) trimalloc(regions *
13030                                            (int) sizeof(struct otri));
13031   } else {
13032     regiontris = (struct otri *) NULL;
13033   }
13034 
13035   if (((holes > 0) && !b->noholes) || !b->convex || (regions > 0)) {
13036     /* Initialize a pool of viri to be used for holes, concavities, */
13037     /*   regional attributes, and/or regional area constraints.     */
13038     poolinit(&m->viri, sizeof(triangle *), VIRUSPERBLOCK, VIRUSPERBLOCK, 0);
13039   }
13040 
13041   if (!b->convex) {
13042     /* Mark as infected any unprotected triangles on the boundary. */
13043     /*   This is one way by which concavities are created.         */
13044     infecthull(m, b);
13045   }
13046 
13047   if ((holes > 0) && !b->noholes) {
13048     /* Infect each triangle in which a hole lies. */
13049     for (i = 0; i < 2 * holes; i += 2) {
13050       /* Ignore holes that aren't within the bounds of the mesh. */
13051       if ((holelist[i] >= m->xmin) && (holelist[i] <= m->xmax)
13052           && (holelist[i + 1] >= m->ymin) && (holelist[i + 1] <= m->ymax)) {
13053         /* Start searching from some triangle on the outer boundary. */
13054         searchtri.tri = m->dummytri;
13055         searchtri.orient = 0;
13056         symself(searchtri);
13057         /* Ensure that the hole is to the left of this boundary edge; */
13058         /*   otherwise, locate() will falsely report that the hole    */
13059         /*   falls within the starting triangle.                      */
13060         org(searchtri, searchorg);
13061         dest(searchtri, searchdest);
13062         if (counterclockwise(m, b, searchorg, searchdest, &holelist[i]) >
13063             0.0) {
13064           /* Find a triangle that contains the hole. */
13065           intersect = locate(m, b, &holelist[i], &searchtri);
13066           if ((intersect != OUTSIDE) && (!infected(searchtri))) {
13067             /* Infect the triangle.  This is done by marking the triangle  */
13068             /*   as infected and including the triangle in the virus pool. */
13069             infect(searchtri);
13070             holetri = (triangle **) poolalloc(&m->viri);
13071             *holetri = searchtri.tri;
13072           }
13073         }
13074       }
13075     }
13076   }
13077 
13078   /* Now, we have to find all the regions BEFORE we carve the holes, because */
13079   /*   locate() won't work when the triangulation is no longer convex.       */
13080   /*   (Incidentally, this is the reason why regional attributes and area    */
13081   /*   constraints can't be used when refining a preexisting mesh, which     */
13082   /*   might not be convex; they can only be used with a freshly             */
13083   /*   triangulated PSLG.)                                                   */
13084   if (regions > 0) {
13085     /* Find the starting triangle for each region. */
13086     for (i = 0; i < regions; i++) {
13087       regiontris[i].tri = m->dummytri;
13088       /* Ignore region points that aren't within the bounds of the mesh. */
13089       if ((regionlist[4 * i] >= m->xmin) && (regionlist[4 * i] <= m->xmax) &&
13090           (regionlist[4 * i + 1] >= m->ymin) &&
13091           (regionlist[4 * i + 1] <= m->ymax)) {
13092         /* Start searching from some triangle on the outer boundary. */
13093         searchtri.tri = m->dummytri;
13094         searchtri.orient = 0;
13095         symself(searchtri);
13096         /* Ensure that the region point is to the left of this boundary */
13097         /*   edge; otherwise, locate() will falsely report that the     */
13098         /*   region point falls within the starting triangle.           */
13099         org(searchtri, searchorg);
13100         dest(searchtri, searchdest);
13101         if (counterclockwise(m, b, searchorg, searchdest, &regionlist[4 * i]) >
13102             0.0) {
13103           /* Find a triangle that contains the region point. */
13104           intersect = locate(m, b, &regionlist[4 * i], &searchtri);
13105           if ((intersect != OUTSIDE) && (!infected(searchtri))) {
13106             /* Record the triangle for processing after the */
13107             /*   holes have been carved.                    */
13108             otricopy(searchtri, regiontris[i]);
13109           }
13110         }
13111       }
13112     }
13113   }
13114 
13115   if (m->viri.items > 0) {
13116     /* Carve the holes and concavities. */
13117     plague(m, b);
13118   }
13119   /* The virus pool should be empty now. */
13120 
13121   if (regions > 0) {
13122     if (!b->quiet) {
13123       if (b->regionattrib) {
13124         if (b->vararea) {
13125           printf("Spreading regional attributes and area constraints.\n");
13126         } else {
13127           printf("Spreading regional attributes.\n");
13128         }
13129       } else {
13130         printf("Spreading regional area constraints.\n");
13131       }
13132     }
13133     if (b->regionattrib && !b->refine) {
13134       /* Assign every triangle a regional attribute of zero. */
13135       traversalinit(&m->triangles);
13136       triangleloop.orient = 0;
13137       triangleloop.tri = triangletraverse(m);
13138       while (triangleloop.tri != (triangle *) NULL) {
13139         setelemattribute(triangleloop, m->eextras, 0.0);
13140         triangleloop.tri = triangletraverse(m);
13141       }
13142     }
13143     for (i = 0; i < regions; i++) {
13144       if (regiontris[i].tri != m->dummytri) {
13145         /* Make sure the triangle under consideration still exists. */
13146         /*   It may have been eaten by the virus.                   */
13147         if (!deadtri(regiontris[i].tri)) {
13148           /* Put one triangle in the virus pool. */
13149           infect(regiontris[i]);
13150           regiontri = (triangle **) poolalloc(&m->viri);
13151           *regiontri = regiontris[i].tri;
13152           /* Apply one region's attribute and/or area constraint. */
13153           regionplague(m, b, regionlist[4 * i + 2], regionlist[4 * i + 3]);
13154           /* The virus pool should be empty now. */
13155         }
13156       }
13157     }
13158     if (b->regionattrib && !b->refine) {
13159       /* Note the fact that each triangle has an additional attribute. */
13160       m->eextras++;
13161     }
13162   }
13163 
13164   /* Free up memory. */
13165   if (((holes > 0) && !b->noholes) || !b->convex || (regions > 0)) {
13166     pooldeinit(&m->viri);
13167   }
13168   if (regions > 0) {
13169     trifree((VOID *) regiontris);
13170   }
13171 }
13172 
13173 /**                                                                         **/
13174 /**                                                                         **/
13175 /********* Carving out holes and concavities ends here               *********/
13176 
13177 /********* Mesh quality maintenance begins here                      *********/
13178 /**                                                                         **/
13179 /**                                                                         **/
13180 
13181 /*****************************************************************************/
13182 /*                                                                           */
13183 /*  tallyencs()   Traverse the entire list of subsegments, and check each    */
13184 /*                to see if it is encroached.  If so, add it to the list.    */
13185 /*                                                                           */
13186 /*****************************************************************************/
13187 
13188 #ifndef CDT_ONLY
13189 
13190 #ifdef ANSI_DECLARATORS
13191 void tallyencs(struct mesh *m, struct behavior *b)
13192 #else /* not ANSI_DECLARATORS */
13193 void tallyencs(m, b)
13194 struct mesh *m;
13195 struct behavior *b;
13196 #endif /* not ANSI_DECLARATORS */
13197 
13198 {
13199   struct osub subsegloop;
13200   int dummy;
13201 
13202   traversalinit(&m->subsegs);
13203   subsegloop.ssorient = 0;
13204   subsegloop.ss = subsegtraverse(m);
13205   while (subsegloop.ss != (subseg *) NULL) {
13206     /* If the segment is encroached, add it to the list. */
13207     dummy = checkseg4encroach(m, b, &subsegloop);
13208     subsegloop.ss = subsegtraverse(m);
13209   }
13210 }
13211 
13212 #endif /* not CDT_ONLY */
13213 
13214 /*****************************************************************************/
13215 /*                                                                           */
13216 /*  precisionerror()  Print an error message for precision problems.         */
13217 /*                                                                           */
13218 /*****************************************************************************/
13219 
13220 #ifndef CDT_ONLY
13221 
13222 void precisionerror()
13223 {
13224   printf("Try increasing the area criterion and/or reducing the minimum\n");
13225   printf("  allowable angle so that tiny triangles are not created.\n");
13226 #ifdef SINGLE
13227   printf("Alternatively, try recompiling me with double precision\n");
13228   printf("  arithmetic (by removing \"#define SINGLE\" from the\n");
13229   printf("  source file or \"-DSINGLE\" from the makefile).\n");
13230 #endif /* SINGLE */
13231 }
13232 
13233 #endif /* not CDT_ONLY */
13234 
13235 /*****************************************************************************/
13236 /*                                                                           */
13237 /*  splitencsegs()   Split all the encroached subsegments.                   */
13238 /*                                                                           */
13239 /*  Each encroached subsegment is repaired by splitting it - inserting a     */
13240 /*  vertex at or near its midpoint.  Newly inserted vertices may encroach    */
13241 /*  upon other subsegments; these are also repaired.                         */
13242 /*                                                                           */
13243 /*  `triflaws' is a flag that specifies whether one should take note of new  */
13244 /*  bad triangles that result from inserting vertices to repair encroached   */
13245 /*  subsegments.                                                             */
13246 /*                                                                           */
13247 /*****************************************************************************/
13248 
13249 #ifndef CDT_ONLY
13250 
13251 #ifdef ANSI_DECLARATORS
13252 void splitencsegs(struct mesh *m, struct behavior *b, int triflaws)
13253 #else /* not ANSI_DECLARATORS */
13254 void splitencsegs(m, b, triflaws)
13255 struct mesh *m;
13256 struct behavior *b;
13257 int triflaws;
13258 #endif /* not ANSI_DECLARATORS */
13259 
13260 {
13261   struct otri enctri;
13262   struct otri testtri;
13263   struct osub testsh;
13264   struct osub currentenc;
13265   struct badsubseg *encloop;
13266   vertex eorg, edest, eapex;
13267   vertex newvertex;
13268   enum insertvertexresult success;
13269   REAL segmentlength, nearestpoweroftwo;
13270   REAL split;
13271   REAL multiplier, divisor;
13272   int acuteorg, acuteorg2, acutedest, acutedest2;
13273   int dummy;
13274   int i;
13275   triangle ptr;                     /* Temporary variable used by stpivot(). */
13276   subseg sptr;                        /* Temporary variable used by snext(). */
13277 
13278   /* Note that steinerleft == -1 if an unlimited number */
13279   /*   of Steiner points is allowed.                    */
13280   while ((m->badsubsegs.items > 0) && (m->steinerleft != 0)) {
13281     traversalinit(&m->badsubsegs);
13282     encloop = badsubsegtraverse(m);
13283     while ((encloop != (struct badsubseg *) NULL) && (m->steinerleft != 0)) {
13284       sdecode(encloop->encsubseg, currentenc);
13285       sorg(currentenc, eorg);
13286       sdest(currentenc, edest);
13287       /* Make sure that this segment is still the same segment it was   */
13288       /*   when it was determined to be encroached.  If the segment was */
13289       /*   enqueued multiple times (because several newly inserted      */
13290       /*   vertices encroached it), it may have already been split.     */
13291       if (!deadsubseg(currentenc.ss) &&
13292           (eorg == encloop->subsegorg) && (edest == encloop->subsegdest)) {
13293         /* To decide where to split a segment, we need to know if the   */
13294         /*   segment shares an endpoint with an adjacent segment.       */
13295         /*   The concern is that, if we simply split every encroached   */
13296         /*   segment in its center, two adjacent segments with a small  */
13297         /*   angle between them might lead to an infinite loop; each    */
13298         /*   vertex added to split one segment will encroach upon the   */
13299         /*   other segment, which must then be split with a vertex that */
13300         /*   will encroach upon the first segment, and so on forever.   */
13301         /* To avoid this, imagine a set of concentric circles, whose    */
13302         /*   radii are powers of two, about each segment endpoint.      */
13303         /*   These concentric circles determine where the segment is    */
13304         /*   split.  (If both endpoints are shared with adjacent        */
13305         /*   segments, split the segment in the middle, and apply the   */
13306         /*   concentric circles for later splittings.)                  */
13307 
13308         /* Is the origin shared with another segment? */
13309         stpivot(currentenc, enctri);
13310         lnext(enctri, testtri);
13311         tspivot(testtri, testsh);
13312         acuteorg = testsh.ss != m->dummysub;
13313         /* Is the destination shared with another segment? */
13314         lnextself(testtri);
13315         tspivot(testtri, testsh);
13316         acutedest = testsh.ss != m->dummysub;
13317 
13318         /* If we're using Chew's algorithm (rather than Ruppert's) */
13319         /*   to define encroachment, delete free vertices from the */
13320         /*   subsegment's diametral circle.                        */
13321         if (!b->conformdel && !acuteorg && !acutedest) {
13322           apex(enctri, eapex);
13323           while ((vertextype(eapex) == FREEVERTEX) &&
13324                  ((eorg[0] - eapex[0]) * (edest[0] - eapex[0]) +
13325                   (eorg[1] - eapex[1]) * (edest[1] - eapex[1]) < 0.0)) {
13326             deletevertex(m, b, &testtri);
13327             stpivot(currentenc, enctri);
13328             apex(enctri, eapex);
13329             lprev(enctri, testtri);
13330           }
13331         }
13332 
13333         /* Now, check the other side of the segment, if there's a triangle */
13334         /*   there.                                                        */
13335         sym(enctri, testtri);
13336         if (testtri.tri != m->dummytri) {
13337           /* Is the destination shared with another segment? */
13338           lnextself(testtri);
13339           tspivot(testtri, testsh);
13340           acutedest2 = testsh.ss != m->dummysub;
13341           acutedest = acutedest || acutedest2;
13342           /* Is the origin shared with another segment? */
13343           lnextself(testtri);
13344           tspivot(testtri, testsh);
13345           acuteorg2 = testsh.ss != m->dummysub;
13346           acuteorg = acuteorg || acuteorg2;
13347 
13348           /* Delete free vertices from the subsegment's diametral circle. */
13349           if (!b->conformdel && !acuteorg2 && !acutedest2) {
13350             org(testtri, eapex);
13351             while ((vertextype(eapex) == FREEVERTEX) &&
13352                    ((eorg[0] - eapex[0]) * (edest[0] - eapex[0]) +
13353                     (eorg[1] - eapex[1]) * (edest[1] - eapex[1]) < 0.0)) {
13354               deletevertex(m, b, &testtri);
13355               sym(enctri, testtri);
13356               apex(testtri, eapex);
13357               lprevself(testtri);
13358             }
13359           }
13360         }
13361 
13362         /* Use the concentric circles if exactly one endpoint is shared */
13363         /*   with another adjacent segment.                             */
13364         if (acuteorg || acutedest) {
13365           segmentlength = sqrt((edest[0] - eorg[0]) * (edest[0] - eorg[0]) +
13366                                (edest[1] - eorg[1]) * (edest[1] - eorg[1]));
13367           /* Find the power of two that most evenly splits the segment.  */
13368           /*   The worst case is a 2:1 ratio between subsegment lengths. */
13369           nearestpoweroftwo = 1.0;
13370           while (segmentlength > 3.0 * nearestpoweroftwo) {
13371             nearestpoweroftwo *= 2.0;
13372           }
13373           while (segmentlength < 1.5 * nearestpoweroftwo) {
13374             nearestpoweroftwo *= 0.5;
13375           }
13376           /* Where do we split the segment? */
13377           split = nearestpoweroftwo / segmentlength;
13378           if (acutedest) {
13379             split = 1.0 - split;
13380           }
13381         } else {
13382           /* If we're not worried about adjacent segments, split */
13383           /*   this segment in the middle.                       */
13384           split = 0.5;
13385         }
13386 
13387         /* Create the new vertex. */
13388         newvertex = (vertex) poolalloc(&m->vertices);
13389         /* Interpolate its coordinate and attributes. */
13390         for (i = 0; i < 2 + m->nextras; i++) {
13391           newvertex[i] = eorg[i] + split * (edest[i] - eorg[i]);
13392         }
13393 
13394         if (!b->noexact) {
13395           /* Roundoff in the above calculation may yield a `newvertex'   */
13396           /*   that is not precisely collinear with `eorg' and `edest'.  */
13397           /*   Improve collinearity by one step of iterative refinement. */
13398           multiplier = counterclockwise(m, b, eorg, edest, newvertex);
13399           divisor = ((eorg[0] - edest[0]) * (eorg[0] - edest[0]) +
13400                      (eorg[1] - edest[1]) * (eorg[1] - edest[1]));
13401           if ((multiplier != 0.0) && (divisor != 0.0)) {
13402             multiplier = multiplier / divisor;
13403             /* Watch out for NANs. */
13404             if (multiplier == multiplier) {
13405               newvertex[0] += multiplier * (edest[1] - eorg[1]);
13406               newvertex[1] += multiplier * (eorg[0] - edest[0]);
13407             }
13408           }
13409         }
13410 
13411         setvertexmark(newvertex, mark(currentenc));
13412         setvertextype(newvertex, SEGMENTVERTEX);
13413         if (b->verbose > 1) {
13414           printf(
13415   "  Splitting subsegment (%.12g, %.12g) (%.12g, %.12g) at (%.12g, %.12g).\n",
13416                  (double)eorg[0], (double)eorg[1], (double)edest[0], (double)edest[1],
13417                  (double)newvertex[0], (double)newvertex[1]);
13418         }
13419         /* Check whether the new vertex lies on an endpoint. */
13420         if (((newvertex[0] == eorg[0]) && (newvertex[1] == eorg[1])) ||
13421             ((newvertex[0] == edest[0]) && (newvertex[1] == edest[1]))) {
13422           printf("Error:  Ran out of precision at (%.12g, %.12g).\n",
13423                  (double)newvertex[0], (double)newvertex[1]);
13424           printf("I attempted to split a segment to a smaller size than\n");
13425           printf("  can be accommodated by the finite precision of\n");
13426           printf("  floating point arithmetic.\n");
13427           precisionerror();
13428           triexit(1);
13429         }
13430         /* Insert the splitting vertex.  This should always succeed. */
13431         success = insertvertex(m, b, newvertex, &enctri, &currentenc,
13432                                1, triflaws);
13433         if ((success != SUCCESSFULVERTEX) && (success != ENCROACHINGVERTEX)) {
13434           printf("Internal error in splitencsegs():\n");
13435           printf("  Failure to split a segment.\n");
13436           internalerror();
13437         }
13438         if (m->steinerleft > 0) {
13439           m->steinerleft--;
13440         }
13441         /* Check the two new subsegments to see if they're encroached. */
13442         dummy = checkseg4encroach(m, b, &currentenc);
13443         snextself(currentenc);
13444         dummy = checkseg4encroach(m, b, &currentenc);
13445       }
13446 
13447       badsubsegdealloc(m, encloop);
13448       encloop = badsubsegtraverse(m);
13449     }
13450   }
13451 }
13452 
13453 #endif /* not CDT_ONLY */
13454 
13455 /*****************************************************************************/
13456 /*                                                                           */
13457 /*  tallyfaces()   Test every triangle in the mesh for quality measures.     */
13458 /*                                                                           */
13459 /*****************************************************************************/
13460 
13461 #ifndef CDT_ONLY
13462 
13463 #ifdef ANSI_DECLARATORS
13464 void tallyfaces(struct mesh *m, struct behavior *b)
13465 #else /* not ANSI_DECLARATORS */
13466 void tallyfaces(m, b)
13467 struct mesh *m;
13468 struct behavior *b;
13469 #endif /* not ANSI_DECLARATORS */
13470 
13471 {
13472   struct otri triangleloop;
13473 
13474   if (b->verbose) {
13475     printf("  Making a list of bad triangles.\n");
13476   }
13477   traversalinit(&m->triangles);
13478   triangleloop.orient = 0;
13479   triangleloop.tri = triangletraverse(m);
13480   while (triangleloop.tri != (triangle *) NULL) {
13481     /* If the triangle is bad, enqueue it. */
13482     testtriangle(m, b, &triangleloop);
13483     triangleloop.tri = triangletraverse(m);
13484   }
13485 }
13486 
13487 #endif /* not CDT_ONLY */
13488 
13489 /*****************************************************************************/
13490 /*                                                                           */
13491 /*  splittriangle()   Inserts a vertex at the circumcenter of a triangle.    */
13492 /*                    Deletes the newly inserted vertex if it encroaches     */
13493 /*                    upon a segment.                                        */
13494 /*                                                                           */
13495 /*****************************************************************************/
13496 
13497 #ifndef CDT_ONLY
13498 
13499 #ifdef ANSI_DECLARATORS
13500 void splittriangle(struct mesh *m, struct behavior *b,
13501                    struct badtriang *badtri)
13502 #else /* not ANSI_DECLARATORS */
13503 void splittriangle(m, b, badtri)
13504 struct mesh *m;
13505 struct behavior *b;
13506 struct badtriang *badtri;
13507 #endif /* not ANSI_DECLARATORS */
13508 
13509 {
13510   struct otri badotri;
13511   vertex borg, bdest, bapex;
13512   vertex newvertex;
13513   REAL xi, eta;
13514   enum insertvertexresult success;
13515   int errorflag;
13516   int i;
13517 
13518   decode(badtri->poortri, badotri);
13519   org(badotri, borg);
13520   dest(badotri, bdest);
13521   apex(badotri, bapex);
13522   /* Make sure that this triangle is still the same triangle it was      */
13523   /*   when it was tested and determined to be of bad quality.           */
13524   /*   Subsequent transformations may have made it a different triangle. */
13525   if (!deadtri(badotri.tri) && (borg == badtri->triangorg) &&
13526       (bdest == badtri->triangdest) && (bapex == badtri->triangapex)) {
13527     if (b->verbose > 1) {
13528       printf("  Splitting this triangle at its circumcenter:\n");
13529       printf("    (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n", (double)borg[0],
13530              (double)borg[1], (double)bdest[0], (double)bdest[1], (double)bapex[0], (double)bapex[1]);
13531     }
13532 
13533     errorflag = 0;
13534     /* Create a new vertex at the triangle's circumcenter. */
13535     newvertex = (vertex) poolalloc(&m->vertices);
13536     findcircumcenter(m, b, borg, bdest, bapex, newvertex, &xi, &eta, 1);
13537 
13538     /* Check whether the new vertex lies on a triangle vertex. */
13539     if (((newvertex[0] == borg[0]) && (newvertex[1] == borg[1])) ||
13540         ((newvertex[0] == bdest[0]) && (newvertex[1] == bdest[1])) ||
13541         ((newvertex[0] == bapex[0]) && (newvertex[1] == bapex[1]))) {
13542       if (!b->quiet) {
13543         printf(
13544              "Warning:  New vertex (%.12g, %.12g) falls on existing vertex.\n",
13545                (double)newvertex[0], (double)newvertex[1]);
13546         errorflag = 1;
13547       }
13548       vertexdealloc(m, newvertex);
13549     } else {
13550       for (i = 2; i < 2 + m->nextras; i++) {
13551         /* Interpolate the vertex attributes at the circumcenter. */
13552         newvertex[i] = borg[i] + xi * (bdest[i] - borg[i])
13553                               + eta * (bapex[i] - borg[i]);
13554       }
13555       /* The new vertex must be in the interior, and therefore is a */
13556       /*   free vertex with a marker of zero.                       */
13557       setvertexmark(newvertex, 0);
13558       setvertextype(newvertex, FREEVERTEX);
13559 
13560       /* Ensure that the handle `badotri' does not represent the longest  */
13561       /*   edge of the triangle.  This ensures that the circumcenter must */
13562       /*   fall to the left of this edge, so point location will work.    */
13563       /*   (If the angle org-apex-dest exceeds 90 degrees, then the       */
13564       /*   circumcenter lies outside the org-dest edge, and eta is        */
13565       /*   negative.  Roundoff error might prevent eta from being         */
13566       /*   negative when it should be, so I test eta against xi.)         */
13567       if (eta < xi) {
13568         lprevself(badotri);
13569       }
13570 
13571       /* Insert the circumcenter, searching from the edge of the triangle, */
13572       /*   and maintain the Delaunay property of the triangulation.        */
13573       success = insertvertex(m, b, newvertex, &badotri, (struct osub *) NULL,
13574                              1, 1);
13575       if (success == SUCCESSFULVERTEX) {
13576         if (m->steinerleft > 0) {
13577           m->steinerleft--;
13578         }
13579       } else if (success == ENCROACHINGVERTEX) {
13580         /* If the newly inserted vertex encroaches upon a subsegment, */
13581         /*   delete the new vertex.                                   */
13582         undovertex(m, b);
13583         if (b->verbose > 1) {
13584           printf("  Rejecting (%.12g, %.12g).\n", (double)newvertex[0], (double)newvertex[1]);
13585         }
13586         vertexdealloc(m, newvertex);
13587       } else if (success == VIOLATINGVERTEX) {
13588         /* Failed to insert the new vertex, but some subsegment was */
13589         /*   marked as being encroached.                            */
13590         vertexdealloc(m, newvertex);
13591       } else {                                 /* success == DUPLICATEVERTEX */
13592         /* Couldn't insert the new vertex because a vertex is already there. */
13593         if (!b->quiet) {
13594           printf(
13595             "Warning:  New vertex (%.12g, %.12g) falls on existing vertex.\n",
13596                  (double)newvertex[0], (double)newvertex[1]);
13597           errorflag = 1;
13598         }
13599         vertexdealloc(m, newvertex);
13600       }
13601     }
13602     if (errorflag) {
13603       if (b->verbose) {
13604         printf("  The new vertex is at the circumcenter of triangle\n");
13605         printf("    (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
13606                (double)borg[0], (double)borg[1], (double)bdest[0], (double)bdest[1], (double)bapex[0], (double)bapex[1]);
13607       }
13608       printf("This probably means that I am trying to refine triangles\n");
13609       printf("  to a smaller size than can be accommodated by the finite\n");
13610       printf("  precision of floating point arithmetic.  (You can be\n");
13611       printf("  sure of this if I fail to terminate.)\n");
13612       precisionerror();
13613     }
13614   }
13615 }
13616 
13617 #endif /* not CDT_ONLY */
13618 
13619 /*****************************************************************************/
13620 /*                                                                           */
13621 /*  enforcequality()   Remove all the encroached subsegments and bad         */
13622 /*                     triangles from the triangulation.                     */
13623 /*                                                                           */
13624 /*****************************************************************************/
13625 
13626 #ifndef CDT_ONLY
13627 
13628 #ifdef ANSI_DECLARATORS
13629 void enforcequality(struct mesh *m, struct behavior *b)
13630 #else /* not ANSI_DECLARATORS */
13631 void enforcequality(m, b)
13632 struct mesh *m;
13633 struct behavior *b;
13634 #endif /* not ANSI_DECLARATORS */
13635 
13636 {
13637   struct badtriang *badtri;
13638   int i;
13639 
13640   if (!b->quiet) {
13641     printf("Adding Steiner points to enforce quality.\n");
13642   }
13643   /* Initialize the pool of encroached subsegments. */
13644   poolinit(&m->badsubsegs, sizeof(struct badsubseg), BADSUBSEGPERBLOCK,
13645            BADSUBSEGPERBLOCK, 0);
13646   if (b->verbose) {
13647     printf("  Looking for encroached subsegments.\n");
13648   }
13649   /* Test all segments to see if they're encroached. */
13650   tallyencs(m, b);
13651   if (b->verbose && (m->badsubsegs.items > 0)) {
13652     printf("  Splitting encroached subsegments.\n");
13653   }
13654   /* Fix encroached subsegments without noting bad triangles. */
13655   splitencsegs(m, b, 0);
13656   /* At this point, if we haven't run out of Steiner points, the */
13657   /*   triangulation should be (conforming) Delaunay.            */
13658 
13659   /* Next, we worry about enforcing triangle quality. */
13660   if ((b->minangle > 0.0) || b->vararea || b->fixedarea || b->usertest) {
13661     /* Initialize the pool of bad triangles. */
13662     poolinit(&m->badtriangles, sizeof(struct badtriang), BADTRIPERBLOCK,
13663              BADTRIPERBLOCK, 0);
13664     /* Initialize the queues of bad triangles. */
13665     for (i = 0; i < 4096; i++) {
13666       m->queuefront[i] = (struct badtriang *) NULL;
13667     }
13668     m->firstnonemptyq = -1;
13669     /* Test all triangles to see if they're bad. */
13670     tallyfaces(m, b);
13671     /* Initialize the pool of recently flipped triangles. */
13672     poolinit(&m->flipstackers, sizeof(struct flipstacker), FLIPSTACKERPERBLOCK,
13673              FLIPSTACKERPERBLOCK, 0);
13674     m->checkquality = 1;
13675     if (b->verbose) {
13676       printf("  Splitting bad triangles.\n");
13677     }
13678     while ((m->badtriangles.items > 0) && (m->steinerleft != 0)) {
13679       /* Fix one bad triangle by inserting a vertex at its circumcenter. */
13680       badtri = dequeuebadtriang(m);
13681       splittriangle(m, b, badtri);
13682       if (m->badsubsegs.items > 0) {
13683         /* Put bad triangle back in queue for another try later. */
13684         enqueuebadtriang(m, b, badtri);
13685         /* Fix any encroached subsegments that resulted. */
13686         /*   Record any new bad triangles that result.   */
13687         splitencsegs(m, b, 1);
13688       } else {
13689         /* Return the bad triangle to the pool. */
13690         pooldealloc(&m->badtriangles, (VOID *) badtri);
13691       }
13692     }
13693   }
13694   /* At this point, if the "-D" switch was selected and we haven't run out  */
13695   /*   of Steiner points, the triangulation should be (conforming) Delaunay */
13696   /*   and have no low-quality triangles.                                   */
13697 
13698   /* Might we have run out of Steiner points too soon? */
13699   if (!b->quiet && b->conformdel && (m->badsubsegs.items > 0) &&
13700       (m->steinerleft == 0)) {
13701     printf("\nWarning:  I ran out of Steiner points, but the mesh has\n");
13702     if (m->badsubsegs.items == 1) {
13703       printf("  one encroached subsegment, and therefore might not be truly\n"
13704              );
13705     } else {
13706       printf("  %ld encroached subsegments, and therefore might not be truly\n"
13707              , m->badsubsegs.items);
13708     }
13709     printf("  Delaunay.  If the Delaunay property is important to you,\n");
13710     printf("  try increasing the number of Steiner points (controlled by\n");
13711     printf("  the -S switch) slightly and try again.\n\n");
13712   }
13713 }
13714 
13715 #endif /* not CDT_ONLY */
13716 
13717 /**                                                                         **/
13718 /**                                                                         **/
13719 /********* Mesh quality maintenance ends here                        *********/
13720 
13721 /*****************************************************************************/
13722 /*                                                                           */
13723 /*  highorder()   Create extra nodes for quadratic subparametric elements.   */
13724 /*                                                                           */
13725 /*****************************************************************************/
13726 
13727 #ifdef ANSI_DECLARATORS
13728 void highorder(struct mesh *m, struct behavior *b)
13729 #else /* not ANSI_DECLARATORS */
13730 void highorder(m, b)
13731 struct mesh *m;
13732 struct behavior *b;
13733 #endif /* not ANSI_DECLARATORS */
13734 
13735 {
13736   struct otri triangleloop, trisym;
13737   struct osub checkmark;
13738   vertex newvertex;
13739   vertex torg, tdest;
13740   int i;
13741   triangle ptr;                         /* Temporary variable used by sym(). */
13742   subseg sptr;                      /* Temporary variable used by tspivot(). */
13743 
13744   if (!b->quiet) {
13745     printf("Adding vertices for second-order triangles.\n");
13746   }
13747   /* The following line ensures that dead items in the pool of nodes    */
13748   /*   cannot be allocated for the extra nodes associated with high     */
13749   /*   order elements.  This ensures that the primary nodes (at the     */
13750   /*   corners of elements) will occur earlier in the output files, and */
13751   /*   have lower indices, than the extra nodes.                        */
13752   m->vertices.deaditemstack = (VOID *) NULL;
13753 
13754   traversalinit(&m->triangles);
13755   triangleloop.tri = triangletraverse(m);
13756   /* To loop over the set of edges, loop over all triangles, and look at   */
13757   /*   the three edges of each triangle.  If there isn't another triangle  */
13758   /*   adjacent to the edge, operate on the edge.  If there is another     */
13759   /*   adjacent triangle, operate on the edge only if the current triangle */
13760   /*   has a smaller pointer than its neighbor.  This way, each edge is    */
13761   /*   considered only once.                                               */
13762   while (triangleloop.tri != (triangle *) NULL) {
13763     for (triangleloop.orient = 0; triangleloop.orient < 3;
13764          triangleloop.orient++) {
13765       sym(triangleloop, trisym);
13766       if ((triangleloop.tri < trisym.tri) || (trisym.tri == m->dummytri)) {
13767         org(triangleloop, torg);
13768         dest(triangleloop, tdest);
13769         /* Create a new node in the middle of the edge.  Interpolate */
13770         /*   its attributes.                                         */
13771         newvertex = (vertex) poolalloc(&m->vertices);
13772         for (i = 0; i < 2 + m->nextras; i++) {
13773           newvertex[i] = 0.5 * (torg[i] + tdest[i]);
13774         }
13775         /* Set the new node's marker to zero or one, depending on */
13776         /*   whether it lies on a boundary.                       */
13777         setvertexmark(newvertex, trisym.tri == m->dummytri);
13778         setvertextype(newvertex,
13779                       trisym.tri == m->dummytri ? FREEVERTEX : SEGMENTVERTEX);
13780         if (b->usesegments) {
13781           tspivot(triangleloop, checkmark);
13782           /* If this edge is a segment, transfer the marker to the new node. */
13783           if (checkmark.ss != m->dummysub) {
13784             setvertexmark(newvertex, mark(checkmark));
13785             setvertextype(newvertex, SEGMENTVERTEX);
13786           }
13787         }
13788         if (b->verbose > 1) {
13789           printf("  Creating (%.12g, %.12g).\n", (double)newvertex[0], (double)newvertex[1]);
13790         }
13791         /* Record the new node in the (one or two) adjacent elements. */
13792         triangleloop.tri[m->highorderindex + triangleloop.orient] =
13793                 (triangle) newvertex;
13794         if (trisym.tri != m->dummytri) {
13795           trisym.tri[m->highorderindex + trisym.orient] = (triangle) newvertex;
13796         }
13797       }
13798     }
13799     triangleloop.tri = triangletraverse(m);
13800   }
13801 }
13802 
13803 /********* File I/O routines begin here                              *********/
13804 /**                                                                         **/
13805 /**                                                                         **/
13806 
13807 /*****************************************************************************/
13808 /*                                                                           */
13809 /*  readline()   Read a nonempty line from a file.                           */
13810 /*                                                                           */
13811 /*  A line is considered "nonempty" if it contains something that looks like */
13812 /*  a number.  Comments (prefaced by `#') are ignored.                       */
13813 /*                                                                           */
13814 /*****************************************************************************/
13815 
13816 #ifndef TRILIBRARY
13817 
13818 #ifdef ANSI_DECLARATORS
13819 char *readline(char *string, FILE *infile, char *infilename)
13820 #else /* not ANSI_DECLARATORS */
13821 char *readline(string, infile, infilename)
13822 char *string;
13823 FILE *infile;
13824 char *infilename;
13825 #endif /* not ANSI_DECLARATORS */
13826 
13827 {
13828   char *result;
13829 
13830   /* Search for something that looks like a number. */
13831   do {
13832     result = fgets(string, INPUTLINESIZE, infile);
13833     if (result == (char *) NULL) {
13834       printf("  Error:  Unexpected end of file in %s.\n", infilename);
13835       triexit(1);
13836     }
13837     /* Skip anything that doesn't look like a number, a comment, */
13838     /*   or the end of a line.                                   */
13839     while ((*result != '\0') && (*result != '#')
13840            && (*result != '.') && (*result != '+') && (*result != '-')
13841            && ((*result < '0') || (*result > '9'))) {
13842       result++;
13843     }
13844   /* If it's a comment or end of line, read another line and try again. */
13845   } while ((*result == '#') || (*result == '\0'));
13846   return result;
13847 }
13848 
13849 #endif /* not TRILIBRARY */
13850 
13851 /*****************************************************************************/
13852 /*                                                                           */
13853 /*  findfield()   Find the next field of a string.                           */
13854 /*                                                                           */
13855 /*  Jumps past the current field by searching for whitespace, then jumps     */
13856 /*  past the whitespace to find the next field.                              */
13857 /*                                                                           */
13858 /*****************************************************************************/
13859 
13860 #ifndef TRILIBRARY
13861 
13862 #ifdef ANSI_DECLARATORS
13863 char *findfield(char *string)
13864 #else /* not ANSI_DECLARATORS */
13865 char *findfield(string)
13866 char *string;
13867 #endif /* not ANSI_DECLARATORS */
13868 
13869 {
13870   char *result;
13871 
13872   result = string;
13873   /* Skip the current field.  Stop upon reaching whitespace. */
13874   while ((*result != '\0') && (*result != '#')
13875          && (*result != ' ') && (*result != '\t')) {
13876     result++;
13877   }
13878   /* Now skip the whitespace and anything else that doesn't look like a */
13879   /*   number, a comment, or the end of a line.                         */
13880   while ((*result != '\0') && (*result != '#')
13881          && (*result != '.') && (*result != '+') && (*result != '-')
13882          && ((*result < '0') || (*result > '9'))) {
13883     result++;
13884   }
13885   /* Check for a comment (prefixed with `#'). */
13886   if (*result == '#') {
13887     *result = '\0';
13888   }
13889   return result;
13890 }
13891 
13892 #endif /* not TRILIBRARY */
13893 
13894 /*****************************************************************************/
13895 /*                                                                           */
13896 /*  readnodes()   Read the vertices from a file, which may be a .node or     */
13897 /*                .poly file.                                                */
13898 /*                                                                           */
13899 /*****************************************************************************/
13900 
13901 #ifndef TRILIBRARY
13902 
13903 #ifdef ANSI_DECLARATORS
13904 void readnodes(struct mesh *m, struct behavior *b, char *nodefilename,
13905                char *polyfilename, FILE **polyfile)
13906 #else /* not ANSI_DECLARATORS */
13907 void readnodes(m, b, nodefilename, polyfilename, polyfile)
13908 struct mesh *m;
13909 struct behavior *b;
13910 char *nodefilename;
13911 char *polyfilename;
13912 FILE **polyfile;
13913 #endif /* not ANSI_DECLARATORS */
13914 
13915 {
13916   FILE *infile;
13917   vertex vertexloop;
13918   char inputline[INPUTLINESIZE];
13919   char *stringptr;
13920   char *infilename;
13921   REAL x, y;
13922   int firstnode;
13923   int nodemarkers;
13924   int currentmarker;
13925   int i, j;
13926 
13927   if (b->poly) {
13928     /* Read the vertices from a .poly file. */
13929     if (!b->quiet) {
13930       printf("Opening %s.\n", polyfilename);
13931     }
13932     *polyfile = fopen(polyfilename, "r");
13933     if (*polyfile == (FILE *) NULL) {
13934       printf("  Error:  Cannot access file %s.\n", polyfilename);
13935       triexit(1);
13936     }
13937     /* Read number of vertices, number of dimensions, number of vertex */
13938     /*   attributes, and number of boundary markers.                   */
13939     stringptr = readline(inputline, *polyfile, polyfilename);
13940     m->invertices = (int) strtol(stringptr, &stringptr, 0);
13941     stringptr = findfield(stringptr);
13942     if (*stringptr == '\0') {
13943       m->mesh_dim = 2;
13944     } else {
13945       m->mesh_dim = (int) strtol(stringptr, &stringptr, 0);
13946     }
13947     stringptr = findfield(stringptr);
13948     if (*stringptr == '\0') {
13949       m->nextras = 0;
13950     } else {
13951       m->nextras = (int) strtol(stringptr, &stringptr, 0);
13952     }
13953     stringptr = findfield(stringptr);
13954     if (*stringptr == '\0') {
13955       nodemarkers = 0;
13956     } else {
13957       nodemarkers = (int) strtol(stringptr, &stringptr, 0);
13958     }
13959     if (m->invertices > 0) {
13960       infile = *polyfile;
13961       infilename = polyfilename;
13962       m->readnodefile = 0;
13963     } else {
13964       /* If the .poly file claims there are zero vertices, that means that */
13965       /*   the vertices should be read from a separate .node file.         */
13966       m->readnodefile = 1;
13967       infilename = nodefilename;
13968     }
13969   } else {
13970     m->readnodefile = 1;
13971     infilename = nodefilename;
13972     *polyfile = (FILE *) NULL;
13973   }
13974 
13975   if (m->readnodefile) {
13976     /* Read the vertices from a .node file. */
13977     if (!b->quiet) {
13978       printf("Opening %s.\n", nodefilename);
13979     }
13980     infile = fopen(nodefilename, "r");
13981     if (infile == (FILE *) NULL) {
13982       printf("  Error:  Cannot access file %s.\n", nodefilename);
13983       triexit(1);
13984     }
13985     /* Read number of vertices, number of dimensions, number of vertex */
13986     /*   attributes, and number of boundary markers.                   */
13987     stringptr = readline(inputline, infile, nodefilename);
13988     m->invertices = (int) strtol(stringptr, &stringptr, 0);
13989     stringptr = findfield(stringptr);
13990     if (*stringptr == '\0') {
13991       m->mesh_dim = 2;
13992     } else {
13993       m->mesh_dim = (int) strtol(stringptr, &stringptr, 0);
13994     }
13995     stringptr = findfield(stringptr);
13996     if (*stringptr == '\0') {
13997       m->nextras = 0;
13998     } else {
13999       m->nextras = (int) strtol(stringptr, &stringptr, 0);
14000     }
14001     stringptr = findfield(stringptr);
14002     if (*stringptr == '\0') {
14003       nodemarkers = 0;
14004     } else {
14005       nodemarkers = (int) strtol(stringptr, &stringptr, 0);
14006     }
14007   }
14008 
14009   if (m->invertices < 3) {
14010     printf("Error:  Input must have at least three input vertices.\n");
14011     triexit(1);
14012   }
14013   if (m->mesh_dim != 2) {
14014     printf("Error:  Triangle only works with two-dimensional meshes.\n");
14015     triexit(1);
14016   }
14017   if (m->nextras == 0) {
14018     b->weighted = 0;
14019   }
14020 
14021   initializevertexpool(m, b);
14022 
14023   /* Read the vertices. */
14024   for (i = 0; i < m->invertices; i++) {
14025     vertexloop = (vertex) poolalloc(&m->vertices);
14026     stringptr = readline(inputline, infile, infilename);
14027     if (i == 0) {
14028       firstnode = (int) strtol(stringptr, &stringptr, 0);
14029       if ((firstnode == 0) || (firstnode == 1)) {
14030         b->firstnumber = firstnode;
14031       }
14032     }
14033     stringptr = findfield(stringptr);
14034     if (*stringptr == '\0') {
14035       printf("Error:  Vertex %d has no x coordinate.\n", b->firstnumber + i);
14036       triexit(1);
14037     }
14038     x = (REAL) strtod(stringptr, &stringptr);
14039     stringptr = findfield(stringptr);
14040     if (*stringptr == '\0') {
14041       printf("Error:  Vertex %d has no y coordinate.\n", b->firstnumber + i);
14042       triexit(1);
14043     }
14044     y = (REAL) strtod(stringptr, &stringptr);
14045     vertexloop[0] = x;
14046     vertexloop[1] = y;
14047     /* Read the vertex attributes. */
14048     for (j = 2; j < 2 + m->nextras; j++) {
14049       stringptr = findfield(stringptr);
14050       if (*stringptr == '\0') {
14051         vertexloop[j] = 0.0;
14052       } else {
14053         vertexloop[j] = (REAL) strtod(stringptr, &stringptr);
14054       }
14055     }
14056     if (nodemarkers) {
14057       /* Read a vertex marker. */
14058       stringptr = findfield(stringptr);
14059       if (*stringptr == '\0') {
14060         setvertexmark(vertexloop, 0);
14061       } else {
14062         currentmarker = (int) strtol(stringptr, &stringptr, 0);
14063         setvertexmark(vertexloop, currentmarker);
14064       }
14065     } else {
14066       /* If no markers are specified in the file, they default to zero. */
14067       setvertexmark(vertexloop, 0);
14068     }
14069     setvertextype(vertexloop, INPUTVERTEX);
14070     /* Determine the smallest and largest x and y coordinates. */
14071     if (i == 0) {
14072       m->xmin = m->xmax = x;
14073       m->ymin = m->ymax = y;
14074     } else {
14075       m->xmin = (x < m->xmin) ? x : m->xmin;
14076       m->xmax = (x > m->xmax) ? x : m->xmax;
14077       m->ymin = (y < m->ymin) ? y : m->ymin;
14078       m->ymax = (y > m->ymax) ? y : m->ymax;
14079     }
14080   }
14081   if (m->readnodefile) {
14082     fclose(infile);
14083   }
14084 
14085   /* Nonexistent x value used as a flag to mark circle events in sweepline */
14086   /*   Delaunay algorithm.                                                 */
14087   m->xminextreme = 10 * m->xmin - 9 * m->xmax;
14088 }
14089 
14090 #endif /* not TRILIBRARY */
14091 
14092 /*****************************************************************************/
14093 /*                                                                           */
14094 /*  transfernodes()   Read the vertices from memory.                         */
14095 /*                                                                           */
14096 /*****************************************************************************/
14097 
14098 #ifdef TRILIBRARY
14099 
14100 #ifdef ANSI_DECLARATORS
14101 void transfernodes(struct mesh *m, struct behavior *b, REAL *pointlist,
14102                    REAL *pointattriblist, int *pointmarkerlist,
14103                    int numberofpoints, int numberofpointattribs)
14104 #else /* not ANSI_DECLARATORS */
14105 void transfernodes(m, b, pointlist, pointattriblist, pointmarkerlist,
14106                    numberofpoints, numberofpointattribs)
14107 struct mesh *m;
14108 struct behavior *b;
14109 REAL *pointlist;
14110 REAL *pointattriblist;
14111 int *pointmarkerlist;
14112 int numberofpoints;
14113 int numberofpointattribs;
14114 #endif /* not ANSI_DECLARATORS */
14115 
14116 {
14117   vertex vertexloop;
14118   REAL x, y;
14119   int i, j;
14120   int coordindex;
14121   int attribindex;
14122 
14123   m->invertices = numberofpoints;
14124   m->mesh_dim = 2;
14125   m->nextras = numberofpointattribs;
14126   m->readnodefile = 0;
14127   if (m->invertices < 3) {
14128     printf("Error:  Input must have at least three input vertices.\n");
14129     triexit(1);
14130   }
14131   if (m->nextras == 0) {
14132     b->weighted = 0;
14133   }
14134 
14135   initializevertexpool(m, b);
14136 
14137   /* Read the vertices. */
14138   coordindex = 0;
14139   attribindex = 0;
14140   for (i = 0; i < m->invertices; i++) {
14141     vertexloop = (vertex) poolalloc(&m->vertices);
14142     /* Read the vertex coordinates. */
14143     x = vertexloop[0] = pointlist[coordindex++];
14144     y = vertexloop[1] = pointlist[coordindex++];
14145     /* Read the vertex attributes. */
14146     for (j = 0; j < numberofpointattribs; j++) {
14147       vertexloop[2 + j] = pointattriblist[attribindex++];
14148     }
14149     if (pointmarkerlist != (int *) NULL) {
14150       /* Read a vertex marker. */
14151       setvertexmark(vertexloop, pointmarkerlist[i]);
14152     } else {
14153       /* If no markers are specified, they default to zero. */
14154       setvertexmark(vertexloop, 0);
14155     }
14156     setvertextype(vertexloop, INPUTVERTEX);
14157     /* Determine the smallest and largest x and y coordinates. */
14158     if (i == 0) {
14159       m->xmin = m->xmax = x;
14160       m->ymin = m->ymax = y;
14161     } else {
14162       m->xmin = (x < m->xmin) ? x : m->xmin;
14163       m->xmax = (x > m->xmax) ? x : m->xmax;
14164       m->ymin = (y < m->ymin) ? y : m->ymin;
14165       m->ymax = (y > m->ymax) ? y : m->ymax;
14166     }
14167   }
14168 
14169   /* Nonexistent x value used as a flag to mark circle events in sweepline */
14170   /*   Delaunay algorithm.                                                 */
14171   m->xminextreme = 10 * m->xmin - 9 * m->xmax;
14172 }
14173 
14174 #endif /* TRILIBRARY */
14175 
14176 /*****************************************************************************/
14177 /*                                                                           */
14178 /*  readholes()   Read the holes, and possibly regional attributes and area  */
14179 /*                constraints, from a .poly file.                            */
14180 /*                                                                           */
14181 /*****************************************************************************/
14182 
14183 #ifndef TRILIBRARY
14184 
14185 #ifdef ANSI_DECLARATORS
14186 void readholes(struct mesh *m, struct behavior *b,
14187                FILE *polyfile, char *polyfilename, REAL **hlist, int *holes,
14188                REAL **rlist, int *regions)
14189 #else /* not ANSI_DECLARATORS */
14190 void readholes(m, b, polyfile, polyfilename, hlist, holes, rlist, regions)
14191 struct mesh *m;
14192 struct behavior *b;
14193 FILE *polyfile;
14194 char *polyfilename;
14195 REAL **hlist;
14196 int *holes;
14197 REAL **rlist;
14198 int *regions;
14199 #endif /* not ANSI_DECLARATORS */
14200 
14201 {
14202   REAL *holelist;
14203   REAL *regionlist;
14204   char inputline[INPUTLINESIZE];
14205   char *stringptr;
14206   int index;
14207   int i;
14208 
14209   /* Read the holes. */
14210   stringptr = readline(inputline, polyfile, polyfilename);
14211   *holes = (int) strtol(stringptr, &stringptr, 0);
14212   if (*holes > 0) {
14213     holelist = (REAL *) trimalloc(2 * *holes * (int) sizeof(REAL));
14214     *hlist = holelist;
14215     for (i = 0; i < 2 * *holes; i += 2) {
14216       stringptr = readline(inputline, polyfile, polyfilename);
14217       stringptr = findfield(stringptr);
14218       if (*stringptr == '\0') {
14219         printf("Error:  Hole %d has no x coordinate.\n",
14220                b->firstnumber + (i >> 1));
14221         triexit(1);
14222       } else {
14223         holelist[i] = (REAL) strtod(stringptr, &stringptr);
14224       }
14225       stringptr = findfield(stringptr);
14226       if (*stringptr == '\0') {
14227         printf("Error:  Hole %d has no y coordinate.\n",
14228                b->firstnumber + (i >> 1));
14229         triexit(1);
14230       } else {
14231         holelist[i + 1] = (REAL) strtod(stringptr, &stringptr);
14232       }
14233     }
14234   } else {
14235     *hlist = (REAL *) NULL;
14236   }
14237 
14238 #ifndef CDT_ONLY
14239   if ((b->regionattrib || b->vararea) && !b->refine) {
14240     /* Read the area constraints. */
14241     stringptr = readline(inputline, polyfile, polyfilename);
14242     *regions = (int) strtol(stringptr, &stringptr, 0);
14243     if (*regions > 0) {
14244       regionlist = (REAL *) trimalloc(4 * *regions * (int) sizeof(REAL));
14245       *rlist = regionlist;
14246       index = 0;
14247       for (i = 0; i < *regions; i++) {
14248         stringptr = readline(inputline, polyfile, polyfilename);
14249         stringptr = findfield(stringptr);
14250         if (*stringptr == '\0') {
14251           printf("Error:  Region %d has no x coordinate.\n",
14252                  b->firstnumber + i);
14253           triexit(1);
14254         } else {
14255           regionlist[index++] = (REAL) strtod(stringptr, &stringptr);
14256         }
14257         stringptr = findfield(stringptr);
14258         if (*stringptr == '\0') {
14259           printf("Error:  Region %d has no y coordinate.\n",
14260                  b->firstnumber + i);
14261           triexit(1);
14262         } else {
14263           regionlist[index++] = (REAL) strtod(stringptr, &stringptr);
14264         }
14265         stringptr = findfield(stringptr);
14266         if (*stringptr == '\0') {
14267           printf(
14268             "Error:  Region %d has no region attribute or area constraint.\n",
14269                  b->firstnumber + i);
14270           triexit(1);
14271         } else {
14272           regionlist[index++] = (REAL) strtod(stringptr, &stringptr);
14273         }
14274         stringptr = findfield(stringptr);
14275         if (*stringptr == '\0') {
14276           regionlist[index] = regionlist[index - 1];
14277         } else {
14278           regionlist[index] = (REAL) strtod(stringptr, &stringptr);
14279         }
14280         index++;
14281       }
14282     }
14283   } else {
14284     /* Set `*regions' to zero to avoid an accidental free() later. */
14285     *regions = 0;
14286     *rlist = (REAL *) NULL;
14287   }
14288 #endif /* not CDT_ONLY */
14289 
14290   fclose(polyfile);
14291 }
14292 
14293 #endif /* not TRILIBRARY */
14294 
14295 /*****************************************************************************/
14296 /*                                                                           */
14297 /*  finishfile()   Write the command line to the output file so the user     */
14298 /*                 can remember how the file was generated.  Close the file. */
14299 /*                                                                           */
14300 /*****************************************************************************/
14301 
14302 #ifndef TRILIBRARY
14303 
14304 #ifdef ANSI_DECLARATORS
14305 void finishfile(FILE *outfile, int argc, char **argv)
14306 #else /* not ANSI_DECLARATORS */
14307 void finishfile(outfile, argc, argv)
14308 FILE *outfile;
14309 int argc;
14310 char **argv;
14311 #endif /* not ANSI_DECLARATORS */
14312 
14313 {
14314   int i;
14315 
14316   fprintf(outfile, "# Generated by");
14317   for (i = 0; i < argc; i++) {
14318     fprintf(outfile, " ");
14319     fputs(argv[i], outfile);
14320   }
14321   fprintf(outfile, "\n");
14322   fclose(outfile);
14323 }
14324 
14325 #endif /* not TRILIBRARY */
14326 
14327 /*****************************************************************************/
14328 /*                                                                           */
14329 /*  writenodes()   Number the vertices and write them to a .node file.       */
14330 /*                                                                           */
14331 /*  To save memory, the vertex numbers are written over the boundary markers */
14332 /*  after the vertices are written to a file.                                */
14333 /*                                                                           */
14334 /*****************************************************************************/
14335 
14336 #ifdef TRILIBRARY
14337 
14338 #ifdef ANSI_DECLARATORS
14339 void writenodes(struct mesh *m, struct behavior *b, REAL **pointlist,
14340                 REAL **pointattriblist, int **pointmarkerlist)
14341 #else /* not ANSI_DECLARATORS */
14342 void writenodes(m, b, pointlist, pointattriblist, pointmarkerlist)
14343 struct mesh *m;
14344 struct behavior *b;
14345 REAL **pointlist;
14346 REAL **pointattriblist;
14347 int **pointmarkerlist;
14348 #endif /* not ANSI_DECLARATORS */
14349 
14350 #else /* not TRILIBRARY */
14351 
14352 #ifdef ANSI_DECLARATORS
14353 void writenodes(struct mesh *m, struct behavior *b, char *nodefilename,
14354                 int argc, char **argv)
14355 #else /* not ANSI_DECLARATORS */
14356 void writenodes(m, b, nodefilename, argc, argv)
14357 struct mesh *m;
14358 struct behavior *b;
14359 char *nodefilename;
14360 int argc;
14361 char **argv;
14362 #endif /* not ANSI_DECLARATORS */
14363 
14364 #endif /* not TRILIBRARY */
14365 
14366 {
14367 #ifdef TRILIBRARY
14368   REAL *plist;
14369   REAL *palist;
14370   int *pmlist;
14371   int coordindex;
14372   int attribindex;
14373 #else /* not TRILIBRARY */
14374   FILE *outfile;
14375 #endif /* not TRILIBRARY */
14376   vertex vertexloop;
14377   long outvertices;
14378   int vertexnumber;
14379   int i;
14380 
14381   if (b->jettison) {
14382     outvertices = m->vertices.items - m->undeads;
14383   } else {
14384     outvertices = m->vertices.items;
14385   }
14386 
14387 #ifdef TRILIBRARY
14388   if (!b->quiet) {
14389     printf("Writing vertices.\n");
14390   }
14391   /* Allocate memory for output vertices if necessary. */
14392   if (*pointlist == (REAL *) NULL) {
14393     *pointlist = (REAL *) trimalloc((int) (outvertices * 2 * sizeof(REAL)));
14394   }
14395   /* Allocate memory for output vertex attributes if necessary. */
14396   if ((m->nextras > 0) && (*pointattriblist == (REAL *) NULL)) {
14397     *pointattriblist = (REAL *) trimalloc((int) (outvertices * m->nextras *
14398                                                  sizeof(REAL)));
14399   }
14400   /* Allocate memory for output vertex markers if necessary. */
14401   if (!b->nobound && (*pointmarkerlist == (int *) NULL)) {
14402     *pointmarkerlist = (int *) trimalloc((int) (outvertices * sizeof(int)));
14403   }
14404   plist = *pointlist;
14405   palist = *pointattriblist;
14406   pmlist = *pointmarkerlist;
14407   coordindex = 0;
14408   attribindex = 0;
14409 #else /* not TRILIBRARY */
14410   if (!b->quiet) {
14411     printf("Writing %s.\n", nodefilename);
14412   }
14413   outfile = fopen(nodefilename, "w");
14414   if (outfile == (FILE *) NULL) {
14415     printf("  Error:  Cannot create file %s.\n", nodefilename);
14416     triexit(1);
14417   }
14418   /* Number of vertices, number of dimensions, number of vertex attributes, */
14419   /*   and number of boundary markers (zero or one).                        */
14420   fprintf(outfile, "%ld  %d  %d  %d\n", outvertices, m->mesh_dim,
14421           m->nextras, 1 - b->nobound);
14422 #endif /* not TRILIBRARY */
14423 
14424   traversalinit(&m->vertices);
14425   vertexnumber = b->firstnumber;
14426   vertexloop = vertextraverse(m);
14427   while (vertexloop != (vertex) NULL) {
14428     if (!b->jettison || (vertextype(vertexloop) != UNDEADVERTEX)) {
14429 #ifdef TRILIBRARY
14430       /* X and y coordinates. */
14431       plist[coordindex++] = vertexloop[0];
14432       plist[coordindex++] = vertexloop[1];
14433       /* Vertex attributes. */
14434       for (i = 0; i < m->nextras; i++) {
14435         palist[attribindex++] = vertexloop[2 + i];
14436       }
14437       if (!b->nobound) {
14438         /* Copy the boundary marker. */
14439         pmlist[vertexnumber - b->firstnumber] = vertexmark(vertexloop);
14440       }
14441 #else /* not TRILIBRARY */
14442       /* Vertex number, x and y coordinates. */
14443       fprintf(outfile, "%4d    %.17g  %.17g", vertexnumber, vertexloop[0],
14444               vertexloop[1]);
14445       for (i = 0; i < m->nextras; i++) {
14446         /* Write an attribute. */
14447         fprintf(outfile, "  %.17g", vertexloop[i + 2]);
14448       }
14449       if (b->nobound) {
14450         fprintf(outfile, "\n");
14451       } else {
14452         /* Write the boundary marker. */
14453         fprintf(outfile, "    %d\n", vertexmark(vertexloop));
14454       }
14455 #endif /* not TRILIBRARY */
14456 
14457       setvertexmark(vertexloop, vertexnumber);
14458       vertexnumber++;
14459     }
14460     vertexloop = vertextraverse(m);
14461   }
14462 
14463 #ifndef TRILIBRARY
14464   finishfile(outfile, argc, argv);
14465 #endif /* not TRILIBRARY */
14466 }
14467 
14468 /*****************************************************************************/
14469 /*                                                                           */
14470 /*  numbernodes()   Number the vertices.                                     */
14471 /*                                                                           */
14472 /*  Each vertex is assigned a marker equal to its number.                    */
14473 /*                                                                           */
14474 /*  Used when writenodes() is not called because no .node file is written.   */
14475 /*                                                                           */
14476 /*****************************************************************************/
14477 
14478 #ifdef ANSI_DECLARATORS
14479 void numbernodes(struct mesh *m, struct behavior *b)
14480 #else /* not ANSI_DECLARATORS */
14481 void numbernodes(m, b)
14482 struct mesh *m;
14483 struct behavior *b;
14484 #endif /* not ANSI_DECLARATORS */
14485 
14486 {
14487   vertex vertexloop;
14488   int vertexnumber;
14489 
14490   traversalinit(&m->vertices);
14491   vertexnumber = b->firstnumber;
14492   vertexloop = vertextraverse(m);
14493   while (vertexloop != (vertex) NULL) {
14494     setvertexmark(vertexloop, vertexnumber);
14495     if (!b->jettison || (vertextype(vertexloop) != UNDEADVERTEX)) {
14496       vertexnumber++;
14497     }
14498     vertexloop = vertextraverse(m);
14499   }
14500 }
14501 
14502 /*****************************************************************************/
14503 /*                                                                           */
14504 /*  writeelements()   Write the triangles to an .ele file.                   */
14505 /*                                                                           */
14506 /*****************************************************************************/
14507 
14508 #ifdef TRILIBRARY
14509 
14510 #ifdef ANSI_DECLARATORS
14511 void writeelements(struct mesh *m, struct behavior *b,
14512                    int **trianglelist, REAL **triangleattriblist)
14513 #else /* not ANSI_DECLARATORS */
14514 void writeelements(m, b, trianglelist, triangleattriblist)
14515 struct mesh *m;
14516 struct behavior *b;
14517 int **trianglelist;
14518 REAL **triangleattriblist;
14519 #endif /* not ANSI_DECLARATORS */
14520 
14521 #else /* not TRILIBRARY */
14522 
14523 #ifdef ANSI_DECLARATORS
14524 void writeelements(struct mesh *m, struct behavior *b, char *elefilename,
14525                    int argc, char **argv)
14526 #else /* not ANSI_DECLARATORS */
14527 void writeelements(m, b, elefilename, argc, argv)
14528 struct mesh *m;
14529 struct behavior *b;
14530 char *elefilename;
14531 int argc;
14532 char **argv;
14533 #endif /* not ANSI_DECLARATORS */
14534 
14535 #endif /* not TRILIBRARY */
14536 
14537 {
14538 #ifdef TRILIBRARY
14539   int *tlist;
14540   REAL *talist;
14541   int vertexindex;
14542   int attribindex;
14543 #else /* not TRILIBRARY */
14544   FILE *outfile;
14545 #endif /* not TRILIBRARY */
14546   struct otri triangleloop;
14547   vertex p1, p2, p3;
14548   vertex mid1, mid2, mid3;
14549   long elementnumber;
14550   int i;
14551 
14552 #ifdef TRILIBRARY
14553   if (!b->quiet) {
14554     printf("Writing triangles.\n");
14555   }
14556   /* Allocate memory for output triangles if necessary. */
14557   if (*trianglelist == (int *) NULL) {
14558     *trianglelist = (int *) trimalloc((int) (m->triangles.items *
14559                                              ((b->order + 1) * (b->order + 2) /
14560                                               2) * sizeof(int)));
14561   }
14562   /* Allocate memory for output triangle attributes if necessary. */
14563   if ((m->eextras > 0) && (*triangleattriblist == (REAL *) NULL)) {
14564     *triangleattriblist = (REAL *) trimalloc((int) (m->triangles.items *
14565                                                     m->eextras *
14566                                                     sizeof(REAL)));
14567   }
14568   tlist = *trianglelist;
14569   talist = *triangleattriblist;
14570   vertexindex = 0;
14571   attribindex = 0;
14572 #else /* not TRILIBRARY */
14573   if (!b->quiet) {
14574     printf("Writing %s.\n", elefilename);
14575   }
14576   outfile = fopen(elefilename, "w");
14577   if (outfile == (FILE *) NULL) {
14578     printf("  Error:  Cannot create file %s.\n", elefilename);
14579     triexit(1);
14580   }
14581   /* Number of triangles, vertices per triangle, attributes per triangle. */
14582   fprintf(outfile, "%ld  %d  %d\n", m->triangles.items,
14583           (b->order + 1) * (b->order + 2) / 2, m->eextras);
14584 #endif /* not TRILIBRARY */
14585 
14586   traversalinit(&m->triangles);
14587   triangleloop.tri = triangletraverse(m);
14588   triangleloop.orient = 0;
14589   elementnumber = b->firstnumber;
14590   while (triangleloop.tri != (triangle *) NULL) {
14591     org(triangleloop, p1);
14592     dest(triangleloop, p2);
14593     apex(triangleloop, p3);
14594     if (b->order == 1) {
14595 #ifdef TRILIBRARY
14596       tlist[vertexindex++] = vertexmark(p1);
14597       tlist[vertexindex++] = vertexmark(p2);
14598       tlist[vertexindex++] = vertexmark(p3);
14599 #else /* not TRILIBRARY */
14600       /* Triangle number, indices for three vertices. */
14601       fprintf(outfile, "%4ld    %4d  %4d  %4d", elementnumber,
14602               vertexmark(p1), vertexmark(p2), vertexmark(p3));
14603 #endif /* not TRILIBRARY */
14604     } else {
14605       mid1 = (vertex) triangleloop.tri[m->highorderindex + 1];
14606       mid2 = (vertex) triangleloop.tri[m->highorderindex + 2];
14607       mid3 = (vertex) triangleloop.tri[m->highorderindex];
14608 #ifdef TRILIBRARY
14609       tlist[vertexindex++] = vertexmark(p1);
14610       tlist[vertexindex++] = vertexmark(p2);
14611       tlist[vertexindex++] = vertexmark(p3);
14612       tlist[vertexindex++] = vertexmark(mid1);
14613       tlist[vertexindex++] = vertexmark(mid2);
14614       tlist[vertexindex++] = vertexmark(mid3);
14615 #else /* not TRILIBRARY */
14616       /* Triangle number, indices for six vertices. */
14617       fprintf(outfile, "%4ld    %4d  %4d  %4d  %4d  %4d  %4d", elementnumber,
14618               vertexmark(p1), vertexmark(p2), vertexmark(p3), vertexmark(mid1),
14619               vertexmark(mid2), vertexmark(mid3));
14620 #endif /* not TRILIBRARY */
14621     }
14622 
14623 #ifdef TRILIBRARY
14624     for (i = 0; i < m->eextras; i++) {
14625       talist[attribindex++] = elemattribute(triangleloop, i);
14626     }
14627 #else /* not TRILIBRARY */
14628     for (i = 0; i < m->eextras; i++) {
14629       fprintf(outfile, "  %.17g", elemattribute(triangleloop, i));
14630     }
14631     fprintf(outfile, "\n");
14632 #endif /* not TRILIBRARY */
14633 
14634     triangleloop.tri = triangletraverse(m);
14635     elementnumber++;
14636   }
14637 
14638 #ifndef TRILIBRARY
14639   finishfile(outfile, argc, argv);
14640 #endif /* not TRILIBRARY */
14641 }
14642 
14643 /*****************************************************************************/
14644 /*                                                                           */
14645 /*  writepoly()   Write the segments and holes to a .poly file.              */
14646 /*                                                                           */
14647 /*****************************************************************************/
14648 
14649 #ifdef TRILIBRARY
14650 
14651 #ifdef ANSI_DECLARATORS
14652 void writepoly(struct mesh *m, struct behavior *b,
14653                int **segmentlist, int **segmentmarkerlist)
14654 #else /* not ANSI_DECLARATORS */
14655 void writepoly(m, b, segmentlist, segmentmarkerlist)
14656 struct mesh *m;
14657 struct behavior *b;
14658 int **segmentlist;
14659 int **segmentmarkerlist;
14660 #endif /* not ANSI_DECLARATORS */
14661 
14662 #else /* not TRILIBRARY */
14663 
14664 #ifdef ANSI_DECLARATORS
14665 void writepoly(struct mesh *m, struct behavior *b, char *polyfilename,
14666                REAL *holelist, int holes, REAL *regionlist, int regions,
14667                int argc, char **argv)
14668 #else /* not ANSI_DECLARATORS */
14669 void writepoly(m, b, polyfilename, holelist, holes, regionlist, regions,
14670                argc, argv)
14671 struct mesh *m;
14672 struct behavior *b;
14673 char *polyfilename;
14674 REAL *holelist;
14675 int holes;
14676 REAL *regionlist;
14677 int regions;
14678 int argc;
14679 char **argv;
14680 #endif /* not ANSI_DECLARATORS */
14681 
14682 #endif /* not TRILIBRARY */
14683 
14684 {
14685 #ifdef TRILIBRARY
14686   int *slist;
14687   int *smlist;
14688   int index;
14689 #else /* not TRILIBRARY */
14690   FILE *outfile;
14691   long holenumber, regionnumber;
14692 #endif /* not TRILIBRARY */
14693   struct osub subsegloop;
14694   vertex endpoint1, endpoint2;
14695   long subsegnumber;
14696 
14697 #ifdef TRILIBRARY
14698   if (!b->quiet) {
14699     printf("Writing segments.\n");
14700   }
14701   /* Allocate memory for output segments if necessary. */
14702   if (*segmentlist == (int *) NULL) {
14703     *segmentlist = (int *) trimalloc((int) (m->subsegs.items * 2 *
14704                                             sizeof(int)));
14705   }
14706   /* Allocate memory for output segment markers if necessary. */
14707   if (!b->nobound && (*segmentmarkerlist == (int *) NULL)) {
14708     *segmentmarkerlist = (int *) trimalloc((int) (m->subsegs.items *
14709                                                   sizeof(int)));
14710   }
14711   slist = *segmentlist;
14712   smlist = *segmentmarkerlist;
14713   index = 0;
14714 #else /* not TRILIBRARY */
14715   if (!b->quiet) {
14716     printf("Writing %s.\n", polyfilename);
14717   }
14718   outfile = fopen(polyfilename, "w");
14719   if (outfile == (FILE *) NULL) {
14720     printf("  Error:  Cannot create file %s.\n", polyfilename);
14721     triexit(1);
14722   }
14723   /* The zero indicates that the vertices are in a separate .node file. */
14724   /*   Followed by number of dimensions, number of vertex attributes,   */
14725   /*   and number of boundary markers (zero or one).                    */
14726   fprintf(outfile, "%d  %d  %d  %d\n", 0, m->mesh_dim, m->nextras,
14727           1 - b->nobound);
14728   /* Number of segments, number of boundary markers (zero or one). */
14729   fprintf(outfile, "%ld  %d\n", m->subsegs.items, 1 - b->nobound);
14730 #endif /* not TRILIBRARY */
14731 
14732   traversalinit(&m->subsegs);
14733   subsegloop.ss = subsegtraverse(m);
14734   subsegloop.ssorient = 0;
14735   subsegnumber = b->firstnumber;
14736   while (subsegloop.ss != (subseg *) NULL) {
14737     sorg(subsegloop, endpoint1);
14738     sdest(subsegloop, endpoint2);
14739 #ifdef TRILIBRARY
14740     /* Copy indices of the segment's two endpoints. */
14741     slist[index++] = vertexmark(endpoint1);
14742     slist[index++] = vertexmark(endpoint2);
14743     if (!b->nobound) {
14744       /* Copy the boundary marker. */
14745       smlist[subsegnumber - b->firstnumber] = mark(subsegloop);
14746     }
14747 #else /* not TRILIBRARY */
14748     /* Segment number, indices of its two endpoints, and possibly a marker. */
14749     if (b->nobound) {
14750       fprintf(outfile, "%4ld    %4d  %4d\n", subsegnumber,
14751               vertexmark(endpoint1), vertexmark(endpoint2));
14752     } else {
14753       fprintf(outfile, "%4ld    %4d  %4d    %4d\n", subsegnumber,
14754               vertexmark(endpoint1), vertexmark(endpoint2), mark(subsegloop));
14755     }
14756 #endif /* not TRILIBRARY */
14757 
14758     subsegloop.ss = subsegtraverse(m);
14759     subsegnumber++;
14760   }
14761 
14762 #ifndef TRILIBRARY
14763 #ifndef CDT_ONLY
14764   fprintf(outfile, "%d\n", holes);
14765   if (holes > 0) {
14766     for (holenumber = 0; holenumber < holes; holenumber++) {
14767       /* Hole number, x and y coordinates. */
14768       fprintf(outfile, "%4ld   %.17g  %.17g\n", b->firstnumber + holenumber,
14769               holelist[2 * holenumber], holelist[2 * holenumber + 1]);
14770     }
14771   }
14772   if (regions > 0) {
14773     fprintf(outfile, "%d\n", regions);
14774     for (regionnumber = 0; regionnumber < regions; regionnumber++) {
14775       /* Region number, x and y coordinates, attribute, maximum area. */
14776       fprintf(outfile, "%4ld   %.17g  %.17g  %.17g  %.17g\n",
14777               b->firstnumber + regionnumber,
14778               regionlist[4 * regionnumber], regionlist[4 * regionnumber + 1],
14779               regionlist[4 * regionnumber + 2],
14780               regionlist[4 * regionnumber + 3]);
14781     }
14782   }
14783 #endif /* not CDT_ONLY */
14784 
14785   finishfile(outfile, argc, argv);
14786 #endif /* not TRILIBRARY */
14787 }
14788 
14789 /*****************************************************************************/
14790 /*                                                                           */
14791 /*  writeedges()   Write the edges to an .edge file.                         */
14792 /*                                                                           */
14793 /*****************************************************************************/
14794 
14795 #ifdef TRILIBRARY
14796 
14797 #ifdef ANSI_DECLARATORS
14798 void writeedges(struct mesh *m, struct behavior *b,
14799                 int **edgelist, int **edgemarkerlist)
14800 #else /* not ANSI_DECLARATORS */
14801 void writeedges(m, b, edgelist, edgemarkerlist)
14802 struct mesh *m;
14803 struct behavior *b;
14804 int **edgelist;
14805 int **edgemarkerlist;
14806 #endif /* not ANSI_DECLARATORS */
14807 
14808 #else /* not TRILIBRARY */
14809 
14810 #ifdef ANSI_DECLARATORS
14811 void writeedges(struct mesh *m, struct behavior *b, char *edgefilename,
14812                 int argc, char **argv)
14813 #else /* not ANSI_DECLARATORS */
14814 void writeedges(m, b, edgefilename, argc, argv)
14815 struct mesh *m;
14816 struct behavior *b;
14817 char *edgefilename;
14818 int argc;
14819 char **argv;
14820 #endif /* not ANSI_DECLARATORS */
14821 
14822 #endif /* not TRILIBRARY */
14823 
14824 {
14825 #ifdef TRILIBRARY
14826   int *elist;
14827   int *emlist;
14828   int index;
14829 #else /* not TRILIBRARY */
14830   FILE *outfile;
14831 #endif /* not TRILIBRARY */
14832   struct otri triangleloop, trisym;
14833   struct osub checkmark;
14834   vertex p1, p2;
14835   long edgenumber;
14836   triangle ptr;                         /* Temporary variable used by sym(). */
14837   subseg sptr;                      /* Temporary variable used by tspivot(). */
14838 
14839 #ifdef TRILIBRARY
14840   if (!b->quiet) {
14841     printf("Writing edges.\n");
14842   }
14843   /* Allocate memory for edges if necessary. */
14844   if (*edgelist == (int *) NULL) {
14845     *edgelist = (int *) trimalloc((int) (m->edges * 2 * sizeof(int)));
14846   }
14847   /* Allocate memory for edge markers if necessary. */
14848   if (!b->nobound && (*edgemarkerlist == (int *) NULL)) {
14849     *edgemarkerlist = (int *) trimalloc((int) (m->edges * sizeof(int)));
14850   }
14851   elist = *edgelist;
14852   emlist = *edgemarkerlist;
14853   index = 0;
14854 #else /* not TRILIBRARY */
14855   if (!b->quiet) {
14856     printf("Writing %s.\n", edgefilename);
14857   }
14858   outfile = fopen(edgefilename, "w");
14859   if (outfile == (FILE *) NULL) {
14860     printf("  Error:  Cannot create file %s.\n", edgefilename);
14861     triexit(1);
14862   }
14863   /* Number of edges, number of boundary markers (zero or one). */
14864   fprintf(outfile, "%ld  %d\n", m->edges, 1 - b->nobound);
14865 #endif /* not TRILIBRARY */
14866 
14867   traversalinit(&m->triangles);
14868   triangleloop.tri = triangletraverse(m);
14869   edgenumber = b->firstnumber;
14870   /* To loop over the set of edges, loop over all triangles, and look at   */
14871   /*   the three edges of each triangle.  If there isn't another triangle  */
14872   /*   adjacent to the edge, operate on the edge.  If there is another     */
14873   /*   adjacent triangle, operate on the edge only if the current triangle */
14874   /*   has a smaller pointer than its neighbor.  This way, each edge is    */
14875   /*   considered only once.                                               */
14876   while (triangleloop.tri != (triangle *) NULL) {
14877     for (triangleloop.orient = 0; triangleloop.orient < 3;
14878          triangleloop.orient++) {
14879       sym(triangleloop, trisym);
14880       if ((triangleloop.tri < trisym.tri) || (trisym.tri == m->dummytri)) {
14881         org(triangleloop, p1);
14882         dest(triangleloop, p2);
14883 #ifdef TRILIBRARY
14884         elist[index++] = vertexmark(p1);
14885         elist[index++] = vertexmark(p2);
14886 #endif /* TRILIBRARY */
14887         if (b->nobound) {
14888 #ifndef TRILIBRARY
14889           /* Edge number, indices of two endpoints. */
14890           fprintf(outfile, "%4ld   %d  %d\n", edgenumber,
14891                   vertexmark(p1), vertexmark(p2));
14892 #endif /* not TRILIBRARY */
14893         } else {
14894           /* Edge number, indices of two endpoints, and a boundary marker. */
14895           /*   If there's no subsegment, the boundary marker is zero.      */
14896           if (b->usesegments) {
14897             tspivot(triangleloop, checkmark);
14898             if (checkmark.ss == m->dummysub) {
14899 #ifdef TRILIBRARY
14900               emlist[edgenumber - b->firstnumber] = 0;
14901 #else /* not TRILIBRARY */
14902               fprintf(outfile, "%4ld   %d  %d  %d\n", edgenumber,
14903                       vertexmark(p1), vertexmark(p2), 0);
14904 #endif /* not TRILIBRARY */
14905             } else {
14906 #ifdef TRILIBRARY
14907               emlist[edgenumber - b->firstnumber] = mark(checkmark);
14908 #else /* not TRILIBRARY */
14909               fprintf(outfile, "%4ld   %d  %d  %d\n", edgenumber,
14910                       vertexmark(p1), vertexmark(p2), mark(checkmark));
14911 #endif /* not TRILIBRARY */
14912             }
14913           } else {
14914 #ifdef TRILIBRARY
14915             emlist[edgenumber - b->firstnumber] = trisym.tri == m->dummytri;
14916 #else /* not TRILIBRARY */
14917             fprintf(outfile, "%4ld   %d  %d  %d\n", edgenumber,
14918                     vertexmark(p1), vertexmark(p2), trisym.tri == m->dummytri);
14919 #endif /* not TRILIBRARY */
14920           }
14921         }
14922         edgenumber++;
14923       }
14924     }
14925     triangleloop.tri = triangletraverse(m);
14926   }
14927 
14928 #ifndef TRILIBRARY
14929   finishfile(outfile, argc, argv);
14930 #endif /* not TRILIBRARY */
14931 }
14932 
14933 /*****************************************************************************/
14934 /*                                                                           */
14935 /*  writevoronoi()   Write the Voronoi diagram to a .v.node and .v.edge      */
14936 /*                   file.                                                   */
14937 /*                                                                           */
14938 /*  The Voronoi diagram is the geometric dual of the Delaunay triangulation. */
14939 /*  Hence, the Voronoi vertices are listed by traversing the Delaunay        */
14940 /*  triangles, and the Voronoi edges are listed by traversing the Delaunay   */
14941 /*  edges.                                                                   */
14942 /*                                                                           */
14943 /*  WARNING:  In order to assign numbers to the Voronoi vertices, this       */
14944 /*  procedure messes up the subsegments or the extra nodes of every          */
14945 /*  element.  Hence, you should call this procedure last.                    */
14946 /*                                                                           */
14947 /*****************************************************************************/
14948 
14949 #ifdef TRILIBRARY
14950 
14951 #ifdef ANSI_DECLARATORS
14952 void writevoronoi(struct mesh *m, struct behavior *b, REAL **vpointlist,
14953                   REAL **vpointattriblist, int **vpointmarkerlist,
14954                   int **vedgelist, int **vedgemarkerlist, REAL **vnormlist)
14955 #else /* not ANSI_DECLARATORS */
14956 void writevoronoi(m, b, vpointlist, vpointattriblist, vpointmarkerlist,
14957                   vedgelist, vedgemarkerlist, vnormlist)
14958 struct mesh *m;
14959 struct behavior *b;
14960 REAL **vpointlist;
14961 REAL **vpointattriblist;
14962 int **vpointmarkerlist;
14963 int **vedgelist;
14964 int **vedgemarkerlist;
14965 REAL **vnormlist;
14966 #endif /* not ANSI_DECLARATORS */
14967 
14968 #else /* not TRILIBRARY */
14969 
14970 #ifdef ANSI_DECLARATORS
14971 void writevoronoi(struct mesh *m, struct behavior *b, char *vnodefilename,
14972                   char *vedgefilename, int argc, char **argv)
14973 #else /* not ANSI_DECLARATORS */
14974 void writevoronoi(m, b, vnodefilename, vedgefilename, argc, argv)
14975 struct mesh *m;
14976 struct behavior *b;
14977 char *vnodefilename;
14978 char *vedgefilename;
14979 int argc;
14980 char **argv;
14981 #endif /* not ANSI_DECLARATORS */
14982 
14983 #endif /* not TRILIBRARY */
14984 
14985 {
14986 #ifdef TRILIBRARY
14987   REAL *plist;
14988   REAL *palist;
14989   int *elist;
14990   REAL *normlist;
14991   int coordindex;
14992   int attribindex;
14993 #else /* not TRILIBRARY */
14994   FILE *outfile;
14995 #endif /* not TRILIBRARY */
14996   struct otri triangleloop, trisym;
14997   vertex torg, tdest, tapex;
14998   REAL circumcenter[2];
14999   REAL xi, eta;
15000   long vnodenumber, vedgenumber;
15001   int p1, p2;
15002   int i;
15003   triangle ptr;                         /* Temporary variable used by sym(). */
15004 
15005 #ifdef TRILIBRARY
15006   if (!b->quiet) {
15007     printf("Writing Voronoi vertices.\n");
15008   }
15009   /* Allocate memory for Voronoi vertices if necessary. */
15010   if (*vpointlist == (REAL *) NULL) {
15011     *vpointlist = (REAL *) trimalloc((int) (m->triangles.items * 2 *
15012                                             sizeof(REAL)));
15013   }
15014   /* Allocate memory for Voronoi vertex attributes if necessary. */
15015   if (*vpointattriblist == (REAL *) NULL) {
15016     *vpointattriblist = (REAL *) trimalloc((int) (m->triangles.items *
15017                                                   m->nextras * sizeof(REAL)));
15018   }
15019   *vpointmarkerlist = (int *) NULL;
15020   plist = *vpointlist;
15021   palist = *vpointattriblist;
15022   coordindex = 0;
15023   attribindex = 0;
15024 #else /* not TRILIBRARY */
15025   if (!b->quiet) {
15026     printf("Writing %s.\n", vnodefilename);
15027   }
15028   outfile = fopen(vnodefilename, "w");
15029   if (outfile == (FILE *) NULL) {
15030     printf("  Error:  Cannot create file %s.\n", vnodefilename);
15031     triexit(1);
15032   }
15033   /* Number of triangles, two dimensions, number of vertex attributes, */
15034   /*   no markers.                                                     */
15035   fprintf(outfile, "%ld  %d  %d  %d\n", m->triangles.items, 2, m->nextras, 0);
15036 #endif /* not TRILIBRARY */
15037 
15038   traversalinit(&m->triangles);
15039   triangleloop.tri = triangletraverse(m);
15040   triangleloop.orient = 0;
15041   vnodenumber = b->firstnumber;
15042   while (triangleloop.tri != (triangle *) NULL) {
15043     org(triangleloop, torg);
15044     dest(triangleloop, tdest);
15045     apex(triangleloop, tapex);
15046     findcircumcenter(m, b, torg, tdest, tapex, circumcenter, &xi, &eta, 0);
15047 #ifdef TRILIBRARY
15048     /* X and y coordinates. */
15049     plist[coordindex++] = circumcenter[0];
15050     plist[coordindex++] = circumcenter[1];
15051     for (i = 2; i < 2 + m->nextras; i++) {
15052       /* Interpolate the vertex attributes at the circumcenter. */
15053       palist[attribindex++] = torg[i] + xi * (tdest[i] - torg[i])
15054                                      + eta * (tapex[i] - torg[i]);
15055     }
15056 #else /* not TRILIBRARY */
15057     /* Voronoi vertex number, x and y coordinates. */
15058     fprintf(outfile, "%4ld    %.17g  %.17g", vnodenumber, circumcenter[0],
15059             circumcenter[1]);
15060     for (i = 2; i < 2 + m->nextras; i++) {
15061       /* Interpolate the vertex attributes at the circumcenter. */
15062       fprintf(outfile, "  %.17g", torg[i] + xi * (tdest[i] - torg[i])
15063                                          + eta * (tapex[i] - torg[i]));
15064     }
15065     fprintf(outfile, "\n");
15066 #endif /* not TRILIBRARY */
15067 
15068     * (int *) (triangleloop.tri + 6) = (int) vnodenumber;
15069     triangleloop.tri = triangletraverse(m);
15070     vnodenumber++;
15071   }
15072 
15073 #ifndef TRILIBRARY
15074   finishfile(outfile, argc, argv);
15075 #endif /* not TRILIBRARY */
15076 
15077 #ifdef TRILIBRARY
15078   if (!b->quiet) {
15079     printf("Writing Voronoi edges.\n");
15080   }
15081   /* Allocate memory for output Voronoi edges if necessary. */
15082   if (*vedgelist == (int *) NULL) {
15083     *vedgelist = (int *) trimalloc((int) (m->edges * 2 * sizeof(int)));
15084   }
15085   *vedgemarkerlist = (int *) NULL;
15086   /* Allocate memory for output Voronoi norms if necessary. */
15087   if (*vnormlist == (REAL *) NULL) {
15088     *vnormlist = (REAL *) trimalloc((int) (m->edges * 2 * sizeof(REAL)));
15089   }
15090   elist = *vedgelist;
15091   normlist = *vnormlist;
15092   coordindex = 0;
15093 #else /* not TRILIBRARY */
15094   if (!b->quiet) {
15095     printf("Writing %s.\n", vedgefilename);
15096   }
15097   outfile = fopen(vedgefilename, "w");
15098   if (outfile == (FILE *) NULL) {
15099     printf("  Error:  Cannot create file %s.\n", vedgefilename);
15100     triexit(1);
15101   }
15102   /* Number of edges, zero boundary markers. */
15103   fprintf(outfile, "%ld  %d\n", m->edges, 0);
15104 #endif /* not TRILIBRARY */
15105 
15106   traversalinit(&m->triangles);
15107   triangleloop.tri = triangletraverse(m);
15108   vedgenumber = b->firstnumber;
15109   /* To loop over the set of edges, loop over all triangles, and look at   */
15110   /*   the three edges of each triangle.  If there isn't another triangle  */
15111   /*   adjacent to the edge, operate on the edge.  If there is another     */
15112   /*   adjacent triangle, operate on the edge only if the current triangle */
15113   /*   has a smaller pointer than its neighbor.  This way, each edge is    */
15114   /*   considered only once.                                               */
15115   while (triangleloop.tri != (triangle *) NULL) {
15116     for (triangleloop.orient = 0; triangleloop.orient < 3;
15117          triangleloop.orient++) {
15118       sym(triangleloop, trisym);
15119       if ((triangleloop.tri < trisym.tri) || (trisym.tri == m->dummytri)) {
15120         /* Find the number of this triangle (and Voronoi vertex). */
15121         p1 = * (int *) (triangleloop.tri + 6);
15122         if (trisym.tri == m->dummytri) {
15123           org(triangleloop, torg);
15124           dest(triangleloop, tdest);
15125 #ifdef TRILIBRARY
15126           /* Copy an infinite ray.  Index of one endpoint, and -1. */
15127           elist[coordindex] = p1;
15128           normlist[coordindex++] = tdest[1] - torg[1];
15129           elist[coordindex] = -1;
15130           normlist[coordindex++] = torg[0] - tdest[0];
15131 #else /* not TRILIBRARY */
15132           /* Write an infinite ray.  Edge number, index of one endpoint, -1, */
15133           /*   and x and y coordinates of a vector representing the          */
15134           /*   direction of the ray.                                         */
15135           fprintf(outfile, "%4ld   %d  %d   %.17g  %.17g\n", vedgenumber,
15136                   p1, -1, tdest[1] - torg[1], torg[0] - tdest[0]);
15137 #endif /* not TRILIBRARY */
15138         } else {
15139           /* Find the number of the adjacent triangle (and Voronoi vertex). */
15140           p2 = * (int *) (trisym.tri + 6);
15141           /* Finite edge.  Write indices of two endpoints. */
15142 #ifdef TRILIBRARY
15143           elist[coordindex] = p1;
15144           normlist[coordindex++] = 0.0;
15145           elist[coordindex] = p2;
15146           normlist[coordindex++] = 0.0;
15147 #else /* not TRILIBRARY */
15148           fprintf(outfile, "%4ld   %d  %d\n", vedgenumber, p1, p2);
15149 #endif /* not TRILIBRARY */
15150         }
15151         vedgenumber++;
15152       }
15153     }
15154     triangleloop.tri = triangletraverse(m);
15155   }
15156 
15157 #ifndef TRILIBRARY
15158   finishfile(outfile, argc, argv);
15159 #endif /* not TRILIBRARY */
15160 }
15161 
15162 #ifdef TRILIBRARY
15163 
15164 #ifdef ANSI_DECLARATORS
15165 void writeneighbors(struct mesh *m, struct behavior *b, int **neighborlist)
15166 #else /* not ANSI_DECLARATORS */
15167 void writeneighbors(m, b, neighborlist)
15168 struct mesh *m;
15169 struct behavior *b;
15170 int **neighborlist;
15171 #endif /* not ANSI_DECLARATORS */
15172 
15173 #else /* not TRILIBRARY */
15174 
15175 #ifdef ANSI_DECLARATORS
15176 void writeneighbors(struct mesh *m, struct behavior *b, char *neighborfilename,
15177                     int argc, char **argv)
15178 #else /* not ANSI_DECLARATORS */
15179 void writeneighbors(m, b, neighborfilename, argc, argv)
15180 struct mesh *m;
15181 struct behavior *b;
15182 char *neighborfilename;
15183 int argc;
15184 char **argv;
15185 #endif /* not ANSI_DECLARATORS */
15186 
15187 #endif /* not TRILIBRARY */
15188 
15189 {
15190 #ifdef TRILIBRARY
15191   int *nlist;
15192   int index;
15193 #else /* not TRILIBRARY */
15194   FILE *outfile;
15195 #endif /* not TRILIBRARY */
15196   struct otri triangleloop, trisym;
15197   long elementnumber;
15198   int neighbor1, neighbor2, neighbor3;
15199   triangle ptr;                         /* Temporary variable used by sym(). */
15200 
15201 #ifdef TRILIBRARY
15202   if (!b->quiet) {
15203     printf("Writing neighbors.\n");
15204   }
15205   /* Allocate memory for neighbors if necessary. */
15206   if (*neighborlist == (int *) NULL) {
15207     *neighborlist = (int *) trimalloc((int) (m->triangles.items * 3 *
15208                                              sizeof(int)));
15209   }
15210   nlist = *neighborlist;
15211   index = 0;
15212 #else /* not TRILIBRARY */
15213   if (!b->quiet) {
15214     printf("Writing %s.\n", neighborfilename);
15215   }
15216   outfile = fopen(neighborfilename, "w");
15217   if (outfile == (FILE *) NULL) {
15218     printf("  Error:  Cannot create file %s.\n", neighborfilename);
15219     triexit(1);
15220   }
15221   /* Number of triangles, three neighbors per triangle. */
15222   fprintf(outfile, "%ld  %d\n", m->triangles.items, 3);
15223 #endif /* not TRILIBRARY */
15224 
15225   traversalinit(&m->triangles);
15226   triangleloop.tri = triangletraverse(m);
15227   triangleloop.orient = 0;
15228   elementnumber = b->firstnumber;
15229   while (triangleloop.tri != (triangle *) NULL) {
15230     * (int *) (triangleloop.tri + 6) = (int) elementnumber;
15231     triangleloop.tri = triangletraverse(m);
15232     elementnumber++;
15233   }
15234   * (int *) (m->dummytri + 6) = -1;
15235 
15236   traversalinit(&m->triangles);
15237   triangleloop.tri = triangletraverse(m);
15238   elementnumber = b->firstnumber;
15239   while (triangleloop.tri != (triangle *) NULL) {
15240     triangleloop.orient = 1;
15241     sym(triangleloop, trisym);
15242     neighbor1 = * (int *) (trisym.tri + 6);
15243     triangleloop.orient = 2;
15244     sym(triangleloop, trisym);
15245     neighbor2 = * (int *) (trisym.tri + 6);
15246     triangleloop.orient = 0;
15247     sym(triangleloop, trisym);
15248     neighbor3 = * (int *) (trisym.tri + 6);
15249 #ifdef TRILIBRARY
15250     nlist[index++] = neighbor1;
15251     nlist[index++] = neighbor2;
15252     nlist[index++] = neighbor3;
15253 #else /* not TRILIBRARY */
15254     /* Triangle number, neighboring triangle numbers. */
15255     fprintf(outfile, "%4ld    %d  %d  %d\n", elementnumber,
15256             neighbor1, neighbor2, neighbor3);
15257 #endif /* not TRILIBRARY */
15258 
15259     triangleloop.tri = triangletraverse(m);
15260     elementnumber++;
15261   }
15262 
15263 #ifndef TRILIBRARY
15264   finishfile(outfile, argc, argv);
15265 #endif /* not TRILIBRARY */
15266 }
15267 
15268 /*****************************************************************************/
15269 /*                                                                           */
15270 /*  writeoff()   Write the triangulation to an .off file.                    */
15271 /*                                                                           */
15272 /*  OFF stands for the Object File Format, a format used by the Geometry     */
15273 /*  Center's Geomview package.                                               */
15274 /*                                                                           */
15275 /*****************************************************************************/
15276 
15277 #ifndef TRILIBRARY
15278 
15279 #ifdef ANSI_DECLARATORS
15280 void writeoff(struct mesh *m, struct behavior *b, char *offfilename,
15281               int argc, char **argv)
15282 #else /* not ANSI_DECLARATORS */
15283 void writeoff(m, b, offfilename, argc, argv)
15284 struct mesh *m;
15285 struct behavior *b;
15286 char *offfilename;
15287 int argc;
15288 char **argv;
15289 #endif /* not ANSI_DECLARATORS */
15290 
15291 {
15292   FILE *outfile;
15293   struct otri triangleloop;
15294   vertex vertexloop;
15295   vertex p1, p2, p3;
15296   long outvertices;
15297 
15298   if (!b->quiet) {
15299     printf("Writing %s.\n", offfilename);
15300   }
15301 
15302   if (b->jettison) {
15303     outvertices = m->vertices.items - m->undeads;
15304   } else {
15305     outvertices = m->vertices.items;
15306   }
15307 
15308   outfile = fopen(offfilename, "w");
15309   if (outfile == (FILE *) NULL) {
15310     printf("  Error:  Cannot create file %s.\n", offfilename);
15311     triexit(1);
15312   }
15313   /* Number of vertices, triangles, and edges. */
15314   fprintf(outfile, "OFF\n%ld  %ld  %ld\n", outvertices, m->triangles.items,
15315           m->edges);
15316 
15317   /* Write the vertices. */
15318   traversalinit(&m->vertices);
15319   vertexloop = vertextraverse(m);
15320   while (vertexloop != (vertex) NULL) {
15321     if (!b->jettison || (vertextype(vertexloop) != UNDEADVERTEX)) {
15322       /* The "0.0" is here because the OFF format uses 3D coordinates. */
15323       fprintf(outfile, " %.17g  %.17g  %.17g\n", vertexloop[0], vertexloop[1],
15324               0.0);
15325     }
15326     vertexloop = vertextraverse(m);
15327   }
15328 
15329   /* Write the triangles. */
15330   traversalinit(&m->triangles);
15331   triangleloop.tri = triangletraverse(m);
15332   triangleloop.orient = 0;
15333   while (triangleloop.tri != (triangle *) NULL) {
15334     org(triangleloop, p1);
15335     dest(triangleloop, p2);
15336     apex(triangleloop, p3);
15337     /* The "3" means a three-vertex polygon. */
15338     fprintf(outfile, " 3   %4d  %4d  %4d\n", vertexmark(p1) - b->firstnumber,
15339             vertexmark(p2) - b->firstnumber, vertexmark(p3) - b->firstnumber);
15340     triangleloop.tri = triangletraverse(m);
15341   }
15342   finishfile(outfile, argc, argv);
15343 }
15344 
15345 #endif /* not TRILIBRARY */
15346 
15347 /**                                                                         **/
15348 /**                                                                         **/
15349 /********* File I/O routines end here                                *********/
15350 
15351 /*****************************************************************************/
15352 /*                                                                           */
15353 /*  quality_statistics()   Print statistics about the quality of the mesh.   */
15354 /*                                                                           */
15355 /*****************************************************************************/
15356 
15357 #ifdef ANSI_DECLARATORS
15358 void quality_statistics(struct mesh *m, struct behavior *b)
15359 #else /* not ANSI_DECLARATORS */
15360 void quality_statistics(m, b)
15361 struct mesh *m;
15362 struct behavior *b;
15363 #endif /* not ANSI_DECLARATORS */
15364 
15365 {
15366   struct otri triangleloop;
15367   vertex p[3];
15368   REAL cossquaretable[8];
15369   REAL ratiotable[16];
15370   REAL dx[3], dy[3];
15371   REAL edgelength[3];
15372   REAL dotproduct;
15373   REAL cossquare;
15374   REAL triarea;
15375   REAL shortest, longest;
15376   REAL trilongest2;
15377   REAL smallestarea, biggestarea;
15378   REAL triminaltitude2;
15379   REAL minaltitude;
15380   REAL triaspect2;
15381   REAL worstaspect;
15382   REAL smallestangle, biggestangle;
15383   REAL radconst, degconst;
15384   int angletable[18];
15385   int aspecttable[16];
15386   int aspectindex;
15387   int tendegree;
15388   int acutebiggest;
15389   int i, ii, j, k;
15390 
15391   printf("Mesh quality statistics:\n\n");
15392   radconst = PI / 18.0;
15393   degconst = 180.0 / PI;
15394   for (i = 0; i < 8; i++) {
15395     cossquaretable[i] = cos(radconst * (REAL) (i + 1));
15396     cossquaretable[i] = cossquaretable[i] * cossquaretable[i];
15397   }
15398   for (i = 0; i < 18; i++) {
15399     angletable[i] = 0;
15400   }
15401 
15402   ratiotable[0]  =      1.5;      ratiotable[1]  =     2.0;
15403   ratiotable[2]  =      2.5;      ratiotable[3]  =     3.0;
15404   ratiotable[4]  =      4.0;      ratiotable[5]  =     6.0;
15405   ratiotable[6]  =     10.0;      ratiotable[7]  =    15.0;
15406   ratiotable[8]  =     25.0;      ratiotable[9]  =    50.0;
15407   ratiotable[10] =    100.0;      ratiotable[11] =   300.0;
15408   ratiotable[12] =   1000.0;      ratiotable[13] = 10000.0;
15409   ratiotable[14] = 100000.0;      ratiotable[15] =     0.0;
15410   for (i = 0; i < 16; i++) {
15411     aspecttable[i] = 0;
15412   }
15413 
15414   worstaspect = 0.0;
15415   minaltitude = m->xmax - m->xmin + m->ymax - m->ymin;
15416   minaltitude = minaltitude * minaltitude;
15417   shortest = minaltitude;
15418   longest = 0.0;
15419   smallestarea = minaltitude;
15420   biggestarea = 0.0;
15421   worstaspect = 0.0;
15422   smallestangle = 0.0;
15423   biggestangle = 2.0;
15424   acutebiggest = 1;
15425 
15426   traversalinit(&m->triangles);
15427   triangleloop.tri = triangletraverse(m);
15428   triangleloop.orient = 0;
15429   while (triangleloop.tri != (triangle *) NULL) {
15430     org(triangleloop, p[0]);
15431     dest(triangleloop, p[1]);
15432     apex(triangleloop, p[2]);
15433     trilongest2 = 0.0;
15434 
15435     for (i = 0; i < 3; i++) {
15436       j = plus1mod3[i];
15437       k = minus1mod3[i];
15438       dx[i] = p[j][0] - p[k][0];
15439       dy[i] = p[j][1] - p[k][1];
15440       edgelength[i] = dx[i] * dx[i] + dy[i] * dy[i];
15441       if (edgelength[i] > trilongest2) {
15442         trilongest2 = edgelength[i];
15443       }
15444       if (edgelength[i] > longest) {
15445         longest = edgelength[i];
15446       }
15447       if (edgelength[i] < shortest) {
15448         shortest = edgelength[i];
15449       }
15450     }
15451 
15452     triarea = counterclockwise(m, b, p[0], p[1], p[2]);
15453     if (triarea < smallestarea) {
15454       smallestarea = triarea;
15455     }
15456     if (triarea > biggestarea) {
15457       biggestarea = triarea;
15458     }
15459     triminaltitude2 = triarea * triarea / trilongest2;
15460     if (triminaltitude2 < minaltitude) {
15461       minaltitude = triminaltitude2;
15462     }
15463     triaspect2 = trilongest2 / triminaltitude2;
15464     if (triaspect2 > worstaspect) {
15465       worstaspect = triaspect2;
15466     }
15467     aspectindex = 0;
15468     while ((triaspect2 > ratiotable[aspectindex] * ratiotable[aspectindex])
15469            && (aspectindex < 15)) {
15470       aspectindex++;
15471     }
15472     aspecttable[aspectindex]++;
15473 
15474     for (i = 0; i < 3; i++) {
15475       j = plus1mod3[i];
15476       k = minus1mod3[i];
15477       dotproduct = dx[j] * dx[k] + dy[j] * dy[k];
15478       cossquare = dotproduct * dotproduct / (edgelength[j] * edgelength[k]);
15479       tendegree = 8;
15480       for (ii = 7; ii >= 0; ii--) {
15481         if (cossquare > cossquaretable[ii]) {
15482           tendegree = ii;
15483         }
15484       }
15485       if (dotproduct <= 0.0) {
15486         angletable[tendegree]++;
15487         if (cossquare > smallestangle) {
15488           smallestangle = cossquare;
15489         }
15490         if (acutebiggest && (cossquare < biggestangle)) {
15491           biggestangle = cossquare;
15492         }
15493       } else {
15494         angletable[17 - tendegree]++;
15495         if (acutebiggest || (cossquare > biggestangle)) {
15496           biggestangle = cossquare;
15497           acutebiggest = 0;
15498         }
15499       }
15500     }
15501     triangleloop.tri = triangletraverse(m);
15502   }
15503 
15504   shortest = sqrt(shortest);
15505   longest = sqrt(longest);
15506   minaltitude = sqrt(minaltitude);
15507   worstaspect = sqrt(worstaspect);
15508   smallestarea *= 0.5;
15509   biggestarea *= 0.5;
15510   if (smallestangle >= 1.0) {
15511     smallestangle = 0.0;
15512   } else {
15513     smallestangle = degconst * acos(sqrt(smallestangle));
15514   }
15515   if (biggestangle >= 1.0) {
15516     biggestangle = 180.0;
15517   } else {
15518     if (acutebiggest) {
15519       biggestangle = degconst * acos(sqrt(biggestangle));
15520     } else {
15521       biggestangle = 180.0 - degconst * acos(sqrt(biggestangle));
15522     }
15523   }
15524 
15525   printf("  Smallest area: %16.5g   |  Largest area: %16.5g\n",
15526          (double)smallestarea, (double)biggestarea);
15527   printf("  Shortest edge: %16.5g   |  Longest edge: %16.5g\n",
15528          (double)shortest, (double)longest);
15529   printf("  Shortest altitude: %12.5g   |  Largest aspect ratio: %8.5g\n\n",
15530          (double)minaltitude, (double)worstaspect);
15531 
15532   printf("  Triangle aspect ratio histogram:\n");
15533   printf("  1.1547 - %-6.6g    :  %8d    | %6.6g - %-6.6g     :  %8d\n",
15534          (double)ratiotable[0], aspecttable[0], (double)ratiotable[7], (double)ratiotable[8],
15535          aspecttable[8]);
15536   for (i = 1; i < 7; i++) {
15537     printf("  %6.6g - %-6.6g    :  %8d    | %6.6g - %-6.6g     :  %8d\n",
15538            (double)ratiotable[i - 1], (double)ratiotable[i], aspecttable[i],
15539            (double)ratiotable[i + 7], (double)ratiotable[i + 8], aspecttable[i + 8]);
15540   }
15541   printf("  %6.6g - %-6.6g    :  %8d    | %6.6g -            :  %8d\n",
15542          (double)ratiotable[6], (double)ratiotable[7], aspecttable[7], (double)ratiotable[14],
15543          aspecttable[15]);
15544   printf("  (Aspect ratio is longest edge divided by shortest altitude)\n\n");
15545 
15546   printf("  Smallest angle: %15.5g   |  Largest angle: %15.5g\n\n",
15547          (double)smallestangle, (double)biggestangle);
15548 
15549   printf("  Angle histogram:\n");
15550   for (i = 0; i < 9; i++) {
15551     printf("    %3d - %3d degrees:  %8d    |    %3d - %3d degrees:  %8d\n",
15552            i * 10, i * 10 + 10, angletable[i],
15553            i * 10 + 90, i * 10 + 100, angletable[i + 9]);
15554   }
15555   printf("\n");
15556 }
15557 
15558 /*****************************************************************************/
15559 /*                                                                           */
15560 /*  statistics()   Print all sorts of cool facts.                            */
15561 /*                                                                           */
15562 /*****************************************************************************/
15563 
15564 #ifdef ANSI_DECLARATORS
15565 void statistics(struct mesh *m, struct behavior *b)
15566 #else /* not ANSI_DECLARATORS */
15567 void statistics(m, b)
15568 struct mesh *m;
15569 struct behavior *b;
15570 #endif /* not ANSI_DECLARATORS */
15571 
15572 {
15573   printf("\nStatistics:\n\n");
15574   printf("  Input vertices: %d\n", m->invertices);
15575   if (b->refine) {
15576     printf("  Input triangles: %d\n", m->inelements);
15577   }
15578   if (b->poly) {
15579     printf("  Input segments: %d\n", m->insegments);
15580     if (!b->refine) {
15581       printf("  Input holes: %d\n", m->holes);
15582     }
15583   }
15584 
15585   printf("\n  Mesh vertices: %ld\n", m->vertices.items - m->undeads);
15586   printf("  Mesh triangles: %ld\n", m->triangles.items);
15587   printf("  Mesh edges: %ld\n", m->edges);
15588   printf("  Mesh exterior boundary edges: %ld\n", m->hullsize);
15589   if (b->poly || b->refine) {
15590     printf("  Mesh interior boundary edges: %ld\n",
15591            m->subsegs.items - m->hullsize);
15592     printf("  Mesh subsegments (constrained edges): %ld\n",
15593            m->subsegs.items);
15594   }
15595   printf("\n");
15596 
15597   if (b->verbose) {
15598     quality_statistics(m, b);
15599     printf("Memory allocation statistics:\n\n");
15600     printf("  Maximum number of vertices: %ld\n", m->vertices.maxitems);
15601     printf("  Maximum number of triangles: %ld\n", m->triangles.maxitems);
15602     if (m->subsegs.maxitems > 0) {
15603       printf("  Maximum number of subsegments: %ld\n", m->subsegs.maxitems);
15604     }
15605     if (m->viri.maxitems > 0) {
15606       printf("  Maximum number of viri: %ld\n", m->viri.maxitems);
15607     }
15608     if (m->badsubsegs.maxitems > 0) {
15609       printf("  Maximum number of encroached subsegments: %ld\n",
15610              m->badsubsegs.maxitems);
15611     }
15612     if (m->badtriangles.maxitems > 0) {
15613       printf("  Maximum number of bad triangles: %ld\n",
15614              m->badtriangles.maxitems);
15615     }
15616     if (m->flipstackers.maxitems > 0) {
15617       printf("  Maximum number of stacked triangle flips: %ld\n",
15618              m->flipstackers.maxitems);
15619     }
15620     if (m->splaynodes.maxitems > 0) {
15621       printf("  Maximum number of splay tree nodes: %ld\n",
15622              m->splaynodes.maxitems);
15623     }
15624     printf("  Approximate heap memory use (bytes): %ld\n\n",
15625            m->vertices.maxitems * m->vertices.itembytes +
15626            m->triangles.maxitems * m->triangles.itembytes +
15627            m->subsegs.maxitems * m->subsegs.itembytes +
15628            m->viri.maxitems * m->viri.itembytes +
15629            m->badsubsegs.maxitems * m->badsubsegs.itembytes +
15630            m->badtriangles.maxitems * m->badtriangles.itembytes +
15631            m->flipstackers.maxitems * m->flipstackers.itembytes +
15632            m->splaynodes.maxitems * m->splaynodes.itembytes);
15633 
15634     printf("Algorithmic statistics:\n\n");
15635     if (!b->weighted) {
15636       printf("  Number of incircle tests: %ld\n", m->incirclecount);
15637     } else {
15638       printf("  Number of 3D orientation tests: %ld\n", m->orient3dcount);
15639     }
15640     printf("  Number of 2D orientation tests: %ld\n", m->counterclockcount);
15641     if (m->hyperbolacount > 0) {
15642       printf("  Number of right-of-hyperbola tests: %ld\n",
15643              m->hyperbolacount);
15644     }
15645     if (m->circletopcount > 0) {
15646       printf("  Number of circle top computations: %ld\n",
15647              m->circletopcount);
15648     }
15649     if (m->circumcentercount > 0) {
15650       printf("  Number of triangle circumcenter computations: %ld\n",
15651              m->circumcentercount);
15652     }
15653     printf("\n");
15654   }
15655 }
15656 
15657 /*****************************************************************************/
15658 /*                                                                           */
15659 /*  main() or triangulate()   Gosh, do everything.                           */
15660 /*                                                                           */
15661 /*  The sequence is roughly as follows.  Many of these steps can be skipped, */
15662 /*  depending on the command line switches.                                  */
15663 /*                                                                           */
15664 /*  - Initialize constants and parse the command line.                       */
15665 /*  - Read the vertices from a file and either                               */
15666 /*    - triangulate them (no -r), or                                         */
15667 /*    - read an old mesh from files and reconstruct it (-r).                 */
15668 /*  - Insert the PSLG segments (-p), and possibly segments on the convex     */
15669 /*      hull (-c).                                                           */
15670 /*  - Read the holes (-p), regional attributes (-pA), and regional area      */
15671 /*      constraints (-pa).  Carve the holes and concavities, and spread the  */
15672 /*      regional attributes and area constraints.                            */
15673 /*  - Enforce the constraints on minimum angle (-q) and maximum area (-a).   */
15674 /*      Also enforce the conforming Delaunay property (-q and -a).           */
15675 /*  - Compute the number of edges in the resulting mesh.                     */
15676 /*  - Promote the mesh's linear triangles to higher order elements (-o).     */
15677 /*  - Write the output files and print the statistics.                       */
15678 /*  - Check the consistency and Delaunay property of the mesh (-C).          */
15679 /*                                                                           */
15680 /*****************************************************************************/
15681 
15682 #ifdef TRILIBRARY
15683 
15684 #ifdef ANSI_DECLARATORS
15685 void triangulate(char *triswitches, struct triangulateio *in,
15686                  struct triangulateio *out, struct triangulateio *vorout)
15687 #else /* not ANSI_DECLARATORS */
15688 void triangulate(triswitches, in, out, vorout)
15689 char *triswitches;
15690 struct triangulateio *in;
15691 struct triangulateio *out;
15692 struct triangulateio *vorout;
15693 #endif /* not ANSI_DECLARATORS */
15694 
15695 #else /* not TRILIBRARY */
15696 
15697 #ifdef ANSI_DECLARATORS
15698 int main(int argc, char **argv)
15699 #else /* not ANSI_DECLARATORS */
15700 int main(argc, argv)
15701 int argc;
15702 char **argv;
15703 #endif /* not ANSI_DECLARATORS */
15704 
15705 #endif /* not TRILIBRARY */
15706 
15707 {
15708   struct mesh m;
15709   struct behavior b;
15710   REAL *holearray;                                        /* Array of holes. */
15711   REAL *regionarray;   /* Array of regional attributes and area constraints. */
15712 #ifndef TRILIBRARY
15713   FILE *polyfile;
15714 #endif /* not TRILIBRARY */
15715 #ifndef NO_TIMER
15716   /* Variables for timing the performance of Triangle.  The types are */
15717   /*   defined in sys/time.h.                                         */
15718   struct timeval tv0, tv1, tv2, tv3, tv4, tv5, tv6;
15719   struct timezone tz;
15720 #endif /* not NO_TIMER */
15721 
15722 #ifndef NO_TIMER
15723   gettimeofday(&tv0, &tz);
15724 #endif /* not NO_TIMER */
15725 
15726   triangleinit(&m);
15727 #ifdef TRILIBRARY
15728   parsecommandline(1, &triswitches, &b);
15729 #else /* not TRILIBRARY */
15730   parsecommandline(argc, argv, &b);
15731 #endif /* not TRILIBRARY */
15732   m.steinerleft = b.steiner;
15733 
15734 #ifdef TRILIBRARY
15735   transfernodes(&m, &b, in->pointlist, in->pointattributelist,
15736                 in->pointmarkerlist, in->numberofpoints,
15737                 in->numberofpointattributes);
15738 #else /* not TRILIBRARY */
15739   readnodes(&m, &b, b.innodefilename, b.inpolyfilename, &polyfile);
15740 #endif /* not TRILIBRARY */
15741 
15742 #ifndef NO_TIMER
15743   if (!b.quiet) {
15744     gettimeofday(&tv1, &tz);
15745   }
15746 #endif /* not NO_TIMER */
15747 
15748 #ifdef CDT_ONLY
15749   m.hullsize = delaunay(&m, &b);                /* Triangulate the vertices. */
15750 #else /* not CDT_ONLY */
15751   if (b.refine) {
15752     /* Read and reconstruct a mesh. */
15753 #ifdef TRILIBRARY
15754     m.hullsize = reconstruct(&m, &b, in->trianglelist,
15755                              in->triangleattributelist, in->trianglearealist,
15756                              in->numberoftriangles, in->numberofcorners,
15757                              in->numberoftriangleattributes,
15758                              in->segmentlist, in->segmentmarkerlist,
15759                              in->numberofsegments);
15760 #else /* not TRILIBRARY */
15761     m.hullsize = reconstruct(&m, &b, b.inelefilename, b.areafilename,
15762                              b.inpolyfilename, polyfile);
15763 #endif /* not TRILIBRARY */
15764   } else {
15765     m.hullsize = delaunay(&m, &b);              /* Triangulate the vertices. */
15766   }
15767 #endif /* not CDT_ONLY */
15768 
15769 #ifndef NO_TIMER
15770   if (!b.quiet) {
15771     gettimeofday(&tv2, &tz);
15772     if (b.refine) {
15773       printf("Mesh reconstruction");
15774     } else {
15775       printf("Delaunay");
15776     }
15777     printf(" milliseconds:  %ld\n", 1000l * (tv2.tv_sec - tv1.tv_sec) +
15778            (tv2.tv_usec - tv1.tv_usec) / 1000l);
15779   }
15780 #endif /* not NO_TIMER */
15781 
15782   /* Ensure that no vertex can be mistaken for a triangular bounding */
15783   /*   box vertex in insertvertex().                                 */
15784   m.infvertex1 = (vertex) NULL;
15785   m.infvertex2 = (vertex) NULL;
15786   m.infvertex3 = (vertex) NULL;
15787 
15788   if (b.usesegments) {
15789     m.checksegments = 1;                /* Segments will be introduced next. */
15790     if (!b.refine) {
15791       /* Insert PSLG segments and/or convex hull segments. */
15792 #ifdef TRILIBRARY
15793       formskeleton(&m, &b, in->segmentlist,
15794                    in->segmentmarkerlist, in->numberofsegments);
15795 #else /* not TRILIBRARY */
15796       formskeleton(&m, &b, polyfile, b.inpolyfilename);
15797 #endif /* not TRILIBRARY */
15798     }
15799   }
15800 
15801 #ifndef NO_TIMER
15802   if (!b.quiet) {
15803     gettimeofday(&tv3, &tz);
15804     if (b.usesegments && !b.refine) {
15805       printf("Segment milliseconds:  %ld\n",
15806              1000l * (tv3.tv_sec - tv2.tv_sec) +
15807              (tv3.tv_usec - tv2.tv_usec) / 1000l);
15808     }
15809   }
15810 #endif /* not NO_TIMER */
15811 
15812   if (b.poly && (m.triangles.items > 0)) {
15813 #ifdef TRILIBRARY
15814     holearray = in->holelist;
15815     m.holes = in->numberofholes;
15816     regionarray = in->regionlist;
15817     m.regions = in->numberofregions;
15818 #else /* not TRILIBRARY */
15819     readholes(&m, &b, polyfile, b.inpolyfilename, &holearray, &m.holes,
15820               &regionarray, &m.regions);
15821 #endif /* not TRILIBRARY */
15822     if (!b.refine) {
15823       /* Carve out holes and concavities. */
15824       carveholes(&m, &b, holearray, m.holes, regionarray, m.regions);
15825     }
15826   } else {
15827     /* Without a PSLG, there can be no holes or regional attributes   */
15828     /*   or area constraints.  The following are set to zero to avoid */
15829     /*   an accidental free() later.                                  */
15830     m.holes = 0;
15831     m.regions = 0;
15832   }
15833 
15834 #ifndef NO_TIMER
15835   if (!b.quiet) {
15836     gettimeofday(&tv4, &tz);
15837     if (b.poly && !b.refine) {
15838       printf("Hole milliseconds:  %ld\n", 1000l * (tv4.tv_sec - tv3.tv_sec) +
15839              (tv4.tv_usec - tv3.tv_usec) / 1000l);
15840     }
15841   }
15842 #endif /* not NO_TIMER */
15843 
15844 #ifndef CDT_ONLY
15845   if (b.quality && (m.triangles.items > 0)) {
15846     enforcequality(&m, &b);           /* Enforce angle and area constraints. */
15847   }
15848 #endif /* not CDT_ONLY */
15849 
15850 #ifndef NO_TIMER
15851   if (!b.quiet) {
15852     gettimeofday(&tv5, &tz);
15853 #ifndef CDT_ONLY
15854     if (b.quality) {
15855       printf("Quality milliseconds:  %ld\n",
15856              1000l * (tv5.tv_sec - tv4.tv_sec) +
15857              (tv5.tv_usec - tv4.tv_usec) / 1000l);
15858     }
15859 #endif /* not CDT_ONLY */
15860   }
15861 #endif /* not NO_TIMER */
15862 
15863   /* Calculate the number of edges. */
15864   m.edges = (3l * m.triangles.items + m.hullsize) / 2l;
15865 
15866   if (b.order > 1) {
15867     highorder(&m, &b);       /* Promote elements to higher polynomial order. */
15868   }
15869   if (!b.quiet) {
15870     printf("\n");
15871   }
15872 
15873 #ifdef TRILIBRARY
15874   if (b.jettison) {
15875     out->numberofpoints = m.vertices.items - m.undeads;
15876   } else {
15877     out->numberofpoints = m.vertices.items;
15878   }
15879   out->numberofpointattributes = m.nextras;
15880   out->numberoftriangles = m.triangles.items;
15881   out->numberofcorners = (b.order + 1) * (b.order + 2) / 2;
15882   out->numberoftriangleattributes = m.eextras;
15883   out->numberofedges = m.edges;
15884   if (b.usesegments) {
15885     out->numberofsegments = m.subsegs.items;
15886   } else {
15887     out->numberofsegments = m.hullsize;
15888   }
15889   if (vorout != (struct triangulateio *) NULL) {
15890     vorout->numberofpoints = m.triangles.items;
15891     vorout->numberofpointattributes = m.nextras;
15892     vorout->numberofedges = m.edges;
15893   }
15894 #endif /* TRILIBRARY */
15895   /* If not using iteration numbers, don't write a .node file if one was */
15896   /*   read, because the original one would be overwritten!              */
15897   if (b.nonodewritten || (b.noiterationnum && m.readnodefile)) {
15898     if (!b.quiet) {
15899 #ifdef TRILIBRARY
15900       printf("NOT writing vertices.\n");
15901 #else /* not TRILIBRARY */
15902       printf("NOT writing a .node file.\n");
15903 #endif /* not TRILIBRARY */
15904     }
15905     numbernodes(&m, &b);         /* We must remember to number the vertices. */
15906   } else {
15907     /* writenodes() numbers the vertices too. */
15908 #ifdef TRILIBRARY
15909     writenodes(&m, &b, &out->pointlist, &out->pointattributelist,
15910                &out->pointmarkerlist);
15911 #else /* not TRILIBRARY */
15912     writenodes(&m, &b, b.outnodefilename, argc, argv);
15913 #endif /* TRILIBRARY */
15914   }
15915   if (b.noelewritten) {
15916     if (!b.quiet) {
15917 #ifdef TRILIBRARY
15918       printf("NOT writing triangles.\n");
15919 #else /* not TRILIBRARY */
15920       printf("NOT writing an .ele file.\n");
15921 #endif /* not TRILIBRARY */
15922     }
15923   } else {
15924 #ifdef TRILIBRARY
15925     writeelements(&m, &b, &out->trianglelist, &out->triangleattributelist);
15926 #else /* not TRILIBRARY */
15927     writeelements(&m, &b, b.outelefilename, argc, argv);
15928 #endif /* not TRILIBRARY */
15929   }
15930   /* The -c switch (convex switch) causes a PSLG to be written */
15931   /*   even if none was read.                                  */
15932   if (b.poly || b.convex) {
15933     /* If not using iteration numbers, don't overwrite the .poly file. */
15934     if (b.nopolywritten || b.noiterationnum) {
15935       if (!b.quiet) {
15936 #ifdef TRILIBRARY
15937         printf("NOT writing segments.\n");
15938 #else /* not TRILIBRARY */
15939         printf("NOT writing a .poly file.\n");
15940 #endif /* not TRILIBRARY */
15941       }
15942     } else {
15943 #ifdef TRILIBRARY
15944       writepoly(&m, &b, &out->segmentlist, &out->segmentmarkerlist);
15945       out->numberofholes = m.holes;
15946       out->numberofregions = m.regions;
15947       if (b.poly) {
15948         out->holelist = in->holelist;
15949         out->regionlist = in->regionlist;
15950       } else {
15951         out->holelist = (REAL *) NULL;
15952         out->regionlist = (REAL *) NULL;
15953       }
15954 #else /* not TRILIBRARY */
15955       writepoly(&m, &b, b.outpolyfilename, holearray, m.holes, regionarray,
15956                 m.regions, argc, argv);
15957 #endif /* not TRILIBRARY */
15958     }
15959   }
15960 #ifndef TRILIBRARY
15961 #ifndef CDT_ONLY
15962   if (m.regions > 0) {
15963     trifree((VOID *) regionarray);
15964   }
15965 #endif /* not CDT_ONLY */
15966   if (m.holes > 0) {
15967     trifree((VOID *) holearray);
15968   }
15969   if (b.geomview) {
15970     writeoff(&m, &b, b.offfilename, argc, argv);
15971   }
15972 #endif /* not TRILIBRARY */
15973   if (b.edgesout) {
15974 #ifdef TRILIBRARY
15975     writeedges(&m, &b, &out->edgelist, &out->edgemarkerlist);
15976 #else /* not TRILIBRARY */
15977     writeedges(&m, &b, b.edgefilename, argc, argv);
15978 #endif /* not TRILIBRARY */
15979   }
15980   if (b.voronoi) {
15981 #ifdef TRILIBRARY
15982     writevoronoi(&m, &b, &vorout->pointlist, &vorout->pointattributelist,
15983                  &vorout->pointmarkerlist, &vorout->edgelist,
15984                  &vorout->edgemarkerlist, &vorout->normlist);
15985 #else /* not TRILIBRARY */
15986     writevoronoi(&m, &b, b.vnodefilename, b.vedgefilename, argc, argv);
15987 #endif /* not TRILIBRARY */
15988   }
15989   if (b.neighbors) {
15990 #ifdef TRILIBRARY
15991     writeneighbors(&m, &b, &out->neighborlist);
15992 #else /* not TRILIBRARY */
15993     writeneighbors(&m, &b, b.neighborfilename, argc, argv);
15994 #endif /* not TRILIBRARY */
15995   }
15996 
15997   if (!b.quiet) {
15998 #ifndef NO_TIMER
15999     gettimeofday(&tv6, &tz);
16000     printf("\nOutput milliseconds:  %ld\n",
16001            1000l * (tv6.tv_sec - tv5.tv_sec) +
16002            (tv6.tv_usec - tv5.tv_usec) / 1000l);
16003     printf("Total running milliseconds:  %ld\n",
16004            1000l * (tv6.tv_sec - tv0.tv_sec) +
16005            (tv6.tv_usec - tv0.tv_usec) / 1000l);
16006 #endif /* not NO_TIMER */
16007 
16008     statistics(&m, &b);
16009   }
16010 
16011 #ifndef REDUCED
16012   if (b.docheck) {
16013     checkmesh(&m, &b);
16014     checkdelaunay(&m, &b);
16015   }
16016 #endif /* not REDUCED */
16017 
16018   triangledeinit(&m, &b);
16019 #ifndef TRILIBRARY
16020   return 0;
16021 #endif /* not TRILIBRARY */
16022 }
16023