]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/gtkgensurf/triangle.c
netradiant: strip 16-bit png to 8-bit, fix #153
[xonotic/netradiant.git] / contrib / gtkgensurf / triangle.c
1 #define ANSI_DECLARATORS
2 /*****************************************************************************/
3 /*                                                                           */
4 /*      888888888        ,o,                          / 888                  */
5 /*         888    88o88o  "    o8888o  88o8888o o88888o 888  o88888o         */
6 /*         888    888    888       88b 888  888 888 888 888 d888  88b        */
7 /*         888    888    888  o88^o888 888  888 "88888" 888 8888oo888        */
8 /*         888    888    888 C888  888 888  888  /      888 q888             */
9 /*         888    888    888  "88o^888 888  888 Cb      888  "88oooo"        */
10 /*                                              "8oo8D                       */
11 /*                                                                           */
12 /*  A Two-Dimensional Quality Mesh Generator and Delaunay Triangulator.      */
13 /*  (triangle.c)                                                             */
14 /*                                                                           */
15 /*  Version 1.3                                                              */
16 /*  July 19, 1996                                                            */
17 /*                                                                           */
18 /*  Copyright 1996                                                           */
19 /*  Jonathan Richard Shewchuk                                                */
20 /*  School of Computer Science                                               */
21 /*  Carnegie Mellon University                                               */
22 /*  5000 Forbes Avenue                                                       */
23 /*  Pittsburgh, Pennsylvania  15213-3891                                     */
24 /*  jrs@cs.cmu.edu                                                           */
25 /*                                                                           */
26 /*  This program may be freely redistributed under the condition that the    */
27 /*    copyright notices (including this entire header and the copyright      */
28 /*    notice printed when the `-h' switch is selected) are not removed, and  */
29 /*    no compensation is received.  Private, research, and institutional     */
30 /*    use is free.  You may distribute modified versions of this code UNDER  */
31 /*    THE CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE TO IT IN THE   */
32 /*    SAME FILE REMAIN UNDER COPYRIGHT OF THE ORIGINAL AUTHOR, BOTH SOURCE   */
33 /*    AND OBJECT CODE ARE MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR    */
34 /*    NOTICE IS GIVEN OF THE MODIFICATIONS.  Distribution of this code as    */
35 /*    part of a commercial system is permissible ONLY BY DIRECT ARRANGEMENT  */
36 /*    WITH THE AUTHOR.  (If you are not directly supplying this code to a    */
37 /*    customer, and you are instead telling them how they can obtain it for  */
38 /*    free, then you are not required to make any arrangement with me.)      */
39 /*                                                                           */
40 /*  Hypertext instructions for Triangle are available on the Web at          */
41 /*                                                                           */
42 /*      http://www.cs.cmu.edu/~quake/triangle.html                           */
43 /*                                                                           */
44 /*  Some of the references listed below are marked [*].  These are available */
45 /*    for downloading from the Web page                                      */
46 /*                                                                           */
47 /*      http://www.cs.cmu.edu/~quake/triangle.research.html                  */
48 /*                                                                           */
49 /*  A paper discussing some aspects of Triangle is available.  See Jonathan  */
50 /*    Richard Shewchuk, "Triangle:  Engineering a 2D Quality Mesh Generator  */
51 /*    and Delaunay Triangulator," First Workshop on Applied Computational    */
52 /*    Geometry, ACM, May 1996.  [*]                                          */
53 /*                                                                           */
54 /*  Triangle was created as part of the Archimedes project in the School of  */
55 /*    Computer Science at Carnegie Mellon University.  Archimedes is a       */
56 /*    system for compiling parallel finite element solvers.  For further     */
57 /*    information, see Anja Feldmann, Omar Ghattas, John R. Gilbert, Gary L. */
58 /*    Miller, David R. O'Hallaron, Eric J. Schwabe, Jonathan R. Shewchuk,    */
59 /*    and Shang-Hua Teng, "Automated Parallel Solution of Unstructured PDE   */
60 /*    Problems."  To appear in Communications of the ACM, we hope.           */
61 /*                                                                           */
62 /*  The quality mesh generation algorithm is due to Jim Ruppert, "A          */
63 /*    Delaunay Refinement Algorithm for Quality 2-Dimensional Mesh           */
64 /*    Generation," Journal of Algorithms 18(3):548-585, May 1995.  [*]       */
65 /*                                                                           */
66 /*  My implementation of the divide-and-conquer and incremental Delaunay     */
67 /*    triangulation algorithms follows closely the presentation of Guibas    */
68 /*    and Stolfi, even though I use a triangle-based data structure instead  */
69 /*    of their quad-edge data structure.  (In fact, I originally implemented */
70 /*    Triangle using the quad-edge data structure, but switching to a        */
71 /*    triangle-based data structure sped Triangle by a factor of two.)  The  */
72 /*    mesh manipulation primitives and the two aforementioned Delaunay       */
73 /*    triangulation algorithms are described by Leonidas J. Guibas and Jorge */
74 /*    Stolfi, "Primitives for the Manipulation of General Subdivisions and   */
75 /*    the Computation of Voronoi Diagrams," ACM Transactions on Graphics     */
76 /*    4(2):74-123, April 1985.                                               */
77 /*                                                                           */
78 /*  Their O(n log n) divide-and-conquer algorithm is adapted from Der-Tsai   */
79 /*    Lee and Bruce J. Schachter, "Two Algorithms for Constructing the       */
80 /*    Delaunay Triangulation," International Journal of Computer and         */
81 /*    Information Science 9(3):219-242, 1980.  The idea to improve the       */
82 /*    divide-and-conquer algorithm by alternating between vertical and       */
83 /*    horizontal cuts was introduced by Rex A. Dwyer, "A Faster Divide-and-  */
84 /*    Conquer Algorithm for Constructing Delaunay Triangulations,"           */
85 /*    Algorithmica 2(2):137-151, 1987.                                       */
86 /*                                                                           */
87 /*  The incremental insertion algorithm was first proposed by C. L. Lawson,  */
88 /*    "Software for C1 Surface Interpolation," in Mathematical Software III, */
89 /*    John R. Rice, editor, Academic Press, New York, pp. 161-194, 1977.     */
90 /*    For point location, I use the algorithm of Ernst P. Mucke, Isaac       */
91 /*    Saias, and Binhai Zhu, "Fast Randomized Point Location Without         */
92 /*    Preprocessing in Two- and Three-dimensional Delaunay Triangulations,"  */
93 /*    Proceedings of the Twelfth Annual Symposium on Computational Geometry, */
94 /*    ACM, May 1996.  [*]  If I were to randomize the order of point         */
95 /*    insertion (I currently don't bother), their result combined with the   */
96 /*    result of Leonidas J. Guibas, Donald E. Knuth, and Micha Sharir,       */
97 /*    "Randomized Incremental Construction of Delaunay and Voronoi           */
98 /*    Diagrams," Algorithmica 7(4):381-413, 1992, would yield an expected    */
99 /*    O(n^{4/3}) bound on running time.                                      */
100 /*                                                                           */
101 /*  The O(n log n) sweepline Delaunay triangulation algorithm is taken from  */
102 /*    Steven Fortune, "A Sweepline Algorithm for Voronoi Diagrams",          */
103 /*    Algorithmica 2(2):153-174, 1987.  A random sample of edges on the      */
104 /*    boundary of the triangulation are maintained in a splay tree for the   */
105 /*    purpose of point location.  Splay trees are described by Daniel        */
106 /*    Dominic Sleator and Robert Endre Tarjan, "Self-Adjusting Binary Search */
107 /*    Trees," Journal of the ACM 32(3):652-686, July 1985.                   */
108 /*                                                                           */
109 /*  The algorithms for exact computation of the signs of determinants are    */
110 /*    described in Jonathan Richard Shewchuk, "Adaptive Precision Floating-  */
111 /*    Point Arithmetic and Fast Robust Geometric Predicates," Technical      */
112 /*    Report CMU-CS-96-140, School of Computer Science, Carnegie Mellon      */
113 /*    University, Pittsburgh, Pennsylvania, May 1996.  [*]  (Submitted to    */
114 /*    Discrete & Computational Geometry.)  An abbreviated version appears as */
115 /*    Jonathan Richard Shewchuk, "Robust Adaptive Floating-Point Geometric   */
116 /*    Predicates," Proceedings of the Twelfth Annual Symposium on Computa-   */
117 /*    tional Geometry, ACM, May 1996.  [*]  Many of the ideas for my exact   */
118 /*    arithmetic routines originate with Douglas M. Priest, "Algorithms for  */
119 /*    Arbitrary Precision Floating Point Arithmetic," Tenth Symposium on     */
120 /*    Computer Arithmetic, 132-143, IEEE Computer Society Press, 1991.  [*]  */
121 /*    Many of the ideas for the correct evaluation of the signs of           */
122 /*    determinants are taken from Steven Fortune and Christopher J. Van Wyk, */
123 /*    "Efficient Exact Arithmetic for Computational Geometry," Proceedings   */
124 /*    of the Ninth Annual Symposium on Computational Geometry, ACM,          */
125 /*    pp. 163-172, May 1993, and from Steven Fortune, "Numerical Stability   */
126 /*    of Algorithms for 2D Delaunay Triangulations," International Journal   */
127 /*    of Computational Geometry & Applications 5(1-2):193-213, March-June    */
128 /*    1995.                                                                  */
129 /*                                                                           */
130 /*  For definitions of and results involving Delaunay triangulations,        */
131 /*    constrained and conforming versions thereof, and other aspects of      */
132 /*    triangular mesh generation, see the excellent survey by Marshall Bern  */
133 /*    and David Eppstein, "Mesh Generation and Optimal Triangulation," in    */
134 /*    Computing and Euclidean Geometry, Ding-Zhu Du and Frank Hwang,         */
135 /*    editors, World Scientific, Singapore, pp. 23-90, 1992.                 */
136 /*                                                                           */
137 /*  The time for incrementally adding PSLG (planar straight line graph)      */
138 /*    segments to create a constrained Delaunay triangulation is probably    */
139 /*    O(n^2) per segment in the worst case and O(n) per edge in the common   */
140 /*    case, where n is the number of triangles that intersect the segment    */
141 /*    before it is inserted.  This doesn't count point location, which can   */
142 /*    be much more expensive.  (This note does not apply to conforming       */
143 /*    Delaunay triangulations, for which a different method is used to       */
144 /*    insert segments.)                                                      */
145 /*                                                                           */
146 /*  The time for adding segments to a conforming Delaunay triangulation is   */
147 /*    not clear, but does not depend upon n alone.  In some cases, very      */
148 /*    small features (like a point lying next to a segment) can cause a      */
149 /*    single segment to be split an arbitrary number of times.  Of course,   */
150 /*    floating-point precision is a practical barrier to how much this can   */
151 /*    happen.                                                                */
152 /*                                                                           */
153 /*  The time for deleting a point from a Delaunay triangulation is O(n^2) in */
154 /*    the worst case and O(n) in the common case, where n is the degree of   */
155 /*    the point being deleted.  I could improve this to expected O(n) time   */
156 /*    by "inserting" the neighboring vertices in random order, but n is      */
157 /*    usually quite small, so it's not worth the bother.  (The O(n) time     */
158 /*    for random insertion follows from L. Paul Chew, "Building Voronoi      */
159 /*    Diagrams for Convex Polygons in Linear Expected Time," Technical       */
160 /*    Report PCS-TR90-147, Department of Mathematics and Computer Science,   */
161 /*    Dartmouth College, 1990.                                               */
162 /*                                                                           */
163 /*  Ruppert's Delaunay refinement algorithm typically generates triangles    */
164 /*    at a linear rate (constant time per triangle) after the initial        */
165 /*    triangulation is formed.  There may be pathological cases where more   */
166 /*    time is required, but these never arise in practice.                   */
167 /*                                                                           */
168 /*  The segment intersection formulae are straightforward.  If you want to   */
169 /*    see them derived, see Franklin Antonio.  "Faster Line Segment          */
170 /*    Intersection."  In Graphics Gems III (David Kirk, editor), pp. 199-    */
171 /*    202.  Academic Press, Boston, 1992.                                    */
172 /*                                                                           */
173 /*  If you make any improvements to this code, please please please let me   */
174 /*    know, so that I may obtain the improvements.  Even if you don't change */
175 /*    the code, I'd still love to hear what it's being used for.             */
176 /*                                                                           */
177 /*  Disclaimer:  Neither I nor Carnegie Mellon warrant this code in any way  */
178 /*    whatsoever.  This code is provided "as-is".  Use at your own risk.     */
179 /*                                                                           */
180 /*****************************************************************************/
181
182 /* For single precision (which will save some memory and reduce paging),     */
183 /*   define the symbol SINGLE by using the -DSINGLE compiler switch or by    */
184 /*   writing "#define SINGLE" below.                                         */
185 /*                                                                           */
186 /* For double precision (which will allow you to refine meshes to a smaller  */
187 /*   edge length), leave SINGLE undefined.                                   */
188 /*                                                                           */
189 /* Double precision uses more memory, but improves the resolution of the     */
190 /*   meshes you can generate with Triangle.  It also reduces the likelihood  */
191 /*   of a floating exception due to overflow.  Finally, it is much faster    */
192 /*   than single precision on 64-bit architectures like the DEC Alpha.  I    */
193 /*   recommend double precision unless you want to generate a mesh for which */
194 /*   you do not have enough memory.                                          */
195
196 #define SINGLE
197
198 #ifdef SINGLE
199 #define REAL float
200 #else /* not SINGLE */
201 #define REAL double
202 #endif /* not SINGLE */
203
204 /* If yours is not a Unix system, define the NO_TIMER compiler switch to     */
205 /*   remove the Unix-specific timing code.                                   */
206
207 #define NO_TIMER
208
209 /* To insert lots of self-checks for internal errors, define the SELF_CHECK  */
210 /*   symbol.  This will slow down the program significantly.  It is best to  */
211 /*   define the symbol using the -DSELF_CHECK compiler switch, but you could */
212 /*   write "#define SELF_CHECK" below.  If you are modifying this code, I    */
213 /*   recommend you turn self-checks on.                                      */
214
215 /* #define SELF_CHECK */
216
217 /* To compile Triangle as a callable object library (triangle.o), define the */
218 /*   TRILIBRARY symbol.  Read the file triangle.h for details on how to call */
219 /*   the procedure triangulate() that results.                               */
220
221 #define TRILIBRARY
222
223 /* It is possible to generate a smaller version of Triangle using one or     */
224 /*   both of the following symbols.  Define the REDUCED symbol to eliminate  */
225 /*   all features that are primarily of research interest; specifically, the */
226 /*   -i, -F, -s, and -C switches.  Define the CDT_ONLY symbol to eliminate   */
227 /*   all meshing algorithms above and beyond constrained Delaunay            */
228 /*   triangulation; specifically, the -r, -q, -a, -S, and -s switches.       */
229 /*   These reductions are most likely to be useful when generating an object */
230 /*   library (triangle.o) by defining the TRILIBRARY symbol.                 */
231
232 #define REDUCED
233 #define CDT_ONLY
234
235 /* On some machines, the exact arithmetic routines might be defeated by the  */
236 /*   use of internal extended precision floating-point registers.  Sometimes */
237 /*   this problem can be fixed by defining certain values to be volatile,    */
238 /*   thus forcing them to be stored to memory and rounded off.  This isn't   */
239 /*   a great solution, though, as it slows Triangle down.                    */
240 /*                                                                           */
241 /* To try this out, write "#define INEXACT volatile" below.  Normally,       */
242 /*   however, INEXACT should be defined to be nothing.  ("#define INEXACT".) */
243
244 #define INEXACT /* Nothing */
245 /* #define INEXACT volatile */
246
247 /* Maximum number of characters in a file name (including the null).         */
248
249 #define FILENAMESIZE 512
250
251 /* Maximum number of characters in a line read from a file (including the    */
252 /*   null).                                                                  */
253
254 #define INPUTLINESIZE 512
255
256 /* For efficiency, a variety of data structures are allocated in bulk.  The  */
257 /*   following constants determine how many of each structure is allocated   */
258 /*   at once.                                                                */
259
260 #define TRIPERBLOCK 4092           /* Number of triangles allocated at once. */
261 #define SHELLEPERBLOCK 508       /* Number of shell edges allocated at once. */
262 #define POINTPERBLOCK 4092            /* Number of points allocated at once. */
263 #define VIRUSPERBLOCK 1020   /* Number of virus triangles allocated at once. */
264 /* Number of encroached segments allocated at once. */
265 #define BADSEGMENTPERBLOCK 252
266 /* Number of skinny triangles allocated at once. */
267 #define BADTRIPERBLOCK 4092
268 /* Number of splay tree nodes allocated at once. */
269 #define SPLAYNODEPERBLOCK 508
270
271 /* The point marker DEADPOINT is an arbitrary number chosen large enough to  */
272 /*   (hopefully) not conflict with user boundary markers.  Make sure that it */
273 /*   is small enough to fit into your machine's integer size.                */
274
275 #define DEADPOINT -1073741824
276
277 /* The next line is used to outsmart some very stupid compilers.  If your    */
278 /*   compiler is smarter, feel free to replace the "int" with "void".        */
279 /*   Not that it matters.                                                    */
280
281 #define VOID int
282
283 /* Two constants for algorithms based on random sampling.  Both constants    */
284 /*   have been chosen empirically to optimize their respective algorithms.   */
285
286 /* Used for the point location scheme of Mucke, Saias, and Zhu, to decide    */
287 /*   how large a random sample of triangles to inspect.                      */
288 #define SAMPLEFACTOR 11
289 /* Used in Fortune's sweepline Delaunay algorithm to determine what fraction */
290 /*   of boundary edges should be maintained in the splay tree for point      */
291 /*   location on the front.                                                  */
292 #define SAMPLERATE 10
293
294 /* A number that speaks for itself, every kissable digit.                    */
295
296 #define PI 3.141592653589793238462643383279502884197169399375105820974944592308
297
298 /* Another fave.                                                             */
299
300 #define SQUAREROOTTWO 1.4142135623730950488016887242096980785696718753769480732
301
302 /* And here's one for those of you who are intimidated by math.              */
303
304 #define ONETHIRD 0.333333333333333333333333333333333333333333333333333333333333
305
306 #include <stdio.h>
307 #include <string.h>
308 #include <math.h>
309 #ifndef NO_TIMER
310 #include <sys/time.h>
311 #endif /* NO_TIMER */
312 #ifdef TRILIBRARY
313 #include "triangle.h"
314 #endif /* TRILIBRARY */
315
316 /* The following obscenity seems to be necessary to ensure that this program */
317 /* will port to Dec Alphas running OSF/1, because their stdio.h file commits */
318 /* the unpardonable sin of including stdlib.h.  Hence, malloc(), free(), and */
319 /* exit() may or may not already be defined at this point.  I declare these  */
320 /* functions explicitly because some non-ANSI C compilers lack stdlib.h.     */
321
322 #ifndef _STDLIB_H_
323 extern void *malloc();
324 extern void free();
325 extern void exit();
326 extern double strtod();
327 extern long strtol();
328 #endif /* _STDLIB_H_ */
329
330 /* A few forward declarations.                                               */
331
332 void poolrestart();
333 #ifndef TRILIBRARY
334 char *readline();
335 char *findfield();
336 #endif /* not TRILIBRARY */
337
338 /* Labels that signify whether a record consists primarily of pointers or of */
339 /*   floating-point words.  Used to make decisions about data alignment.     */
340
341 enum wordtype {POINTER, FLOATINGPOINT};
342
343 /* Labels that signify the result of point location.  The result of a        */
344 /*   search indicates that the point falls in the interior of a triangle, on */
345 /*   an edge, on a vertex, or outside the mesh.                              */
346
347 enum locateresult {INTRIANGLE, ONEDGE, ONVERTEX, OUTSIDE};
348
349 /* Labels that signify the result of site insertion.  The result indicates   */
350 /*   that the point was inserted with complete success, was inserted but     */
351 /*   encroaches on a segment, was not inserted because it lies on a segment, */
352 /*   or was not inserted because another point occupies the same location.   */
353
354 enum insertsiteresult {SUCCESSFULPOINT, ENCROACHINGPOINT, VIOLATINGPOINT,
355                                            DUPLICATEPOINT};
356
357 /* Labels that signify the result of direction finding.  The result          */
358 /*   indicates that a segment connecting the two query points falls within   */
359 /*   the direction triangle, along the left edge of the direction triangle,  */
360 /*   or along the right edge of the direction triangle.                      */
361
362 enum finddirectionresult {WITHIN, LEFTCOLLINEAR, RIGHTCOLLINEAR};
363
364 /* Labels that signify the result of the circumcenter computation routine.   */
365 /*   The return value indicates which edge of the triangle is shortest.      */
366
367 enum circumcenterresult {OPPOSITEORG, OPPOSITEDEST, OPPOSITEAPEX};
368
369 /*****************************************************************************/
370 /*                                                                           */
371 /*  The basic mesh data structures                                           */
372 /*                                                                           */
373 /*  There are three:  points, triangles, and shell edges (abbreviated        */
374 /*  `shelle').  These three data structures, linked by pointers, comprise    */
375 /*  the mesh.  A point simply represents a point in space and its properties.*/
376 /*  A triangle is a triangle.  A shell edge is a special data structure used */
377 /*  to represent impenetrable segments in the mesh (including the outer      */
378 /*  boundary, boundaries of holes, and internal boundaries separating two    */
379 /*  triangulated regions).  Shell edges represent boundaries defined by the  */
380 /*  user that triangles may not lie across.                                  */
381 /*                                                                           */
382 /*  A triangle consists of a list of three vertices, a list of three         */
383 /*  adjoining triangles, a list of three adjoining shell edges (when shell   */
384 /*  edges are used), an arbitrary number of optional user-defined floating-  */
385 /*  point attributes, and an optional area constraint.  The latter is an     */
386 /*  upper bound on the permissible area of each triangle in a region, used   */
387 /*  for mesh refinement.                                                     */
388 /*                                                                           */
389 /*  For a triangle on a boundary of the mesh, some or all of the neighboring */
390 /*  triangles may not be present.  For a triangle in the interior of the     */
391 /*  mesh, often no neighboring shell edges are present.  Such absent         */
392 /*  triangles and shell edges are never represented by NULL pointers; they   */
393 /*  are represented by two special records:  `dummytri', the triangle that   */
394 /*  fills "outer space", and `dummysh', the omnipresent shell edge.          */
395 /*  `dummytri' and `dummysh' are used for several reasons; for instance,     */
396 /*  they can be dereferenced and their contents examined without causing the */
397 /*  memory protection exception that would occur if NULL were dereferenced.  */
398 /*                                                                           */
399 /*  However, it is important to understand that a triangle includes other    */
400 /*  information as well.  The pointers to adjoining vertices, triangles, and */
401 /*  shell edges are ordered in a way that indicates their geometric relation */
402 /*  to each other.  Furthermore, each of these pointers contains orientation */
403 /*  information.  Each pointer to an adjoining triangle indicates which face */
404 /*  of that triangle is contacted.  Similarly, each pointer to an adjoining  */
405 /*  shell edge indicates which side of that shell edge is contacted, and how */
406 /*  the shell edge is oriented relative to the triangle.                     */
407 /*                                                                           */
408 /*  Shell edges are found abutting edges of triangles; either sandwiched     */
409 /*  between two triangles, or resting against one triangle on an exterior    */
410 /*  boundary or hole boundary.                                               */
411 /*                                                                           */
412 /*  A shell edge consists of a list of two vertices, a list of two           */
413 /*  adjoining shell edges, and a list of two adjoining triangles.  One of    */
414 /*  the two adjoining triangles may not be present (though there should      */
415 /*  always be one), and neighboring shell edges might not be present.        */
416 /*  Shell edges also store a user-defined integer "boundary marker".         */
417 /*  Typically, this integer is used to indicate what sort of boundary        */
418 /*  conditions are to be applied at that location in a finite element        */
419 /*  simulation.                                                              */
420 /*                                                                           */
421 /*  Like triangles, shell edges maintain information about the relative      */
422 /*  orientation of neighboring objects.                                      */
423 /*                                                                           */
424 /*  Points are relatively simple.  A point is a list of floating point       */
425 /*  numbers, starting with the x, and y coordinates, followed by an          */
426 /*  arbitrary number of optional user-defined floating-point attributes,     */
427 /*  followed by an integer boundary marker.  During the segment insertion    */
428 /*  phase, there is also a pointer from each point to a triangle that may    */
429 /*  contain it.  Each pointer is not always correct, but when one is, it     */
430 /*  speeds up segment insertion.  These pointers are assigned values once    */
431 /*  at the beginning of the segment insertion phase, and are not used or     */
432 /*  updated at any other time.  Edge swapping during segment insertion will  */
433 /*  render some of them incorrect.  Hence, don't rely upon them for          */
434 /*  anything.  For the most part, points do not have any information about   */
435 /*  what triangles or shell edges they are linked to.                        */
436 /*                                                                           */
437 /*****************************************************************************/
438
439 /*****************************************************************************/
440 /*                                                                           */
441 /*  Handles                                                                  */
442 /*                                                                           */
443 /*  The oriented triangle (`triedge') and oriented shell edge (`edge') data  */
444 /*  structures defined below do not themselves store any part of the mesh.   */
445 /*  The mesh itself is made of `triangle's, `shelle's, and `point's.         */
446 /*                                                                           */
447 /*  Oriented triangles and oriented shell edges will usually be referred to  */
448 /*  as "handles".  A handle is essentially a pointer into the mesh; it       */
449 /*  allows you to "hold" one particular part of the mesh.  Handles are used  */
450 /*  to specify the regions in which one is traversing and modifying the mesh.*/
451 /*  A single `triangle' may be held by many handles, or none at all.  (The   */
452 /*  latter case is not a memory leak, because the triangle is still          */
453 /*  connected to other triangles in the mesh.)                               */
454 /*                                                                           */
455 /*  A `triedge' is a handle that holds a triangle.  It holds a specific side */
456 /*  of the triangle.  An `edge' is a handle that holds a shell edge.  It     */
457 /*  holds either the left or right side of the edge.                         */
458 /*                                                                           */
459 /*  Navigation about the mesh is accomplished through a set of mesh          */
460 /*  manipulation primitives, further below.  Many of these primitives take   */
461 /*  a handle and produce a new handle that holds the mesh near the first     */
462 /*  handle.  Other primitives take two handles and glue the corresponding    */
463 /*  parts of the mesh together.  The exact position of the handles is        */
464 /*  important.  For instance, when two triangles are glued together by the   */
465 /*  bond() primitive, they are glued by the sides on which the handles lie.  */
466 /*                                                                           */
467 /*  Because points have no information about which triangles they are        */
468 /*  attached to, I commonly represent a point by use of a handle whose       */
469 /*  origin is the point.  A single handle can simultaneously represent a     */
470 /*  triangle, an edge, and a point.                                          */
471 /*                                                                           */
472 /*****************************************************************************/
473
474 /* The triangle data structure.  Each triangle contains three pointers to    */
475 /*   adjoining triangles, plus three pointers to vertex points, plus three   */
476 /*   pointers to shell edges (defined below; these pointers are usually      */
477 /*   `dummysh').  It may or may not also contain user-defined attributes     */
478 /*   and/or a floating-point "area constraint".  It may also contain extra   */
479 /*   pointers for nodes, when the user asks for high-order elements.         */
480 /*   Because the size and structure of a `triangle' is not decided until     */
481 /*   runtime, I haven't simply defined the type `triangle' to be a struct.   */
482
483 typedef REAL **triangle;            /* Really:  typedef triangle *triangle   */
484
485 /* An oriented triangle:  includes a pointer to a triangle and orientation.  */
486 /*   The orientation denotes an edge of the triangle.  Hence, there are      */
487 /*   three possible orientations.  By convention, each edge is always        */
488 /*   directed to point counterclockwise about the corresponding triangle.    */
489
490 struct triedge {
491         triangle *tri;
492         int orient;                                       /* Ranges from 0 to 2. */
493 };
494
495 /* The shell data structure.  Each shell edge contains two pointers to       */
496 /*   adjoining shell edges, plus two pointers to vertex points, plus two     */
497 /*   pointers to adjoining triangles, plus one shell marker.                 */
498
499 typedef REAL **shelle;                  /* Really:  typedef shelle *shelle   */
500
501 /* An oriented shell edge:  includes a pointer to a shell edge and an        */
502 /*   orientation.  The orientation denotes a side of the edge.  Hence, there */
503 /*   are two possible orientations.  By convention, the edge is always       */
504 /*   directed so that the "side" denoted is the right side of the edge.      */
505
506 struct edge {
507         shelle *sh;
508         int shorient;                                     /* Ranges from 0 to 1. */
509 };
510
511 /* The point data structure.  Each point is actually an array of REALs.      */
512 /*   The number of REALs is unknown until runtime.  An integer boundary      */
513 /*   marker, and sometimes a pointer to a triangle, is appended after the    */
514 /*   REALs.                                                                  */
515
516 typedef REAL *point;
517
518 /* A queue used to store encroached segments.  Each segment's vertices are   */
519 /*   stored so that one can check whether a segment is still the same.       */
520
521 struct badsegment {
522         struct edge encsegment;                        /* An encroached segment. */
523         point segorg, segdest;                              /* The two vertices. */
524         struct badsegment *nextsegment;   /* Pointer to next encroached segment. */
525 };
526
527 /* A queue used to store bad triangles.  The key is the square of the cosine */
528 /*   of the smallest angle of the triangle.  Each triangle's vertices are    */
529 /*   stored so that one can check whether a triangle is still the same.      */
530
531 struct badface {
532         struct triedge badfacetri;                            /* A bad triangle. */
533         REAL key;                           /* cos^2 of smallest (apical) angle. */
534         point faceorg, facedest, faceapex;                /* The three vertices. */
535         struct badface *nextface;               /* Pointer to next bad triangle. */
536 };
537
538 /* A node in a heap used to store events for the sweepline Delaunay          */
539 /*   algorithm.  Nodes do not point directly to their parents or children in */
540 /*   the heap.  Instead, each node knows its position in the heap, and can   */
541 /*   look up its parent and children in a separate array.  The `eventptr'    */
542 /*   points either to a `point' or to a triangle (in encoded format, so that */
543 /*   an orientation is included).  In the latter case, the origin of the     */
544 /*   oriented triangle is the apex of a "circle event" of the sweepline      */
545 /*   algorithm.  To distinguish site events from circle events, all circle   */
546 /*   events are given an invalid (smaller than `xmin') x-coordinate `xkey'.  */
547
548 struct event {
549         REAL xkey, ykey;                            /* Coordinates of the event. */
550         VOID *eventptr;     /* Can be a point or the location of a circle event. */
551         int heapposition;            /* Marks this event's position in the heap. */
552 };
553
554 /* A node in the splay tree.  Each node holds an oriented ghost triangle     */
555 /*   that represents a boundary edge of the growing triangulation.  When a   */
556 /*   circle event covers two boundary edges with a triangle, so that they    */
557 /*   are no longer boundary edges, those edges are not immediately deleted   */
558 /*   from the tree; rather, they are lazily deleted when they are next       */
559 /*   encountered.  (Since only a random sample of boundary edges are kept    */
560 /*   in the tree, lazy deletion is faster.)  `keydest' is used to verify     */
561 /*   that a triangle is still the same as when it entered the splay tree; if */
562 /*   it has been rotated (due to a circle event), it no longer represents a  */
563 /*   boundary edge and should be deleted.                                    */
564
565 struct splaynode {
566         struct triedge keyedge;                /* Lprev of an edge on the front. */
567         point keydest;          /* Used to verify that splay node is still live. */
568         struct splaynode *lchild, *rchild;            /* Children in splay tree. */
569 };
570
571 /* A type used to allocate memory.  firstblock is the first block of items.  */
572 /*   nowblock is the block from which items are currently being allocated.   */
573 /*   nextitem points to the next slab of free memory for an item.            */
574 /*   deaditemstack is the head of a linked list (stack) of deallocated items */
575 /*   that can be recycled.  unallocateditems is the number of items that     */
576 /*   remain to be allocated from nowblock.                                   */
577 /*                                                                           */
578 /* Traversal is the process of walking through the entire list of items, and */
579 /*   is separate from allocation.  Note that a traversal will visit items on */
580 /*   the "deaditemstack" stack as well as live items.  pathblock points to   */
581 /*   the block currently being traversed.  pathitem points to the next item  */
582 /*   to be traversed.  pathitemsleft is the number of items that remain to   */
583 /*   be traversed in pathblock.                                              */
584 /*                                                                           */
585 /* itemwordtype is set to POINTER or FLOATINGPOINT, and is used to suggest   */
586 /*   what sort of word the record is primarily made up of.  alignbytes       */
587 /*   determines how new records should be aligned in memory.  itembytes and  */
588 /*   itemwords are the length of a record in bytes (after rounding up) and   */
589 /*   words.  itemsperblock is the number of items allocated at once in a     */
590 /*   single block.  items is the number of currently allocated items.        */
591 /*   maxitems is the maximum number of items that have been allocated at     */
592 /*   once; it is the current number of items plus the number of records kept */
593 /*   on deaditemstack.                                                       */
594
595 struct memorypool {
596         VOID **firstblock, **nowblock;
597         VOID *nextitem;
598         VOID *deaditemstack;
599         VOID **pathblock;
600         VOID *pathitem;
601         enum wordtype itemwordtype;
602         int alignbytes;
603         int itembytes, itemwords;
604         int itemsperblock;
605         long items, maxitems;
606         int unallocateditems;
607         int pathitemsleft;
608 };
609
610 /* Variables used to allocate memory for triangles, shell edges, points,     */
611 /*   viri (triangles being eaten), bad (encroached) segments, bad (skinny    */
612 /*   or too large) triangles, and splay tree nodes.                          */
613
614 static struct memorypool triangles;
615 static struct memorypool shelles;
616 static struct memorypool points;
617 static struct memorypool viri;
618 static struct memorypool badsegments;
619 static struct memorypool badtriangles;
620 static struct memorypool splaynodes;
621
622 /* Variables that maintain the bad triangle queues.  The tails are pointers  */
623 /*   to the pointers that have to be filled in to enqueue an item.           */
624
625 static struct badface *queuefront[64];
626 static struct badface **queuetail[64];
627
628 static REAL xmin, xmax, ymin, ymax;                              /* x and y bounds. */
629 static REAL xminextreme;        /* Nonexistent x value used as a flag in sweepline. */
630 static int inpoints;                                     /* Number of input points. */
631 static int inelements;                                /* Number of input triangles. */
632 static int insegments;                                 /* Number of input segments. */
633 static int holes;                                         /* Number of input holes. */
634 static int regions;                                     /* Number of input regions. */
635 static long edges;                                       /* Number of output edges. */
636 static int mesh_dim;                                  /* Dimension (ought to be 2). */
637 static int nextras;                              /* Number of attributes per point. */
638 static int eextras;                           /* Number of attributes per triangle. */
639 static long hullsize;                            /* Number of edges of convex hull. */
640 static int triwords;                                   /* Total words per triangle. */
641 static int shwords;                                  /* Total words per shell edge. */
642 static int pointmarkindex;             /* Index to find boundary marker of a point. */
643 static int point2triindex;         /* Index to find a triangle adjacent to a point. */
644 static int highorderindex;    /* Index to find extra nodes for high-order elements. */
645 static int elemattribindex;              /* Index to find attributes of a triangle. */
646 static int areaboundindex;               /* Index to find area bound of a triangle. */
647 static int checksegments;           /* Are there segments in the triangulation yet? */
648 static int readnodefile;                             /* Has a .node file been read? */
649 static long samples;                /* Number of random samples for point location. */
650 static unsigned long randomseed;                     /* Current random number seed. */
651
652 static REAL splitter;       /* Used to split REAL factors for exact multiplication. */
653 static REAL epsilon;                             /* Floating-point machine epsilon. */
654 static REAL resulterrbound;
655 static REAL ccwerrboundA, ccwerrboundB, ccwerrboundC;
656 static REAL iccerrboundA, iccerrboundB, iccerrboundC;
657
658 static long incirclecount;                   /* Number of incircle tests performed. */
659 static long counterclockcount;       /* Number of counterclockwise tests performed. */
660 static long hyperbolacount;        /* Number of right-of-hyperbola tests performed. */
661 static long circumcentercount;    /* Number of circumcenter calculations performed. */
662 static long circletopcount;         /* Number of circle top calculations performed. */
663
664 /* Switches for the triangulator.                                            */
665 /*   poly: -p switch.  refine: -r switch.                                    */
666 /*   quality: -q switch.                                                     */
667 /*     minangle: minimum angle bound, specified after -q switch.             */
668 /*     goodangle: cosine squared of minangle.                                */
669 /*   vararea: -a switch without number.                                      */
670 /*   fixedarea: -a switch with number.                                       */
671 /*     maxarea: maximum area bound, specified after -a switch.               */
672 /*   regionattrib: -A switch.  convex: -c switch.                            */
673 /*   firstnumber: inverse of -z switch.  All items are numbered starting     */
674 /*     from firstnumber.                                                     */
675 /*   edgesout: -e switch.  voronoi: -v switch.                               */
676 /*   neighbors: -n switch.  geomview: -g switch.                             */
677 /*   nobound: -B switch.  nopolywritten: -P switch.                          */
678 /*   nonodewritten: -N switch.  noelewritten: -E switch.                     */
679 /*   noiterationnum: -I switch.  noholes: -O switch.                         */
680 /*   noexact: -X switch.                                                     */
681 /*   order: element order, specified after -o switch.                        */
682 /*   nobisect: count of how often -Y switch is selected.                     */
683 /*   steiner: maximum number of Steiner points, specified after -S switch.   */
684 /*     steinerleft: number of Steiner points not yet used.                   */
685 /*   incremental: -i switch.  sweepline: -F switch.                          */
686 /*   dwyer: inverse of -l switch.                                            */
687 /*   splitseg: -s switch.                                                    */
688 /*   docheck: -C switch.                                                     */
689 /*   quiet: -Q switch.  verbose: count of how often -V switch is selected.   */
690 /*   useshelles: -p, -r, -q, or -c switch; determines whether shell edges    */
691 /*     are used at all.                                                      */
692 /*                                                                           */
693 /* Read the instructions to find out the meaning of these switches.          */
694
695 static int poly, refine, quality, vararea, fixedarea, regionattrib, convex;
696 static int firstnumber;
697 static int edgesout, voronoi, neighbors, geomview;
698 static int nobound, nopolywritten, nonodewritten, noelewritten, noiterationnum;
699 static int noholes, noexact;
700 static int incremental, sweepline, dwyer;
701 static int splitseg;
702 static int docheck;
703 static int quiet, verbose;
704 static int useshelles;
705 static int order;
706 static int nobisect;
707 static int steiner, steinerleft;
708 static REAL minangle, goodangle;
709 static REAL maxarea;
710
711 /* Variables for file names.                                                 */
712
713 #ifndef TRILIBRARY
714 char innodefilename[FILENAMESIZE];
715 char inelefilename[FILENAMESIZE];
716 char inpolyfilename[FILENAMESIZE];
717 char areafilename[FILENAMESIZE];
718 char outnodefilename[FILENAMESIZE];
719 char outelefilename[FILENAMESIZE];
720 char outpolyfilename[FILENAMESIZE];
721 char edgefilename[FILENAMESIZE];
722 char vnodefilename[FILENAMESIZE];
723 char vedgefilename[FILENAMESIZE];
724 char neighborfilename[FILENAMESIZE];
725 char offfilename[FILENAMESIZE];
726 #endif /* not TRILIBRARY */
727
728 /* Triangular bounding box points.                                           */
729
730 static point infpoint1, infpoint2, infpoint3;
731
732 /* Pointer to the `triangle' that occupies all of "outer space".             */
733
734 static triangle *dummytri;
735 static triangle *dummytribase;      /* Keep base address so we can free() it later. */
736
737 /* Pointer to the omnipresent shell edge.  Referenced by any triangle or     */
738 /*   shell edge that isn't really connected to a shell edge at that          */
739 /*   location.                                                               */
740
741 static shelle *dummysh;
742 static shelle *dummyshbase;         /* Keep base address so we can free() it later. */
743
744 /* Pointer to a recently visited triangle.  Improves point location if       */
745 /*   proximate points are inserted sequentially.                             */
746
747 static struct triedge recenttri;
748
749 /*****************************************************************************/
750 /*                                                                           */
751 /*  Mesh manipulation primitives.  Each triangle contains three pointers to  */
752 /*  other triangles, with orientations.  Each pointer points not to the      */
753 /*  first byte of a triangle, but to one of the first three bytes of a       */
754 /*  triangle.  It is necessary to extract both the triangle itself and the   */
755 /*  orientation.  To save memory, I keep both pieces of information in one   */
756 /*  pointer.  To make this possible, I assume that all triangles are aligned */
757 /*  to four-byte boundaries.  The `decode' routine below decodes a pointer,  */
758 /*  extracting an orientation (in the range 0 to 2) and a pointer to the     */
759 /*  beginning of a triangle.  The `encode' routine compresses a pointer to a */
760 /*  triangle and an orientation into a single pointer.  My assumptions that  */
761 /*  triangles are four-byte-aligned and that the `unsigned long' type is     */
762 /*  long enough to hold a pointer are two of the few kludges in this program.*/
763 /*                                                                           */
764 /*  Shell edges are manipulated similarly.  A pointer to a shell edge        */
765 /*  carries both an address and an orientation in the range 0 to 1.          */
766 /*                                                                           */
767 /*  The other primitives take an oriented triangle or oriented shell edge,   */
768 /*  and return an oriented triangle or oriented shell edge or point; or they */
769 /*  change the connections in the data structure.                            */
770 /*                                                                           */
771 /*****************************************************************************/
772
773 /********* Mesh manipulation primitives begin here                   *********/
774 /**                                                                         **/
775 /**                                                                         **/
776
777 /* Fast lookup arrays to speed some of the mesh manipulation primitives.     */
778
779 int plus1mod3[3] = {1, 2, 0};
780 int minus1mod3[3] = {2, 0, 1};
781
782 /********* Primitives for triangles                                  *********/
783 /*                                                                           */
784 /*                                                                           */
785
786 /* decode() converts a pointer to an oriented triangle.  The orientation is  */
787 /*   extracted from the two least significant bits of the pointer.           */
788
789 #define decode( ptr, triedge )                                                                                                  \
790         ( triedge ).orient = (int) ( (unsigned long) ( ptr ) & (unsigned long) 3l );      \
791         ( triedge ).tri = (triangle *)                                                                                            \
792                                           ( (unsigned long) ( ptr ) ^ (unsigned long) ( triedge ).orient )
793
794 /* encode() compresses an oriented triangle into a single pointer.  It       */
795 /*   relies on the assumption that all triangles are aligned to four-byte    */
796 /*   boundaries, so the two least significant bits of (triedge).tri are zero.*/
797
798 #define encode( triedge )                                                                                                               \
799         (triangle) ( (unsigned long) ( triedge ).tri | (unsigned long) ( triedge ).orient )
800
801 /* The following edge manipulation primitives are all described by Guibas    */
802 /*   and Stolfi.  However, they use an edge-based data structure, whereas I  */
803 /*   am using a triangle-based data structure.                               */
804
805 /* sym() finds the abutting triangle, on the same edge.  Note that the       */
806 /*   edge direction is necessarily reversed, because triangle/edge handles   */
807 /*   are always directed counterclockwise around the triangle.               */
808
809 #define sym( triedge1, triedge2 )                                                                                               \
810         ptr = ( triedge1 ).tri[( triedge1 ).orient];                                                                    \
811         decode( ptr, triedge2 );
812
813 #define symself( triedge )                                                                                                              \
814         ptr = ( triedge ).tri[( triedge ).orient];                                                                              \
815         decode( ptr, triedge );
816
817 /* lnext() finds the next edge (counterclockwise) of a triangle.             */
818
819 #define lnext( triedge1, triedge2 )                                                                                             \
820         ( triedge2 ).tri = ( triedge1 ).tri;                                                                                    \
821         ( triedge2 ).orient = plus1mod3[( triedge1 ).orient]
822
823 #define lnextself( triedge )                                                                                                    \
824         ( triedge ).orient = plus1mod3[( triedge ).orient]
825
826 /* lprev() finds the previous edge (clockwise) of a triangle.                */
827
828 #define lprev( triedge1, triedge2 )                                                                                             \
829         ( triedge2 ).tri = ( triedge1 ).tri;                                                                                    \
830         ( triedge2 ).orient = minus1mod3[( triedge1 ).orient]
831
832 #define lprevself( triedge )                                                                                                    \
833         ( triedge ).orient = minus1mod3[( triedge ).orient]
834
835 /* onext() spins counterclockwise around a point; that is, it finds the next */
836 /*   edge with the same origin in the counterclockwise direction.  This edge */
837 /*   will be part of a different triangle.                                   */
838
839 #define onext( triedge1, triedge2 )                                                                                             \
840         lprev( triedge1, triedge2 );                                                                                              \
841         symself( triedge2 );
842
843 #define onextself( triedge )                                                                                                    \
844         lprevself( triedge );                                                                                                             \
845         symself( triedge );
846
847 /* oprev() spins clockwise around a point; that is, it finds the next edge   */
848 /*   with the same origin in the clockwise direction.  This edge will be     */
849 /*   part of a different triangle.                                           */
850
851 #define oprev( triedge1, triedge2 )                                                                                             \
852         sym( triedge1, triedge2 );                                                                                                        \
853         lnextself( triedge2 );
854
855 #define oprevself( triedge )                                                                                                    \
856         symself( triedge );                                                                                                                       \
857         lnextself( triedge );
858
859 /* dnext() spins counterclockwise around a point; that is, it finds the next */
860 /*   edge with the same destination in the counterclockwise direction.  This */
861 /*   edge will be part of a different triangle.                              */
862
863 #define dnext( triedge1, triedge2 )                                                                                             \
864         sym( triedge1, triedge2 );                                                                                                        \
865         lprevself( triedge2 );
866
867 #define dnextself( triedge )                                                                                                    \
868         symself( triedge );                                                                                                                       \
869         lprevself( triedge );
870
871 /* dprev() spins clockwise around a point; that is, it finds the next edge   */
872 /*   with the same destination in the clockwise direction.  This edge will   */
873 /*   be part of a different triangle.                                        */
874
875 #define dprev( triedge1, triedge2 )                                                                                             \
876         lnext( triedge1, triedge2 );                                                                                              \
877         symself( triedge2 );
878
879 #define dprevself( triedge )                                                                                                    \
880         lnextself( triedge );                                                                                                             \
881         symself( triedge );
882
883 /* rnext() moves one edge counterclockwise about the adjacent triangle.      */
884 /*   (It's best understood by reading Guibas and Stolfi.  It involves        */
885 /*   changing triangles twice.)                                              */
886
887 #define rnext( triedge1, triedge2 )                                                                                             \
888         sym( triedge1, triedge2 );                                                                                                        \
889         lnextself( triedge2 );                                                                                                            \
890         symself( triedge2 );
891
892 #define rnextself( triedge )                                                                                                    \
893         symself( triedge );                                                                                                                       \
894         lnextself( triedge );                                                                                                             \
895         symself( triedge );
896
897 /* rnext() moves one edge clockwise about the adjacent triangle.             */
898 /*   (It's best understood by reading Guibas and Stolfi.  It involves        */
899 /*   changing triangles twice.)                                              */
900
901 #define rprev( triedge1, triedge2 )                                                                                             \
902         sym( triedge1, triedge2 );                                                                                                        \
903         lprevself( triedge2 );                                                                                                            \
904         symself( triedge2 );
905
906 #define rprevself( triedge )                                                                                                    \
907         symself( triedge );                                                                                                                       \
908         lprevself( triedge );                                                                                                             \
909         symself( triedge );
910
911 /* These primitives determine or set the origin, destination, or apex of a   */
912 /* triangle.                                                                 */
913
914 #define org( triedge, pointptr )                                                                                                \
915         pointptr = (point) ( triedge ).tri[plus1mod3[( triedge ).orient] + 3]
916
917 #define dest( triedge, pointptr )                                                                                               \
918         pointptr = (point) ( triedge ).tri[minus1mod3[( triedge ).orient] + 3]
919
920 #define apex( triedge, pointptr )                                                                                               \
921         pointptr = (point) ( triedge ).tri[( triedge ).orient + 3]
922
923 #define setorg( triedge, pointptr )                                                                                             \
924         ( triedge ).tri[plus1mod3[( triedge ).orient] + 3] = (triangle) pointptr
925
926 #define setdest( triedge, pointptr )                                                                                    \
927         ( triedge ).tri[minus1mod3[( triedge ).orient] + 3] = (triangle) pointptr
928
929 #define setapex( triedge, pointptr )                                                                                    \
930         ( triedge ).tri[( triedge ).orient + 3] = (triangle) pointptr
931
932 #define setvertices2null( triedge )                                                                                             \
933         ( triedge ).tri[3] = (triangle) NULL;                                                                             \
934         ( triedge ).tri[4] = (triangle) NULL;                                                                             \
935         ( triedge ).tri[5] = (triangle) NULL;
936
937 /* Bond two triangles together.                                              */
938
939 #define bond( triedge1, triedge2 )                                                                                              \
940         ( triedge1 ).tri[( triedge1 ).orient] = encode( triedge2 );                                               \
941         ( triedge2 ).tri[( triedge2 ).orient] = encode( triedge1 )
942
943 /* Dissolve a bond (from one side).  Note that the other triangle will still */
944 /*   think it's connected to this triangle.  Usually, however, the other     */
945 /*   triangle is being deleted entirely, or bonded to another triangle, so   */
946 /*   it doesn't matter.                                                      */
947
948 #define dissolve( triedge )                                                                                                             \
949         ( triedge ).tri[( triedge ).orient] = (triangle) dummytri
950
951 /* Copy a triangle/edge handle.                                              */
952
953 #define triedgecopy( triedge1, triedge2 )                                                                               \
954         ( triedge2 ).tri = ( triedge1 ).tri;                                                                                    \
955         ( triedge2 ).orient = ( triedge1 ).orient
956
957 /* Test for equality of triangle/edge handles.                               */
958
959 #define triedgeequal( triedge1, triedge2 )                                                                              \
960         ( ( ( triedge1 ).tri == ( triedge2 ).tri ) &&                                                                      \
961           ( ( triedge1 ).orient == ( triedge2 ).orient ) )
962
963 /* Primitives to infect or cure a triangle with the virus.  These rely on    */
964 /*   the assumption that all shell edges are aligned to four-byte boundaries.*/
965
966 #define infect( triedge )                                                                                                               \
967         ( triedge ).tri[6] = (triangle)                                                                                           \
968                                                  ( (unsigned long) ( triedge ).tri[6] | (unsigned long) 2l )
969
970 #define uninfect( triedge )                                                                                                             \
971         ( triedge ).tri[6] = (triangle)                                                                                           \
972                                                  ( (unsigned long) ( triedge ).tri[6] & ~(unsigned long) 2l )
973
974 /* Test a triangle for viral infection.                                      */
975
976 #define infected( triedge )                                                                                                             \
977         ( ( (unsigned long) ( triedge ).tri[6] & (unsigned long) 2l ) != 0 )
978
979 /* Check or set a triangle's attributes.                                     */
980
981 #define elemattribute( triedge, attnum )                                                                                \
982         ( (REAL *) ( triedge ).tri )[elemattribindex + ( attnum )]
983
984 #define setelemattribute( triedge, attnum, value )                                                              \
985         ( (REAL *) ( triedge ).tri )[elemattribindex + ( attnum )] = (REAL)value
986
987 /* Check or set a triangle's maximum area bound.                             */
988
989 #define areabound( triedge )  ( (REAL *) ( triedge ).tri )[areaboundindex]
990
991 #define setareabound( triedge, value )                                                                                  \
992         ( (REAL *) ( triedge ).tri )[areaboundindex] = (REAL)value
993
994 /********* Primitives for shell edges                                *********/
995 /*                                                                           */
996 /*                                                                           */
997
998 /* sdecode() converts a pointer to an oriented shell edge.  The orientation  */
999 /*   is extracted from the least significant bit of the pointer.  The two    */
1000 /*   least significant bits (one for orientation, one for viral infection)   */
1001 /*   are masked out to produce the real pointer.                             */
1002
1003 #define sdecode( sptr, edge )                                                                                                   \
1004         ( edge ).shorient = (int) ( (unsigned long) ( sptr ) & (unsigned long) 1l );      \
1005         ( edge ).sh = (shelle *)                                                                                                          \
1006                                   ( (unsigned long) ( sptr ) & ~(unsigned long) 3l )
1007
1008 /* sencode() compresses an oriented shell edge into a single pointer.  It    */
1009 /*   relies on the assumption that all shell edges are aligned to two-byte   */
1010 /*   boundaries, so the least significant bit of (edge).sh is zero.          */
1011
1012 #define sencode( edge )                                                                                                                 \
1013         (shelle) ( (unsigned long) ( edge ).sh | (unsigned long) ( edge ).shorient )
1014
1015 /* ssym() toggles the orientation of a shell edge.                           */
1016
1017 #define ssym( edge1, edge2 )                                                                                                    \
1018         ( edge2 ).sh = ( edge1 ).sh;                                                                                                    \
1019         ( edge2 ).shorient = 1 - ( edge1 ).shorient
1020
1021 #define ssymself( edge )                                                                                                                \
1022         ( edge ).shorient = 1 - ( edge ).shorient
1023
1024 /* spivot() finds the other shell edge (from the same segment) that shares   */
1025 /*   the same origin.                                                        */
1026
1027 #define spivot( edge1, edge2 )                                                                                                  \
1028         sptr = ( edge1 ).sh[( edge1 ).shorient];                                                                                \
1029         sdecode( sptr, edge2 )
1030
1031 #define spivotself( edge )                                                                                                              \
1032         sptr = ( edge ).sh[( edge ).shorient];                                                                                  \
1033         sdecode( sptr, edge )
1034
1035 /* snext() finds the next shell edge (from the same segment) in sequence;    */
1036 /*   one whose origin is the input shell edge's destination.                 */
1037
1038 #define snext( edge1, edge2 )                                                                                                   \
1039         sptr = ( edge1 ).sh[1 - ( edge1 ).shorient];                                                                    \
1040         sdecode( sptr, edge2 )
1041
1042 #define snextself( edge )                                                                                                               \
1043         sptr = ( edge ).sh[1 - ( edge ).shorient];                                                                              \
1044         sdecode( sptr, edge )
1045
1046 /* These primitives determine or set the origin or destination of a shell    */
1047 /*   edge.                                                                   */
1048
1049 #define sorg( edge, pointptr )                                                                                                  \
1050         pointptr = (point) ( edge ).sh[2 + ( edge ).shorient]
1051
1052 #define sdest( edge, pointptr )                                                                                                 \
1053         pointptr = (point) ( edge ).sh[3 - ( edge ).shorient]
1054
1055 #define setsorg( edge, pointptr )                                                                                               \
1056         ( edge ).sh[2 + ( edge ).shorient] = (shelle) pointptr
1057
1058 #define setsdest( edge, pointptr )                                                                                              \
1059         ( edge ).sh[3 - ( edge ).shorient] = (shelle) pointptr
1060
1061 /* These primitives read or set a shell marker.  Shell markers are used to   */
1062 /*   hold user boundary information.                                         */
1063
1064 #define mark( edge )  ( *(int *) ( ( edge ).sh + 6 ) )
1065
1066 #define setmark( edge, value )                                                                                                  \
1067         *(int *) ( ( edge ).sh + 6 ) = value
1068
1069 /* Bond two shell edges together.                                            */
1070
1071 #define sbond( edge1, edge2 )                                                                                                   \
1072         ( edge1 ).sh[( edge1 ).shorient] = sencode( edge2 );                                                      \
1073         ( edge2 ).sh[( edge2 ).shorient] = sencode( edge1 )
1074
1075 /* Dissolve a shell edge bond (from one side).  Note that the other shell    */
1076 /*   edge will still think it's connected to this shell edge.                */
1077
1078 #define sdissolve( edge )                                                                                                               \
1079         ( edge ).sh[( edge ).shorient] = (shelle) dummysh
1080
1081 /* Copy a shell edge.                                                        */
1082
1083 #define shellecopy( edge1, edge2 )                                                                                              \
1084         ( edge2 ).sh = ( edge1 ).sh;                                                                                                    \
1085         ( edge2 ).shorient = ( edge1 ).shorient
1086
1087 /* Test for equality of shell edges.                                         */
1088
1089 #define shelleequal( edge1, edge2 )                                                                                             \
1090         ( ( ( edge1 ).sh == ( edge2 ).sh ) &&                                                                                      \
1091           ( ( edge1 ).shorient == ( edge2 ).shorient ) )
1092
1093 /********* Primitives for interacting triangles and shell edges      *********/
1094 /*                                                                           */
1095 /*                                                                           */
1096
1097 /* tspivot() finds a shell edge abutting a triangle.                         */
1098
1099 #define tspivot( triedge, edge )                                                                                                \
1100         sptr = (shelle) ( triedge ).tri[6 + ( triedge ).orient];                                                \
1101         sdecode( sptr, edge )
1102
1103 /* stpivot() finds a triangle abutting a shell edge.  It requires that the   */
1104 /*   variable `ptr' of type `triangle' be defined.                           */
1105
1106 #define stpivot( edge, triedge )                                                                                                \
1107         ptr = (triangle) ( edge ).sh[4 + ( edge ).shorient];                                                    \
1108         decode( ptr, triedge )
1109
1110 /* Bond a triangle to a shell edge.                                          */
1111
1112 #define tsbond( triedge, edge )                                                                                                 \
1113         ( triedge ).tri[6 + ( triedge ).orient] = (triangle) sencode( edge );                     \
1114         ( edge ).sh[4 + ( edge ).shorient] = (shelle) encode( triedge )
1115
1116 /* Dissolve a bond (from the triangle side).                                 */
1117
1118 #define tsdissolve( triedge )                                                                                                   \
1119         ( triedge ).tri[6 + ( triedge ).orient] = (triangle) dummysh
1120
1121 /* Dissolve a bond (from the shell edge side).                               */
1122
1123 #define stdissolve( edge )                                                                                                              \
1124         ( edge ).sh[4 + ( edge ).shorient] = (shelle) dummytri
1125
1126 /********* Primitives for points                                     *********/
1127 /*                                                                           */
1128 /*                                                                           */
1129
1130 #define pointmark( pt )  ( (int *) ( pt ) )[pointmarkindex]
1131
1132 #define setpointmark( pt, value )                                                                                               \
1133         ( (int *) ( pt ) )[pointmarkindex] = value
1134
1135 #define point2tri( pt )  ( (triangle *) ( pt ) )[point2triindex]
1136
1137 #define setpoint2tri( pt, value )                                                                                               \
1138         ( (triangle *) ( pt ) )[point2triindex] = value
1139
1140 /**                                                                         **/
1141 /**                                                                         **/
1142 /********* Mesh manipulation primitives end here                     *********/
1143
1144 /********* User interaction routines begin here                      *********/
1145 /**                                                                         **/
1146 /**                                                                         **/
1147
1148 /*****************************************************************************/
1149 /*                                                                           */
1150 /*  syntax()   Print list of command line switches.                          */
1151 /*                                                                           */
1152 /*****************************************************************************/
1153
1154 #ifndef TRILIBRARY
1155
1156 void syntax(){
1157 #ifdef CDT_ONLY
1158 #ifdef REDUCED
1159         printf( "triangle [-pAcevngBPNEIOXzo_lQVh] input_file\n" );
1160 #else /* not REDUCED */
1161         printf( "triangle [-pAcevngBPNEIOXzo_iFlCQVh] input_file\n" );
1162 #endif /* not REDUCED */
1163 #else /* not CDT_ONLY */
1164 #ifdef REDUCED
1165         printf( "triangle [-prq__a__AcevngBPNEIOXzo_YS__lQVh] input_file\n" );
1166 #else /* not REDUCED */
1167         printf( "triangle [-prq__a__AcevngBPNEIOXzo_YS__iFlsCQVh] input_file\n" );
1168 #endif /* not REDUCED */
1169 #endif /* not CDT_ONLY */
1170
1171         printf( "    -p  Triangulates a Planar Straight Line Graph (.poly file).\n" );
1172 #ifndef CDT_ONLY
1173         printf( "    -r  Refines a previously generated mesh.\n" );
1174         printf(
1175                 "    -q  Quality mesh generation.  A minimum angle may be specified.\n" );
1176         printf( "    -a  Applies a maximum triangle area constraint.\n" );
1177 #endif /* not CDT_ONLY */
1178         printf(
1179                 "    -A  Applies attributes to identify elements in certain regions.\n" );
1180         printf( "    -c  Encloses the convex hull with segments.\n" );
1181         printf( "    -e  Generates an edge list.\n" );
1182         printf( "    -v  Generates a Voronoi diagram.\n" );
1183         printf( "    -n  Generates a list of triangle neighbors.\n" );
1184         printf( "    -g  Generates an .off file for Geomview.\n" );
1185         printf( "    -B  Suppresses output of boundary information.\n" );
1186         printf( "    -P  Suppresses output of .poly file.\n" );
1187         printf( "    -N  Suppresses output of .node file.\n" );
1188         printf( "    -E  Suppresses output of .ele file.\n" );
1189         printf( "    -I  Suppresses mesh iteration numbers.\n" );
1190         printf( "    -O  Ignores holes in .poly file.\n" );
1191         printf( "    -X  Suppresses use of exact arithmetic.\n" );
1192         printf( "    -z  Numbers all items starting from zero (rather than one).\n" );
1193         printf( "    -o2 Generates second-order subparametric elements.\n" );
1194 #ifndef CDT_ONLY
1195         printf( "    -Y  Suppresses boundary segment splitting.\n" );
1196         printf( "    -S  Specifies maximum number of added Steiner points.\n" );
1197 #endif /* not CDT_ONLY */
1198 #ifndef REDUCED
1199         printf( "    -i  Uses incremental method, rather than divide-and-conquer.\n" );
1200         printf( "    -F  Uses Fortune's sweepline algorithm, rather than d-and-c.\n" );
1201 #endif /* not REDUCED */
1202         printf( "    -l  Uses vertical cuts only, rather than alternating cuts.\n" );
1203 #ifndef REDUCED
1204 #ifndef CDT_ONLY
1205         printf(
1206                 "    -s  Force segments into mesh by splitting (instead of using CDT).\n" );
1207 #endif /* not CDT_ONLY */
1208         printf( "    -C  Check consistency of final mesh.\n" );
1209 #endif /* not REDUCED */
1210         printf( "    -Q  Quiet:  No terminal output except errors.\n" );
1211         printf( "    -V  Verbose:  Detailed information on what I'm doing.\n" );
1212         printf( "    -h  Help:  Detailed instructions for Triangle.\n" );
1213         exit( 0 );
1214 }
1215
1216 #endif /* not TRILIBRARY */
1217
1218 /*****************************************************************************/
1219 /*                                                                           */
1220 /*  info()   Print out complete instructions.                                */
1221 /*                                                                           */
1222 /*****************************************************************************/
1223
1224 #ifndef TRILIBRARY
1225
1226 void info(){
1227         printf( "Triangle\n" );
1228         printf(
1229                 "A Two-Dimensional Quality Mesh Generator and Delaunay Triangulator.\n" );
1230         printf( "Version 1.3\n\n" );
1231         printf(
1232                 "Copyright 1996 Jonathan Richard Shewchuk  (bugs/comments to jrs@cs.cmu.edu)\n"
1233                 );
1234         printf( "School of Computer Science / Carnegie Mellon University\n" );
1235         printf( "5000 Forbes Avenue / Pittsburgh, Pennsylvania  15213-3891\n" );
1236         printf(
1237                 "Created as part of the Archimedes project (tools for parallel FEM).\n" );
1238         printf(
1239                 "Supported in part by NSF Grant CMS-9318163 and an NSERC 1967 Scholarship.\n" );
1240         printf( "There is no warranty whatsoever.  Use at your own risk.\n" );
1241 #ifdef SINGLE
1242         printf( "This executable is compiled for single precision arithmetic.\n\n\n" );
1243 #else /* not SINGLE */
1244         printf( "This executable is compiled for double precision arithmetic.\n\n\n" );
1245 #endif /* not SINGLE */
1246         printf(
1247                 "Triangle generates exact Delaunay triangulations, constrained Delaunay\n" );
1248         printf(
1249                 "triangulations, and quality conforming Delaunay triangulations.  The latter\n"
1250                 );
1251         printf(
1252                 "can be generated with no small angles, and are thus suitable for finite\n" );
1253         printf(
1254                 "element analysis.  If no command line switches are specified, your .node\n" );
1255         printf(
1256                 "input file will be read, and the Delaunay triangulation will be returned in\n"
1257                 );
1258         printf( ".node and .ele output files.  The command syntax is:\n\n" );
1259 #ifdef CDT_ONLY
1260 #ifdef REDUCED
1261         printf( "triangle [-pAcevngBPNEIOXzo_lQVh] input_file\n\n" );
1262 #else /* not REDUCED */
1263         printf( "triangle [-pAcevngBPNEIOXzo_iFlCQVh] input_file\n\n" );
1264 #endif /* not REDUCED */
1265 #else /* not CDT_ONLY */
1266 #ifdef REDUCED
1267         printf( "triangle [-prq__a__AcevngBPNEIOXzo_YS__lQVh] input_file\n\n" );
1268 #else /* not REDUCED */
1269         printf( "triangle [-prq__a__AcevngBPNEIOXzo_YS__iFlsCQVh] input_file\n\n" );
1270 #endif /* not REDUCED */
1271 #endif /* not CDT_ONLY */
1272         printf(
1273                 "Underscores indicate that numbers may optionally follow certain switches;\n" );
1274         printf(
1275                 "do not leave any space between a switch and its numeric parameter.\n" );
1276         printf(
1277                 "input_file must be a file with extension .node, or extension .poly if the\n" );
1278         printf(
1279                 "-p switch is used.  If -r is used, you must supply .node and .ele files,\n" );
1280         printf(
1281                 "and possibly a .poly file and .area file as well.  The formats of these\n" );
1282         printf( "files are described below.\n\n" );
1283         printf( "Command Line Switches:\n\n" );
1284         printf(
1285                 "    -p  Reads a Planar Straight Line Graph (.poly file), which can specify\n"
1286                 );
1287         printf(
1288                 "        points, segments, holes, and regional attributes and area\n" );
1289         printf(
1290                 "        constraints.  Will generate a constrained Delaunay triangulation\n" );
1291         printf(
1292                 "        fitting the input; or, if -s, -q, or -a is used, a conforming\n" );
1293         printf(
1294                 "        Delaunay triangulation.  If -p is not used, Triangle reads a .node\n"
1295                 );
1296         printf( "        file by default.\n" );
1297         printf(
1298                 "    -r  Refines a previously generated mesh.  The mesh is read from a .node\n"
1299                 );
1300         printf(
1301                 "        file and an .ele file.  If -p is also used, a .poly file is read\n" );
1302         printf(
1303                 "        and used to constrain edges in the mesh.  Further details on\n" );
1304         printf( "        refinement are given below.\n" );
1305         printf(
1306                 "    -q  Quality mesh generation by Jim Ruppert's Delaunay refinement\n" );
1307         printf(
1308                 "        algorithm.  Adds points to the mesh to ensure that no angles\n" );
1309         printf(
1310                 "        smaller than 20 degrees occur.  An alternative minimum angle may be\n"
1311                 );
1312         printf(
1313                 "        specified after the `q'.  If the minimum angle is 20.7 degrees or\n" );
1314         printf(
1315                 "        smaller, the triangulation algorithm is theoretically guaranteed to\n"
1316                 );
1317         printf(
1318                 "        terminate (assuming infinite precision arithmetic - Triangle may\n" );
1319         printf(
1320                 "        fail to terminate if you run out of precision).  In practice, the\n" );
1321         printf(
1322                 "        algorithm often succeeds for minimum angles up to 33.8 degrees.\n" );
1323         printf(
1324                 "        For highly refined meshes, however, it may be necessary to reduce\n" );
1325         printf(
1326                 "        the minimum angle to well below 20 to avoid problems associated\n" );
1327         printf(
1328                 "        with insufficient floating-point precision.  The specified angle\n" );
1329         printf( "        may include a decimal point.\n" );
1330         printf(
1331                 "    -a  Imposes a maximum triangle area.  If a number follows the `a', no\n" );
1332         printf(
1333                 "        triangle will be generated whose area is larger than that number.\n" );
1334         printf(
1335                 "        If no number is specified, an .area file (if -r is used) or .poly\n" );
1336         printf(
1337                 "        file (if -r is not used) specifies a number of maximum area\n" );
1338         printf(
1339                 "        constraints.  An .area file contains a separate area constraint for\n"
1340                 );
1341         printf(
1342                 "        each triangle, and is useful for refining a finite element mesh\n" );
1343         printf(
1344                 "        based on a posteriori error estimates.  A .poly file can optionally\n"
1345                 );
1346         printf(
1347                 "        contain an area constraint for each segment-bounded region, thereby\n"
1348                 );
1349         printf(
1350                 "        enforcing triangle densities in a first triangulation.  You can\n" );
1351         printf(
1352                 "        impose both a fixed area constraint and a varying area constraint\n" );
1353         printf(
1354                 "        by invoking the -a switch twice, once with and once without a\n" );
1355         printf(
1356                 "        number following.  Each area specified may include a decimal point.\n"
1357                 );
1358         printf(
1359                 "    -A  Assigns an additional attribute to each triangle that identifies\n" );
1360         printf(
1361                 "        what segment-bounded region each triangle belongs to.  Attributes\n" );
1362         printf(
1363                 "        are assigned to regions by the .poly file.  If a region is not\n" );
1364         printf(
1365                 "        explicitly marked by the .poly file, triangles in that region are\n" );
1366         printf(
1367                 "        assigned an attribute of zero.  The -A switch has an effect only\n" );
1368         printf( "        when the -p switch is used and the -r switch is not.\n" );
1369         printf(
1370                 "    -c  Creates segments on the convex hull of the triangulation.  If you\n" );
1371         printf(
1372                 "        are triangulating a point set, this switch causes a .poly file to\n" );
1373         printf(
1374                 "        be written, containing all edges in the convex hull.  (By default,\n"
1375                 );
1376         printf(
1377                 "        a .poly file is written only if a .poly file is read.)  If you are\n"
1378                 );
1379         printf(
1380                 "        triangulating a PSLG, this switch specifies that the interior of\n" );
1381         printf(
1382                 "        the convex hull of the PSLG should be triangulated.  If you do not\n"
1383                 );
1384         printf(
1385                 "        use this switch when triangulating a PSLG, it is assumed that you\n" );
1386         printf(
1387                 "        have identified the region to be triangulated by surrounding it\n" );
1388         printf(
1389                 "        with segments of the input PSLG.  Beware:  if you are not careful,\n"
1390                 );
1391         printf(
1392                 "        this switch can cause the introduction of an extremely thin angle\n" );
1393         printf(
1394                 "        between a PSLG segment and a convex hull segment, which can cause\n" );
1395         printf(
1396                 "        overrefinement or failure if Triangle runs out of precision.  If\n" );
1397         printf(
1398                 "        you are refining a mesh, the -c switch works differently; it\n" );
1399         printf(
1400                 "        generates the set of boundary edges of the mesh, rather than the\n" );
1401         printf( "        convex hull.\n" );
1402         printf(
1403                 "    -e  Outputs (to an .edge file) a list of edges of the triangulation.\n" );
1404         printf(
1405                 "    -v  Outputs the Voronoi diagram associated with the triangulation.\n" );
1406         printf( "        Does not attempt to detect degeneracies.\n" );
1407         printf(
1408                 "    -n  Outputs (to a .neigh file) a list of triangles neighboring each\n" );
1409         printf( "        triangle.\n" );
1410         printf(
1411                 "    -g  Outputs the mesh to an Object File Format (.off) file, suitable for\n"
1412                 );
1413         printf( "        viewing with the Geometry Center's Geomview package.\n" );
1414         printf(
1415                 "    -B  No boundary markers in the output .node, .poly, and .edge output\n" );
1416         printf(
1417                 "        files.  See the detailed discussion of boundary markers below.\n" );
1418         printf(
1419                 "    -P  No output .poly file.  Saves disk space, but you lose the ability\n" );
1420         printf(
1421                 "        to impose segment constraints on later refinements of the mesh.\n" );
1422         printf( "    -N  No output .node file.\n" );
1423         printf( "    -E  No output .ele file.\n" );
1424         printf(
1425                 "    -I  No iteration numbers.  Suppresses the output of .node and .poly\n" );
1426         printf(
1427                 "        files, so your input files won't be overwritten.  (If your input is\n"
1428                 );
1429         printf(
1430                 "        a .poly file only, a .node file will be written.)  Cannot be used\n" );
1431         printf(
1432                 "        with the -r switch, because that would overwrite your input .ele\n" );
1433         printf(
1434                 "        file.  Shouldn't be used with the -s, -q, or -a switch if you are\n" );
1435         printf(
1436                 "        using a .node file for input, because no .node file will be\n" );
1437         printf( "        written, so there will be no record of any added points.\n" );
1438         printf( "    -O  No holes.  Ignores the holes in the .poly file.\n" );
1439         printf(
1440                 "    -X  No exact arithmetic.  Normally, Triangle uses exact floating-point\n"
1441                 );
1442         printf(
1443                 "        arithmetic for certain tests if it thinks the inexact tests are not\n"
1444                 );
1445         printf(
1446                 "        accurate enough.  Exact arithmetic ensures the robustness of the\n" );
1447         printf(
1448                 "        triangulation algorithms, despite floating-point roundoff error.\n" );
1449         printf(
1450                 "        Disabling exact arithmetic with the -X switch will cause a small\n" );
1451         printf(
1452                 "        improvement in speed and create the possibility (albeit small) that\n"
1453                 );
1454         printf(
1455                 "        Triangle will fail to produce a valid mesh.  Not recommended.\n" );
1456         printf(
1457                 "    -z  Numbers all items starting from zero (rather than one).  Note that\n"
1458                 );
1459         printf(
1460                 "        this switch is normally overrided by the value used to number the\n" );
1461         printf(
1462                 "        first point of the input .node or .poly file.  However, this switch\n"
1463                 );
1464         printf( "        is useful when calling Triangle from another program.\n" );
1465         printf(
1466                 "    -o2 Generates second-order subparametric elements with six nodes each.\n"
1467                 );
1468         printf(
1469                 "    -Y  No new points on the boundary.  This switch is useful when the mesh\n"
1470                 );
1471         printf(
1472                 "        boundary must be preserved so that it conforms to some adjacent\n" );
1473         printf(
1474                 "        mesh.  Be forewarned that you will probably sacrifice some of the\n" );
1475         printf(
1476                 "        quality of the mesh; Triangle will try, but the resulting mesh may\n"
1477                 );
1478         printf(
1479                 "        contain triangles of poor aspect ratio.  Works well if all the\n" );
1480         printf(
1481                 "        boundary points are closely spaced.  Specify this switch twice\n" );
1482         printf(
1483                 "        (`-YY') to prevent all segment splitting, including internal\n" );
1484         printf( "        boundaries.\n" );
1485         printf(
1486                 "    -S  Specifies the maximum number of Steiner points (points that are not\n"
1487                 );
1488         printf(
1489                 "        in the input, but are added to meet the constraints of minimum\n" );
1490         printf(
1491                 "        angle and maximum area).  The default is to allow an unlimited\n" );
1492         printf(
1493                 "        number.  If you specify this switch with no number after it,\n" );
1494         printf(
1495                 "        the limit is set to zero.  Triangle always adds points at segment\n" );
1496         printf(
1497                 "        intersections, even if it needs to use more points than the limit\n" );
1498         printf(
1499                 "        you set.  When Triangle inserts segments by splitting (-s), it\n" );
1500         printf(
1501                 "        always adds enough points to ensure that all the segments appear in\n"
1502                 );
1503         printf(
1504                 "        the triangulation, again ignoring the limit.  Be forewarned that\n" );
1505         printf(
1506                 "        the -S switch may result in a conforming triangulation that is not\n"
1507                 );
1508         printf(
1509                 "        truly Delaunay, because Triangle may be forced to stop adding\n" );
1510         printf(
1511                 "        points when the mesh is in a state where a segment is non-Delaunay\n"
1512                 );
1513         printf(
1514                 "        and needs to be split.  If so, Triangle will print a warning.\n" );
1515         printf(
1516                 "    -i  Uses an incremental rather than divide-and-conquer algorithm to\n" );
1517         printf(
1518                 "        form a Delaunay triangulation.  Try it if the divide-and-conquer\n" );
1519         printf( "        algorithm fails.\n" );
1520         printf(
1521                 "    -F  Uses Steven Fortune's sweepline algorithm to form a Delaunay\n" );
1522         printf(
1523                 "        triangulation.  Warning:  does not use exact arithmetic for all\n" );
1524         printf( "        calculations.  An exact result is not guaranteed.\n" );
1525         printf(
1526                 "    -l  Uses only vertical cuts in the divide-and-conquer algorithm.  By\n" );
1527         printf(
1528                 "        default, Triangle uses alternating vertical and horizontal cuts,\n" );
1529         printf(
1530                 "        which usually improve the speed except with point sets that are\n" );
1531         printf(
1532                 "        small or short and wide.  This switch is primarily of theoretical\n" );
1533         printf( "        interest.\n" );
1534         printf(
1535                 "    -s  Specifies that segments should be forced into the triangulation by\n"
1536                 );
1537         printf(
1538                 "        recursively splitting them at their midpoints, rather than by\n" );
1539         printf(
1540                 "        generating a constrained Delaunay triangulation.  Segment splitting\n"
1541                 );
1542         printf(
1543                 "        is true to Ruppert's original algorithm, but can create needlessly\n"
1544                 );
1545         printf( "        small triangles near external small features.\n" );
1546         printf(
1547                 "    -C  Check the consistency of the final mesh.  Uses exact arithmetic for\n"
1548                 );
1549         printf(
1550                 "        checking, even if the -X switch is used.  Useful if you suspect\n" );
1551         printf( "        Triangle is buggy.\n" );
1552         printf(
1553                 "    -Q  Quiet: Suppresses all explanation of what Triangle is doing, unless\n"
1554                 );
1555         printf( "        an error occurs.\n" );
1556         printf(
1557                 "    -V  Verbose: Gives detailed information about what Triangle is doing.\n" );
1558         printf(
1559                 "        Add more `V's for increasing amount of detail.  `-V' gives\n" );
1560         printf(
1561                 "        information on algorithmic progress and more detailed statistics.\n" );
1562         printf(
1563                 "        `-VV' gives point-by-point details, and will print so much that\n" );
1564         printf(
1565                 "        Triangle will run much more slowly.  `-VVV' gives information only\n"
1566                 );
1567         printf( "        a debugger could love.\n" );
1568         printf( "    -h  Help:  Displays these instructions.\n" );
1569         printf( "\n" );
1570         printf( "Definitions:\n" );
1571         printf( "\n" );
1572         printf(
1573                 "  A Delaunay triangulation of a point set is a triangulation whose vertices\n"
1574                 );
1575         printf(
1576                 "  are the point set, having the property that no point in the point set\n" );
1577         printf(
1578                 "  falls in the interior of the circumcircle (circle that passes through all\n"
1579                 );
1580         printf( "  three vertices) of any triangle in the triangulation.\n\n" );
1581         printf(
1582                 "  A Voronoi diagram of a point set is a subdivision of the plane into\n" );
1583         printf(
1584                 "  polygonal regions (some of which may be infinite), where each region is\n" );
1585         printf(
1586                 "  the set of points in the plane that are closer to some input point than\n" );
1587         printf(
1588                 "  to any other input point.  (The Voronoi diagram is the geometric dual of\n"
1589                 );
1590         printf( "  the Delaunay triangulation.)\n\n" );
1591         printf(
1592                 "  A Planar Straight Line Graph (PSLG) is a collection of points and\n" );
1593         printf(
1594                 "  segments.  Segments are simply edges, whose endpoints are points in the\n" );
1595         printf(
1596                 "  PSLG.  The file format for PSLGs (.poly files) is described below.\n" );
1597         printf( "\n" );
1598         printf(
1599                 "  A constrained Delaunay triangulation of a PSLG is similar to a Delaunay\n" );
1600         printf(
1601                 "  triangulation, but each PSLG segment is present as a single edge in the\n" );
1602         printf(
1603                 "  triangulation.  (A constrained Delaunay triangulation is not truly a\n" );
1604         printf( "  Delaunay triangulation.)\n\n" );
1605         printf(
1606                 "  A conforming Delaunay triangulation of a PSLG is a true Delaunay\n" );
1607         printf(
1608                 "  triangulation in which each PSLG segment may have been subdivided into\n" );
1609         printf(
1610                 "  several edges by the insertion of additional points.  These inserted\n" );
1611         printf(
1612                 "  points are necessary to allow the segments to exist in the mesh while\n" );
1613         printf( "  maintaining the Delaunay property.\n\n" );
1614         printf( "File Formats:\n\n" );
1615         printf(
1616                 "  All files may contain comments prefixed by the character '#'.  Points,\n" );
1617         printf(
1618                 "  triangles, edges, holes, and maximum area constraints must be numbered\n" );
1619         printf(
1620                 "  consecutively, starting from either 1 or 0.  Whichever you choose, all\n" );
1621         printf(
1622                 "  input files must be consistent; if the nodes are numbered from 1, so must\n"
1623                 );
1624         printf(
1625                 "  be all other objects.  Triangle automatically detects your choice while\n" );
1626         printf(
1627                 "  reading the .node (or .poly) file.  (When calling Triangle from another\n" );
1628         printf(
1629                 "  program, use the -z switch if you wish to number objects from zero.)\n" );
1630         printf( "  Examples of these file formats are given below.\n\n" );
1631         printf( "  .node files:\n" );
1632         printf(
1633                 "    First line:  <# of points> <dimension (must be 2)> <# of attributes>\n" );
1634         printf(
1635                 "                                           <# of boundary markers (0 or 1)>\n"
1636                 );
1637         printf(
1638                 "    Remaining lines:  <point #> <x> <y> [attributes] [boundary marker]\n" );
1639         printf( "\n" );
1640         printf(
1641                 "    The attributes, which are typically floating-point values of physical\n" );
1642         printf(
1643                 "    quantities (such as mass or conductivity) associated with the nodes of\n"
1644                 );
1645         printf(
1646                 "    a finite element mesh, are copied unchanged to the output mesh.  If -s,\n"
1647                 );
1648         printf(
1649                 "    -q, or -a is selected, each new Steiner point added to the mesh will\n" );
1650         printf( "    have attributes assigned to it by linear interpolation.\n\n" );
1651         printf(
1652                 "    If the fourth entry of the first line is `1', the last column of the\n" );
1653         printf(
1654                 "    remainder of the file is assumed to contain boundary markers.  Boundary\n"
1655                 );
1656         printf(
1657                 "    markers are used to identify boundary points and points resting on PSLG\n"
1658                 );
1659         printf(
1660                 "    segments; a complete description appears in a section below.  The .node\n"
1661                 );
1662         printf(
1663                 "    file produced by Triangle will contain boundary markers in the last\n" );
1664         printf( "    column unless they are suppressed by the -B switch.\n\n" );
1665         printf( "  .ele files:\n" );
1666         printf(
1667                 "    First line:  <# of triangles> <points per triangle> <# of attributes>\n" );
1668         printf(
1669                 "    Remaining lines:  <triangle #> <point> <point> <point> ... [attributes]\n"
1670                 );
1671         printf( "\n" );
1672         printf(
1673                 "    Points are indices into the corresponding .node file.  The first three\n"
1674                 );
1675         printf(
1676                 "    points are the corners, and are listed in counterclockwise order around\n"
1677                 );
1678         printf(
1679                 "    each triangle.  (The remaining points, if any, depend on the type of\n" );
1680         printf(
1681                 "    finite element used.)  The attributes are just like those of .node\n" );
1682         printf(
1683                 "    files.  Because there is no simple mapping from input to output\n" );
1684         printf(
1685                 "    triangles, an attempt is made to interpolate attributes, which may\n" );
1686         printf(
1687                 "    result in a good deal of diffusion of attributes among nearby triangles\n"
1688                 );
1689         printf(
1690                 "    as the triangulation is refined.  Diffusion does not occur across\n" );
1691         printf(
1692                 "    segments, so attributes used to identify segment-bounded regions remain\n"
1693                 );
1694         printf(
1695                 "    intact.  In output .ele files, all triangles have three points each\n" );
1696         printf(
1697                 "    unless the -o2 switch is used, in which case they have six, and the\n" );
1698         printf(
1699                 "    fourth, fifth, and sixth points lie on the midpoints of the edges\n" );
1700         printf( "    opposite the first, second, and third corners.\n\n" );
1701         printf( "  .poly files:\n" );
1702         printf(
1703                 "    First line:  <# of points> <dimension (must be 2)> <# of attributes>\n" );
1704         printf(
1705                 "                                           <# of boundary markers (0 or 1)>\n"
1706                 );
1707         printf(
1708                 "    Following lines:  <point #> <x> <y> [attributes] [boundary marker]\n" );
1709         printf( "    One line:  <# of segments> <# of boundary markers (0 or 1)>\n" );
1710         printf(
1711                 "    Following lines:  <segment #> <endpoint> <endpoint> [boundary marker]\n" );
1712         printf( "    One line:  <# of holes>\n" );
1713         printf( "    Following lines:  <hole #> <x> <y>\n" );
1714         printf(
1715                 "    Optional line:  <# of regional attributes and/or area constraints>\n" );
1716         printf(
1717                 "    Optional following lines:  <constraint #> <x> <y> <attrib> <max area>\n" );
1718         printf( "\n" );
1719         printf(
1720                 "    A .poly file represents a PSLG, as well as some additional information.\n"
1721                 );
1722         printf(
1723                 "    The first section lists all the points, and is identical to the format\n"
1724                 );
1725         printf(
1726                 "    of .node files.  <# of points> may be set to zero to indicate that the\n"
1727                 );
1728         printf(
1729                 "    points are listed in a separate .node file; .poly files produced by\n" );
1730         printf(
1731                 "    Triangle always have this format.  This has the advantage that a point\n"
1732                 );
1733         printf(
1734                 "    set may easily be triangulated with or without segments.  (The same\n" );
1735         printf(
1736                 "    effect can be achieved, albeit using more disk space, by making a copy\n"
1737                 );
1738         printf(
1739                 "    of the .poly file with the extension .node; all sections of the file\n" );
1740         printf( "    but the first are ignored.)\n\n" );
1741         printf(
1742                 "    The second section lists the segments.  Segments are edges whose\n" );
1743         printf(
1744                 "    presence in the triangulation is enforced.  Each segment is specified\n" );
1745         printf(
1746                 "    by listing the indices of its two endpoints.  This means that you must\n"
1747                 );
1748         printf(
1749                 "    include its endpoints in the point list.  If -s, -q, and -a are not\n" );
1750         printf(
1751                 "    selected, Triangle will produce a constrained Delaunay triangulation,\n" );
1752         printf(
1753                 "    in which each segment appears as a single edge in the triangulation.\n" );
1754         printf(
1755                 "    If -q or -a is selected, Triangle will produce a conforming Delaunay\n" );
1756         printf(
1757                 "    triangulation, in which segments may be subdivided into smaller edges.\n"
1758                 );
1759         printf( "    Each segment, like each point, may have a boundary marker.\n\n" );
1760         printf(
1761                 "    The third section lists holes (and concavities, if -c is selected) in\n" );
1762         printf(
1763                 "    the triangulation.  Holes are specified by identifying a point inside\n" );
1764         printf(
1765                 "    each hole.  After the triangulation is formed, Triangle creates holes\n" );
1766         printf(
1767                 "    by eating triangles, spreading out from each hole point until its\n" );
1768         printf(
1769                 "    progress is blocked by PSLG segments; you must be careful to enclose\n" );
1770         printf(
1771                 "    each hole in segments, or your whole triangulation may be eaten away.\n" );
1772         printf(
1773                 "    If the two triangles abutting a segment are eaten, the segment itself\n" );
1774         printf(
1775                 "    is also eaten.  Do not place a hole directly on a segment; if you do,\n" );
1776         printf( "    Triangle will choose one side of the segment arbitrarily.\n\n" );
1777         printf(
1778                 "    The optional fourth section lists regional attributes (to be assigned\n" );
1779         printf(
1780                 "    to all triangles in a region) and regional constraints on the maximum\n" );
1781         printf(
1782                 "    triangle area.  Triangle will read this section only if the -A switch\n" );
1783         printf(
1784                 "    is used or the -a switch is used without a number following it, and the\n"
1785                 );
1786         printf(
1787                 "    -r switch is not used.  Regional attributes and area constraints are\n" );
1788         printf(
1789                 "    propagated in the same manner as holes; you specify a point for each\n" );
1790         printf(
1791                 "    attribute and/or constraint, and the attribute and/or constraint will\n" );
1792         printf(
1793                 "    affect the whole region (bounded by segments) containing the point.  If\n"
1794                 );
1795         printf(
1796                 "    two values are written on a line after the x and y coordinate, the\n" );
1797         printf(
1798                 "    former is assumed to be a regional attribute (but will only be applied\n"
1799                 );
1800         printf(
1801                 "    if the -A switch is selected), and the latter is assumed to be a\n" );
1802         printf(
1803                 "    regional area constraint (but will only be applied if the -a switch is\n"
1804                 );
1805         printf(
1806                 "    selected).  You may also specify just one value after the coordinates,\n"
1807                 );
1808         printf(
1809                 "    which can serve as both an attribute and an area constraint, depending\n"
1810                 );
1811         printf(
1812                 "    on the choice of switches.  If you are using the -A and -a switches\n" );
1813         printf(
1814                 "    simultaneously and wish to assign an attribute to some region without\n" );
1815         printf( "    imposing an area constraint, use a negative maximum area.\n\n" );
1816         printf(
1817                 "    When a triangulation is created from a .poly file, you must either\n" );
1818         printf(
1819                 "    enclose the entire region to be triangulated in PSLG segments, or\n" );
1820         printf(
1821                 "    use the -c switch, which encloses the convex hull of the input point\n" );
1822         printf(
1823                 "    set.  If you do not use the -c switch, Triangle will eat all triangles\n"
1824                 );
1825         printf(
1826                 "    on the outer boundary that are not protected by segments; if you are\n" );
1827         printf(
1828                 "    not careful, your whole triangulation may be eaten away.  If you do\n" );
1829         printf(
1830                 "    use the -c switch, you can still produce concavities by appropriate\n" );
1831         printf( "    placement of holes just inside the convex hull.\n\n" );
1832         printf(
1833                 "    An ideal PSLG has no intersecting segments, nor any points that lie\n" );
1834         printf(
1835                 "    upon segments (except, of course, the endpoints of each segment.)  You\n"
1836                 );
1837         printf(
1838                 "    aren't required to make your .poly files ideal, but you should be aware\n"
1839                 );
1840         printf(
1841                 "    of what can go wrong.  Segment intersections are relatively safe -\n" );
1842         printf(
1843                 "    Triangle will calculate the intersection points for you and add them to\n"
1844                 );
1845         printf(
1846                 "    the triangulation - as long as your machine's floating-point precision\n"
1847                 );
1848         printf(
1849                 "    doesn't become a problem.  You are tempting the fates if you have three\n"
1850                 );
1851         printf(
1852                 "    segments that cross at the same location, and expect Triangle to figure\n"
1853                 );
1854         printf(
1855                 "    out where the intersection point is.  Thanks to floating-point roundoff\n"
1856                 );
1857         printf(
1858                 "    error, Triangle will probably decide that the three segments intersect\n"
1859                 );
1860         printf(
1861                 "    at three different points, and you will find a minuscule triangle in\n" );
1862         printf(
1863                 "    your output - unless Triangle tries to refine the tiny triangle, uses\n" );
1864         printf(
1865                 "    up the last bit of machine precision, and fails to terminate at all.\n" );
1866         printf(
1867                 "    You're better off putting the intersection point in the input files,\n" );
1868         printf(
1869                 "    and manually breaking up each segment into two.  Similarly, if you\n" );
1870         printf(
1871                 "    place a point at the middle of a segment, and hope that Triangle will\n" );
1872         printf(
1873                 "    break up the segment at that point, you might get lucky.  On the other\n"
1874                 );
1875         printf(
1876                 "    hand, Triangle might decide that the point doesn't lie precisely on the\n"
1877                 );
1878         printf(
1879                 "    line, and you'll have a needle-sharp triangle in your output - or a lot\n"
1880                 );
1881         printf( "    of tiny triangles if you're generating a quality mesh.\n\n" );
1882         printf(
1883                 "    When Triangle reads a .poly file, it also writes a .poly file, which\n" );
1884         printf(
1885                 "    includes all edges that are part of input segments.  If the -c switch\n" );
1886         printf(
1887                 "    is used, the output .poly file will also include all of the edges on\n" );
1888         printf(
1889                 "    the convex hull.  Hence, the output .poly file is useful for finding\n" );
1890         printf(
1891                 "    edges associated with input segments and setting boundary conditions in\n"
1892                 );
1893         printf(
1894                 "    finite element simulations.  More importantly, you will need it if you\n"
1895                 );
1896         printf(
1897                 "    plan to refine the output mesh, and don't want segments to be missing\n" );
1898         printf( "    in later triangulations.\n\n" );
1899         printf( "  .area files:\n" );
1900         printf( "    First line:  <# of triangles>\n" );
1901         printf( "    Following lines:  <triangle #> <maximum area>\n\n" );
1902         printf(
1903                 "    An .area file associates with each triangle a maximum area that is used\n"
1904                 );
1905         printf(
1906                 "    for mesh refinement.  As with other file formats, every triangle must\n" );
1907         printf(
1908                 "    be represented, and they must be numbered consecutively.  A triangle\n" );
1909         printf(
1910                 "    may be left unconstrained by assigning it a negative maximum area.\n" );
1911         printf( "\n" );
1912         printf( "  .edge files:\n" );
1913         printf( "    First line:  <# of edges> <# of boundary markers (0 or 1)>\n" );
1914         printf(
1915                 "    Following lines:  <edge #> <endpoint> <endpoint> [boundary marker]\n" );
1916         printf( "\n" );
1917         printf(
1918                 "    Endpoints are indices into the corresponding .node file.  Triangle can\n"
1919                 );
1920         printf(
1921                 "    produce .edge files (use the -e switch), but cannot read them.  The\n" );
1922         printf(
1923                 "    optional column of boundary markers is suppressed by the -B switch.\n" );
1924         printf( "\n" );
1925         printf(
1926                 "    In Voronoi diagrams, one also finds a special kind of edge that is an\n" );
1927         printf(
1928                 "    infinite ray with only one endpoint.  For these edges, a different\n" );
1929         printf( "    format is used:\n\n" );
1930         printf( "        <edge #> <endpoint> -1 <direction x> <direction y>\n\n" );
1931         printf(
1932                 "    The `direction' is a floating-point vector that indicates the direction\n"
1933                 );
1934         printf( "    of the infinite ray.\n\n" );
1935         printf( "  .neigh files:\n" );
1936         printf(
1937                 "    First line:  <# of triangles> <# of neighbors per triangle (always 3)>\n"
1938                 );
1939         printf(
1940                 "    Following lines:  <triangle #> <neighbor> <neighbor> <neighbor>\n" );
1941         printf( "\n" );
1942         printf(
1943                 "    Neighbors are indices into the corresponding .ele file.  An index of -1\n"
1944                 );
1945         printf(
1946                 "    indicates a mesh boundary, and therefore no neighbor.  Triangle can\n" );
1947         printf(
1948                 "    produce .neigh files (use the -n switch), but cannot read them.\n" );
1949         printf( "\n" );
1950         printf(
1951                 "    The first neighbor of triangle i is opposite the first corner of\n" );
1952         printf( "    triangle i, and so on.\n\n" );
1953         printf( "Boundary Markers:\n\n" );
1954         printf(
1955                 "  Boundary markers are tags used mainly to identify which output points and\n"
1956                 );
1957         printf(
1958                 "  edges are associated with which PSLG segment, and to identify which\n" );
1959         printf(
1960                 "  points and edges occur on a boundary of the triangulation.  A common use\n"
1961                 );
1962         printf(
1963                 "  is to determine where boundary conditions should be applied to a finite\n" );
1964         printf(
1965                 "  element mesh.  You can prevent boundary markers from being written into\n" );
1966         printf( "  files produced by Triangle by using the -B switch.\n\n" );
1967         printf(
1968                 "  The boundary marker associated with each segment in an output .poly file\n"
1969                 );
1970         printf( "  or edge in an output .edge file is chosen as follows:\n" );
1971         printf(
1972                 "    - If an output edge is part or all of a PSLG segment with a nonzero\n" );
1973         printf(
1974                 "      boundary marker, then the edge is assigned the same marker.\n" );
1975         printf(
1976                 "    - Otherwise, if the edge occurs on a boundary of the triangulation\n" );
1977         printf(
1978                 "      (including boundaries of holes), then the edge is assigned the marker\n"
1979                 );
1980         printf( "      one (1).\n" );
1981         printf( "    - Otherwise, the edge is assigned the marker zero (0).\n" );
1982         printf(
1983                 "  The boundary marker associated with each point in an output .node file is\n"
1984                 );
1985         printf( "  chosen as follows:\n" );
1986         printf(
1987                 "    - If a point is assigned a nonzero boundary marker in the input file,\n" );
1988         printf(
1989                 "      then it is assigned the same marker in the output .node file.\n" );
1990         printf(
1991                 "    - Otherwise, if the point lies on a PSLG segment (including the\n" );
1992         printf(
1993                 "      segment's endpoints) with a nonzero boundary marker, then the point\n" );
1994         printf(
1995                 "      is assigned the same marker.  If the point lies on several such\n" );
1996         printf( "      segments, one of the markers is chosen arbitrarily.\n" );
1997         printf(
1998                 "    - Otherwise, if the point occurs on a boundary of the triangulation,\n" );
1999         printf( "      then the point is assigned the marker one (1).\n" );
2000         printf( "    - Otherwise, the point is assigned the marker zero (0).\n" );
2001         printf( "\n" );
2002         printf(
2003                 "  If you want Triangle to determine for you which points and edges are on\n" );
2004         printf(
2005                 "  the boundary, assign them the boundary marker zero (or use no markers at\n"
2006                 );
2007         printf(
2008                 "  all) in your input files.  Alternatively, you can mark some of them and\n" );
2009         printf( "  leave others marked zero, allowing Triangle to label them.\n\n" );
2010         printf( "Triangulation Iteration Numbers:\n\n" );
2011         printf(
2012                 "  Because Triangle can read and refine its own triangulations, input\n" );
2013         printf(
2014                 "  and output files have iteration numbers.  For instance, Triangle might\n" );
2015         printf(
2016                 "  read the files mesh.3.node, mesh.3.ele, and mesh.3.poly, refine the\n" );
2017         printf(
2018                 "  triangulation, and output the files mesh.4.node, mesh.4.ele, and\n" );
2019         printf( "  mesh.4.poly.  Files with no iteration number are treated as if\n" );
2020         printf(
2021                 "  their iteration number is zero; hence, Triangle might read the file\n" );
2022         printf(
2023                 "  points.node, triangulate it, and produce the files points.1.node and\n" );
2024         printf( "  points.1.ele.\n\n" );
2025         printf(
2026                 "  Iteration numbers allow you to create a sequence of successively finer\n" );
2027         printf(
2028                 "  meshes suitable for multigrid methods.  They also allow you to produce a\n"
2029                 );
2030         printf(
2031                 "  sequence of meshes using error estimate-driven mesh refinement.\n" );
2032         printf( "\n" );
2033         printf(
2034                 "  If you're not using refinement or quality meshing, and you don't like\n" );
2035         printf(
2036                 "  iteration numbers, use the -I switch to disable them.  This switch will\n" );
2037         printf(
2038                 "  also disable output of .node and .poly files to prevent your input files\n"
2039                 );
2040         printf(
2041                 "  from being overwritten.  (If the input is a .poly file that contains its\n"
2042                 );
2043         printf( "  own points, a .node file will be written.)\n\n" );
2044         printf( "Examples of How to Use Triangle:\n\n" );
2045         printf(
2046                 "  `triangle dots' will read points from dots.node, and write their Delaunay\n"
2047                 );
2048         printf(
2049                 "  triangulation to dots.1.node and dots.1.ele.  (dots.1.node will be\n" );
2050         printf(
2051                 "  identical to dots.node.)  `triangle -I dots' writes the triangulation to\n"
2052                 );
2053         printf(
2054                 "  dots.ele instead.  (No additional .node file is needed, so none is\n" );
2055         printf( "  written.)\n\n" );
2056         printf(
2057                 "  `triangle -pe object.1' will read a PSLG from object.1.poly (and possibly\n"
2058                 );
2059         printf(
2060                 "  object.1.node, if the points are omitted from object.1.poly) and write\n" );
2061         printf( "  their constrained Delaunay triangulation to object.2.node and\n" );
2062         printf(
2063                 "  object.2.ele.  The segments will be copied to object.2.poly, and all\n" );
2064         printf( "  edges will be written to object.2.edge.\n\n" );
2065         printf(
2066                 "  `triangle -pq31.5a.1 object' will read a PSLG from object.poly (and\n" );
2067         printf(
2068                 "  possibly object.node), generate a mesh whose angles are all greater than\n"
2069                 );
2070         printf(
2071                 "  31.5 degrees and whose triangles all have area smaller than 0.1, and\n" );
2072         printf(
2073                 "  write the mesh to object.1.node and object.1.ele.  Each segment may have\n"
2074                 );
2075         printf(
2076                 "  been broken up into multiple edges; the resulting constrained edges are\n" );
2077         printf( "  written to object.1.poly.\n\n" );
2078         printf(
2079                 "  Here is a sample file `box.poly' describing a square with a square hole:\n"
2080                 );
2081         printf( "\n" );
2082         printf(
2083                 "    # A box with eight points in 2D, no attributes, one boundary marker.\n" );
2084         printf( "    8 2 0 1\n" );
2085         printf( "    # Outer box has these vertices:\n" );
2086         printf( "     1   0 0   0\n" );
2087         printf( "     2   0 3   0\n" );
2088         printf( "     3   3 0   0\n" );
2089         printf( "     4   3 3   33     # A special marker for this point.\n" );
2090         printf( "    # Inner square has these vertices:\n" );
2091         printf( "     5   1 1   0\n" );
2092         printf( "     6   1 2   0\n" );
2093         printf( "     7   2 1   0\n" );
2094         printf( "     8   2 2   0\n" );
2095         printf( "    # Five segments with boundary markers.\n" );
2096         printf( "    5 1\n" );
2097         printf( "     1   1 2   5      # Left side of outer box.\n" );
2098         printf( "     2   5 7   0      # Segments 2 through 5 enclose the hole.\n" );
2099         printf( "     3   7 8   0\n" );
2100         printf( "     4   8 6   10\n" );
2101         printf( "     5   6 5   0\n" );
2102         printf( "    # One hole in the middle of the inner square.\n" );
2103         printf( "    1\n" );
2104         printf( "     1   1.5 1.5\n\n" );
2105         printf(
2106                 "  Note that some segments are missing from the outer square, so one must\n" );
2107         printf(
2108                 "  use the `-c' switch.  After `triangle -pqc box.poly', here is the output\n"
2109                 );
2110         printf(
2111                 "  file `box.1.node', with twelve points.  The last four points were added\n" );
2112         printf(
2113                 "  to meet the angle constraint.  Points 1, 2, and 9 have markers from\n" );
2114         printf(
2115                 "  segment 1.  Points 6 and 8 have markers from segment 4.  All the other\n" );
2116         printf(
2117                 "  points but 4 have been marked to indicate that they lie on a boundary.\n" );
2118         printf( "\n" );
2119         printf( "    12  2  0  1\n" );
2120         printf( "       1    0   0      5\n" );
2121         printf( "       2    0   3      5\n" );
2122         printf( "       3    3   0      1\n" );
2123         printf( "       4    3   3     33\n" );
2124         printf( "       5    1   1      1\n" );
2125         printf( "       6    1   2     10\n" );
2126         printf( "       7    2   1      1\n" );
2127         printf( "       8    2   2     10\n" );
2128         printf( "       9    0   1.5    5\n" );
2129         printf( "      10    1.5   0    1\n" );
2130         printf( "      11    3   1.5    1\n" );
2131         printf( "      12    1.5   3    1\n" );
2132         printf( "    # Generated by triangle -pqc box.poly\n\n" );
2133         printf( "  Here is the output file `box.1.ele', with twelve triangles.\n\n" );
2134         printf( "    12  3  0\n" );
2135         printf( "       1     5   6   9\n" );
2136         printf( "       2    10   3   7\n" );
2137         printf( "       3     6   8  12\n" );
2138         printf( "       4     9   1   5\n" );
2139         printf( "       5     6   2   9\n" );
2140         printf( "       6     7   3  11\n" );
2141         printf( "       7    11   4   8\n" );
2142         printf( "       8     7   5  10\n" );
2143         printf( "       9    12   2   6\n" );
2144         printf( "      10     8   7  11\n" );
2145         printf( "      11     5   1  10\n" );
2146         printf( "      12     8   4  12\n" );
2147         printf( "    # Generated by triangle -pqc box.poly\n\n" );
2148         printf(
2149                 "  Here is the output file `box.1.poly'.  Note that segments have been added\n"
2150                 );
2151         printf(
2152                 "  to represent the convex hull, and some segments have been split by newly\n"
2153                 );
2154         printf(
2155                 "  added points.  Note also that <# of points> is set to zero to indicate\n" );
2156         printf( "  that the points should be read from the .node file.\n\n" );
2157         printf( "    0  2  0  1\n" );
2158         printf( "    12  1\n" );
2159         printf( "       1     1   9     5\n" );
2160         printf( "       2     5   7     1\n" );
2161         printf( "       3     8   7     1\n" );
2162         printf( "       4     6   8    10\n" );
2163         printf( "       5     5   6     1\n" );
2164         printf( "       6     3  10     1\n" );
2165         printf( "       7     4  11     1\n" );
2166         printf( "       8     2  12     1\n" );
2167         printf( "       9     9   2     5\n" );
2168         printf( "      10    10   1     1\n" );
2169         printf( "      11    11   3     1\n" );
2170         printf( "      12    12   4     1\n" );
2171         printf( "    1\n" );
2172         printf( "       1   1.5 1.5\n" );
2173         printf( "    # Generated by triangle -pqc box.poly\n\n" );
2174         printf( "Refinement and Area Constraints:\n\n" );
2175         printf(
2176                 "  The -r switch causes a mesh (.node and .ele files) to be read and\n" );
2177         printf(
2178                 "  refined.  If the -p switch is also used, a .poly file is read and used to\n"
2179                 );
2180         printf(
2181                 "  specify edges that are constrained and cannot be eliminated (although\n" );
2182         printf(
2183                 "  they can be divided into smaller edges) by the refinement process.\n" );
2184         printf( "\n" );
2185         printf(
2186                 "  When you refine a mesh, you generally want to impose tighter quality\n" );
2187         printf(
2188                 "  constraints.  One way to accomplish this is to use -q with a larger\n" );
2189         printf(
2190                 "  angle, or -a followed by a smaller area than you used to generate the\n" );
2191         printf(
2192                 "  mesh you are refining.  Another way to do this is to create an .area\n" );
2193         printf(
2194                 "  file, which specifies a maximum area for each triangle, and use the -a\n" );
2195         printf(
2196                 "  switch (without a number following).  Each triangle's area constraint is\n"
2197                 );
2198         printf(
2199                 "  applied to that triangle.  Area constraints tend to diffuse as the mesh\n" );
2200         printf(
2201                 "  is refined, so if there are large variations in area constraint between\n" );
2202         printf( "  adjacent triangles, you may not get the results you want.\n\n" );
2203         printf(
2204                 "  If you are refining a mesh composed of linear (three-node) elements, the\n"
2205                 );
2206         printf(
2207                 "  output mesh will contain all the nodes present in the input mesh, in the\n"
2208                 );
2209         printf(
2210                 "  same order, with new nodes added at the end of the .node file.  However,\n"
2211                 );
2212         printf(
2213                 "  there is no guarantee that each output element is contained in a single\n" );
2214         printf(
2215                 "  input element.  Often, output elements will overlap two input elements,\n" );
2216         printf(
2217                 "  and input edges are not present in the output mesh.  Hence, a sequence of\n"
2218                 );
2219         printf(
2220                 "  refined meshes will form a hierarchy of nodes, but not a hierarchy of\n" );
2221         printf(
2222                 "  elements.  If you a refining a mesh of higher-order elements, the\n" );
2223         printf(
2224                 "  hierarchical property applies only to the nodes at the corners of an\n" );
2225         printf( "  element; other nodes may not be present in the refined mesh.\n\n" );
2226         printf(
2227                 "  It is important to understand that maximum area constraints in .poly\n" );
2228         printf(
2229                 "  files are handled differently from those in .area files.  A maximum area\n"
2230                 );
2231         printf(
2232                 "  in a .poly file applies to the whole (segment-bounded) region in which a\n"
2233                 );
2234         printf(
2235                 "  point falls, whereas a maximum area in an .area file applies to only one\n"
2236                 );
2237         printf(
2238                 "  triangle.  Area constraints in .poly files are used only when a mesh is\n" );
2239         printf(
2240                 "  first generated, whereas area constraints in .area files are used only to\n"
2241                 );
2242         printf(
2243                 "  refine an existing mesh, and are typically based on a posteriori error\n" );
2244         printf(
2245                 "  estimates resulting from a finite element simulation on that mesh.\n" );
2246         printf( "\n" );
2247         printf(
2248                 "  `triangle -rq25 object.1' will read object.1.node and object.1.ele, then\n"
2249                 );
2250         printf(
2251                 "  refine the triangulation to enforce a 25 degree minimum angle, and then\n" );
2252         printf(
2253                 "  write the refined triangulation to object.2.node and object.2.ele.\n" );
2254         printf( "\n" );
2255         printf(
2256                 "  `triangle -rpaa6.2 z.3' will read z.3.node, z.3.ele, z.3.poly, and\n" );
2257         printf(
2258                 "  z.3.area.  After reconstructing the mesh and its segments, Triangle will\n"
2259                 );
2260         printf(
2261                 "  refine the mesh so that no triangle has area greater than 6.2, and\n" );
2262         printf(
2263                 "  furthermore the triangles satisfy the maximum area constraints in\n" );
2264         printf(
2265                 "  z.3.area.  The output is written to z.4.node, z.4.ele, and z.4.poly.\n" );
2266         printf( "\n" );
2267         printf(
2268                 "  The sequence `triangle -qa1 x', `triangle -rqa.3 x.1', `triangle -rqa.1\n" );
2269         printf(
2270                 "  x.2' creates a sequence of successively finer meshes x.1, x.2, and x.3,\n" );
2271         printf( "  suitable for multigrid.\n\n" );
2272         printf( "Convex Hulls and Mesh Boundaries:\n\n" );
2273         printf(
2274                 "  If the input is a point set (rather than a PSLG), Triangle produces its\n" );
2275         printf(
2276                 "  convex hull as a by-product in the output .poly file if you use the -c\n" );
2277         printf(
2278                 "  switch.  There are faster algorithms for finding a two-dimensional convex\n"
2279                 );
2280         printf(
2281                 "  hull than triangulation, of course, but this one comes for free.  If the\n"
2282                 );
2283         printf(
2284                 "  input is an unconstrained mesh (you are using the -r switch but not the\n" );
2285         printf(
2286                 "  -p switch), Triangle produces a list of its boundary edges (including\n" );
2287         printf( "  hole boundaries) as a by-product if you use the -c switch.\n\n" );
2288         printf( "Voronoi Diagrams:\n\n" );
2289         printf(
2290                 "  The -v switch produces a Voronoi diagram, in files suffixed .v.node and\n" );
2291         printf(
2292                 "  .v.edge.  For example, `triangle -v points' will read points.node,\n" );
2293         printf(
2294                 "  produce its Delaunay triangulation in points.1.node and points.1.ele,\n" );
2295         printf(
2296                 "  and produce its Voronoi diagram in points.1.v.node and points.1.v.edge.\n" );
2297         printf(
2298                 "  The .v.node file contains a list of all Voronoi vertices, and the .v.edge\n"
2299                 );
2300         printf(
2301                 "  file contains a list of all Voronoi edges, some of which may be infinite\n"
2302                 );
2303         printf(
2304                 "  rays.  (The choice of filenames makes it easy to run the set of Voronoi\n" );
2305         printf( "  vertices through Triangle, if so desired.)\n\n" );
2306         printf(
2307                 "  This implementation does not use exact arithmetic to compute the Voronoi\n"
2308                 );
2309         printf(
2310                 "  vertices, and does not check whether neighboring vertices are identical.\n"
2311                 );
2312         printf(
2313                 "  Be forewarned that if the Delaunay triangulation is degenerate or\n" );
2314         printf(
2315                 "  near-degenerate, the Voronoi diagram may have duplicate points, crossing\n"
2316                 );
2317         printf(
2318                 "  edges, or infinite rays whose direction vector is zero.  Also, if you\n" );
2319         printf(
2320                 "  generate a constrained (as opposed to conforming) Delaunay triangulation,\n"
2321                 );
2322         printf(
2323                 "  or if the triangulation has holes, the corresponding Voronoi diagram is\n" );
2324         printf( "  likely to have crossing edges and unlikely to make sense.\n\n" );
2325         printf( "Mesh Topology:\n\n" );
2326         printf(
2327                 "  You may wish to know which triangles are adjacent to a certain Delaunay\n" );
2328         printf(
2329                 "  edge in an .edge file, which Voronoi regions are adjacent to a certain\n" );
2330         printf(
2331                 "  Voronoi edge in a .v.edge file, or which Voronoi regions are adjacent to\n"
2332                 );
2333         printf(
2334                 "  each other.  All of this information can be found by cross-referencing\n" );
2335         printf(
2336                 "  output files with the recollection that the Delaunay triangulation and\n" );
2337         printf( "  the Voronoi diagrams are planar duals.\n\n" );
2338         printf(
2339                 "  Specifically, edge i of an .edge file is the dual of Voronoi edge i of\n" );
2340         printf(
2341                 "  the corresponding .v.edge file, and is rotated 90 degrees counterclock-\n" );
2342         printf(
2343                 "  wise from the Voronoi edge.  Triangle j of an .ele file is the dual of\n" );
2344         printf(
2345                 "  vertex j of the corresponding .v.node file; and Voronoi region k is the\n" );
2346         printf( "  dual of point k of the corresponding .node file.\n\n" );
2347         printf(
2348                 "  Hence, to find the triangles adjacent to a Delaunay edge, look at the\n" );
2349         printf(
2350                 "  vertices of the corresponding Voronoi edge; their dual triangles are on\n" );
2351         printf(
2352                 "  the left and right of the Delaunay edge, respectively.  To find the\n" );
2353         printf(
2354                 "  Voronoi regions adjacent to a Voronoi edge, look at the endpoints of the\n"
2355                 );
2356         printf(
2357                 "  corresponding Delaunay edge; their dual regions are on the right and left\n"
2358                 );
2359         printf(
2360                 "  of the Voronoi edge, respectively.  To find which Voronoi regions are\n" );
2361         printf( "  adjacent to each other, just read the list of Delaunay edges.\n" );
2362         printf( "\n" );
2363         printf( "Statistics:\n" );
2364         printf( "\n" );
2365         printf(
2366                 "  After generating a mesh, Triangle prints a count of the number of points,\n"
2367                 );
2368         printf(
2369                 "  triangles, edges, boundary edges, and segments in the output mesh.  If\n" );
2370         printf(
2371                 "  you've forgotten the statistics for an existing mesh, the -rNEP switches\n"
2372                 );
2373         printf(
2374                 "  (or -rpNEP if you've got a .poly file for the existing mesh) will\n" );
2375         printf( "  regenerate these statistics without writing any output.\n\n" );
2376         printf(
2377                 "  The -V switch produces extended statistics, including a rough estimate\n" );
2378         printf(
2379                 "  of memory use and a histogram of triangle aspect ratios and angles in the\n"
2380                 );
2381         printf( "  mesh.\n\n" );
2382         printf( "Exact Arithmetic:\n\n" );
2383         printf(
2384                 "  Triangle uses adaptive exact arithmetic to perform what computational\n" );
2385         printf(
2386                 "  geometers call the `orientation' and `incircle' tests.  If the floating-\n"
2387                 );
2388         printf(
2389                 "  point arithmetic of your machine conforms to the IEEE 754 standard (as\n" );
2390         printf(
2391                 "  most workstations do), and does not use extended precision internal\n" );
2392         printf(
2393                 "  registers, then your output is guaranteed to be an absolutely true\n" );
2394         printf( "  Delaunay or conforming Delaunay triangulation, roundoff error\n" );
2395         printf(
2396                 "  notwithstanding.  The word `adaptive' implies that these arithmetic\n" );
2397         printf(
2398                 "  routines compute the result only to the precision necessary to guarantee\n"
2399                 );
2400         printf(
2401                 "  correctness, so they are usually nearly as fast as their approximate\n" );
2402         printf(
2403                 "  counterparts.  The exact tests can be disabled with the -X switch.  On\n" );
2404         printf(
2405                 "  most inputs, this switch will reduce the computation time by about eight\n"
2406                 );
2407         printf(
2408                 "  percent - it's not worth the risk.  There are rare difficult inputs\n" );
2409         printf(
2410                 "  (having many collinear and cocircular points), however, for which the\n" );
2411         printf(
2412                 "  difference could be a factor of two.  These are precisely the inputs most\n"
2413                 );
2414         printf( "  likely to cause errors if you use the -X switch.\n\n" );
2415         printf(
2416                 "  Unfortunately, these routines don't solve every numerical problem.  Exact\n"
2417                 );
2418         printf(
2419                 "  arithmetic is not used to compute the positions of points, because the\n" );
2420         printf(
2421                 "  bit complexity of point coordinates would grow without bound.  Hence,\n" );
2422         printf(
2423                 "  segment intersections aren't computed exactly; in very unusual cases,\n" );
2424         printf(
2425                 "  roundoff error in computing an intersection point might actually lead to\n"
2426                 );
2427         printf(
2428                 "  an inverted triangle and an invalid triangulation.  (This is one reason\n" );
2429         printf(
2430                 "  to compute your own intersection points in your .poly files.)  Similarly,\n"
2431                 );
2432         printf(
2433                 "  exact arithmetic is not used to compute the vertices of the Voronoi\n" );
2434         printf( "  diagram.\n\n" );
2435         printf(
2436                 "  Underflow and overflow can also cause difficulties; the exact arithmetic\n"
2437                 );
2438         printf(
2439                 "  routines do not ameliorate out-of-bounds exponents, which can arise\n" );
2440         printf(
2441                 "  during the orientation and incircle tests.  As a rule of thumb, you\n" );
2442         printf(
2443                 "  should ensure that your input values are within a range such that their\n" );
2444         printf(
2445                 "  third powers can be taken without underflow or overflow.  Underflow can\n" );
2446         printf(
2447                 "  silently prevent the tests from being performed exactly, while overflow\n" );
2448         printf( "  will typically cause a floating exception.\n\n" );
2449         printf( "Calling Triangle from Another Program:\n\n" );
2450         printf( "  Read the file triangle.h for details.\n\n" );
2451         printf( "Troubleshooting:\n\n" );
2452         printf( "  Please read this section before mailing me bugs.\n\n" );
2453         printf( "  `My output mesh has no triangles!'\n\n" );
2454         printf(
2455                 "    If you're using a PSLG, you've probably failed to specify a proper set\n"
2456                 );
2457         printf(
2458                 "    of bounding segments, or forgotten to use the -c switch.  Or you may\n" );
2459         printf(
2460                 "    have placed a hole badly.  To test these possibilities, try again with\n"
2461                 );
2462         printf(
2463                 "    the -c and -O switches.  Alternatively, all your input points may be\n" );
2464         printf(
2465                 "    collinear, in which case you can hardly expect to triangulate them.\n" );
2466         printf( "\n" );
2467         printf( "  `Triangle doesn't terminate, or just crashes.'\n" );
2468         printf( "\n" );
2469         printf(
2470                 "    Bad things can happen when triangles get so small that the distance\n" );
2471         printf(
2472                 "    between their vertices isn't much larger than the precision of your\n" );
2473         printf(
2474                 "    machine's arithmetic.  If you've compiled Triangle for single-precision\n"
2475                 );
2476         printf(
2477                 "    arithmetic, you might do better by recompiling it for double-precision.\n"
2478                 );
2479         printf(
2480                 "    Then again, you might just have to settle for more lenient constraints\n"
2481                 );
2482         printf(
2483                 "    on the minimum angle and the maximum area than you had planned.\n" );
2484         printf( "\n" );
2485         printf(
2486                 "    You can minimize precision problems by ensuring that the origin lies\n" );
2487         printf(
2488                 "    inside your point set, or even inside the densest part of your\n" );
2489         printf(
2490                 "    mesh.  On the other hand, if you're triangulating an object whose x\n" );
2491         printf(
2492                 "    coordinates all fall between 6247133 and 6247134, you're not leaving\n" );
2493         printf( "    much floating-point precision for Triangle to work with.\n\n" );
2494         printf(
2495                 "    Precision problems can occur covertly if the input PSLG contains two\n" );
2496         printf(
2497                 "    segments that meet (or intersect) at a very small angle, or if such an\n"
2498                 );
2499         printf(
2500                 "    angle is introduced by the -c switch, which may occur if a point lies\n" );
2501         printf(
2502                 "    ever-so-slightly inside the convex hull, and is connected by a PSLG\n" );
2503         printf(
2504                 "    segment to a point on the convex hull.  If you don't realize that a\n" );
2505         printf(
2506                 "    small angle is being formed, you might never discover why Triangle is\n" );
2507         printf(
2508                 "    crashing.  To check for this possibility, use the -S switch (with an\n" );
2509         printf(
2510                 "    appropriate limit on the number of Steiner points, found by trial-and-\n"
2511                 );
2512         printf(
2513                 "    error) to stop Triangle early, and view the output .poly file with\n" );
2514         printf(
2515                 "    Show Me (described below).  Look carefully for small angles between\n" );
2516         printf(
2517                 "    segments; zoom in closely, as such segments might look like a single\n" );
2518         printf( "    segment from a distance.\n\n" );
2519         printf(
2520                 "    If some of the input values are too large, Triangle may suffer a\n" );
2521         printf(
2522                 "    floating exception due to overflow when attempting to perform an\n" );
2523         printf(
2524                 "    orientation or incircle test.  (Read the section on exact arithmetic\n" );
2525         printf(
2526                 "    above.)  Again, I recommend compiling Triangle for double (rather\n" );
2527         printf( "    than single) precision arithmetic.\n\n" );
2528         printf(
2529                 "  `The numbering of the output points doesn't match the input points.'\n" );
2530         printf( "\n" );
2531         printf(
2532                 "    You may have eaten some of your input points with a hole, or by placing\n"
2533                 );
2534         printf( "    them outside the area enclosed by segments.\n\n" );
2535         printf(
2536                 "  `Triangle executes without incident, but when I look at the resulting\n" );
2537         printf(
2538                 "  mesh, it has overlapping triangles or other geometric inconsistencies.'\n" );
2539         printf( "\n" );
2540         printf(
2541                 "    If you select the -X switch, Triangle's divide-and-conquer Delaunay\n" );
2542         printf(
2543                 "    triangulation algorithm occasionally makes mistakes due to floating-\n" );
2544         printf(
2545                 "    point roundoff error.  Although these errors are rare, don't use the -X\n"
2546                 );
2547         printf( "    switch.  If you still have problems, please report the bug.\n" );
2548         printf( "\n" );
2549         printf(
2550                 "  Strange things can happen if you've taken liberties with your PSLG.  Do\n" );
2551         printf(
2552                 "  you have a point lying in the middle of a segment?  Triangle sometimes\n" );
2553         printf(
2554                 "  copes poorly with that sort of thing.  Do you want to lay out a collinear\n"
2555                 );
2556         printf(
2557                 "  row of evenly spaced, segment-connected points?  Have you simply defined\n"
2558                 );
2559         printf(
2560                 "  one long segment connecting the leftmost point to the rightmost point,\n" );
2561         printf(
2562                 "  and a bunch of points lying along it?  This method occasionally works,\n" );
2563         printf(
2564                 "  especially with horizontal and vertical lines, but often it doesn't, and\n"
2565                 );
2566         printf(
2567                 "  you'll have to connect each adjacent pair of points with a separate\n" );
2568         printf( "  segment.  If you don't like it, tough.\n\n" );
2569         printf(
2570                 "  Furthermore, if you have segments that intersect other than at their\n" );
2571         printf(
2572                 "  endpoints, try not to let the intersections fall extremely close to PSLG\n"
2573                 );
2574         printf( "  points or each other.\n\n" );
2575         printf(
2576                 "  If you have problems refining a triangulation not produced by Triangle:\n" );
2577         printf(
2578                 "  Are you sure the triangulation is geometrically valid?  Is it formatted\n" );
2579         printf(
2580                 "  correctly for Triangle?  Are the triangles all listed so the first three\n"
2581                 );
2582         printf( "  points are their corners in counterclockwise order?\n\n" );
2583         printf( "Show Me:\n\n" );
2584         printf(
2585                 "  Triangle comes with a separate program named `Show Me', whose primary\n" );
2586         printf(
2587                 "  purpose is to draw meshes on your screen or in PostScript.  Its secondary\n"
2588                 );
2589         printf(
2590                 "  purpose is to check the validity of your input files, and do so more\n" );
2591         printf(
2592                 "  thoroughly than Triangle does.  Show Me requires that you have the X\n" );
2593         printf(
2594                 "  Windows system.  If you didn't receive Show Me with Triangle, complain to\n"
2595                 );
2596         printf( "  whomever you obtained Triangle from, then send me mail.\n\n" );
2597         printf( "Triangle on the Web:\n\n" );
2598         printf(
2599                 "  To see an illustrated, updated version of these instructions, check out\n" );
2600         printf( "\n" );
2601         printf( "    http://www.cs.cmu.edu/~quake/triangle.html\n" );
2602         printf( "\n" );
2603         printf( "A Brief Plea:\n" );
2604         printf( "\n" );
2605         printf(
2606                 "  If you use Triangle, and especially if you use it to accomplish real\n" );
2607         printf(
2608                 "  work, I would like very much to hear from you.  A short letter or email\n" );
2609         printf(
2610                 "  (to jrs@cs.cmu.edu) describing how you use Triangle will mean a lot to\n" );
2611         printf(
2612                 "  me.  The more people I know are using this program, the more easily I can\n"
2613                 );
2614         printf(
2615                 "  justify spending time on improvements and on the three-dimensional\n" );
2616         printf(
2617                 "  successor to Triangle, which in turn will benefit you.  Also, I can put\n" );
2618         printf(
2619                 "  you on a list to receive email whenever a new version of Triangle is\n" );
2620         printf( "  available.\n\n" );
2621         printf(
2622                 "  If you use a mesh generated by Triangle in a publication, please include\n"
2623                 );
2624         printf( "  an acknowledgment as well.\n\n" );
2625         printf( "Research credit:\n\n" );
2626         printf(
2627                 "  Of course, I can take credit for only a fraction of the ideas that made\n" );
2628         printf(
2629                 "  this mesh generator possible.  Triangle owes its existence to the efforts\n"
2630                 );
2631         printf(
2632                 "  of many fine computational geometers and other researchers, including\n" );
2633         printf(
2634                 "  Marshall Bern, L. Paul Chew, Boris Delaunay, Rex A. Dwyer, David\n" );
2635         printf(
2636                 "  Eppstein, Steven Fortune, Leonidas J. Guibas, Donald E. Knuth, C. L.\n" );
2637         printf(
2638                 "  Lawson, Der-Tsai Lee, Ernst P. Mucke, Douglas M. Priest, Jim Ruppert,\n" );
2639         printf(
2640                 "  Isaac Saias, Bruce J. Schachter, Micha Sharir, Jorge Stolfi, Christopher\n"
2641                 );
2642         printf(
2643                 "  J. Van Wyk, David F. Watson, and Binhai Zhu.  See the comments at the\n" );
2644         printf( "  beginning of the source code for references.\n\n" );
2645         exit( 0 );
2646 }
2647
2648 #endif /* not TRILIBRARY */
2649
2650 /*****************************************************************************/
2651 /*                                                                           */
2652 /*  internalerror()   Ask the user to send me the defective product.  Exit.  */
2653 /*                                                                           */
2654 /*****************************************************************************/
2655
2656 void internalerror(){
2657         printf( "  Please report this bug to jrs@cs.cmu.edu\n" );
2658         printf( "  Include the message above, your input data set, and the exact\n" );
2659         printf( "    command line you used to run Triangle.\n" );
2660         exit( 1 );
2661 }
2662
2663 /*****************************************************************************/
2664 /*                                                                           */
2665 /*  parsecommandline()   Read the command line, identify switches, and set   */
2666 /*                       up options and file names.                          */
2667 /*                                                                           */
2668 /*  The effects of this routine are felt entirely through global variables.  */
2669 /*                                                                           */
2670 /*****************************************************************************/
2671
2672 void parsecommandline( argc, argv )
2673 int argc;
2674 char **argv;
2675 {
2676 #ifdef TRILIBRARY
2677 #define STARTINDEX 0
2678 #else /* not TRILIBRARY */
2679 #define STARTINDEX 1
2680         int increment;
2681         int meshnumber;
2682 #endif /* not TRILIBRARY */
2683         int i, j;
2684 #ifndef CDT_ONLY
2685         int k;
2686         char workstring[FILENAMESIZE];
2687 #endif
2688
2689         poly = refine = quality = vararea = fixedarea = regionattrib = convex = 0;
2690         firstnumber = 1;
2691         edgesout = voronoi = neighbors = geomview = 0;
2692         nobound = nopolywritten = nonodewritten = noelewritten = noiterationnum = 0;
2693         noholes = noexact = 0;
2694         incremental = sweepline = 0;
2695         dwyer = 1;
2696         splitseg = 0;
2697         docheck = 0;
2698         nobisect = 0;
2699         steiner = -1;
2700         order = 1;
2701         minangle = 0.0;
2702         maxarea = -1.0;
2703         quiet = verbose = 0;
2704 #ifndef TRILIBRARY
2705         innodefilename[0] = '\0';
2706 #endif /* not TRILIBRARY */
2707
2708         for ( i = STARTINDEX; i < argc; i++ ) {
2709 #ifndef TRILIBRARY
2710                 if ( argv[i][0] == '-' ) {
2711 #endif /* not TRILIBRARY */
2712                 for ( j = STARTINDEX; argv[i][j] != '\0'; j++ ) {
2713                         if ( argv[i][j] == 'p' ) {
2714                                 poly = 1;
2715                         }
2716 #ifndef CDT_ONLY
2717                         if ( argv[i][j] == 'r' ) {
2718                                 refine = 1;
2719                         }
2720                         if ( argv[i][j] == 'q' ) {
2721                                 quality = 1;
2722                                 if ( ( ( argv[i][j + 1] >= '0' ) && ( argv[i][j + 1] <= '9' ) ) ||
2723                                          ( argv[i][j + 1] == '.' ) ) {
2724                                         k = 0;
2725                                         while ( ( ( argv[i][j + 1] >= '0' ) && ( argv[i][j + 1] <= '9' ) ) ||
2726                                                         ( argv[i][j + 1] == '.' ) ) {
2727                                                 j++;
2728                                                 workstring[k] = argv[i][j];
2729                                                 k++;
2730                                         }
2731                                         workstring[k] = '\0';
2732                                         minangle = (REAL) strtod( workstring, (char **) NULL );
2733                                 }
2734                                 else {
2735                                         minangle = 20.0;
2736                                 }
2737                         }
2738                         if ( argv[i][j] == 'a' ) {
2739                                 quality = 1;
2740                                 if ( ( ( argv[i][j + 1] >= '0' ) && ( argv[i][j + 1] <= '9' ) ) ||
2741                                          ( argv[i][j + 1] == '.' ) ) {
2742                                         fixedarea = 1;
2743                                         k = 0;
2744                                         while ( ( ( argv[i][j + 1] >= '0' ) && ( argv[i][j + 1] <= '9' ) ) ||
2745                                                         ( argv[i][j + 1] == '.' ) ) {
2746                                                 j++;
2747                                                 workstring[k] = argv[i][j];
2748                                                 k++;
2749                                         }
2750                                         workstring[k] = '\0';
2751                                         maxarea = (REAL) strtod( workstring, (char **) NULL );
2752                                         if ( maxarea <= 0.0 ) {
2753                                                 printf( "Error:  Maximum area must be greater than zero.\n" );
2754                                                 exit( 1 );
2755                                         }
2756                                 }
2757                                 else {
2758                                         vararea = 1;
2759                                 }
2760                         }
2761 #endif /* not CDT_ONLY */
2762                         if ( argv[i][j] == 'A' ) {
2763                                 regionattrib = 1;
2764                         }
2765                         if ( argv[i][j] == 'c' ) {
2766                                 convex = 1;
2767                         }
2768                         if ( argv[i][j] == 'z' ) {
2769                                 firstnumber = 0;
2770                         }
2771                         if ( argv[i][j] == 'e' ) {
2772                                 edgesout = 1;
2773                         }
2774                         if ( argv[i][j] == 'v' ) {
2775                                 voronoi = 1;
2776                         }
2777                         if ( argv[i][j] == 'n' ) {
2778                                 neighbors = 1;
2779                         }
2780                         if ( argv[i][j] == 'g' ) {
2781                                 geomview = 1;
2782                         }
2783                         if ( argv[i][j] == 'B' ) {
2784                                 nobound = 1;
2785                         }
2786                         if ( argv[i][j] == 'P' ) {
2787                                 nopolywritten = 1;
2788                         }
2789                         if ( argv[i][j] == 'N' ) {
2790                                 nonodewritten = 1;
2791                         }
2792                         if ( argv[i][j] == 'E' ) {
2793                                 noelewritten = 1;
2794                         }
2795 #ifndef TRILIBRARY
2796                         if ( argv[i][j] == 'I' ) {
2797                                 noiterationnum = 1;
2798                         }
2799 #endif /* not TRILIBRARY */
2800                         if ( argv[i][j] == 'O' ) {
2801                                 noholes = 1;
2802                         }
2803                         if ( argv[i][j] == 'X' ) {
2804                                 noexact = 1;
2805                         }
2806                         if ( argv[i][j] == 'o' ) {
2807                                 if ( argv[i][j + 1] == '2' ) {
2808                                         j++;
2809                                         order = 2;
2810                                 }
2811                         }
2812 #ifndef CDT_ONLY
2813                         if ( argv[i][j] == 'Y' ) {
2814                                 nobisect++;
2815                         }
2816                         if ( argv[i][j] == 'S' ) {
2817                                 steiner = 0;
2818                                 while ( ( argv[i][j + 1] >= '0' ) && ( argv[i][j + 1] <= '9' ) ) {
2819                                         j++;
2820                                         steiner = steiner * 10 + (int) ( argv[i][j] - '0' );
2821                                 }
2822                         }
2823 #endif /* not CDT_ONLY */
2824 #ifndef REDUCED
2825                         if ( argv[i][j] == 'i' ) {
2826                                 incremental = 1;
2827                         }
2828                         if ( argv[i][j] == 'F' ) {
2829                                 sweepline = 1;
2830                         }
2831 #endif /* not REDUCED */
2832                         if ( argv[i][j] == 'l' ) {
2833                                 dwyer = 0;
2834                         }
2835 #ifndef REDUCED
2836 #ifndef CDT_ONLY
2837                         if ( argv[i][j] == 's' ) {
2838                                 splitseg = 1;
2839                         }
2840 #endif /* not CDT_ONLY */
2841                         if ( argv[i][j] == 'C' ) {
2842                                 docheck = 1;
2843                         }
2844 #endif /* not REDUCED */
2845                         if ( argv[i][j] == 'Q' ) {
2846                                 quiet = 1;
2847                         }
2848                         if ( argv[i][j] == 'V' ) {
2849                                 verbose++;
2850                         }
2851 #ifndef TRILIBRARY
2852                         if ( ( argv[i][j] == 'h' ) || ( argv[i][j] == 'H' ) ||
2853                                  ( argv[i][j] == '?' ) ) {
2854                                 info();
2855                         }
2856 #endif /* not TRILIBRARY */
2857                 }
2858 #ifndef TRILIBRARY
2859         } else {
2860                 strncpy( innodefilename, argv[i], FILENAMESIZE - 1 );
2861                 innodefilename[FILENAMESIZE - 1] = '\0';
2862         }
2863 #endif /* not TRILIBRARY */
2864         }
2865 #ifndef TRILIBRARY
2866         if ( innodefilename[0] == '\0' ) {
2867                 syntax();
2868         }
2869         if ( !strcmp( &innodefilename[strlen( innodefilename ) - 5], ".node" ) ) {
2870                 innodefilename[strlen( innodefilename ) - 5] = '\0';
2871         }
2872         if ( !strcmp( &innodefilename[strlen( innodefilename ) - 5], ".poly" ) ) {
2873                 innodefilename[strlen( innodefilename ) - 5] = '\0';
2874                 poly = 1;
2875         }
2876 #ifndef CDT_ONLY
2877         if ( !strcmp( &innodefilename[strlen( innodefilename ) - 4], ".ele" ) ) {
2878                 innodefilename[strlen( innodefilename ) - 4] = '\0';
2879                 refine = 1;
2880         }
2881         if ( !strcmp( &innodefilename[strlen( innodefilename ) - 5], ".area" ) ) {
2882                 innodefilename[strlen( innodefilename ) - 5] = '\0';
2883                 refine = 1;
2884                 quality = 1;
2885                 vararea = 1;
2886         }
2887 #endif /* not CDT_ONLY */
2888 #endif /* not TRILIBRARY */
2889         steinerleft = steiner;
2890         useshelles = poly || refine || quality || convex;
2891         goodangle = (REAL)cos( minangle * PI / 180.0 );
2892         goodangle *= goodangle;
2893         if ( refine && noiterationnum ) {
2894                 printf(
2895                         "Error:  You cannot use the -I switch when refining a triangulation.\n" );
2896                 exit( 1 );
2897         }
2898         /* Be careful not to allocate space for element area constraints that */
2899         /*   will never be assigned any value (other than the default -1.0).  */
2900         if ( !refine && !poly ) {
2901                 vararea = 0;
2902         }
2903         /* Be careful not to add an extra attribute to each element unless the */
2904         /*   input supports it (PSLG in, but not refining a preexisting mesh). */
2905         if ( refine || !poly ) {
2906                 regionattrib = 0;
2907         }
2908
2909 #ifndef TRILIBRARY
2910         strcpy( inpolyfilename, innodefilename );
2911         strcpy( inelefilename, innodefilename );
2912         strcpy( areafilename, innodefilename );
2913         increment = 0;
2914         strcpy( workstring, innodefilename );
2915         j = 1;
2916         while ( workstring[j] != '\0' ) {
2917                 if ( ( workstring[j] == '.' ) && ( workstring[j + 1] != '\0' ) ) {
2918                         increment = j + 1;
2919                 }
2920                 j++;
2921         }
2922         meshnumber = 0;
2923         if ( increment > 0 ) {
2924                 j = increment;
2925                 do {
2926                         if ( ( workstring[j] >= '0' ) && ( workstring[j] <= '9' ) ) {
2927                                 meshnumber = meshnumber * 10 + (int) ( workstring[j] - '0' );
2928                         }
2929                         else {
2930                                 increment = 0;
2931                         }
2932                         j++;
2933                 } while ( workstring[j] != '\0' );
2934         }
2935         if ( noiterationnum ) {
2936                 strcpy( outnodefilename, innodefilename );
2937                 strcpy( outelefilename, innodefilename );
2938                 strcpy( edgefilename, innodefilename );
2939                 strcpy( vnodefilename, innodefilename );
2940                 strcpy( vedgefilename, innodefilename );
2941                 strcpy( neighborfilename, innodefilename );
2942                 strcpy( offfilename, innodefilename );
2943                 strcat( outnodefilename, ".node" );
2944                 strcat( outelefilename, ".ele" );
2945                 strcat( edgefilename, ".edge" );
2946                 strcat( vnodefilename, ".v.node" );
2947                 strcat( vedgefilename, ".v.edge" );
2948                 strcat( neighborfilename, ".neigh" );
2949                 strcat( offfilename, ".off" );
2950         }
2951         else if ( increment == 0 ) {
2952                 strcpy( outnodefilename, innodefilename );
2953                 strcpy( outpolyfilename, innodefilename );
2954                 strcpy( outelefilename, innodefilename );
2955                 strcpy( edgefilename, innodefilename );
2956                 strcpy( vnodefilename, innodefilename );
2957                 strcpy( vedgefilename, innodefilename );
2958                 strcpy( neighborfilename, innodefilename );
2959                 strcpy( offfilename, innodefilename );
2960                 strcat( outnodefilename, ".1.node" );
2961                 strcat( outpolyfilename, ".1.poly" );
2962                 strcat( outelefilename, ".1.ele" );
2963                 strcat( edgefilename, ".1.edge" );
2964                 strcat( vnodefilename, ".1.v.node" );
2965                 strcat( vedgefilename, ".1.v.edge" );
2966                 strcat( neighborfilename, ".1.neigh" );
2967                 strcat( offfilename, ".1.off" );
2968         }
2969         else {
2970                 workstring[increment] = '%';
2971                 workstring[increment + 1] = 'd';
2972                 workstring[increment + 2] = '\0';
2973                 sprintf( outnodefilename, workstring, meshnumber + 1 );
2974                 strcpy( outpolyfilename, outnodefilename );
2975                 strcpy( outelefilename, outnodefilename );
2976                 strcpy( edgefilename, outnodefilename );
2977                 strcpy( vnodefilename, outnodefilename );
2978                 strcpy( vedgefilename, outnodefilename );
2979                 strcpy( neighborfilename, outnodefilename );
2980                 strcpy( offfilename, outnodefilename );
2981                 strcat( outnodefilename, ".node" );
2982                 strcat( outpolyfilename, ".poly" );
2983                 strcat( outelefilename, ".ele" );
2984                 strcat( edgefilename, ".edge" );
2985                 strcat( vnodefilename, ".v.node" );
2986                 strcat( vedgefilename, ".v.edge" );
2987                 strcat( neighborfilename, ".neigh" );
2988                 strcat( offfilename, ".off" );
2989         }
2990         strcat( innodefilename, ".node" );
2991         strcat( inpolyfilename, ".poly" );
2992         strcat( inelefilename, ".ele" );
2993         strcat( areafilename, ".area" );
2994 #endif /* not TRILIBRARY */
2995 }
2996
2997 /**                                                                         **/
2998 /**                                                                         **/
2999 /********* User interaction routines begin here                      *********/
3000
3001 /********* Debugging routines begin here                             *********/
3002 /**                                                                         **/
3003 /**                                                                         **/
3004
3005 /*****************************************************************************/
3006 /*                                                                           */
3007 /*  printtriangle()   Print out the details of a triangle/edge handle.       */
3008 /*                                                                           */
3009 /*  I originally wrote this procedure to simplify debugging; it can be       */
3010 /*  called directly from the debugger, and presents information about a      */
3011 /*  triangle/edge handle in digestible form.  It's also used when the        */
3012 /*  highest level of verbosity (`-VVV') is specified.                        */
3013 /*                                                                           */
3014 /*****************************************************************************/
3015
3016 void printtriangle( t )
3017 struct triedge *t;
3018 {
3019         struct triedge printtri;
3020         struct edge printsh;
3021         point printpoint;
3022
3023         printf( "triangle x%lx with orientation %d:\n", (unsigned long) t->tri,
3024                         t->orient );
3025         decode( t->tri[0], printtri );
3026         if ( printtri.tri == dummytri ) {
3027                 printf( "    [0] = Outer space\n" );
3028         }
3029         else {
3030                 printf( "    [0] = x%lx  %d\n", (unsigned long) printtri.tri,
3031                                 printtri.orient );
3032         }
3033         decode( t->tri[1], printtri );
3034         if ( printtri.tri == dummytri ) {
3035                 printf( "    [1] = Outer space\n" );
3036         }
3037         else {
3038                 printf( "    [1] = x%lx  %d\n", (unsigned long) printtri.tri,
3039                                 printtri.orient );
3040         }
3041         decode( t->tri[2], printtri );
3042         if ( printtri.tri == dummytri ) {
3043                 printf( "    [2] = Outer space\n" );
3044         }
3045         else {
3046                 printf( "    [2] = x%lx  %d\n", (unsigned long) printtri.tri,
3047                                 printtri.orient );
3048         }
3049         org( *t, printpoint );
3050         if ( printpoint == (point) NULL ) {
3051                 printf( "    Origin[%d] = NULL\n", ( t->orient + 1 ) % 3 + 3 );
3052         }
3053         else{
3054                 printf( "    Origin[%d] = x%lx  (%.12g, %.12g)\n",
3055                                 ( t->orient + 1 ) % 3 + 3, (unsigned long) printpoint,
3056                                 printpoint[0], printpoint[1] );
3057         }
3058         dest( *t, printpoint );
3059         if ( printpoint == (point) NULL ) {
3060                 printf( "    Dest  [%d] = NULL\n", ( t->orient + 2 ) % 3 + 3 );
3061         }
3062         else{
3063                 printf( "    Dest  [%d] = x%lx  (%.12g, %.12g)\n",
3064                                 ( t->orient + 2 ) % 3 + 3, (unsigned long) printpoint,
3065                                 printpoint[0], printpoint[1] );
3066         }
3067         apex( *t, printpoint );
3068         if ( printpoint == (point) NULL ) {
3069                 printf( "    Apex  [%d] = NULL\n", t->orient + 3 );
3070         }
3071         else{
3072                 printf( "    Apex  [%d] = x%lx  (%.12g, %.12g)\n",
3073                                 t->orient + 3, (unsigned long) printpoint,
3074                                 printpoint[0], printpoint[1] );
3075         }
3076         if ( useshelles ) {
3077                 sdecode( t->tri[6], printsh );
3078                 if ( printsh.sh != dummysh ) {
3079                         printf( "    [6] = x%lx  %d\n", (unsigned long) printsh.sh,
3080                                         printsh.shorient );
3081                 }
3082                 sdecode( t->tri[7], printsh );
3083                 if ( printsh.sh != dummysh ) {
3084                         printf( "    [7] = x%lx  %d\n", (unsigned long) printsh.sh,
3085                                         printsh.shorient );
3086                 }
3087                 sdecode( t->tri[8], printsh );
3088                 if ( printsh.sh != dummysh ) {
3089                         printf( "    [8] = x%lx  %d\n", (unsigned long) printsh.sh,
3090                                         printsh.shorient );
3091                 }
3092         }
3093         if ( vararea ) {
3094                 printf( "    Area constraint:  %.4g\n", areabound( *t ) );
3095         }
3096 }
3097
3098 /*****************************************************************************/
3099 /*                                                                           */
3100 /*  printshelle()   Print out the details of a shell edge handle.            */
3101 /*                                                                           */
3102 /*  I originally wrote this procedure to simplify debugging; it can be       */
3103 /*  called directly from the debugger, and presents information about a      */
3104 /*  shell edge handle in digestible form.  It's also used when the highest   */
3105 /*  level of verbosity (`-VVV') is specified.                                */
3106 /*                                                                           */
3107 /*****************************************************************************/
3108
3109 void printshelle( s )
3110 struct edge *s;
3111 {
3112         struct edge printsh;
3113         struct triedge printtri;
3114         point printpoint;
3115
3116         printf( "shell edge x%lx with orientation %d and mark %d:\n",
3117                         (unsigned long) s->sh, s->shorient, mark( *s ) );
3118         sdecode( s->sh[0], printsh );
3119         if ( printsh.sh == dummysh ) {
3120                 printf( "    [0] = No shell\n" );
3121         }
3122         else {
3123                 printf( "    [0] = x%lx  %d\n", (unsigned long) printsh.sh,
3124                                 printsh.shorient );
3125         }
3126         sdecode( s->sh[1], printsh );
3127         if ( printsh.sh == dummysh ) {
3128                 printf( "    [1] = No shell\n" );
3129         }
3130         else {
3131                 printf( "    [1] = x%lx  %d\n", (unsigned long) printsh.sh,
3132                                 printsh.shorient );
3133         }
3134         sorg( *s, printpoint );
3135         if ( printpoint == (point) NULL ) {
3136                 printf( "    Origin[%d] = NULL\n", 2 + s->shorient );
3137         }
3138         else{
3139                 printf( "    Origin[%d] = x%lx  (%.12g, %.12g)\n",
3140                                 2 + s->shorient, (unsigned long) printpoint,
3141                                 printpoint[0], printpoint[1] );
3142         }
3143         sdest( *s, printpoint );
3144         if ( printpoint == (point) NULL ) {
3145                 printf( "    Dest  [%d] = NULL\n", 3 - s->shorient );
3146         }
3147         else{
3148                 printf( "    Dest  [%d] = x%lx  (%.12g, %.12g)\n",
3149                                 3 - s->shorient, (unsigned long) printpoint,
3150                                 printpoint[0], printpoint[1] );
3151         }
3152         decode( s->sh[4], printtri );
3153         if ( printtri.tri == dummytri ) {
3154                 printf( "    [4] = Outer space\n" );
3155         }
3156         else {
3157                 printf( "    [4] = x%lx  %d\n", (unsigned long) printtri.tri,
3158                                 printtri.orient );
3159         }
3160         decode( s->sh[5], printtri );
3161         if ( printtri.tri == dummytri ) {
3162                 printf( "    [5] = Outer space\n" );
3163         }
3164         else {
3165                 printf( "    [5] = x%lx  %d\n", (unsigned long) printtri.tri,
3166                                 printtri.orient );
3167         }
3168 }
3169
3170 /**                                                                         **/
3171 /**                                                                         **/
3172 /********* Debugging routines end here                               *********/
3173
3174 /********* Memory management routines begin here                     *********/
3175 /**                                                                         **/
3176 /**                                                                         **/
3177
3178 /*****************************************************************************/
3179 /*                                                                           */
3180 /*  poolinit()   Initialize a pool of memory for allocation of items.        */
3181 /*                                                                           */
3182 /*  This routine initializes the machinery for allocating items.  A `pool'   */
3183 /*  is created whose records have size at least `bytecount'.  Items will be  */
3184 /*  allocated in `itemcount'-item blocks.  Each item is assumed to be a      */
3185 /*  collection of words, and either pointers or floating-point values are    */
3186 /*  assumed to be the "primary" word type.  (The "primary" word type is used */
3187 /*  to determine alignment of items.)  If `alignment' isn't zero, all items  */
3188 /*  will be `alignment'-byte aligned in memory.  `alignment' must be either  */
3189 /*  a multiple or a factor of the primary word size; powers of two are safe. */
3190 /*  `alignment' is normally used to create a few unused bits at the bottom   */
3191 /*  of each item's pointer, in which information may be stored.              */
3192 /*                                                                           */
3193 /*  Don't change this routine unless you understand it.                      */
3194 /*                                                                           */
3195 /*****************************************************************************/
3196
3197 void poolinit( pool, bytecount, itemcount, wtype, alignment )
3198 struct memorypool *pool;
3199 int bytecount;
3200 int itemcount;
3201 enum wordtype wtype;
3202 int alignment;
3203 {
3204         int wordsize;
3205
3206         /* Initialize values in the pool. */
3207         pool->itemwordtype = wtype;
3208         wordsize = ( pool->itemwordtype == POINTER ) ? sizeof( VOID * ) : sizeof( REAL );
3209         /* Find the proper alignment, which must be at least as large as:   */
3210         /*   - The parameter `alignment'.                                   */
3211         /*   - The primary word type, to avoid unaligned accesses.          */
3212         /*   - sizeof(VOID *), so the stack of dead items can be maintained */
3213         /*       without unaligned accesses.                                */
3214         if ( alignment > wordsize ) {
3215                 pool->alignbytes = alignment;
3216         }
3217         else {
3218                 pool->alignbytes = wordsize;
3219         }
3220         if ( sizeof( VOID * ) > pool->alignbytes ) {
3221                 pool->alignbytes = sizeof( VOID * );
3222         }
3223         pool->itemwords = ( ( bytecount + pool->alignbytes - 1 ) / pool->alignbytes )
3224                                           * ( pool->alignbytes / wordsize );
3225         pool->itembytes = pool->itemwords * wordsize;
3226         pool->itemsperblock = itemcount;
3227
3228         /* Allocate a block of items.  Space for `itemsperblock' items and one    */
3229         /*   pointer (to point to the next block) are allocated, as well as space */
3230         /*   to ensure alignment of the items.                                    */
3231         pool->firstblock = (VOID **) malloc( pool->itemsperblock * pool->itembytes
3232                                                                                  + sizeof( VOID * ) + pool->alignbytes );
3233         if ( pool->firstblock == (VOID **) NULL ) {
3234                 printf( "Error:  Out of memory.\n" );
3235                 exit( 1 );
3236         }
3237         /* Set the next block pointer to NULL. */
3238         *( pool->firstblock ) = (VOID *) NULL;
3239         poolrestart( pool );
3240 }
3241
3242 /*****************************************************************************/
3243 /*                                                                           */
3244 /*  poolrestart()   Deallocate all items in a pool.                          */
3245 /*                                                                           */
3246 /*  The pool is returned to its starting state, except that no memory is     */
3247 /*  freed to the operating system.  Rather, the previously allocated blocks  */
3248 /*  are ready to be reused.                                                  */
3249 /*                                                                           */
3250 /*****************************************************************************/
3251
3252 void poolrestart( pool )
3253 struct memorypool *pool;
3254 {
3255         unsigned long alignptr;
3256
3257         pool->items = 0;
3258         pool->maxitems = 0;
3259
3260         /* Set the currently active block. */
3261         pool->nowblock = pool->firstblock;
3262         /* Find the first item in the pool.  Increment by the size of (VOID *). */
3263         alignptr = (unsigned long) ( pool->nowblock + 1 );
3264         /* Align the item on an `alignbytes'-byte boundary. */
3265         pool->nextitem = (VOID *)
3266                                          ( alignptr + (unsigned long) pool->alignbytes
3267                                            - ( alignptr % (unsigned long) pool->alignbytes ) );
3268         /* There are lots of unallocated items left in this block. */
3269         pool->unallocateditems = pool->itemsperblock;
3270         /* The stack of deallocated items is empty. */
3271         pool->deaditemstack = (VOID *) NULL;
3272 }
3273
3274 /*****************************************************************************/
3275 /*                                                                           */
3276 /*  pooldeinit()   Free to the operating system all memory taken by a pool.  */
3277 /*                                                                           */
3278 /*****************************************************************************/
3279
3280 void pooldeinit( pool )
3281 struct memorypool *pool;
3282 {
3283         while ( pool->firstblock != (VOID **) NULL ) {
3284                 pool->nowblock = (VOID **) *( pool->firstblock );
3285                 free( pool->firstblock );
3286                 pool->firstblock = pool->nowblock;
3287         }
3288 }
3289
3290 /*****************************************************************************/
3291 /*                                                                           */
3292 /*  poolalloc()   Allocate space for an item.                                */
3293 /*                                                                           */
3294 /*****************************************************************************/
3295
3296 VOID *poolalloc( pool )
3297 struct memorypool *pool;
3298 {
3299         VOID *newitem;
3300         VOID **newblock;
3301         unsigned long alignptr;
3302
3303         /* First check the linked list of dead items.  If the list is not   */
3304         /*   empty, allocate an item from the list rather than a fresh one. */
3305         if ( pool->deaditemstack != (VOID *) NULL ) {
3306                 newitem = pool->deaditemstack;           /* Take first item in list. */
3307                 pool->deaditemstack = *(VOID **) pool->deaditemstack;
3308         }
3309         else {
3310                 /* Check if there are any free items left in the current block. */
3311                 if ( pool->unallocateditems == 0 ) {
3312                         /* Check if another block must be allocated. */
3313                         if ( *( pool->nowblock ) == (VOID *) NULL ) {
3314                                 /* Allocate a new block of items, pointed to by the previous block. */
3315                                 newblock = (VOID **) malloc( pool->itemsperblock * pool->itembytes
3316                                                                                          + sizeof( VOID * ) + pool->alignbytes );
3317                                 if ( newblock == (VOID **) NULL ) {
3318                                         printf( "Error:  Out of memory.\n" );
3319                                         exit( 1 );
3320                                 }
3321                                 *( pool->nowblock ) = (VOID *) newblock;
3322                                 /* The next block pointer is NULL. */
3323                                 *newblock = (VOID *) NULL;
3324                         }
3325                         /* Move to the new block. */
3326                         pool->nowblock = (VOID **) *( pool->nowblock );
3327                         /* Find the first item in the block.    */
3328                         /*   Increment by the size of (VOID *). */
3329                         alignptr = (unsigned long) ( pool->nowblock + 1 );
3330                         /* Align the item on an `alignbytes'-byte boundary. */
3331                         pool->nextitem = (VOID *)
3332                                                          ( alignptr + (unsigned long) pool->alignbytes
3333                                                            - ( alignptr % (unsigned long) pool->alignbytes ) );
3334                         /* There are lots of unallocated items left in this block. */
3335                         pool->unallocateditems = pool->itemsperblock;
3336                 }
3337                 /* Allocate a new item. */
3338                 newitem = pool->nextitem;
3339                 /* Advance `nextitem' pointer to next free item in block. */
3340                 if ( pool->itemwordtype == POINTER ) {
3341                         pool->nextitem = (VOID *) ( (VOID **) pool->nextitem + pool->itemwords );
3342                 }
3343                 else {
3344                         pool->nextitem = (VOID *) ( (REAL *) pool->nextitem + pool->itemwords );
3345                 }
3346                 pool->unallocateditems--;
3347                 pool->maxitems++;
3348         }
3349         pool->items++;
3350         return newitem;
3351 }
3352
3353 /*****************************************************************************/
3354 /*                                                                           */
3355 /*  pooldealloc()   Deallocate space for an item.                            */
3356 /*                                                                           */
3357 /*  The deallocated space is stored in a queue for later reuse.              */
3358 /*                                                                           */
3359 /*****************************************************************************/
3360
3361 void pooldealloc( pool, dyingitem )
3362 struct memorypool *pool;
3363 VOID *dyingitem;
3364 {
3365         /* Push freshly killed item onto stack. */
3366         *( (VOID **) dyingitem ) = pool->deaditemstack;
3367         pool->deaditemstack = dyingitem;
3368         pool->items--;
3369 }
3370
3371 /*****************************************************************************/
3372 /*                                                                           */
3373 /*  traversalinit()   Prepare to traverse the entire list of items.          */
3374 /*                                                                           */
3375 /*  This routine is used in conjunction with traverse().                     */
3376 /*                                                                           */
3377 /*****************************************************************************/
3378
3379 void traversalinit( pool )
3380 struct memorypool *pool;
3381 {
3382         unsigned long alignptr;
3383
3384         /* Begin the traversal in the first block. */
3385         pool->pathblock = pool->firstblock;
3386         /* Find the first item in the block.  Increment by the size of (VOID *). */
3387         alignptr = (unsigned long) ( pool->pathblock + 1 );
3388         /* Align with item on an `alignbytes'-byte boundary. */
3389         pool->pathitem = (VOID *)
3390                                          ( alignptr + (unsigned long) pool->alignbytes
3391                                            - ( alignptr % (unsigned long) pool->alignbytes ) );
3392         /* Set the number of items left in the current block. */
3393         pool->pathitemsleft = pool->itemsperblock;
3394 }
3395
3396 /*****************************************************************************/
3397 /*                                                                           */
3398 /*  traverse()   Find the next item in the list.                             */
3399 /*                                                                           */
3400 /*  This routine is used in conjunction with traversalinit().  Be forewarned */
3401 /*  that this routine successively returns all items in the list, including  */
3402 /*  deallocated ones on the deaditemqueue.  It's up to you to figure out     */
3403 /*  which ones are actually dead.  Why?  I don't want to allocate extra      */
3404 /*  space just to demarcate dead items.  It can usually be done more         */
3405 /*  space-efficiently by a routine that knows something about the structure  */
3406 /*  of the item.                                                             */
3407 /*                                                                           */
3408 /*****************************************************************************/
3409
3410 VOID *traverse( pool )
3411 struct memorypool *pool;
3412 {
3413         VOID *newitem;
3414         unsigned long alignptr;
3415
3416         /* Stop upon exhausting the list of items. */
3417         if ( pool->pathitem == pool->nextitem ) {
3418                 return (VOID *) NULL;
3419         }
3420         /* Check whether any untraversed items remain in the current block. */
3421         if ( pool->pathitemsleft == 0 ) {
3422                 /* Find the next block. */
3423                 pool->pathblock = (VOID **) *( pool->pathblock );
3424                 /* Find the first item in the block.  Increment by the size of (VOID *). */
3425                 alignptr = (unsigned long) ( pool->pathblock + 1 );
3426                 /* Align with item on an `alignbytes'-byte boundary. */
3427                 pool->pathitem = (VOID *)
3428                                                  ( alignptr + (unsigned long) pool->alignbytes
3429                                                    - ( alignptr % (unsigned long) pool->alignbytes ) );
3430                 /* Set the number of items left in the current block. */
3431                 pool->pathitemsleft = pool->itemsperblock;
3432         }
3433         newitem = pool->pathitem;
3434         /* Find the next item in the block. */
3435         if ( pool->itemwordtype == POINTER ) {
3436                 pool->pathitem = (VOID *) ( (VOID **) pool->pathitem + pool->itemwords );
3437         }
3438         else {
3439                 pool->pathitem = (VOID *) ( (REAL *) pool->pathitem + pool->itemwords );
3440         }
3441         pool->pathitemsleft--;
3442         return newitem;
3443 }
3444
3445 /*****************************************************************************/
3446 /*                                                                           */
3447 /*  dummyinit()   Initialize the triangle that fills "outer space" and the   */
3448 /*                omnipresent shell edge.                                    */
3449 /*                                                                           */
3450 /*  The triangle that fills "outer space", called `dummytri', is pointed to  */
3451 /*  by every triangle and shell edge on a boundary (be it outer or inner) of */
3452 /*  the triangulation.  Also, `dummytri' points to one of the triangles on   */
3453 /*  the convex hull (until the holes and concavities are carved), making it  */
3454 /*  possible to find a starting triangle for point location.                 */
3455 /*                                                                           */
3456 /*  The omnipresent shell edge, `dummysh', is pointed to by every triangle   */
3457 /*  or shell edge that doesn't have a full complement of real shell edges    */
3458 /*  to point to.                                                             */
3459 /*                                                                           */
3460 /*****************************************************************************/
3461
3462 void dummyinit( trianglewords, shellewords )
3463 int trianglewords;
3464 int shellewords;
3465 {
3466         unsigned long alignptr;
3467
3468         /* `triwords' and `shwords' are used by the mesh manipulation primitives */
3469         /*   to extract orientations of triangles and shell edges from pointers. */
3470         triwords = trianglewords;     /* Initialize `triwords' once and for all. */
3471         shwords = shellewords;         /* Initialize `shwords' once and for all. */
3472
3473         /* Set up `dummytri', the `triangle' that occupies "outer space". */
3474         dummytribase = (triangle *) malloc( triwords * sizeof( triangle )
3475                                                                                 + triangles.alignbytes );
3476         if ( dummytribase == (triangle *) NULL ) {
3477                 printf( "Error:  Out of memory.\n" );
3478                 exit( 1 );
3479         }
3480         /* Align `dummytri' on a `triangles.alignbytes'-byte boundary. */
3481         alignptr = (unsigned long) dummytribase;
3482         dummytri = (triangle *)
3483                            ( alignptr + (unsigned long) triangles.alignbytes
3484                                  - ( alignptr % (unsigned long) triangles.alignbytes ) );
3485         /* Initialize the three adjoining triangles to be "outer space".  These  */
3486         /*   will eventually be changed by various bonding operations, but their */
3487         /*   values don't really matter, as long as they can legally be          */
3488         /*   dereferenced.                                                       */
3489         dummytri[0] = (triangle) dummytri;
3490         dummytri[1] = (triangle) dummytri;
3491         dummytri[2] = (triangle) dummytri;
3492         /* Three NULL vertex points. */
3493         dummytri[3] = (triangle) NULL;
3494         dummytri[4] = (triangle) NULL;
3495         dummytri[5] = (triangle) NULL;
3496
3497         if ( useshelles ) {
3498                 /* Set up `dummysh', the omnipresent "shell edge" pointed to by any      */
3499                 /*   triangle side or shell edge end that isn't attached to a real shell */
3500                 /*   edge.                                                               */
3501                 dummyshbase = (shelle *) malloc( shwords * sizeof( shelle )
3502                                                                                  + shelles.alignbytes );
3503                 if ( dummyshbase == (shelle *) NULL ) {
3504                         printf( "Error:  Out of memory.\n" );
3505                         exit( 1 );
3506                 }
3507                 /* Align `dummysh' on a `shelles.alignbytes'-byte boundary. */
3508                 alignptr = (unsigned long) dummyshbase;
3509                 dummysh = (shelle *)
3510                                   ( alignptr + (unsigned long) shelles.alignbytes
3511                                         - ( alignptr % (unsigned long) shelles.alignbytes ) );
3512                 /* Initialize the two adjoining shell edges to be the omnipresent shell */
3513                 /*   edge.  These will eventually be changed by various bonding         */
3514                 /*   operations, but their values don't really matter, as long as they  */
3515                 /*   can legally be dereferenced.                                       */
3516                 dummysh[0] = (shelle) dummysh;
3517                 dummysh[1] = (shelle) dummysh;
3518                 /* Two NULL vertex points. */
3519                 dummysh[2] = (shelle) NULL;
3520                 dummysh[3] = (shelle) NULL;
3521                 /* Initialize the two adjoining triangles to be "outer space". */
3522                 dummysh[4] = (shelle) dummytri;
3523                 dummysh[5] = (shelle) dummytri;
3524                 /* Set the boundary marker to zero. */
3525                 *(int *) ( dummysh + 6 ) = 0;
3526
3527                 /* Initialize the three adjoining shell edges of `dummytri' to be */
3528                 /*   the omnipresent shell edge.                                  */
3529                 dummytri[6] = (triangle) dummysh;
3530                 dummytri[7] = (triangle) dummysh;
3531                 dummytri[8] = (triangle) dummysh;
3532         }
3533 }
3534
3535 /*****************************************************************************/
3536 /*                                                                           */
3537 /*  initializepointpool()   Calculate the size of the point data structure   */
3538 /*                          and initialize its memory pool.                  */
3539 /*                                                                           */
3540 /*  This routine also computes the `pointmarkindex' and `point2triindex'     */
3541 /*  indices used to find values within each point.                           */
3542 /*                                                                           */
3543 /*****************************************************************************/
3544
3545 void initializepointpool(){
3546         int pointsize;
3547
3548         /* The index within each point at which the boundary marker is found.  */
3549         /*   Ensure the point marker is aligned to a sizeof(int)-byte address. */
3550         pointmarkindex = ( ( mesh_dim + nextras ) * sizeof( REAL ) + sizeof( int ) - 1 )
3551                                          / sizeof( int );
3552         pointsize = ( pointmarkindex + 1 ) * sizeof( int );
3553         if ( poly ) {
3554                 /* The index within each point at which a triangle pointer is found.   */
3555                 /*   Ensure the pointer is aligned to a sizeof(triangle)-byte address. */
3556                 point2triindex = ( pointsize + sizeof( triangle ) - 1 ) / sizeof( triangle );
3557                 pointsize = ( point2triindex + 1 ) * sizeof( triangle );
3558         }
3559         /* Initialize the pool of points. */
3560         poolinit( &points, pointsize, POINTPERBLOCK,
3561                           ( sizeof( REAL ) >= sizeof( triangle ) ) ? FLOATINGPOINT : POINTER, 0 );
3562 }
3563
3564 /*****************************************************************************/
3565 /*                                                                           */
3566 /*  initializetrisegpools()   Calculate the sizes of the triangle and shell  */
3567 /*                            edge data structures and initialize their      */
3568 /*                            memory pools.                                  */
3569 /*                                                                           */
3570 /*  This routine also computes the `highorderindex', `elemattribindex', and  */
3571 /*  `areaboundindex' indices used to find values within each triangle.       */
3572 /*                                                                           */
3573 /*****************************************************************************/
3574
3575 void initializetrisegpools(){
3576         int trisize;
3577
3578         /* The index within each triangle at which the extra nodes (above three)  */
3579         /*   associated with high order elements are found.  There are three      */
3580         /*   pointers to other triangles, three pointers to corners, and possibly */
3581         /*   three pointers to shell edges before the extra nodes.                */
3582         highorderindex = 6 + ( useshelles * 3 );
3583         /* The number of bytes occupied by a triangle. */
3584         trisize = ( ( order + 1 ) * ( order + 2 ) / 2 + ( highorderindex - 3 ) ) *
3585                           sizeof( triangle );
3586         /* The index within each triangle at which its attributes are found, */
3587         /*   where the index is measured in REALs.                           */
3588         elemattribindex = ( trisize + sizeof( REAL ) - 1 ) / sizeof( REAL );
3589         /* The index within each triangle at which the maximum area constraint  */
3590         /*   is found, where the index is measured in REALs.  Note that if the  */
3591         /*   `regionattrib' flag is set, an additional attribute will be added. */
3592         areaboundindex = elemattribindex + eextras + regionattrib;
3593         /* If triangle attributes or an area bound are needed, increase the number */
3594         /*   of bytes occupied by a triangle.                                      */
3595         if ( vararea ) {
3596                 trisize = ( areaboundindex + 1 ) * sizeof( REAL );
3597         }
3598         else if ( eextras + regionattrib > 0 ) {
3599                 trisize = areaboundindex * sizeof( REAL );
3600         }
3601         /* If a Voronoi diagram or triangle neighbor graph is requested, make    */
3602         /*   sure there's room to store an integer index in each triangle.  This */
3603         /*   integer index can occupy the same space as the shell edges or       */
3604         /*   attributes or area constraint or extra nodes.                       */
3605         if ( ( voronoi || neighbors ) &&
3606                  ( trisize < 6 * sizeof( triangle ) + sizeof( int ) ) ) {
3607                 trisize = 6 * sizeof( triangle ) + sizeof( int );
3608         }
3609         /* Having determined the memory size of a triangle, initialize the pool. */
3610         poolinit( &triangles, trisize, TRIPERBLOCK, POINTER, 4 );
3611
3612         if ( useshelles ) {
3613                 /* Initialize the pool of shell edges. */
3614                 poolinit( &shelles, 6 * sizeof( triangle ) + sizeof( int ), SHELLEPERBLOCK,
3615                                   POINTER, 4 );
3616
3617                 /* Initialize the "outer space" triangle and omnipresent shell edge. */
3618                 dummyinit( triangles.itemwords, shelles.itemwords );
3619         }
3620         else {
3621                 /* Initialize the "outer space" triangle. */
3622                 dummyinit( triangles.itemwords, 0 );
3623         }
3624 }
3625
3626 /*****************************************************************************/
3627 /*                                                                           */
3628 /*  triangledealloc()   Deallocate space for a triangle, marking it dead.    */
3629 /*                                                                           */
3630 /*****************************************************************************/
3631
3632 void triangledealloc( dyingtriangle )
3633 triangle * dyingtriangle;
3634 {
3635         /* Set triangle's vertices to NULL.  This makes it possible to        */
3636         /*   detect dead triangles when traversing the list of all triangles. */
3637         dyingtriangle[3] = (triangle) NULL;
3638         dyingtriangle[4] = (triangle) NULL;
3639         dyingtriangle[5] = (triangle) NULL;
3640         pooldealloc( &triangles, (VOID *) dyingtriangle );
3641 }
3642
3643 /*****************************************************************************/
3644 /*                                                                           */
3645 /*  triangletraverse()   Traverse the triangles, skipping dead ones.         */
3646 /*                                                                           */
3647 /*****************************************************************************/
3648
3649 triangle *triangletraverse(){
3650         triangle *newtriangle;
3651
3652         do {
3653                 newtriangle = (triangle *) traverse( &triangles );
3654                 if ( newtriangle == (triangle *) NULL ) {
3655                         return (triangle *) NULL;
3656                 }
3657         } while ( newtriangle[3] == (triangle) NULL );        /* Skip dead ones. */
3658         return newtriangle;
3659 }
3660
3661 /*****************************************************************************/
3662 /*                                                                           */
3663 /*  shelledealloc()   Deallocate space for a shell edge, marking it dead.    */
3664 /*                                                                           */
3665 /*****************************************************************************/
3666
3667 void shelledealloc( dyingshelle )
3668 shelle * dyingshelle;
3669 {
3670         /* Set shell edge's vertices to NULL.  This makes it possible to */
3671         /*   detect dead shells when traversing the list of all shells.  */
3672         dyingshelle[2] = (shelle) NULL;
3673         dyingshelle[3] = (shelle) NULL;
3674         pooldealloc( &shelles, (VOID *) dyingshelle );
3675 }
3676
3677 /*****************************************************************************/
3678 /*                                                                           */
3679 /*  shelletraverse()   Traverse the shell edges, skipping dead ones.         */
3680 /*                                                                           */
3681 /*****************************************************************************/
3682
3683 shelle *shelletraverse(){
3684         shelle *newshelle;
3685
3686         do {
3687                 newshelle = (shelle *) traverse( &shelles );
3688                 if ( newshelle == (shelle *) NULL ) {
3689                         return (shelle *) NULL;
3690                 }
3691         } while ( newshelle[2] == (shelle) NULL );            /* Skip dead ones. */
3692         return newshelle;
3693 }
3694
3695 /*****************************************************************************/
3696 /*                                                                           */
3697 /*  pointdealloc()   Deallocate space for a point, marking it dead.          */
3698 /*                                                                           */
3699 /*****************************************************************************/
3700
3701 void pointdealloc( dyingpoint )
3702 point dyingpoint;
3703 {
3704         /* Mark the point as dead.  This makes it possible to detect dead points */
3705         /*   when traversing the list of all points.                             */
3706         setpointmark( dyingpoint, DEADPOINT );
3707         pooldealloc( &points, (VOID *) dyingpoint );
3708 }
3709
3710 /*****************************************************************************/
3711 /*                                                                           */
3712 /*  pointtraverse()   Traverse the points, skipping dead ones.               */
3713 /*                                                                           */
3714 /*****************************************************************************/
3715
3716 point pointtraverse(){
3717         point newpoint;
3718
3719         do {
3720                 newpoint = (point) traverse( &points );
3721                 if ( newpoint == (point) NULL ) {
3722                         return (point) NULL;
3723                 }
3724         } while ( pointmark( newpoint ) == DEADPOINT );       /* Skip dead ones. */
3725         return newpoint;
3726 }
3727
3728 /*****************************************************************************/
3729 /*                                                                           */
3730 /*  badsegmentdealloc()   Deallocate space for a bad segment, marking it     */
3731 /*                        dead.                                              */
3732 /*                                                                           */
3733 /*****************************************************************************/
3734
3735 #ifndef CDT_ONLY
3736
3737 void badsegmentdealloc( dyingseg )
3738 struct edge *dyingseg;
3739 {
3740         /* Set segment's orientation to -1.  This makes it possible to      */
3741         /*   detect dead segments when traversing the list of all segments. */
3742         dyingseg->shorient = -1;
3743         pooldealloc( &badsegments, (VOID *) dyingseg );
3744 }
3745
3746 #endif /* not CDT_ONLY */
3747
3748 /*****************************************************************************/
3749 /*                                                                           */
3750 /*  badsegmenttraverse()   Traverse the bad segments, skipping dead ones.    */
3751 /*                                                                           */
3752 /*****************************************************************************/
3753
3754 #ifndef CDT_ONLY
3755
3756 struct edge *badsegmenttraverse(){
3757         struct edge *newseg;
3758
3759         do {
3760                 newseg = (struct edge *) traverse( &badsegments );
3761                 if ( newseg == (struct edge *) NULL ) {
3762                         return (struct edge *) NULL;
3763                 }
3764         } while ( newseg->shorient == -1 );                   /* Skip dead ones. */
3765         return newseg;
3766 }
3767
3768 #endif /* not CDT_ONLY */
3769
3770 /*****************************************************************************/
3771 /*                                                                           */
3772 /*  getpoint()   Get a specific point, by number, from the list.             */
3773 /*                                                                           */
3774 /*  The first point is number 'firstnumber'.                                 */
3775 /*                                                                           */
3776 /*  Note that this takes O(n) time (with a small constant, if POINTPERBLOCK  */
3777 /*  is large).  I don't care to take the trouble to make it work in constant */
3778 /*  time.                                                                    */
3779 /*                                                                           */
3780 /*****************************************************************************/
3781
3782 point getpoint( number )
3783 int number;
3784 {
3785         VOID **getblock;
3786         point foundpoint;
3787         unsigned long alignptr;
3788         int current;
3789
3790         getblock = points.firstblock;
3791         current = firstnumber;
3792         /* Find the right block. */
3793         while ( current + points.itemsperblock <= number ) {
3794                 getblock = (VOID **) *getblock;
3795                 current += points.itemsperblock;
3796         }
3797         /* Now find the right point. */
3798         alignptr = (unsigned long) ( getblock + 1 );
3799         foundpoint = (point) ( alignptr + (unsigned long) points.alignbytes
3800                                                    - ( alignptr % (unsigned long) points.alignbytes ) );
3801         while ( current < number ) {
3802                 foundpoint += points.itemwords;
3803                 current++;
3804         }
3805         return foundpoint;
3806 }
3807
3808 /*****************************************************************************/
3809 /*                                                                           */
3810 /*  triangledeinit()   Free all remaining allocated memory.                  */
3811 /*                                                                           */
3812 /*****************************************************************************/
3813
3814 void triangledeinit(){
3815         pooldeinit( &triangles );
3816         free( dummytribase );
3817         if ( useshelles ) {
3818                 pooldeinit( &shelles );
3819                 free( dummyshbase );
3820         }
3821         pooldeinit( &points );
3822 #ifndef CDT_ONLY
3823         if ( quality ) {
3824                 pooldeinit( &badsegments );
3825                 if ( ( minangle > 0.0 ) || vararea || fixedarea ) {
3826                         pooldeinit( &badtriangles );
3827                 }
3828         }
3829 #endif /* not CDT_ONLY */
3830 }
3831
3832 /**                                                                         **/
3833 /**                                                                         **/
3834 /********* Memory management routines end here                       *********/
3835
3836 /********* Constructors begin here                                   *********/
3837 /**                                                                         **/
3838 /**                                                                         **/
3839
3840 /*****************************************************************************/
3841 /*                                                                           */
3842 /*  maketriangle()   Create a new triangle with orientation zero.            */
3843 /*                                                                           */
3844 /*****************************************************************************/
3845
3846 void maketriangle( newtriedge )
3847 struct triedge *newtriedge;
3848 {
3849         int i;
3850
3851         newtriedge->tri = (triangle *) poolalloc( &triangles );
3852         /* Initialize the three adjoining triangles to be "outer space". */
3853         newtriedge->tri[0] = (triangle) dummytri;
3854         newtriedge->tri[1] = (triangle) dummytri;
3855         newtriedge->tri[2] = (triangle) dummytri;
3856         /* Three NULL vertex points. */
3857         newtriedge->tri[3] = (triangle) NULL;
3858         newtriedge->tri[4] = (triangle) NULL;
3859         newtriedge->tri[5] = (triangle) NULL;
3860         /* Initialize the three adjoining shell edges to be the omnipresent */
3861         /*   shell edge.                                                    */
3862         if ( useshelles ) {
3863                 newtriedge->tri[6] = (triangle) dummysh;
3864                 newtriedge->tri[7] = (triangle) dummysh;
3865                 newtriedge->tri[8] = (triangle) dummysh;
3866         }
3867         for ( i = 0; i < eextras; i++ ) {
3868                 setelemattribute( *newtriedge, i, 0.0 );
3869         }
3870         if ( vararea ) {
3871                 setareabound( *newtriedge, -1.0 );
3872         }
3873
3874         newtriedge->orient = 0;
3875 }
3876
3877 /*****************************************************************************/
3878 /*                                                                           */
3879 /*  makeshelle()   Create a new shell edge with orientation zero.            */
3880 /*                                                                           */
3881 /*****************************************************************************/
3882
3883 void makeshelle( newedge )
3884 struct edge *newedge;
3885 {
3886         newedge->sh = (shelle *) poolalloc( &shelles );
3887         /* Initialize the two adjoining shell edges to be the omnipresent */
3888         /*   shell edge.                                                  */
3889         newedge->sh[0] = (shelle) dummysh;
3890         newedge->sh[1] = (shelle) dummysh;
3891         /* Two NULL vertex points. */
3892         newedge->sh[2] = (shelle) NULL;
3893         newedge->sh[3] = (shelle) NULL;
3894         /* Initialize the two adjoining triangles to be "outer space". */
3895         newedge->sh[4] = (shelle) dummytri;
3896         newedge->sh[5] = (shelle) dummytri;
3897         /* Set the boundary marker to zero. */
3898         setmark( *newedge, 0 );
3899
3900         newedge->shorient = 0;
3901 }
3902
3903 /**                                                                         **/
3904 /**                                                                         **/
3905 /********* Constructors end here                                     *********/
3906
3907 /********* Determinant evaluation routines begin here                *********/
3908 /**                                                                         **/
3909 /**                                                                         **/
3910
3911 /* The adaptive exact arithmetic geometric predicates implemented herein are */
3912 /*   described in detail in my Technical Report CMU-CS-96-140.  The complete */
3913 /*   reference is given in the header.                                       */
3914
3915 /* Which of the following two methods of finding the absolute values is      */
3916 /*   fastest is compiler-dependent.  A few compilers can inline and optimize */
3917 /*   the fabs() call; but most will incur the overhead of a function call,   */
3918 /*   which is disastrously slow.  A faster way on IEEE machines might be to  */
3919 /*   mask the appropriate bit, but that's difficult to do in C.              */
3920
3921 #define Absolute( a )  ( ( a ) >= 0.0 ? ( a ) : -( a ) )
3922 /* #define Absolute(a)  fabs(a) */
3923
3924 /* Many of the operations are broken up into two pieces, a main part that    */
3925 /*   performs an approximate operation, and a "tail" that computes the       */
3926 /*   roundoff error of that operation.                                       */
3927 /*                                                                           */
3928 /* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(),    */
3929 /*   Split(), and Two_Product() are all implemented as described in the      */
3930 /*   reference.  Each of these macros requires certain variables to be       */
3931 /*   defined in the calling routine.  The variables `bvirt', `c', `abig',    */
3932 /*   `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because   */
3933 /*   they store the result of an operation that may incur roundoff error.    */
3934 /*   The input parameter `x' (or the highest numbered `x_' parameter) must   */
3935 /*   also be declared `INEXACT'.                                             */
3936
3937 #define Fast_Two_Sum_Tail( a, b, x, y ) \
3938         bvirt = x - a; \
3939         y = b - bvirt
3940
3941 #define Fast_Two_Sum( a, b, x, y ) \
3942         x = (REAL) ( a + b ); \
3943         Fast_Two_Sum_Tail( a, b, x, y )
3944
3945 #define Two_Sum_Tail( a, b, x, y ) \
3946         bvirt = (REAL) ( x - a ); \
3947         avirt = x - bvirt; \
3948         bround = b - bvirt;     \
3949         around = a - avirt;     \
3950         y = around + bround
3951
3952 #define Two_Sum( a, b, x, y ) \
3953         x = (REAL) ( a + b ); \
3954         Two_Sum_Tail( a, b, x, y )
3955
3956 #define Two_Diff_Tail( a, b, x, y )     \
3957         bvirt = (REAL) ( a - x ); \
3958         avirt = x + bvirt; \
3959         bround = bvirt - b;     \
3960         around = a - avirt;     \
3961         y = around + bround
3962
3963 #define Two_Diff( a, b, x, y ) \
3964         x = (REAL) ( a - b ); \
3965         Two_Diff_Tail( a, b, x, y )
3966
3967 #define Split( a, ahi, alo ) \
3968         c = (REAL) ( splitter * a ); \
3969         abig = (REAL) ( c - a ); \
3970         ahi = (REAL)( c - abig ); \
3971         alo = (REAL)( a - ahi )
3972
3973 #define Two_Product_Tail( a, b, x, y ) \
3974         Split( a, ahi, alo ); \
3975         Split( b, bhi, blo ); \
3976         err1 = x - ( ahi * bhi ); \
3977         err2 = err1 - ( alo * bhi ); \
3978         err3 = err2 - ( ahi * blo ); \
3979         y = ( alo * blo ) - err3
3980
3981 #define Two_Product( a, b, x, y ) \
3982         x = (REAL) ( a * b ); \
3983         Two_Product_Tail( a, b, x, y )
3984
3985 /* Two_Product_Presplit() is Two_Product() where one of the inputs has       */
3986 /*   already been split.  Avoids redundant splitting.                        */
3987
3988 #define Two_Product_Presplit( a, b, bhi, blo, x, y ) \
3989         x = (REAL) ( a * b ); \
3990         Split( a, ahi, alo ); \
3991         err1 = x - ( ahi * bhi ); \
3992         err2 = err1 - ( alo * bhi ); \
3993         err3 = err2 - ( ahi * blo ); \
3994         y = ( alo * blo ) - err3
3995
3996 /* Square() can be done more quickly than Two_Product().                     */
3997
3998 #define Square_Tail( a, x, y ) \
3999         Split( a, ahi, alo ); \
4000         err1 = x - ( ahi * ahi ); \
4001         err3 = err1 - ( ( ahi + ahi ) * alo ); \
4002         y = ( alo * alo ) - err3
4003
4004 #define Square( a, x, y ) \
4005         x = (REAL) ( a * a ); \
4006         Square_Tail( a, x, y )
4007
4008 /* Macros for summing expansions of various fixed lengths.  These are all    */
4009 /*   unrolled versions of Expansion_Sum().                                   */
4010
4011 #define Two_One_Sum( a1, a0, b, x2, x1, x0 ) \
4012         Two_Sum( a0, b, _i, x0 ); \
4013         Two_Sum( a1, _i, x2, x1 )
4014
4015 #define Two_One_Diff( a1, a0, b, x2, x1, x0 ) \
4016         Two_Diff( a0, b, _i, x0 ); \
4017         Two_Sum( a1, _i, x2, x1 )
4018
4019 #define Two_Two_Sum( a1, a0, b1, b0, x3, x2, x1, x0 ) \
4020         Two_One_Sum( a1, a0, b0, _j, _0, x0 ); \
4021         Two_One_Sum( _j, _0, b1, x3, x2, x1 )
4022
4023 #define Two_Two_Diff( a1, a0, b1, b0, x3, x2, x1, x0 ) \
4024         Two_One_Diff( a1, a0, b0, _j, _0, x0 ); \
4025         Two_One_Diff( _j, _0, b1, x3, x2, x1 )
4026
4027 /*****************************************************************************/
4028 /*                                                                           */
4029 /*  exactinit()   Initialize the variables used for exact arithmetic.        */
4030 /*                                                                           */
4031 /*  `epsilon' is the largest power of two such that 1.0 + epsilon = 1.0 in   */
4032 /*  floating-point arithmetic.  `epsilon' bounds the relative roundoff       */
4033 /*  error.  It is used for floating-point error analysis.                    */
4034 /*                                                                           */
4035 /*  `splitter' is used to split floating-point numbers into two half-        */
4036 /*  length significands for exact multiplication.                            */
4037 /*                                                                           */
4038 /*  I imagine that a highly optimizing compiler might be too smart for its   */
4039 /*  own good, and somehow cause this routine to fail, if it pretends that    */
4040 /*  floating-point arithmetic is too much like real arithmetic.              */
4041 /*                                                                           */
4042 /*  Don't change this routine unless you fully understand it.                */
4043 /*                                                                           */
4044 /*****************************************************************************/
4045
4046 void exactinit(){
4047         REAL half;
4048         REAL check, lastcheck;
4049         int every_other;
4050
4051         every_other = 1;
4052         half = 0.5;
4053         epsilon = 1.0;
4054         splitter = 1.0;
4055         check = 1.0;
4056         /* Repeatedly divide `epsilon' by two until it is too small to add to      */
4057         /*   one without causing roundoff.  (Also check if the sum is equal to     */
4058         /*   the previous sum, for machines that round up instead of using exact   */
4059         /*   rounding.  Not that these routines will work on such machines anyway. */
4060         do {
4061                 lastcheck = check;
4062                 epsilon *= half;
4063                 if ( every_other ) {
4064                         splitter *= 2.0;
4065                 }
4066                 every_other = !every_other;
4067                 check = (REAL)( 1.0 + epsilon );
4068         } while ( ( check != 1.0 ) && ( check != lastcheck ) );
4069         splitter += 1.0;
4070         if ( verbose > 1 ) {
4071                 printf( "Floating point roundoff is of magnitude %.17g\n", epsilon );
4072                 printf( "Floating point splitter is %.17g\n", splitter );
4073         }
4074         /* Error bounds for orientation and incircle tests. */
4075         resulterrbound = (REAL)( ( 3.0 + 8.0 * epsilon ) * epsilon );
4076         ccwerrboundA = (REAL)( ( 3.0 + 16.0 * epsilon ) * epsilon );
4077         ccwerrboundB = (REAL)( ( 2.0 + 12.0 * epsilon ) * epsilon );
4078         ccwerrboundC = (REAL)( ( 9.0 + 64.0 * epsilon ) * epsilon * epsilon );
4079         iccerrboundA = (REAL)( ( 10.0 + 96.0 * epsilon ) * epsilon );
4080         iccerrboundB = (REAL)( ( 4.0 + 48.0 * epsilon ) * epsilon );
4081         iccerrboundC = (REAL)( ( 44.0 + 576.0 * epsilon ) * epsilon * epsilon );
4082 }
4083
4084 /*****************************************************************************/
4085 /*                                                                           */
4086 /*  fast_expansion_sum_zeroelim()   Sum two expansions, eliminating zero     */
4087 /*                                  components from the output expansion.    */
4088 /*                                                                           */
4089 /*  Sets h = e + f.  See my Robust Predicates paper for details.             */
4090 /*                                                                           */
4091 /*  If round-to-even is used (as with IEEE 754), maintains the strongly      */
4092 /*  nonoverlapping property.  (That is, if e is strongly nonoverlapping, h   */
4093 /*  will be also.)  Does NOT maintain the nonoverlapping or nonadjacent      */
4094 /*  properties.                                                              */
4095 /*                                                                           */
4096 /*****************************************************************************/
4097
4098 int fast_expansion_sum_zeroelim( elen, e, flen, f, h )  /* h cannot be e or f. */
4099 int elen;
4100 REAL *e;
4101 int flen;
4102 REAL *f;
4103 REAL *h;
4104 {
4105         REAL Q;
4106         INEXACT REAL Qnew;
4107         INEXACT REAL hh;
4108         INEXACT REAL bvirt;
4109         REAL avirt, bround, around;
4110         int eindex, findex, hindex;
4111         REAL enow, fnow;
4112
4113         enow = e[0];
4114         fnow = f[0];
4115         eindex = findex = 0;
4116         if ( ( fnow > enow ) == ( fnow > -enow ) ) {
4117                 Q = enow;
4118                 enow = e[++eindex];
4119         }
4120         else {
4121                 Q = fnow;
4122                 fnow = f[++findex];
4123         }
4124         hindex = 0;
4125         if ( ( eindex < elen ) && ( findex < flen ) ) {
4126                 if ( ( fnow > enow ) == ( fnow > -enow ) ) {
4127                         Fast_Two_Sum( enow, Q, Qnew, hh );
4128                         enow = e[++eindex];
4129                 }
4130                 else {
4131                         Fast_Two_Sum( fnow, Q, Qnew, hh );
4132                         fnow = f[++findex];
4133                 }
4134                 Q = Qnew;
4135                 if ( hh != 0.0 ) {
4136                         h[hindex++] = hh;
4137                 }
4138                 while ( ( eindex < elen ) && ( findex < flen ) ) {
4139                         if ( ( fnow > enow ) == ( fnow > -enow ) ) {
4140                                 Two_Sum( Q, enow, Qnew, hh );
4141                                 enow = e[++eindex];
4142                         }
4143                         else {
4144                                 Two_Sum( Q, fnow, Qnew, hh );
4145                                 fnow = f[++findex];
4146                         }
4147                         Q = Qnew;
4148                         if ( hh != 0.0 ) {
4149                                 h[hindex++] = hh;
4150                         }
4151                 }
4152         }
4153         while ( eindex < elen ) {
4154                 Two_Sum( Q, enow, Qnew, hh );
4155                 enow = e[++eindex];
4156                 Q = Qnew;
4157                 if ( hh != 0.0 ) {
4158                         h[hindex++] = hh;
4159                 }
4160         }
4161         while ( findex < flen ) {
4162                 Two_Sum( Q, fnow, Qnew, hh );
4163                 fnow = f[++findex];
4164                 Q = Qnew;
4165                 if ( hh != 0.0 ) {
4166                         h[hindex++] = hh;
4167                 }
4168         }
4169         if ( ( Q != 0.0 ) || ( hindex == 0 ) ) {
4170                 h[hindex++] = Q;
4171         }
4172         return hindex;
4173 }
4174
4175 /*****************************************************************************/
4176 /*                                                                           */
4177 /*  scale_expansion_zeroelim()   Multiply an expansion by a scalar,          */
4178 /*                               eliminating zero components from the        */
4179 /*                               output expansion.                           */
4180 /*                                                                           */
4181 /*  Sets h = be.  See my Robust Predicates paper for details.                */
4182 /*                                                                           */
4183 /*  Maintains the nonoverlapping property.  If round-to-even is used (as     */
4184 /*  with IEEE 754), maintains the strongly nonoverlapping and nonadjacent    */
4185 /*  properties as well.  (That is, if e has one of these properties, so      */
4186 /*  will h.)                                                                 */
4187 /*                                                                           */
4188 /*****************************************************************************/
4189
4190 int scale_expansion_zeroelim( elen, e, b, h )   /* e and h cannot be the same. */
4191 int elen;
4192 REAL *e;
4193 REAL b;
4194 REAL *h;
4195 {
4196         INEXACT REAL Q, sum;
4197         REAL hh;
4198         INEXACT REAL product1;
4199         REAL product0;
4200         int eindex, hindex;
4201         REAL enow;
4202         INEXACT REAL bvirt;
4203         REAL avirt, bround, around;
4204         INEXACT REAL c;
4205         INEXACT REAL abig;
4206         REAL ahi, alo, bhi, blo;
4207         REAL err1, err2, err3;
4208
4209         Split( b, bhi, blo );
4210         Two_Product_Presplit( e[0], b, bhi, blo, Q, hh );
4211         hindex = 0;
4212         if ( hh != 0 ) {
4213                 h[hindex++] = hh;
4214         }
4215         for ( eindex = 1; eindex < elen; eindex++ ) {
4216                 enow = e[eindex];
4217                 Two_Product_Presplit( enow, b, bhi, blo, product1, product0 );
4218                 Two_Sum( Q, product0, sum, hh );
4219                 if ( hh != 0 ) {
4220                         h[hindex++] = hh;
4221                 }
4222                 Fast_Two_Sum( product1, sum, Q, hh );
4223                 if ( hh != 0 ) {
4224                         h[hindex++] = hh;
4225                 }
4226         }
4227         if ( ( Q != 0.0 ) || ( hindex == 0 ) ) {
4228                 h[hindex++] = Q;
4229         }
4230         return hindex;
4231 }
4232
4233 /*****************************************************************************/
4234 /*                                                                           */
4235 /*  estimate()   Produce a one-word estimate of an expansion's value.        */
4236 /*                                                                           */
4237 /*  See my Robust Predicates paper for details.                              */
4238 /*                                                                           */
4239 /*****************************************************************************/
4240
4241 REAL estimate( elen, e )
4242 int elen;
4243 REAL *e;
4244 {
4245         REAL Q;
4246         int eindex;
4247
4248         Q = e[0];
4249         for ( eindex = 1; eindex < elen; eindex++ ) {
4250                 Q += e[eindex];
4251         }
4252         return Q;
4253 }
4254
4255 /*****************************************************************************/
4256 /*                                                                           */
4257 /*  counterclockwise()   Return a positive value if the points pa, pb, and   */
4258 /*                       pc occur in counterclockwise order; a negative      */
4259 /*                       value if they occur in clockwise order; and zero    */
4260 /*                       if they are collinear.  The result is also a rough  */
4261 /*                       approximation of twice the signed area of the       */
4262 /*                       triangle defined by the three points.               */
4263 /*                                                                           */
4264 /*  Uses exact arithmetic if necessary to ensure a correct answer.  The      */
4265 /*  result returned is the determinant of a matrix.  This determinant is     */
4266 /*  computed adaptively, in the sense that exact arithmetic is used only to  */
4267 /*  the degree it is needed to ensure that the returned value has the        */
4268 /*  correct sign.  Hence, this function is usually quite fast, but will run  */
4269 /*  more slowly when the input points are collinear or nearly so.            */
4270 /*                                                                           */
4271 /*  See my Robust Predicates paper for details.                              */
4272 /*                                                                           */
4273 /*****************************************************************************/
4274
4275 REAL counterclockwiseadapt( pa, pb, pc, detsum )
4276 point pa;
4277 point pb;
4278 point pc;
4279 REAL detsum;
4280 {
4281         INEXACT REAL acx, acy, bcx, bcy;
4282         REAL acxtail, acytail, bcxtail, bcytail;
4283         INEXACT REAL detleft, detright;
4284         REAL detlefttail, detrighttail;
4285         REAL det, errbound;
4286         REAL B[4], C1[8], C2[12], D[16];
4287         INEXACT REAL B3;
4288         int C1length, C2length, Dlength;
4289         REAL u[4];
4290         INEXACT REAL u3;
4291         INEXACT REAL s1, t1;
4292         REAL s0, t0;
4293
4294         INEXACT REAL bvirt;
4295         REAL avirt, bround, around;
4296         INEXACT REAL c;
4297         INEXACT REAL abig;
4298         REAL ahi, alo, bhi, blo;
4299         REAL err1, err2, err3;
4300         INEXACT REAL _i, _j;
4301         REAL _0;
4302
4303         acx = (REAL) ( pa[0] - pc[0] );
4304         bcx = (REAL) ( pb[0] - pc[0] );
4305         acy = (REAL) ( pa[1] - pc[1] );
4306         bcy = (REAL) ( pb[1] - pc[1] );
4307
4308         Two_Product( acx, bcy, detleft, detlefttail );
4309         Two_Product( acy, bcx, detright, detrighttail );
4310
4311         Two_Two_Diff( detleft, detlefttail, detright, detrighttail,
4312                                   B3, B[2], B[1], B[0] );
4313         B[3] = B3;
4314
4315         det = estimate( 4, B );
4316         errbound = (REAL)( ccwerrboundB * detsum );
4317         if ( ( det >= errbound ) || ( -det >= errbound ) ) {
4318                 return det;
4319         }
4320
4321         Two_Diff_Tail( pa[0], pc[0], acx, acxtail );
4322         Two_Diff_Tail( pb[0], pc[0], bcx, bcxtail );
4323         Two_Diff_Tail( pa[1], pc[1], acy, acytail );
4324         Two_Diff_Tail( pb[1], pc[1], bcy, bcytail );
4325
4326         if ( ( acxtail == 0.0 ) && ( acytail == 0.0 )
4327                  && ( bcxtail == 0.0 ) && ( bcytail == 0.0 ) ) {
4328                 return det;
4329         }
4330
4331         errbound = (REAL)( ccwerrboundC * detsum + resulterrbound * Absolute( det ) );
4332         det += ( acx * bcytail + bcy * acxtail )
4333                    - ( acy * bcxtail + bcx * acytail );
4334         if ( ( det >= errbound ) || ( -det >= errbound ) ) {
4335                 return det;
4336         }
4337
4338         Two_Product( acxtail, bcy, s1, s0 );
4339         Two_Product( acytail, bcx, t1, t0 );
4340         Two_Two_Diff( s1, s0, t1, t0, u3, u[2], u[1], u[0] );
4341         u[3] = u3;
4342         C1length = fast_expansion_sum_zeroelim( 4, B, 4, u, C1 );
4343
4344         Two_Product( acx, bcytail, s1, s0 );
4345         Two_Product( acy, bcxtail, t1, t0 );
4346         Two_Two_Diff( s1, s0, t1, t0, u3, u[2], u[1], u[0] );
4347         u[3] = u3;
4348         C2length = fast_expansion_sum_zeroelim( C1length, C1, 4, u, C2 );
4349
4350         Two_Product( acxtail, bcytail, s1, s0 );
4351         Two_Product( acytail, bcxtail, t1, t0 );
4352         Two_Two_Diff( s1, s0, t1, t0, u3, u[2], u[1], u[0] );
4353         u[3] = u3;
4354         Dlength = fast_expansion_sum_zeroelim( C2length, C2, 4, u, D );
4355
4356         return( D[Dlength - 1] );
4357 }
4358
4359 REAL counterclockwise( pa, pb, pc )
4360 point pa;
4361 point pb;
4362 point pc;
4363 {
4364         REAL detleft, detright, det;
4365         REAL detsum, errbound;
4366
4367         counterclockcount++;
4368
4369         detleft = ( pa[0] - pc[0] ) * ( pb[1] - pc[1] );
4370         detright = ( pa[1] - pc[1] ) * ( pb[0] - pc[0] );
4371         det = detleft - detright;
4372
4373         if ( noexact ) {
4374                 return det;
4375         }
4376
4377         if ( detleft > 0.0 ) {
4378                 if ( detright <= 0.0 ) {
4379                         return det;
4380                 }
4381                 else {
4382                         detsum = detleft + detright;
4383                 }
4384         }
4385         else if ( detleft < 0.0 ) {
4386                 if ( detright >= 0.0 ) {
4387                         return det;
4388                 }
4389                 else {
4390                         detsum = -detleft - detright;
4391                 }
4392         }
4393         else {
4394                 return det;
4395         }
4396
4397         errbound = ccwerrboundA * detsum;
4398         if ( ( det >= errbound ) || ( -det >= errbound ) ) {
4399                 return det;
4400         }
4401
4402         return counterclockwiseadapt( pa, pb, pc, detsum );
4403 }
4404
4405 /*****************************************************************************/
4406 /*                                                                           */
4407 /*  incircle()   Return a positive value if the point pd lies inside the     */
4408 /*               circle passing through pa, pb, and pc; a negative value if  */
4409 /*               it lies outside; and zero if the four points are cocircular.*/
4410 /*               The points pa, pb, and pc must be in counterclockwise       */
4411 /*               order, or the sign of the result will be reversed.          */
4412 /*                                                                           */
4413 /*  Uses exact arithmetic if necessary to ensure a correct answer.  The      */
4414 /*  result returned is the determinant of a matrix.  This determinant is     */
4415 /*  computed adaptively, in the sense that exact arithmetic is used only to  */
4416 /*  the degree it is needed to ensure that the returned value has the        */
4417 /*  correct sign.  Hence, this function is usually quite fast, but will run  */
4418 /*  more slowly when the input points are cocircular or nearly so.           */
4419 /*                                                                           */
4420 /*  See my Robust Predicates paper for details.                              */
4421 /*                                                                           */
4422 /*****************************************************************************/
4423
4424 REAL incircleadapt( pa, pb, pc, pd, permanent )
4425 point pa;
4426 point pb;
4427 point pc;
4428 point pd;
4429 REAL permanent;
4430 {
4431         INEXACT REAL adx, bdx, cdx, ady, bdy, cdy;
4432         REAL det, errbound;
4433
4434         INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1;
4435         REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0;
4436         REAL bc[4], ca[4], ab[4];
4437         INEXACT REAL bc3, ca3, ab3;
4438         REAL axbc[8], axxbc[16], aybc[8], ayybc[16], adet[32];
4439         int axbclen, axxbclen, aybclen, ayybclen, alen;
4440         REAL bxca[8], bxxca[16], byca[8], byyca[16], bdet[32];
4441         int bxcalen, bxxcalen, bycalen, byycalen, blen;
4442         REAL cxab[8], cxxab[16], cyab[8], cyyab[16], cdet[32];
4443         int cxablen, cxxablen, cyablen, cyyablen, clen;
4444         REAL abdet[64];
4445         int ablen;
4446         REAL fin1[1152], fin2[1152];
4447         REAL *finnow, *finother, *finswap;
4448         int finlength;
4449
4450         REAL adxtail, bdxtail, cdxtail, adytail, bdytail, cdytail;
4451         INEXACT REAL adxadx1, adyady1, bdxbdx1, bdybdy1, cdxcdx1, cdycdy1;
4452         REAL adxadx0, adyady0, bdxbdx0, bdybdy0, cdxcdx0, cdycdy0;
4453         REAL aa[4], bb[4], cc[4];
4454         INEXACT REAL aa3, bb3, cc3;
4455         INEXACT REAL ti1, tj1;
4456         REAL ti0, tj0;
4457         REAL u[4], v[4];
4458         INEXACT REAL u3, v3;
4459         REAL temp8[8], temp16a[16], temp16b[16], temp16c[16];
4460         REAL temp32a[32], temp32b[32], temp48[48], temp64[64];
4461         int temp8len, temp16alen, temp16blen, temp16clen;
4462         int temp32alen, temp32blen, temp48len, temp64len;
4463         REAL axtbb[8], axtcc[8], aytbb[8], aytcc[8];
4464         int axtbblen, axtcclen, aytbblen, aytcclen;
4465         REAL bxtaa[8], bxtcc[8], bytaa[8], bytcc[8];
4466         int bxtaalen, bxtcclen, bytaalen, bytcclen;
4467         REAL cxtaa[8], cxtbb[8], cytaa[8], cytbb[8];
4468         int cxtaalen, cxtbblen, cytaalen, cytbblen;
4469         REAL axtbc[8], aytbc[8], bxtca[8], bytca[8], cxtab[8], cytab[8];
4470         int axtbclen, aytbclen, bxtcalen, bytcalen, cxtablen, cytablen;
4471         REAL axtbct[16], aytbct[16], bxtcat[16], bytcat[16], cxtabt[16], cytabt[16];
4472         int axtbctlen, aytbctlen, bxtcatlen, bytcatlen, cxtabtlen, cytabtlen;
4473         REAL axtbctt[8], aytbctt[8], bxtcatt[8];
4474         REAL bytcatt[8], cxtabtt[8], cytabtt[8];
4475         int axtbcttlen, aytbcttlen, bxtcattlen, bytcattlen, cxtabttlen, cytabttlen;
4476         REAL abt[8], bct[8], cat[8];
4477         int abtlen, bctlen, catlen;
4478         REAL abtt[4], bctt[4], catt[4];
4479         int abttlen, bcttlen, cattlen;
4480         INEXACT REAL abtt3, bctt3, catt3;
4481         REAL negate;
4482
4483         INEXACT REAL bvirt;
4484         REAL avirt, bround, around;
4485         INEXACT REAL c;
4486         INEXACT REAL abig;
4487         REAL ahi, alo, bhi, blo;
4488         REAL err1, err2, err3;
4489         INEXACT REAL _i, _j;
4490         REAL _0;
4491
4492         adx = (REAL) ( pa[0] - pd[0] );
4493         bdx = (REAL) ( pb[0] - pd[0] );
4494         cdx = (REAL) ( pc[0] - pd[0] );
4495         ady = (REAL) ( pa[1] - pd[1] );
4496         bdy = (REAL) ( pb[1] - pd[1] );
4497         cdy = (REAL) ( pc[1] - pd[1] );
4498
4499         Two_Product( bdx, cdy, bdxcdy1, bdxcdy0 );
4500         Two_Product( cdx, bdy, cdxbdy1, cdxbdy0 );
4501         Two_Two_Diff( bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0] );
4502         bc[3] = bc3;
4503         axbclen = scale_expansion_zeroelim( 4, bc, adx, axbc );
4504         axxbclen = scale_expansion_zeroelim( axbclen, axbc, adx, axxbc );
4505         aybclen = scale_expansion_zeroelim( 4, bc, ady, aybc );
4506         ayybclen = scale_expansion_zeroelim( aybclen, aybc, ady, ayybc );
4507         alen = fast_expansion_sum_zeroelim( axxbclen, axxbc, ayybclen, ayybc, adet );
4508
4509         Two_Product( cdx, ady, cdxady1, cdxady0 );
4510         Two_Product( adx, cdy, adxcdy1, adxcdy0 );
4511         Two_Two_Diff( cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0] );
4512         ca[3] = ca3;
4513         bxcalen = scale_expansion_zeroelim( 4, ca, bdx, bxca );
4514         bxxcalen = scale_expansion_zeroelim( bxcalen, bxca, bdx, bxxca );
4515         bycalen = scale_expansion_zeroelim( 4, ca, bdy, byca );
4516         byycalen = scale_expansion_zeroelim( bycalen, byca, bdy, byyca );
4517         blen = fast_expansion_sum_zeroelim( bxxcalen, bxxca, byycalen, byyca, bdet );
4518
4519         Two_Product( adx, bdy, adxbdy1, adxbdy0 );
4520         Two_Product( bdx, ady, bdxady1, bdxady0 );
4521         Two_Two_Diff( adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0] );
4522         ab[3] = ab3;
4523         cxablen = scale_expansion_zeroelim( 4, ab, cdx, cxab );
4524         cxxablen = scale_expansion_zeroelim( cxablen, cxab, cdx, cxxab );
4525         cyablen = scale_expansion_zeroelim( 4, ab, cdy, cyab );
4526         cyyablen = scale_expansion_zeroelim( cyablen, cyab, cdy, cyyab );
4527         clen = fast_expansion_sum_zeroelim( cxxablen, cxxab, cyyablen, cyyab, cdet );
4528
4529         ablen = fast_expansion_sum_zeroelim( alen, adet, blen, bdet, abdet );
4530         finlength = fast_expansion_sum_zeroelim( ablen, abdet, clen, cdet, fin1 );
4531
4532         det = estimate( finlength, fin1 );
4533         errbound = (REAL)( iccerrboundB * permanent );
4534         if ( ( det >= errbound ) || ( -det >= errbound ) ) {
4535                 return det;
4536         }
4537
4538         Two_Diff_Tail( pa[0], pd[0], adx, adxtail );
4539         Two_Diff_Tail( pa[1], pd[1], ady, adytail );
4540         Two_Diff_Tail( pb[0], pd[0], bdx, bdxtail );
4541         Two_Diff_Tail( pb[1], pd[1], bdy, bdytail );
4542         Two_Diff_Tail( pc[0], pd[0], cdx, cdxtail );
4543         Two_Diff_Tail( pc[1], pd[1], cdy, cdytail );
4544         if ( ( adxtail == 0.0 ) && ( bdxtail == 0.0 ) && ( cdxtail == 0.0 )
4545                  && ( adytail == 0.0 ) && ( bdytail == 0.0 ) && ( cdytail == 0.0 ) ) {
4546                 return det;
4547         }
4548
4549         errbound = (REAL)( iccerrboundC * permanent + resulterrbound * Absolute( det ) );
4550         det += (REAL)( ( ( adx * adx + ady * ady ) * ( ( bdx * cdytail + cdy * bdxtail )
4551                                                                                                    - ( bdy * cdxtail + cdx * bdytail ) )
4552                                          + 2.0 * ( adx * adxtail + ady * adytail ) * ( bdx * cdy - bdy * cdx ) )
4553                                    + ( ( bdx * bdx + bdy * bdy ) * ( ( cdx * adytail + ady * cdxtail )
4554                                                                                                          - ( cdy * adxtail + adx * cdytail ) )
4555                                            + 2.0 * ( bdx * bdxtail + bdy * bdytail ) * ( cdx * ady - cdy * adx ) )
4556                                    + ( ( cdx * cdx + cdy * cdy ) * ( ( adx * bdytail + bdy * adxtail )
4557                                                                                                          - ( ady * bdxtail + bdx * adytail ) )
4558                                            + 2.0 * ( cdx * cdxtail + cdy * cdytail ) * ( adx * bdy - ady * bdx ) ) );
4559         if ( ( det >= errbound ) || ( -det >= errbound ) ) {
4560                 return det;
4561         }
4562
4563         finnow = fin1;
4564         finother = fin2;
4565
4566         if ( ( bdxtail != 0.0 ) || ( bdytail != 0.0 )
4567                  || ( cdxtail != 0.0 ) || ( cdytail != 0.0 ) ) {
4568                 Square( adx, adxadx1, adxadx0 );
4569                 Square( ady, adyady1, adyady0 );
4570                 Two_Two_Sum( adxadx1, adxadx0, adyady1, adyady0, aa3, aa[2], aa[1], aa[0] );
4571                 aa[3] = aa3;
4572         }
4573         if ( ( cdxtail != 0.0 ) || ( cdytail != 0.0 )
4574                  || ( adxtail != 0.0 ) || ( adytail != 0.0 ) ) {
4575                 Square( bdx, bdxbdx1, bdxbdx0 );
4576                 Square( bdy, bdybdy1, bdybdy0 );
4577                 Two_Two_Sum( bdxbdx1, bdxbdx0, bdybdy1, bdybdy0, bb3, bb[2], bb[1], bb[0] );
4578                 bb[3] = bb3;
4579         }
4580         if ( ( adxtail != 0.0 ) || ( adytail != 0.0 )
4581                  || ( bdxtail != 0.0 ) || ( bdytail != 0.0 ) ) {
4582                 Square( cdx, cdxcdx1, cdxcdx0 );
4583                 Square( cdy, cdycdy1, cdycdy0 );
4584                 Two_Two_Sum( cdxcdx1, cdxcdx0, cdycdy1, cdycdy0, cc3, cc[2], cc[1], cc[0] );
4585                 cc[3] = cc3;
4586         }
4587
4588         if ( adxtail != 0.0 ) {
4589                 axtbclen = scale_expansion_zeroelim( 4, bc, adxtail, axtbc );
4590                 temp16alen = scale_expansion_zeroelim( axtbclen, axtbc, 2.0 * adx,
4591                                                                                            temp16a );
4592
4593                 axtcclen = scale_expansion_zeroelim( 4, cc, adxtail, axtcc );
4594                 temp16blen = scale_expansion_zeroelim( axtcclen, axtcc, bdy, temp16b );
4595
4596                 axtbblen = scale_expansion_zeroelim( 4, bb, adxtail, axtbb );
4597                 temp16clen = scale_expansion_zeroelim( axtbblen, axtbb, -cdy, temp16c );
4598
4599                 temp32alen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4600                                                                                                   temp16blen, temp16b, temp32a );
4601                 temp48len = fast_expansion_sum_zeroelim( temp16clen, temp16c,
4602                                                                                                  temp32alen, temp32a, temp48 );
4603                 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
4604                                                                                                  temp48, finother );
4605                 finswap = finnow; finnow = finother; finother = finswap;
4606         }
4607         if ( adytail != 0.0 ) {
4608                 aytbclen = scale_expansion_zeroelim( 4, bc, adytail, aytbc );
4609                 temp16alen = scale_expansion_zeroelim( aytbclen, aytbc, 2.0 * ady,
4610                                                                                            temp16a );
4611
4612                 aytbblen = scale_expansion_zeroelim( 4, bb, adytail, aytbb );
4613                 temp16blen = scale_expansion_zeroelim( aytbblen, aytbb, cdx, temp16b );
4614
4615                 aytcclen = scale_expansion_zeroelim( 4, cc, adytail, aytcc );
4616                 temp16clen = scale_expansion_zeroelim( aytcclen, aytcc, -bdx, temp16c );
4617
4618                 temp32alen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4619                                                                                                   temp16blen, temp16b, temp32a );
4620                 temp48len = fast_expansion_sum_zeroelim( temp16clen, temp16c,
4621                                                                                                  temp32alen, temp32a, temp48 );
4622                 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
4623                                                                                                  temp48, finother );
4624                 finswap = finnow; finnow = finother; finother = finswap;
4625         }
4626         if ( bdxtail != 0.0 ) {
4627                 bxtcalen = scale_expansion_zeroelim( 4, ca, bdxtail, bxtca );
4628                 temp16alen = scale_expansion_zeroelim( bxtcalen, bxtca, 2.0 * bdx,
4629                                                                                            temp16a );
4630
4631                 bxtaalen = scale_expansion_zeroelim( 4, aa, bdxtail, bxtaa );
4632                 temp16blen = scale_expansion_zeroelim( bxtaalen, bxtaa, cdy, temp16b );
4633
4634                 bxtcclen = scale_expansion_zeroelim( 4, cc, bdxtail, bxtcc );
4635                 temp16clen = scale_expansion_zeroelim( bxtcclen, bxtcc, -ady, temp16c );
4636
4637                 temp32alen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4638                                                                                                   temp16blen, temp16b, temp32a );
4639                 temp48len = fast_expansion_sum_zeroelim( temp16clen, temp16c,
4640                                                                                                  temp32alen, temp32a, temp48 );
4641                 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
4642                                                                                                  temp48, finother );
4643                 finswap = finnow; finnow = finother; finother = finswap;
4644         }
4645         if ( bdytail != 0.0 ) {
4646                 bytcalen = scale_expansion_zeroelim( 4, ca, bdytail, bytca );
4647                 temp16alen = scale_expansion_zeroelim( bytcalen, bytca, 2.0 * bdy,
4648                                                                                            temp16a );
4649
4650                 bytcclen = scale_expansion_zeroelim( 4, cc, bdytail, bytcc );
4651                 temp16blen = scale_expansion_zeroelim( bytcclen, bytcc, adx, temp16b );
4652
4653                 bytaalen = scale_expansion_zeroelim( 4, aa, bdytail, bytaa );
4654                 temp16clen = scale_expansion_zeroelim( bytaalen, bytaa, -cdx, temp16c );
4655
4656                 temp32alen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4657                                                                                                   temp16blen, temp16b, temp32a );
4658                 temp48len = fast_expansion_sum_zeroelim( temp16clen, temp16c,
4659                                                                                                  temp32alen, temp32a, temp48 );
4660                 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
4661                                                                                                  temp48, finother );
4662                 finswap = finnow; finnow = finother; finother = finswap;
4663         }
4664         if ( cdxtail != 0.0 ) {
4665                 cxtablen = scale_expansion_zeroelim( 4, ab, cdxtail, cxtab );
4666                 temp16alen = scale_expansion_zeroelim( cxtablen, cxtab, 2.0 * cdx,
4667                                                                                            temp16a );
4668
4669                 cxtbblen = scale_expansion_zeroelim( 4, bb, cdxtail, cxtbb );
4670                 temp16blen = scale_expansion_zeroelim( cxtbblen, cxtbb, ady, temp16b );
4671
4672                 cxtaalen = scale_expansion_zeroelim( 4, aa, cdxtail, cxtaa );
4673                 temp16clen = scale_expansion_zeroelim( cxtaalen, cxtaa, -bdy, temp16c );
4674
4675                 temp32alen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4676                                                                                                   temp16blen, temp16b, temp32a );
4677                 temp48len = fast_expansion_sum_zeroelim( temp16clen, temp16c,
4678                                                                                                  temp32alen, temp32a, temp48 );
4679                 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
4680                                                                                                  temp48, finother );
4681                 finswap = finnow; finnow = finother; finother = finswap;
4682         }
4683         if ( cdytail != 0.0 ) {
4684                 cytablen = scale_expansion_zeroelim( 4, ab, cdytail, cytab );
4685                 temp16alen = scale_expansion_zeroelim( cytablen, cytab, 2.0 * cdy,
4686                                                                                            temp16a );
4687
4688                 cytaalen = scale_expansion_zeroelim( 4, aa, cdytail, cytaa );
4689                 temp16blen = scale_expansion_zeroelim( cytaalen, cytaa, bdx, temp16b );
4690
4691                 cytbblen = scale_expansion_zeroelim( 4, bb, cdytail, cytbb );
4692                 temp16clen = scale_expansion_zeroelim( cytbblen, cytbb, -adx, temp16c );
4693
4694                 temp32alen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4695                                                                                                   temp16blen, temp16b, temp32a );
4696                 temp48len = fast_expansion_sum_zeroelim( temp16clen, temp16c,
4697                                                                                                  temp32alen, temp32a, temp48 );
4698                 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
4699                                                                                                  temp48, finother );
4700                 finswap = finnow; finnow = finother; finother = finswap;
4701         }
4702
4703         if ( ( adxtail != 0.0 ) || ( adytail != 0.0 ) ) {
4704                 if ( ( bdxtail != 0.0 ) || ( bdytail != 0.0 )
4705                          || ( cdxtail != 0.0 ) || ( cdytail != 0.0 ) ) {
4706                         Two_Product( bdxtail, cdy, ti1, ti0 );
4707                         Two_Product( bdx, cdytail, tj1, tj0 );
4708                         Two_Two_Sum( ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0] );
4709                         u[3] = u3;
4710                         negate = -bdy;
4711                         Two_Product( cdxtail, negate, ti1, ti0 );
4712                         negate = -bdytail;
4713                         Two_Product( cdx, negate, tj1, tj0 );
4714                         Two_Two_Sum( ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0] );
4715                         v[3] = v3;
4716                         bctlen = fast_expansion_sum_zeroelim( 4, u, 4, v, bct );
4717
4718                         Two_Product( bdxtail, cdytail, ti1, ti0 );
4719                         Two_Product( cdxtail, bdytail, tj1, tj0 );
4720                         Two_Two_Diff( ti1, ti0, tj1, tj0, bctt3, bctt[2], bctt[1], bctt[0] );
4721                         bctt[3] = bctt3;
4722                         bcttlen = 4;
4723                 }
4724                 else {
4725                         bct[0] = 0.0;
4726                         bctlen = 1;
4727                         bctt[0] = 0.0;
4728                         bcttlen = 1;
4729                 }
4730
4731                 if ( adxtail != 0.0 ) {
4732                         temp16alen = scale_expansion_zeroelim( axtbclen, axtbc, adxtail, temp16a );
4733                         axtbctlen = scale_expansion_zeroelim( bctlen, bct, adxtail, axtbct );
4734                         temp32alen = scale_expansion_zeroelim( axtbctlen, axtbct, 2.0 * adx,
4735                                                                                                    temp32a );
4736                         temp48len = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4737                                                                                                          temp32alen, temp32a, temp48 );
4738                         finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
4739                                                                                                          temp48, finother );
4740                         finswap = finnow; finnow = finother; finother = finswap;
4741                         if ( bdytail != 0.0 ) {
4742                                 temp8len = scale_expansion_zeroelim( 4, cc, adxtail, temp8 );
4743                                 temp16alen = scale_expansion_zeroelim( temp8len, temp8, bdytail,
4744                                                                                                            temp16a );
4745                                 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp16alen,
4746                                                                                                                  temp16a, finother );
4747                                 finswap = finnow; finnow = finother; finother = finswap;
4748                         }
4749                         if ( cdytail != 0.0 ) {
4750                                 temp8len = scale_expansion_zeroelim( 4, bb, -adxtail, temp8 );
4751                                 temp16alen = scale_expansion_zeroelim( temp8len, temp8, cdytail,
4752                                                                                                            temp16a );
4753                                 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp16alen,
4754                                                                                                                  temp16a, finother );
4755                                 finswap = finnow; finnow = finother; finother = finswap;
4756                         }
4757
4758                         temp32alen = scale_expansion_zeroelim( axtbctlen, axtbct, adxtail,
4759                                                                                                    temp32a );
4760                         axtbcttlen = scale_expansion_zeroelim( bcttlen, bctt, adxtail, axtbctt );
4761                         temp16alen = scale_expansion_zeroelim( axtbcttlen, axtbctt, 2.0 * adx,
4762                                                                                                    temp16a );
4763                         temp16blen = scale_expansion_zeroelim( axtbcttlen, axtbctt, adxtail,
4764                                                                                                    temp16b );
4765                         temp32blen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4766                                                                                                           temp16blen, temp16b, temp32b );
4767                         temp64len = fast_expansion_sum_zeroelim( temp32alen, temp32a,
4768                                                                                                          temp32blen, temp32b, temp64 );
4769                         finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp64len,
4770                                                                                                          temp64, finother );
4771                         finswap = finnow; finnow = finother; finother = finswap;
4772                 }
4773                 if ( adytail != 0.0 ) {
4774                         temp16alen = scale_expansion_zeroelim( aytbclen, aytbc, adytail, temp16a );
4775                         aytbctlen = scale_expansion_zeroelim( bctlen, bct, adytail, aytbct );
4776                         temp32alen = scale_expansion_zeroelim( aytbctlen, aytbct, 2.0 * ady,
4777                                                                                                    temp32a );
4778                         temp48len = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4779                                                                                                          temp32alen, temp32a, temp48 );
4780                         finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
4781                                                                                                          temp48, finother );
4782                         finswap = finnow; finnow = finother; finother = finswap;
4783
4784
4785                         temp32alen = scale_expansion_zeroelim( aytbctlen, aytbct, adytail,
4786                                                                                                    temp32a );
4787                         aytbcttlen = scale_expansion_zeroelim( bcttlen, bctt, adytail, aytbctt );
4788                         temp16alen = scale_expansion_zeroelim( aytbcttlen, aytbctt, 2.0 * ady,
4789                                                                                                    temp16a );
4790                         temp16blen = scale_expansion_zeroelim( aytbcttlen, aytbctt, adytail,
4791                                                                                                    temp16b );
4792                         temp32blen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4793                                                                                                           temp16blen, temp16b, temp32b );
4794                         temp64len = fast_expansion_sum_zeroelim( temp32alen, temp32a,
4795                                                                                                          temp32blen, temp32b, temp64 );
4796                         finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp64len,
4797                                                                                                          temp64, finother );
4798                         finswap = finnow; finnow = finother; finother = finswap;
4799                 }
4800         }
4801         if ( ( bdxtail != 0.0 ) || ( bdytail != 0.0 ) ) {
4802                 if ( ( cdxtail != 0.0 ) || ( cdytail != 0.0 )
4803                          || ( adxtail != 0.0 ) || ( adytail != 0.0 ) ) {
4804                         Two_Product( cdxtail, ady, ti1, ti0 );
4805                         Two_Product( cdx, adytail, tj1, tj0 );
4806                         Two_Two_Sum( ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0] );
4807                         u[3] = u3;
4808                         negate = -cdy;
4809                         Two_Product( adxtail, negate, ti1, ti0 );
4810                         negate = -cdytail;
4811                         Two_Product( adx, negate, tj1, tj0 );
4812                         Two_Two_Sum( ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0] );
4813                         v[3] = v3;
4814                         catlen = fast_expansion_sum_zeroelim( 4, u, 4, v, cat );
4815
4816                         Two_Product( cdxtail, adytail, ti1, ti0 );
4817                         Two_Product( adxtail, cdytail, tj1, tj0 );
4818                         Two_Two_Diff( ti1, ti0, tj1, tj0, catt3, catt[2], catt[1], catt[0] );
4819                         catt[3] = catt3;
4820                         cattlen = 4;
4821                 }
4822                 else {
4823                         cat[0] = 0.0;
4824                         catlen = 1;
4825                         catt[0] = 0.0;
4826                         cattlen = 1;
4827                 }
4828
4829                 if ( bdxtail != 0.0 ) {
4830                         temp16alen = scale_expansion_zeroelim( bxtcalen, bxtca, bdxtail, temp16a );
4831                         bxtcatlen = scale_expansion_zeroelim( catlen, cat, bdxtail, bxtcat );
4832                         temp32alen = scale_expansion_zeroelim( bxtcatlen, bxtcat, 2.0 * bdx,
4833                                                                                                    temp32a );
4834                         temp48len = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4835                                                                                                          temp32alen, temp32a, temp48 );
4836                         finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
4837                                                                                                          temp48, finother );
4838                         finswap = finnow; finnow = finother; finother = finswap;
4839                         if ( cdytail != 0.0 ) {
4840                                 temp8len = scale_expansion_zeroelim( 4, aa, bdxtail, temp8 );
4841                                 temp16alen = scale_expansion_zeroelim( temp8len, temp8, cdytail,
4842                                                                                                            temp16a );
4843                                 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp16alen,
4844                                                                                                                  temp16a, finother );
4845                                 finswap = finnow; finnow = finother; finother = finswap;
4846                         }
4847                         if ( adytail != 0.0 ) {
4848                                 temp8len = scale_expansion_zeroelim( 4, cc, -bdxtail, temp8 );
4849                                 temp16alen = scale_expansion_zeroelim( temp8len, temp8, adytail,
4850                                                                                                            temp16a );
4851                                 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp16alen,
4852                                                                                                                  temp16a, finother );
4853                                 finswap = finnow; finnow = finother; finother = finswap;
4854                         }
4855
4856                         temp32alen = scale_expansion_zeroelim( bxtcatlen, bxtcat, bdxtail,
4857                                                                                                    temp32a );
4858                         bxtcattlen = scale_expansion_zeroelim( cattlen, catt, bdxtail, bxtcatt );
4859                         temp16alen = scale_expansion_zeroelim( bxtcattlen, bxtcatt, 2.0 * bdx,
4860                                                                                                    temp16a );
4861                         temp16blen = scale_expansion_zeroelim( bxtcattlen, bxtcatt, bdxtail,
4862                                                                                                    temp16b );
4863                         temp32blen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4864                                                                                                           temp16blen, temp16b, temp32b );
4865                         temp64len = fast_expansion_sum_zeroelim( temp32alen, temp32a,
4866                                                                                                          temp32blen, temp32b, temp64 );
4867                         finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp64len,
4868                                                                                                          temp64, finother );
4869                         finswap = finnow; finnow = finother; finother = finswap;
4870                 }
4871                 if ( bdytail != 0.0 ) {
4872                         temp16alen = scale_expansion_zeroelim( bytcalen, bytca, bdytail, temp16a );
4873                         bytcatlen = scale_expansion_zeroelim( catlen, cat, bdytail, bytcat );
4874                         temp32alen = scale_expansion_zeroelim( bytcatlen, bytcat, 2.0 * bdy,
4875                                                                                                    temp32a );
4876                         temp48len = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4877                                                                                                          temp32alen, temp32a, temp48 );
4878                         finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
4879                                                                                                          temp48, finother );
4880                         finswap = finnow; finnow = finother; finother = finswap;
4881
4882
4883                         temp32alen = scale_expansion_zeroelim( bytcatlen, bytcat, bdytail,
4884                                                                                                    temp32a );
4885                         bytcattlen = scale_expansion_zeroelim( cattlen, catt, bdytail, bytcatt );
4886                         temp16alen = scale_expansion_zeroelim( bytcattlen, bytcatt, 2.0 * bdy,
4887                                                                                                    temp16a );
4888                         temp16blen = scale_expansion_zeroelim( bytcattlen, bytcatt, bdytail,
4889                                                                                                    temp16b );
4890                         temp32blen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4891                                                                                                           temp16blen, temp16b, temp32b );
4892                         temp64len = fast_expansion_sum_zeroelim( temp32alen, temp32a,
4893                                                                                                          temp32blen, temp32b, temp64 );
4894                         finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp64len,
4895                                                                                                          temp64, finother );
4896                         finswap = finnow; finnow = finother; finother = finswap;
4897                 }
4898         }
4899         if ( ( cdxtail != 0.0 ) || ( cdytail != 0.0 ) ) {
4900                 if ( ( adxtail != 0.0 ) || ( adytail != 0.0 )
4901                          || ( bdxtail != 0.0 ) || ( bdytail != 0.0 ) ) {
4902                         Two_Product( adxtail, bdy, ti1, ti0 );
4903                         Two_Product( adx, bdytail, tj1, tj0 );
4904                         Two_Two_Sum( ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0] );
4905                         u[3] = u3;
4906                         negate = -ady;
4907                         Two_Product( bdxtail, negate, ti1, ti0 );
4908                         negate = -adytail;
4909                         Two_Product( bdx, negate, tj1, tj0 );
4910                         Two_Two_Sum( ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0] );
4911                         v[3] = v3;
4912                         abtlen = fast_expansion_sum_zeroelim( 4, u, 4, v, abt );
4913
4914                         Two_Product( adxtail, bdytail, ti1, ti0 );
4915                         Two_Product( bdxtail, adytail, tj1, tj0 );
4916                         Two_Two_Diff( ti1, ti0, tj1, tj0, abtt3, abtt[2], abtt[1], abtt[0] );
4917                         abtt[3] = abtt3;
4918                         abttlen = 4;
4919                 }
4920                 else {
4921                         abt[0] = 0.0;
4922                         abtlen = 1;
4923                         abtt[0] = 0.0;
4924                         abttlen = 1;
4925                 }
4926
4927                 if ( cdxtail != 0.0 ) {
4928                         temp16alen = scale_expansion_zeroelim( cxtablen, cxtab, cdxtail, temp16a );
4929                         cxtabtlen = scale_expansion_zeroelim( abtlen, abt, cdxtail, cxtabt );
4930                         temp32alen = scale_expansion_zeroelim( cxtabtlen, cxtabt, 2.0 * cdx,
4931                                                                                                    temp32a );
4932                         temp48len = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4933                                                                                                          temp32alen, temp32a, temp48 );
4934                         finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
4935                                                                                                          temp48, finother );
4936                         finswap = finnow; finnow = finother; finother = finswap;
4937                         if ( adytail != 0.0 ) {
4938                                 temp8len = scale_expansion_zeroelim( 4, bb, cdxtail, temp8 );
4939                                 temp16alen = scale_expansion_zeroelim( temp8len, temp8, adytail,
4940                                                                                                            temp16a );
4941                                 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp16alen,
4942                                                                                                                  temp16a, finother );
4943                                 finswap = finnow; finnow = finother; finother = finswap;
4944                         }
4945                         if ( bdytail != 0.0 ) {
4946                                 temp8len = scale_expansion_zeroelim( 4, aa, -cdxtail, temp8 );
4947                                 temp16alen = scale_expansion_zeroelim( temp8len, temp8, bdytail,
4948                                                                                                            temp16a );
4949                                 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp16alen,
4950                                                                                                                  temp16a, finother );
4951                                 finswap = finnow; finnow = finother; finother = finswap;
4952                         }
4953
4954                         temp32alen = scale_expansion_zeroelim( cxtabtlen, cxtabt, cdxtail,
4955                                                                                                    temp32a );
4956                         cxtabttlen = scale_expansion_zeroelim( abttlen, abtt, cdxtail, cxtabtt );
4957                         temp16alen = scale_expansion_zeroelim( cxtabttlen, cxtabtt, 2.0 * cdx,
4958                                                                                                    temp16a );
4959                         temp16blen = scale_expansion_zeroelim( cxtabttlen, cxtabtt, cdxtail,
4960                                                                                                    temp16b );
4961                         temp32blen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4962                                                                                                           temp16blen, temp16b, temp32b );
4963                         temp64len = fast_expansion_sum_zeroelim( temp32alen, temp32a,
4964                                                                                                          temp32blen, temp32b, temp64 );
4965                         finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp64len,
4966                                                                                                          temp64, finother );
4967                         finswap = finnow; finnow = finother; finother = finswap;
4968                 }
4969                 if ( cdytail != 0.0 ) {
4970                         temp16alen = scale_expansion_zeroelim( cytablen, cytab, cdytail, temp16a );
4971                         cytabtlen = scale_expansion_zeroelim( abtlen, abt, cdytail, cytabt );
4972                         temp32alen = scale_expansion_zeroelim( cytabtlen, cytabt, 2.0 * cdy,
4973                                                                                                    temp32a );
4974                         temp48len = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4975                                                                                                          temp32alen, temp32a, temp48 );
4976                         finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
4977                                                                                                          temp48, finother );
4978                         finswap = finnow; finnow = finother; finother = finswap;
4979
4980
4981                         temp32alen = scale_expansion_zeroelim( cytabtlen, cytabt, cdytail,
4982                                                                                                    temp32a );
4983                         cytabttlen = scale_expansion_zeroelim( abttlen, abtt, cdytail, cytabtt );
4984                         temp16alen = scale_expansion_zeroelim( cytabttlen, cytabtt, 2.0 * cdy,
4985                                                                                                    temp16a );
4986                         temp16blen = scale_expansion_zeroelim( cytabttlen, cytabtt, cdytail,
4987                                                                                                    temp16b );
4988                         temp32blen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4989                                                                                                           temp16blen, temp16b, temp32b );
4990                         temp64len = fast_expansion_sum_zeroelim( temp32alen, temp32a,
4991                                                                                                          temp32blen, temp32b, temp64 );
4992                         finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp64len,
4993                                                                                                          temp64, finother );
4994                         finswap = finnow; finnow = finother; finother = finswap;
4995                 }
4996         }
4997
4998         return finnow[finlength - 1];
4999 }
5000
5001 REAL incircle( pa, pb, pc, pd )
5002 point pa;
5003 point pb;
5004 point pc;
5005 point pd;
5006 {
5007         REAL adx, bdx, cdx, ady, bdy, cdy;
5008         REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
5009         REAL alift, blift, clift;
5010         REAL det;
5011         REAL permanent, errbound;
5012
5013         incirclecount++;
5014
5015         adx = pa[0] - pd[0];
5016         bdx = pb[0] - pd[0];
5017         cdx = pc[0] - pd[0];
5018         ady = pa[1] - pd[1];
5019         bdy = pb[1] - pd[1];
5020         cdy = pc[1] - pd[1];
5021
5022         bdxcdy = bdx * cdy;
5023         cdxbdy = cdx * bdy;
5024         alift = adx * adx + ady * ady;
5025
5026         cdxady = cdx * ady;
5027         adxcdy = adx * cdy;
5028         blift = bdx * bdx + bdy * bdy;
5029
5030         adxbdy = adx * bdy;
5031         bdxady = bdx * ady;
5032         clift = cdx * cdx + cdy * cdy;
5033
5034         det = alift * ( bdxcdy - cdxbdy )
5035                   + blift * ( cdxady - adxcdy )
5036                   + clift * ( adxbdy - bdxady );
5037
5038         if ( noexact ) {
5039                 return det;
5040         }
5041
5042         permanent = ( Absolute( bdxcdy ) + Absolute( cdxbdy ) ) * alift
5043                                 + ( Absolute( cdxady ) + Absolute( adxcdy ) ) * blift
5044                                 + ( Absolute( adxbdy ) + Absolute( bdxady ) ) * clift;
5045         errbound = iccerrboundA * permanent;
5046         if ( ( det > errbound ) || ( -det > errbound ) ) {
5047                 return det;
5048         }
5049
5050         return incircleadapt( pa, pb, pc, pd, permanent );
5051 }
5052
5053 /**                                                                         **/
5054 /**                                                                         **/
5055 /********* Determinant evaluation routines end here                  *********/
5056
5057 /*****************************************************************************/
5058 /*                                                                           */
5059 /*  triangleinit()   Initialize some variables.                              */
5060 /*                                                                           */
5061 /*****************************************************************************/
5062
5063 void triangleinit(){
5064         points.maxitems = triangles.maxitems = shelles.maxitems = viri.maxitems =
5065                                                                                                                                   badsegments.maxitems = badtriangles.maxitems = splaynodes.maxitems = 0l;
5066         points.itembytes = triangles.itembytes = shelles.itembytes = viri.itembytes =
5067                                                                                                                                          badsegments.itembytes = badtriangles.itembytes = splaynodes.itembytes = 0;
5068         recenttri.tri = (triangle *) NULL;  /* No triangle has been visited yet. */
5069         samples = 1;          /* Point location should take at least one sample. */
5070         checksegments = 0;    /* There are no segments in the triangulation yet. */
5071         incirclecount = counterclockcount = hyperbolacount = 0;
5072         circumcentercount = circletopcount = 0;
5073         randomseed = 1;
5074
5075         exactinit();                   /* Initialize exact arithmetic constants. */
5076 }
5077
5078 /*****************************************************************************/
5079 /*                                                                           */
5080 /*  randomnation()   Generate a random number between 0 and `choices' - 1.   */
5081 /*                                                                           */
5082 /*  This is a simple linear congruential random number generator.  Hence, it */
5083 /*  is a bad random number generator, but good enough for most randomized    */
5084 /*  geometric algorithms.                                                    */
5085 /*                                                                           */
5086 /*****************************************************************************/
5087
5088 unsigned long randomnation( choices )
5089 unsigned int choices;
5090 {
5091         randomseed = ( randomseed * 1366l + 150889l ) % 714025l;
5092         return randomseed / ( 714025l / choices + 1 );
5093 }
5094
5095 /********* Mesh quality testing routines begin here                  *********/
5096 /**                                                                         **/
5097 /**                                                                         **/
5098
5099 /*****************************************************************************/
5100 /*                                                                           */
5101 /*  checkmesh()   Test the mesh for topological consistency.                 */
5102 /*                                                                           */
5103 /*****************************************************************************/
5104
5105 #ifndef REDUCED
5106
5107 void checkmesh(){
5108         struct triedge triangleloop;
5109         struct triedge oppotri, oppooppotri;
5110         point triorg, tridest, triapex;
5111         point oppoorg, oppodest;
5112         int horrors;
5113         int saveexact;
5114         triangle ptr;                       /* Temporary variable used by sym(). */
5115
5116         /* Temporarily turn on exact arithmetic if it's off. */
5117         saveexact = noexact;
5118         noexact = 0;
5119         if ( !quiet ) {
5120                 printf( "  Checking consistency of mesh...\n" );
5121         }
5122         horrors = 0;
5123         /* Run through the list of triangles, checking each one. */
5124         traversalinit( &triangles );
5125         triangleloop.tri = triangletraverse();
5126         while ( triangleloop.tri != (triangle *) NULL ) {
5127                 /* Check all three edges of the triangle. */
5128                 for ( triangleloop.orient = 0; triangleloop.orient < 3;
5129                           triangleloop.orient++ ) {
5130                         org( triangleloop, triorg );
5131                         dest( triangleloop, tridest );
5132                         if ( triangleloop.orient == 0 ) { /* Only test for inversion once. */
5133                                 /* Test if the triangle is flat or inverted. */
5134                                 apex( triangleloop, triapex );
5135                                 if ( counterclockwise( triorg, tridest, triapex ) <= 0.0 ) {
5136                                         printf( "  !! !! Inverted " );
5137                                         printtriangle( &triangleloop );
5138                                         horrors++;
5139                                 }
5140                         }
5141                         /* Find the neighboring triangle on this edge. */
5142                         sym( triangleloop, oppotri );
5143                         if ( oppotri.tri != dummytri ) {
5144                                 /* Check that the triangle's neighbor knows it's a neighbor. */
5145                                 sym( oppotri, oppooppotri );
5146                                 if ( ( triangleloop.tri != oppooppotri.tri )
5147                                          || ( triangleloop.orient != oppooppotri.orient ) ) {
5148                                         printf( "  !! !! Asymmetric triangle-triangle bond:\n" );
5149                                         if ( triangleloop.tri == oppooppotri.tri ) {
5150                                                 printf( "   (Right triangle, wrong orientation)\n" );
5151                                         }
5152                                         printf( "    First " );
5153                                         printtriangle( &triangleloop );
5154                                         printf( "    Second (nonreciprocating) " );
5155                                         printtriangle( &oppotri );
5156                                         horrors++;
5157                                 }
5158                                 /* Check that both triangles agree on the identities */
5159                                 /*   of their shared vertices.                       */
5160                                 org( oppotri, oppoorg );
5161                                 dest( oppotri, oppodest );
5162                                 if ( ( triorg != oppodest ) || ( tridest != oppoorg ) ) {
5163                                         printf( "  !! !! Mismatched edge coordinates between two triangles:\n"
5164                                                         );
5165                                         printf( "    First mismatched " );
5166                                         printtriangle( &triangleloop );
5167                                         printf( "    Second mismatched " );
5168                                         printtriangle( &oppotri );
5169                                         horrors++;
5170                                 }
5171                         }
5172                 }
5173                 triangleloop.tri = triangletraverse();
5174         }
5175         if ( horrors == 0 ) {
5176                 if ( !quiet ) {
5177                         printf( "  In my studied opinion, the mesh appears to be consistent.\n" );
5178                 }
5179         }
5180         else if ( horrors == 1 ) {
5181                 printf( "  !! !! !! !! Precisely one festering wound discovered.\n" );
5182         }
5183         else {
5184                 printf( "  !! !! !! !! %d abominations witnessed.\n", horrors );
5185         }
5186         /* Restore the status of exact arithmetic. */
5187         noexact = saveexact;
5188 }
5189
5190 #endif /* not REDUCED */
5191
5192 /*****************************************************************************/
5193 /*                                                                           */
5194 /*  checkdelaunay()   Ensure that the mesh is (constrained) Delaunay.        */
5195 /*                                                                           */
5196 /*****************************************************************************/
5197
5198 #ifndef REDUCED
5199
5200 void checkdelaunay(){
5201         struct triedge triangleloop;
5202         struct triedge oppotri;
5203         struct edge opposhelle;
5204         point triorg, tridest, triapex;
5205         point oppoapex;
5206         int shouldbedelaunay;
5207         int horrors;
5208         int saveexact;
5209         triangle ptr;                       /* Temporary variable used by sym(). */
5210         shelle sptr;                    /* Temporary variable used by tspivot(). */
5211
5212         /* Temporarily turn on exact arithmetic if it's off. */
5213         saveexact = noexact;
5214         noexact = 0;
5215         if ( !quiet ) {
5216                 printf( "  Checking Delaunay property of mesh...\n" );
5217         }
5218         horrors = 0;
5219         /* Run through the list of triangles, checking each one. */
5220         traversalinit( &triangles );
5221         triangleloop.tri = triangletraverse();
5222         while ( triangleloop.tri != (triangle *) NULL ) {
5223                 /* Check all three edges of the triangle. */
5224                 for ( triangleloop.orient = 0; triangleloop.orient < 3;
5225                           triangleloop.orient++ ) {
5226                         org( triangleloop, triorg );
5227                         dest( triangleloop, tridest );
5228                         apex( triangleloop, triapex );
5229                         sym( triangleloop, oppotri );
5230                         apex( oppotri, oppoapex );
5231                         /* Only test that the edge is locally Delaunay if there is an   */
5232                         /*   adjoining triangle whose pointer is larger (to ensure that */
5233                         /*   each pair isn't tested twice).                             */
5234                         shouldbedelaunay = ( oppotri.tri != dummytri )
5235                                                            && ( triapex != (point) NULL ) && ( oppoapex != (point) NULL )
5236                                                            && ( triangleloop.tri < oppotri.tri );
5237                         if ( checksegments && shouldbedelaunay ) {
5238                                 /* If a shell edge separates the triangles, then the edge is */
5239                                 /*   constrained, so no local Delaunay test should be done.  */
5240                                 tspivot( triangleloop, opposhelle );
5241                                 if ( opposhelle.sh != dummysh ) {
5242                                         shouldbedelaunay = 0;
5243                                 }
5244                         }
5245                         if ( shouldbedelaunay ) {
5246                                 if ( incircle( triorg, tridest, triapex, oppoapex ) > 0.0 ) {
5247                                         printf( "  !! !! Non-Delaunay pair of triangles:\n" );
5248                                         printf( "    First non-Delaunay " );
5249                                         printtriangle( &triangleloop );
5250                                         printf( "    Second non-Delaunay " );
5251                                         printtriangle( &oppotri );
5252                                         horrors++;
5253                                 }
5254                         }
5255                 }
5256                 triangleloop.tri = triangletraverse();
5257         }
5258         if ( horrors == 0 ) {
5259                 if ( !quiet ) {
5260                         printf(
5261                                 "  By virtue of my perceptive intelligence, I declare the mesh Delaunay.\n" );
5262                 }
5263         }
5264         else if ( horrors == 1 ) {
5265                 printf(
5266                         "  !! !! !! !! Precisely one terrifying transgression identified.\n" );
5267         }
5268         else {
5269                 printf( "  !! !! !! !! %d obscenities viewed with horror.\n", horrors );
5270         }
5271         /* Restore the status of exact arithmetic. */
5272         noexact = saveexact;
5273 }
5274
5275 #endif /* not REDUCED */
5276
5277 /*****************************************************************************/
5278 /*                                                                           */
5279 /*  enqueuebadtri()   Add a bad triangle to the end of a queue.              */
5280 /*                                                                           */
5281 /*  The queue is actually a set of 64 queues.  I use multiple queues to give */
5282 /*  priority to smaller angles.  I originally implemented a heap, but the    */
5283 /*  queues are (to my surprise) much faster.                                 */
5284 /*                                                                           */
5285 /*****************************************************************************/
5286
5287 #ifndef CDT_ONLY
5288
5289 void enqueuebadtri( instri, angle, insapex, insorg, insdest )
5290 struct triedge *instri;
5291 REAL angle;
5292 point insapex;
5293 point insorg;
5294 point insdest;
5295 {
5296         struct badface *newface;
5297         int queuenumber;
5298
5299         if ( verbose > 2 ) {
5300                 printf( "  Queueing bad triangle:\n" );
5301                 printf( "    (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n", insorg[0],
5302                                 insorg[1], insdest[0], insdest[1], insapex[0], insapex[1] );
5303         }
5304         /* Allocate space for the bad triangle. */
5305         newface = (struct badface *) poolalloc( &badtriangles );
5306         triedgecopy( *instri, newface->badfacetri );
5307         newface->key = angle;
5308         newface->faceapex = insapex;
5309         newface->faceorg = insorg;
5310         newface->facedest = insdest;
5311         newface->nextface = (struct badface *) NULL;
5312         /* Determine the appropriate queue to put the bad triangle into. */
5313         if ( angle > 0.6 ) {
5314                 queuenumber = (int) ( 160.0 * ( angle - 0.6 ) );
5315                 if ( queuenumber > 63 ) {
5316                         queuenumber = 63;
5317                 }
5318         }
5319         else {
5320                 /* It's not a bad angle; put the triangle in the lowest-priority queue. */
5321                 queuenumber = 0;
5322         }
5323         /* Add the triangle to the end of a queue. */
5324         *queuetail[queuenumber] = newface;
5325         /* Maintain a pointer to the NULL pointer at the end of the queue. */
5326         queuetail[queuenumber] = &newface->nextface;
5327 }
5328
5329 #endif /* not CDT_ONLY */
5330
5331 /*****************************************************************************/
5332 /*                                                                           */
5333 /*  dequeuebadtri()   Remove a triangle from the front of the queue.         */
5334 /*                                                                           */
5335 /*****************************************************************************/
5336
5337 #ifndef CDT_ONLY
5338
5339 struct badface *dequeuebadtri(){
5340         struct badface *result;
5341         int queuenumber;
5342
5343         /* Look for a nonempty queue. */
5344         for ( queuenumber = 63; queuenumber >= 0; queuenumber-- ) {
5345                 result = queuefront[queuenumber];
5346                 if ( result != (struct badface *) NULL ) {
5347                         /* Remove the triangle from the queue. */
5348                         queuefront[queuenumber] = result->nextface;
5349                         /* Maintain a pointer to the NULL pointer at the end of the queue. */
5350                         if ( queuefront[queuenumber] == (struct badface *) NULL ) {
5351                                 queuetail[queuenumber] = &queuefront[queuenumber];
5352                         }
5353                         return result;
5354                 }
5355         }
5356         return (struct badface *) NULL;
5357 }
5358
5359 #endif /* not CDT_ONLY */
5360
5361 /*****************************************************************************/
5362 /*                                                                           */
5363 /*  checkedge4encroach()   Check a segment to see if it is encroached; add   */
5364 /*                         it to the list if it is.                          */
5365 /*                                                                           */
5366 /*  An encroached segment is an unflippable edge that has a point in its     */
5367 /*  diametral circle (that is, it faces an angle greater than 90 degrees).   */
5368 /*  This definition is due to Ruppert.                                       */
5369 /*                                                                           */
5370 /*  Returns a nonzero value if the edge is encroached.                       */
5371 /*                                                                           */
5372 /*****************************************************************************/
5373
5374 #ifndef CDT_ONLY
5375
5376 int checkedge4encroach( testedge )
5377 struct edge *testedge;
5378 {
5379         struct triedge neighbortri;
5380         struct edge testsym;
5381         struct edge *badedge;
5382         int addtolist;
5383         int sides;
5384         point eorg, edest, eapex;
5385         triangle ptr;                   /* Temporary variable used by stpivot(). */
5386
5387         addtolist = 0;
5388         sides = 0;
5389
5390         sorg( *testedge, eorg );
5391         sdest( *testedge, edest );
5392         /* Check one neighbor of the shell edge. */
5393         stpivot( *testedge, neighbortri );
5394         /* Does the neighbor exist, or is this a boundary edge? */
5395         if ( neighbortri.tri != dummytri ) {
5396                 sides++;
5397                 /* Find a vertex opposite this edge. */
5398                 apex( neighbortri, eapex );
5399                 /* Check whether the vertex is inside the diametral circle of the  */
5400                 /*   shell edge.  Pythagoras' Theorem is used to check whether the */
5401                 /*   angle at the vertex is greater than 90 degrees.               */
5402                 if ( eapex[0] * ( eorg[0] + edest[0] ) + eapex[1] * ( eorg[1] + edest[1] ) >
5403                          eapex[0] * eapex[0] + eorg[0] * edest[0] +
5404                          eapex[1] * eapex[1] + eorg[1] * edest[1] ) {
5405                         addtolist = 1;
5406                 }
5407         }
5408         /* Check the other neighbor of the shell edge. */
5409         ssym( *testedge, testsym );
5410         stpivot( testsym, neighbortri );
5411         /* Does the neighbor exist, or is this a boundary edge? */
5412         if ( neighbortri.tri != dummytri ) {
5413                 sides++;
5414                 /* Find the other vertex opposite this edge. */
5415                 apex( neighbortri, eapex );
5416                 /* Check whether the vertex is inside the diametral circle of the  */
5417                 /*   shell edge.  Pythagoras' Theorem is used to check whether the */
5418                 /*   angle at the vertex is greater than 90 degrees.               */
5419                 if ( eapex[0] * ( eorg[0] + edest[0] ) +
5420                          eapex[1] * ( eorg[1] + edest[1] ) >
5421                          eapex[0] * eapex[0] + eorg[0] * edest[0] +
5422                          eapex[1] * eapex[1] + eorg[1] * edest[1] ) {
5423                         addtolist += 2;
5424                 }
5425         }
5426
5427         if ( addtolist && ( !nobisect || ( ( nobisect == 1 ) && ( sides == 2 ) ) ) ) {
5428                 if ( verbose > 2 ) {
5429                         printf( "  Queueing encroached segment (%.12g, %.12g) (%.12g, %.12g).\n",
5430                                         eorg[0], eorg[1], edest[0], edest[1] );
5431                 }
5432                 /* Add the shell edge to the list of encroached segments. */
5433                 /*   Be sure to get the orientation right.                */
5434                 badedge = (struct edge *) poolalloc( &badsegments );
5435                 if ( addtolist == 1 ) {
5436                         shellecopy( *testedge, *badedge );
5437                 }
5438                 else {
5439                         shellecopy( testsym, *badedge );
5440                 }
5441         }
5442         return addtolist;
5443 }
5444
5445 #endif /* not CDT_ONLY */
5446
5447 /*****************************************************************************/
5448 /*                                                                           */
5449 /*  testtriangle()   Test a face for quality measures.                       */
5450 /*                                                                           */
5451 /*  Tests a triangle to see if it satisfies the minimum angle condition and  */
5452 /*  the maximum area condition.  Triangles that aren't up to spec are added  */
5453 /*  to the bad triangle queue.                                               */
5454 /*                                                                           */
5455 /*****************************************************************************/
5456
5457 #ifndef CDT_ONLY
5458
5459 void testtriangle( testtri )
5460 struct triedge *testtri;
5461 {
5462         struct triedge sametesttri;
5463         struct edge edge1, edge2;
5464         point torg, tdest, tapex;
5465         point anglevertex;
5466         REAL dxod, dyod, dxda, dyda, dxao, dyao;
5467         REAL dxod2, dyod2, dxda2, dyda2, dxao2, dyao2;
5468         REAL apexlen, orglen, destlen;
5469         REAL angle;
5470         REAL area;
5471         shelle sptr;                    /* Temporary variable used by tspivot(). */
5472
5473         org( *testtri, torg );
5474         dest( *testtri, tdest );
5475         apex( *testtri, tapex );
5476         dxod = torg[0] - tdest[0];
5477         dyod = torg[1] - tdest[1];
5478         dxda = tdest[0] - tapex[0];
5479         dyda = tdest[1] - tapex[1];
5480         dxao = tapex[0] - torg[0];
5481         dyao = tapex[1] - torg[1];
5482         dxod2 = dxod * dxod;
5483         dyod2 = dyod * dyod;
5484         dxda2 = dxda * dxda;
5485         dyda2 = dyda * dyda;
5486         dxao2 = dxao * dxao;
5487         dyao2 = dyao * dyao;
5488         /* Find the lengths of the triangle's three edges. */
5489         apexlen = dxod2 + dyod2;
5490         orglen = dxda2 + dyda2;
5491         destlen = dxao2 + dyao2;
5492         if ( ( apexlen < orglen ) && ( apexlen < destlen ) ) {
5493                 /* The edge opposite the apex is shortest. */
5494                 /* Find the square of the cosine of the angle at the apex. */
5495                 angle = dxda * dxao + dyda * dyao;
5496                 angle = angle * angle / ( orglen * destlen );
5497                 anglevertex = tapex;
5498                 lnext( *testtri, sametesttri );
5499                 tspivot( sametesttri, edge1 );
5500                 lnextself( sametesttri );
5501                 tspivot( sametesttri, edge2 );
5502         }
5503         else if ( orglen < destlen ) {
5504                 /* The edge opposite the origin is shortest. */
5505                 /* Find the square of the cosine of the angle at the origin. */
5506                 angle = dxod * dxao + dyod * dyao;
5507                 angle = angle * angle / ( apexlen * destlen );
5508                 anglevertex = torg;
5509                 tspivot( *testtri, edge1 );
5510                 lprev( *testtri, sametesttri );
5511                 tspivot( sametesttri, edge2 );
5512         }
5513         else {
5514                 /* The edge opposite the destination is shortest. */
5515                 /* Find the square of the cosine of the angle at the destination. */
5516                 angle = dxod * dxda + dyod * dyda;
5517                 angle = angle * angle / ( apexlen * orglen );
5518                 anglevertex = tdest;
5519                 tspivot( *testtri, edge1 );
5520                 lnext( *testtri, sametesttri );
5521                 tspivot( sametesttri, edge2 );
5522         }
5523         /* Check if both edges that form the angle are segments. */
5524         if ( ( edge1.sh != dummysh ) && ( edge2.sh != dummysh ) ) {
5525                 /* The angle is a segment intersection. */
5526                 if ( ( angle > 0.9924 ) && !quiet ) {          /* Roughly 5 degrees. */
5527                         if ( angle > 1.0 ) {
5528                                 /* Beware of a floating exception in acos(). */
5529                                 angle = 1.0;
5530                         }
5531                         /* Find the actual angle in degrees, for printing. */
5532                         angle = acos( sqrt( angle ) ) * ( 180.0 / PI );
5533                         printf(
5534                                 "Warning:  Small angle (%.4g degrees) between segments at point\n",
5535                                 angle );
5536                         printf( "  (%.12g, %.12g)\n", anglevertex[0], anglevertex[1] );
5537                 }
5538                 /* Don't add this bad triangle to the list; there's nothing that */
5539                 /*   can be done about a small angle between two segments.       */
5540                 angle = 0.0;
5541         }
5542         /* Check whether the angle is smaller than permitted. */
5543         if ( angle > goodangle ) {
5544                 /* Add this triangle to the list of bad triangles. */
5545                 enqueuebadtri( testtri, angle, tapex, torg, tdest );
5546                 return;
5547         }
5548         if ( vararea || fixedarea ) {
5549                 /* Check whether the area is larger than permitted. */
5550                 area = 0.5 * ( dxod * dyda - dyod * dxda );
5551                 if ( fixedarea && ( area > maxarea ) ) {
5552                         /* Add this triangle to the list of bad triangles. */
5553                         enqueuebadtri( testtri, angle, tapex, torg, tdest );
5554                 }
5555                 else if ( vararea ) {
5556                         /* Nonpositive area constraints are treated as unconstrained. */
5557                         if ( ( area > areabound( *testtri ) ) && ( areabound( *testtri ) > 0.0 ) ) {
5558                                 /* Add this triangle to the list of bad triangles. */
5559                                 enqueuebadtri( testtri, angle, tapex, torg, tdest );
5560                         }
5561                 }
5562         }
5563 }
5564
5565 #endif /* not CDT_ONLY */
5566
5567 /**                                                                         **/
5568 /**                                                                         **/
5569 /********* Mesh quality testing routines end here                    *********/
5570
5571 /********* Point location routines begin here                        *********/
5572 /**                                                                         **/
5573 /**                                                                         **/
5574
5575 /*****************************************************************************/
5576 /*                                                                           */
5577 /*  makepointmap()   Construct a mapping from points to triangles to improve  */
5578 /*                  the speed of point location for segment insertion.       */
5579 /*                                                                           */
5580 /*  Traverses all the triangles, and provides each corner of each triangle   */
5581 /*  with a pointer to that triangle.  Of course, pointers will be            */
5582 /*  overwritten by other pointers because (almost) each point is a corner    */
5583 /*  of several triangles, but in the end every point will point to some      */
5584 /*  triangle that contains it.                                               */
5585 /*                                                                           */
5586 /*****************************************************************************/
5587
5588 void makepointmap(){
5589         struct triedge triangleloop;
5590         point triorg;
5591
5592         if ( verbose ) {
5593                 printf( "    Constructing mapping from points to triangles.\n" );
5594         }
5595         traversalinit( &triangles );
5596         triangleloop.tri = triangletraverse();
5597         while ( triangleloop.tri != (triangle *) NULL ) {
5598                 /* Check all three points of the triangle. */
5599                 for ( triangleloop.orient = 0; triangleloop.orient < 3;
5600                           triangleloop.orient++ ) {
5601                         org( triangleloop, triorg );
5602                         setpoint2tri( triorg, encode( triangleloop ) );
5603                 }
5604                 triangleloop.tri = triangletraverse();
5605         }
5606 }
5607
5608 /*****************************************************************************/
5609 /*                                                                           */
5610 /*  preciselocate()   Find a triangle or edge containing a given point.      */
5611 /*                                                                           */
5612 /*  Begins its search from `searchtri'.  It is important that `searchtri'    */
5613 /*  be a handle with the property that `searchpoint' is strictly to the left */
5614 /*  of the edge denoted by `searchtri', or is collinear with that edge and   */
5615 /*  does not intersect that edge.  (In particular, `searchpoint' should not  */
5616 /*  be the origin or destination of that edge.)                              */
5617 /*                                                                           */
5618 /*  These conditions are imposed because preciselocate() is normally used in */
5619 /*  one of two situations:                                                   */
5620 /*                                                                           */
5621 /*  (1)  To try to find the location to insert a new point.  Normally, we    */
5622 /*       know an edge that the point is strictly to the left of.  In the     */
5623 /*       incremental Delaunay algorithm, that edge is a bounding box edge.   */
5624 /*       In Ruppert's Delaunay refinement algorithm for quality meshing,     */
5625 /*       that edge is the shortest edge of the triangle whose circumcenter   */
5626 /*       is being inserted.                                                  */
5627 /*                                                                           */
5628 /*  (2)  To try to find an existing point.  In this case, any edge on the    */
5629 /*       convex hull is a good starting edge.  The possibility that the      */
5630 /*       vertex one seeks is an endpoint of the starting edge must be        */
5631 /*       screened out before preciselocate() is called.                      */
5632 /*                                                                           */
5633 /*  On completion, `searchtri' is a triangle that contains `searchpoint'.    */
5634 /*                                                                           */
5635 /*  This implementation differs from that given by Guibas and Stolfi.  It    */
5636 /*  walks from triangle to triangle, crossing an edge only if `searchpoint'  */
5637 /*  is on the other side of the line containing that edge.  After entering   */
5638 /*  a triangle, there are two edges by which one can leave that triangle.    */
5639 /*  If both edges are valid (`searchpoint' is on the other side of both      */
5640 /*  edges), one of the two is chosen by drawing a line perpendicular to      */
5641 /*  the entry edge (whose endpoints are `forg' and `fdest') passing through  */
5642 /*  `fapex'.  Depending on which side of this perpendicular `searchpoint'    */
5643 /*  falls on, an exit edge is chosen.                                        */
5644 /*                                                                           */
5645 /*  This implementation is empirically faster than the Guibas and Stolfi     */
5646 /*  point location routine (which I originally used), which tends to spiral  */
5647 /*  in toward its target.                                                    */
5648 /*                                                                           */
5649 /*  Returns ONVERTEX if the point lies on an existing vertex.  `searchtri'   */
5650 /*  is a handle whose origin is the existing vertex.                         */
5651 /*                                                                           */
5652 /*  Returns ONEDGE if the point lies on a mesh edge.  `searchtri' is a       */
5653 /*  handle whose primary edge is the edge on which the point lies.           */
5654 /*                                                                           */
5655 /*  Returns INTRIANGLE if the point lies strictly within a triangle.         */
5656 /*  `searchtri' is a handle on the triangle that contains the point.         */
5657 /*                                                                           */
5658 /*  Returns OUTSIDE if the point lies outside the mesh.  `searchtri' is a    */
5659 /*  handle whose primary edge the point is to the right of.  This might      */
5660 /*  occur when the circumcenter of a triangle falls just slightly outside    */
5661 /*  the mesh due to floating-point roundoff error.  It also occurs when      */
5662 /*  seeking a hole or region point that a foolish user has placed outside    */
5663 /*  the mesh.                                                                */
5664 /*                                                                           */
5665 /*  WARNING:  This routine is designed for convex triangulations, and will   */
5666 /*  not generally work after the holes and concavities have been carved.     */
5667 /*  However, it can still be used to find the circumcenter of a triangle, as */
5668 /*  long as the search is begun from the triangle in question.               */
5669 /*                                                                           */
5670 /*****************************************************************************/
5671
5672 enum locateresult preciselocate( searchpoint, searchtri )
5673 point searchpoint;
5674 struct triedge *searchtri;
5675 {
5676         struct triedge backtracktri;
5677         point forg, fdest, fapex;
5678         point swappoint;
5679         REAL orgorient, destorient;
5680         int moveleft;
5681         triangle ptr;                       /* Temporary variable used by sym(). */
5682
5683         if ( verbose > 2 ) {
5684                 printf( "  Searching for point (%.12g, %.12g).\n",
5685                                 searchpoint[0], searchpoint[1] );
5686         }
5687         /* Where are we? */
5688         org( *searchtri, forg );
5689         dest( *searchtri, fdest );
5690         apex( *searchtri, fapex );
5691         while ( 1 ) {
5692                 if ( verbose > 2 ) {
5693                         printf( "    At (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
5694                                         forg[0], forg[1], fdest[0], fdest[1], fapex[0], fapex[1] );
5695                 }
5696                 /* Check whether the apex is the point we seek. */
5697                 if ( ( fapex[0] == searchpoint[0] ) && ( fapex[1] == searchpoint[1] ) ) {
5698                         lprevself( *searchtri );
5699                         return ONVERTEX;
5700                 }
5701                 /* Does the point lie on the other side of the line defined by the */
5702                 /*   triangle edge opposite the triangle's destination?            */
5703                 destorient = counterclockwise( forg, fapex, searchpoint );
5704                 /* Does the point lie on the other side of the line defined by the */
5705                 /*   triangle edge opposite the triangle's origin?                 */
5706                 orgorient = counterclockwise( fapex, fdest, searchpoint );
5707                 if ( destorient > 0.0 ) {
5708                         if ( orgorient > 0.0 ) {
5709                                 /* Move left if the inner product of (fapex - searchpoint) and  */
5710                                 /*   (fdest - forg) is positive.  This is equivalent to drawing */
5711                                 /*   a line perpendicular to the line (forg, fdest) passing     */
5712                                 /*   through `fapex', and determining which side of this line   */
5713                                 /*   `searchpoint' falls on.                                    */
5714                                 moveleft = ( fapex[0] - searchpoint[0] ) * ( fdest[0] - forg[0] ) +
5715                                                    ( fapex[1] - searchpoint[1] ) * ( fdest[1] - forg[1] ) > 0.0;
5716                         }
5717                         else {
5718                                 moveleft = 1;
5719                         }
5720                 }
5721                 else {
5722                         if ( orgorient > 0.0 ) {
5723                                 moveleft = 0;
5724                         }
5725                         else {
5726                                 /* The point we seek must be on the boundary of or inside this */
5727                                 /*   triangle.                                                 */
5728                                 if ( destorient == 0.0 ) {
5729                                         lprevself( *searchtri );
5730                                         return ONEDGE;
5731                                 }
5732                                 if ( orgorient == 0.0 ) {
5733                                         lnextself( *searchtri );
5734                                         return ONEDGE;
5735                                 }
5736                                 return INTRIANGLE;
5737                         }
5738                 }
5739
5740                 /* Move to another triangle.  Leave a trace `backtracktri' in case */
5741                 /*   floating-point roundoff or some such bogey causes us to walk  */
5742                 /*   off a boundary of the triangulation.  We can just bounce off  */
5743                 /*   the boundary as if it were an elastic band.                   */
5744                 if ( moveleft ) {
5745                         lprev( *searchtri, backtracktri );
5746                         fdest = fapex;
5747                 }
5748                 else {
5749                         lnext( *searchtri, backtracktri );
5750                         forg = fapex;
5751                 }
5752                 sym( backtracktri, *searchtri );
5753
5754                 /* Check for walking off the edge. */
5755                 if ( searchtri->tri == dummytri ) {
5756                         /* Turn around. */
5757                         triedgecopy( backtracktri, *searchtri );
5758                         swappoint = forg;
5759                         forg = fdest;
5760                         fdest = swappoint;
5761                         apex( *searchtri, fapex );
5762                         /* Check if the point really is beyond the triangulation boundary. */
5763                         destorient = counterclockwise( forg, fapex, searchpoint );
5764                         orgorient = counterclockwise( fapex, fdest, searchpoint );
5765                         if ( ( orgorient < 0.0 ) && ( destorient < 0.0 ) ) {
5766                                 return OUTSIDE;
5767                         }
5768                 }
5769                 else {
5770                         apex( *searchtri, fapex );
5771                 }
5772         }
5773 }
5774
5775 /*****************************************************************************/
5776 /*                                                                           */
5777 /*  locate()   Find a triangle or edge containing a given point.             */
5778 /*                                                                           */
5779 /*  Searching begins from one of:  the input `searchtri', a recently         */
5780 /*  encountered triangle `recenttri', or from a triangle chosen from a       */
5781 /*  random sample.  The choice is made by determining which triangle's       */
5782 /*  origin is closest to the point we are searcing for.  Normally,           */
5783 /*  `searchtri' should be a handle on the convex hull of the triangulation.  */
5784 /*                                                                           */
5785 /*  Details on the random sampling method can be found in the Mucke, Saias,  */
5786 /*  and Zhu paper cited in the header of this code.                          */
5787 /*                                                                           */
5788 /*  On completion, `searchtri' is a triangle that contains `searchpoint'.    */
5789 /*                                                                           */
5790 /*  Returns ONVERTEX if the point lies on an existing vertex.  `searchtri'   */
5791 /*  is a handle whose origin is the existing vertex.                         */
5792 /*                                                                           */
5793 /*  Returns ONEDGE if the point lies on a mesh edge.  `searchtri' is a       */
5794 /*  handle whose primary edge is the edge on which the point lies.           */
5795 /*                                                                           */
5796 /*  Returns INTRIANGLE if the point lies strictly within a triangle.         */
5797 /*  `searchtri' is a handle on the triangle that contains the point.         */
5798 /*                                                                           */
5799 /*  Returns OUTSIDE if the point lies outside the mesh.  `searchtri' is a    */
5800 /*  handle whose primary edge the point is to the right of.  This might      */
5801 /*  occur when the circumcenter of a triangle falls just slightly outside    */
5802 /*  the mesh due to floating-point roundoff error.  It also occurs when      */
5803 /*  seeking a hole or region point that a foolish user has placed outside    */
5804 /*  the mesh.                                                                */
5805 /*                                                                           */
5806 /*  WARNING:  This routine is designed for convex triangulations, and will   */
5807 /*  not generally work after the holes and concavities have been carved.     */
5808 /*                                                                           */
5809 /*****************************************************************************/
5810
5811 enum locateresult locate( searchpoint, searchtri )
5812 point searchpoint;
5813 struct triedge *searchtri;
5814 {
5815         VOID **sampleblock;
5816         triangle *firsttri;
5817         struct triedge sampletri;
5818         point torg, tdest;
5819         unsigned long alignptr;
5820         REAL searchdist, dist;
5821         REAL ahead;
5822         long sampleblocks, samplesperblock, samplenum;
5823         long triblocks;
5824         long i, j;
5825         triangle ptr;                       /* Temporary variable used by sym(). */
5826
5827         if ( verbose > 2 ) {
5828                 printf( "  Randomly sampling for a triangle near point (%.12g, %.12g).\n",
5829                                 searchpoint[0], searchpoint[1] );
5830         }
5831         /* Record the distance from the suggested starting triangle to the */
5832         /*   point we seek.                                                */
5833         org( *searchtri, torg );
5834         searchdist = ( searchpoint[0] - torg[0] ) * ( searchpoint[0] - torg[0] )
5835                                  + ( searchpoint[1] - torg[1] ) * ( searchpoint[1] - torg[1] );
5836         if ( verbose > 2 ) {
5837                 printf( "    Boundary triangle has origin (%.12g, %.12g).\n",
5838                                 torg[0], torg[1] );
5839         }
5840
5841         /* If a recently encountered triangle has been recorded and has not been */
5842         /*   deallocated, test it as a good starting point.                      */
5843         if ( recenttri.tri != (triangle *) NULL ) {
5844                 if ( recenttri.tri[3] != (triangle) NULL ) {
5845                         org( recenttri, torg );
5846                         if ( ( torg[0] == searchpoint[0] ) && ( torg[1] == searchpoint[1] ) ) {
5847                                 triedgecopy( recenttri, *searchtri );
5848                                 return ONVERTEX;
5849                         }
5850                         dist = ( searchpoint[0] - torg[0] ) * ( searchpoint[0] - torg[0] )
5851                                    + ( searchpoint[1] - torg[1] ) * ( searchpoint[1] - torg[1] );
5852                         if ( dist < searchdist ) {
5853                                 triedgecopy( recenttri, *searchtri );
5854                                 searchdist = dist;
5855                                 if ( verbose > 2 ) {
5856                                         printf( "    Choosing recent triangle with origin (%.12g, %.12g).\n",
5857                                                         torg[0], torg[1] );
5858                                 }
5859                         }
5860                 }
5861         }
5862
5863         /* The number of random samples taken is proportional to the cube root of */
5864         /*   the number of triangles in the mesh.  The next bit of code assumes   */
5865         /*   that the number of triangles increases monotonically.                */
5866         while ( SAMPLEFACTOR * samples * samples * samples < triangles.items ) {
5867                 samples++;
5868         }
5869         triblocks = ( triangles.maxitems + TRIPERBLOCK - 1 ) / TRIPERBLOCK;
5870         samplesperblock = 1 + ( samples / triblocks );
5871         sampleblocks = samples / samplesperblock;
5872         sampleblock = triangles.firstblock;
5873         sampletri.orient = 0;
5874         for ( i = 0; i < sampleblocks; i++ ) {
5875                 alignptr = (unsigned long) ( sampleblock + 1 );
5876                 firsttri = (triangle *) ( alignptr + (unsigned long) triangles.alignbytes
5877                                                                   - ( alignptr % (unsigned long) triangles.alignbytes ) );
5878                 for ( j = 0; j < samplesperblock; j++ ) {
5879                         if ( i == triblocks - 1 ) {
5880                                 samplenum = randomnation( (int)
5881                                                                                   ( triangles.maxitems - ( i * TRIPERBLOCK ) ) );
5882                         }
5883                         else {
5884                                 samplenum = randomnation( TRIPERBLOCK );
5885                         }
5886                         sampletri.tri = (triangle *)
5887                                                         ( firsttri + ( samplenum * triangles.itemwords ) );
5888                         if ( sampletri.tri[3] != (triangle) NULL ) {
5889                                 org( sampletri, torg );
5890                                 dist = ( searchpoint[0] - torg[0] ) * ( searchpoint[0] - torg[0] )
5891                                            + ( searchpoint[1] - torg[1] ) * ( searchpoint[1] - torg[1] );
5892                                 if ( dist < searchdist ) {
5893                                         triedgecopy( sampletri, *searchtri );
5894                                         searchdist = dist;
5895                                         if ( verbose > 2 ) {
5896                                                 printf( "    Choosing triangle with origin (%.12g, %.12g).\n",
5897                                                                 torg[0], torg[1] );
5898                                         }
5899                                 }
5900                         }
5901                 }
5902                 sampleblock = (VOID **) *sampleblock;
5903         }
5904         /* Where are we? */
5905         org( *searchtri, torg );
5906         dest( *searchtri, tdest );
5907         /* Check the starting triangle's vertices. */
5908         if ( ( torg[0] == searchpoint[0] ) && ( torg[1] == searchpoint[1] ) ) {
5909                 return ONVERTEX;
5910         }
5911         if ( ( tdest[0] == searchpoint[0] ) && ( tdest[1] == searchpoint[1] ) ) {
5912                 lnextself( *searchtri );
5913                 return ONVERTEX;
5914         }
5915         /* Orient `searchtri' to fit the preconditions of calling preciselocate(). */
5916         ahead = counterclockwise( torg, tdest, searchpoint );
5917         if ( ahead < 0.0 ) {
5918                 /* Turn around so that `searchpoint' is to the left of the */
5919                 /*   edge specified by `searchtri'.                        */
5920                 symself( *searchtri );
5921         }
5922         else if ( ahead == 0.0 ) {
5923                 /* Check if `searchpoint' is between `torg' and `tdest'. */
5924                 if ( ( ( torg[0] < searchpoint[0] ) == ( searchpoint[0] < tdest[0] ) )
5925                          && ( ( torg[1] < searchpoint[1] ) == ( searchpoint[1] < tdest[1] ) ) ) {
5926                         return ONEDGE;
5927                 }
5928         }
5929         return preciselocate( searchpoint, searchtri );
5930 }
5931
5932 /**                                                                         **/
5933 /**                                                                         **/
5934 /********* Point location routines end here                          *********/
5935
5936 /********* Mesh transformation routines begin here                   *********/
5937 /**                                                                         **/
5938 /**                                                                         **/
5939
5940 /*****************************************************************************/
5941 /*                                                                           */
5942 /*  insertshelle()   Create a new shell edge and insert it between two       */
5943 /*                   triangles.                                              */
5944 /*                                                                           */
5945 /*  The new shell edge is inserted at the edge described by the handle       */
5946 /*  `tri'.  Its vertices are properly initialized.  The marker `shellemark'  */
5947 /*  is applied to the shell edge and, if appropriate, its vertices.          */
5948 /*                                                                           */
5949 /*****************************************************************************/
5950
5951 void insertshelle( tri, shellemark )
5952 struct triedge *tri;          /* Edge at which to insert the new shell edge. */
5953 int shellemark;                            /* Marker for the new shell edge. */
5954 {
5955         struct triedge oppotri;
5956         struct edge newshelle;
5957         point triorg, tridest;
5958         triangle ptr;                       /* Temporary variable used by sym(). */
5959         shelle sptr;                    /* Temporary variable used by tspivot(). */
5960
5961         /* Mark points if possible. */
5962         org( *tri, triorg );
5963         dest( *tri, tridest );
5964         if ( pointmark( triorg ) == 0 ) {
5965                 setpointmark( triorg, shellemark );
5966         }
5967         if ( pointmark( tridest ) == 0 ) {
5968                 setpointmark( tridest, shellemark );
5969         }
5970         /* Check if there's already a shell edge here. */
5971         tspivot( *tri, newshelle );
5972         if ( newshelle.sh == dummysh ) {
5973                 /* Make new shell edge and initialize its vertices. */
5974                 makeshelle( &newshelle );
5975                 setsorg( newshelle, tridest );
5976                 setsdest( newshelle, triorg );
5977                 /* Bond new shell edge to the two triangles it is sandwiched between. */
5978                 /*   Note that the facing triangle `oppotri' might be equal to        */
5979                 /*   `dummytri' (outer space), but the new shell edge is bonded to it */
5980                 /*   all the same.                                                    */
5981                 tsbond( *tri, newshelle );
5982                 sym( *tri, oppotri );
5983                 ssymself( newshelle );
5984                 tsbond( oppotri, newshelle );
5985                 setmark( newshelle, shellemark );
5986                 if ( verbose > 2 ) {
5987                         printf( "  Inserting new " );
5988                         printshelle( &newshelle );
5989                 }
5990         }
5991         else {
5992                 if ( mark( newshelle ) == 0 ) {
5993                         setmark( newshelle, shellemark );
5994                 }
5995         }
5996 }
5997
5998 /*****************************************************************************/
5999 /*                                                                           */
6000 /*  Terminology                                                              */
6001 /*                                                                           */
6002 /*  A "local transformation" replaces a small set of triangles with another  */
6003 /*  set of triangles.  This may or may not involve inserting or deleting a   */
6004 /*  point.                                                                   */
6005 /*                                                                           */
6006 /*  The term "casing" is used to describe the set of triangles that are      */
6007 /*  attached to the triangles being transformed, but are not transformed     */
6008 /*  themselves.  Think of the casing as a fixed hollow structure inside      */
6009 /*  which all the action happens.  A "casing" is only defined relative to    */
6010 /*  a single transformation; each occurrence of a transformation will        */
6011 /*  involve a different casing.                                              */
6012 /*                                                                           */
6013 /*  A "shell" is similar to a "casing".  The term "shell" describes the set  */
6014 /*  of shell edges (if any) that are attached to the triangles being         */
6015 /*  transformed.  However, I sometimes use "shell" to refer to a single      */
6016 /*  shell edge, so don't get confused.                                       */
6017 /*                                                                           */
6018 /*****************************************************************************/
6019
6020 /*****************************************************************************/
6021 /*                                                                           */
6022 /*  flip()   Transform two triangles to two different triangles by flipping  */
6023 /*           an edge within a quadrilateral.                                 */
6024 /*                                                                           */
6025 /*  Imagine the original triangles, abc and bad, oriented so that the        */
6026 /*  shared edge ab lies in a horizontal plane, with the point b on the left  */
6027 /*  and the point a on the right.  The point c lies below the edge, and the  */
6028 /*  point d lies above the edge.  The `flipedge' handle holds the edge ab    */
6029 /*  of triangle abc, and is directed left, from vertex a to vertex b.        */
6030 /*                                                                           */
6031 /*  The triangles abc and bad are deleted and replaced by the triangles cdb  */
6032 /*  and dca.  The triangles that represent abc and bad are NOT deallocated;  */
6033 /*  they are reused for dca and cdb, respectively.  Hence, any handles that  */
6034 /*  may have held the original triangles are still valid, although not       */
6035 /*  directed as they were before.                                            */
6036 /*                                                                           */
6037 /*  Upon completion of this routine, the `flipedge' handle holds the edge    */
6038 /*  dc of triangle dca, and is directed down, from vertex d to vertex c.     */
6039 /*  (Hence, the two triangles have rotated counterclockwise.)                */
6040 /*                                                                           */
6041 /*  WARNING:  This transformation is geometrically valid only if the         */
6042 /*  quadrilateral adbc is convex.  Furthermore, this transformation is       */
6043 /*  valid only if there is not a shell edge between the triangles abc and    */
6044 /*  bad.  This routine does not check either of these preconditions, and     */
6045 /*  it is the responsibility of the calling routine to ensure that they are  */
6046 /*  met.  If they are not, the streets shall be filled with wailing and      */
6047 /*  gnashing of teeth.                                                       */
6048 /*                                                                           */
6049 /*****************************************************************************/
6050
6051 void flip( flipedge )
6052 struct triedge *flipedge;                    /* Handle for the triangle abc. */
6053 {
6054         struct triedge botleft, botright;
6055         struct triedge topleft, topright;
6056         struct triedge top;
6057         struct triedge botlcasing, botrcasing;
6058         struct triedge toplcasing, toprcasing;
6059         struct edge botlshelle, botrshelle;
6060         struct edge toplshelle, toprshelle;
6061         point leftpoint, rightpoint, botpoint;
6062         point farpoint;
6063         triangle ptr;                       /* Temporary variable used by sym(). */
6064         shelle sptr;                    /* Temporary variable used by tspivot(). */
6065
6066         /* Identify the vertices of the quadrilateral. */
6067         org( *flipedge, rightpoint );
6068         dest( *flipedge, leftpoint );
6069         apex( *flipedge, botpoint );
6070         sym( *flipedge, top );
6071 #ifdef SELF_CHECK
6072         if ( top.tri == dummytri ) {
6073                 printf( "Internal error in flip():  Attempt to flip on boundary.\n" );
6074                 lnextself( *flipedge );
6075                 return;
6076         }
6077         if ( checksegments ) {
6078                 tspivot( *flipedge, toplshelle );
6079                 if ( toplshelle.sh != dummysh ) {
6080                         printf( "Internal error in flip():  Attempt to flip a segment.\n" );
6081                         lnextself( *flipedge );
6082                         return;
6083                 }
6084         }
6085 #endif /* SELF_CHECK */
6086         apex( top, farpoint );
6087
6088         /* Identify the casing of the quadrilateral. */
6089         lprev( top, topleft );
6090         sym( topleft, toplcasing );
6091         lnext( top, topright );
6092         sym( topright, toprcasing );
6093         lnext( *flipedge, botleft );
6094         sym( botleft, botlcasing );
6095         lprev( *flipedge, botright );
6096         sym( botright, botrcasing );
6097         /* Rotate the quadrilateral one-quarter turn counterclockwise. */
6098         bond( topleft, botlcasing );
6099         bond( botleft, botrcasing );
6100         bond( botright, toprcasing );
6101         bond( topright, toplcasing );
6102
6103         if ( checksegments ) {
6104                 /* Check for shell edges and rebond them to the quadrilateral. */
6105                 tspivot( topleft, toplshelle );
6106                 tspivot( botleft, botlshelle );
6107                 tspivot( botright, botrshelle );
6108                 tspivot( topright, toprshelle );
6109                 if ( toplshelle.sh == dummysh ) {
6110                         tsdissolve( topright );
6111                 }
6112                 else {
6113                         tsbond( topright, toplshelle );
6114                 }
6115                 if ( botlshelle.sh == dummysh ) {
6116                         tsdissolve( topleft );
6117                 }
6118                 else {
6119                         tsbond( topleft, botlshelle );
6120                 }
6121                 if ( botrshelle.sh == dummysh ) {
6122                         tsdissolve( botleft );
6123                 }
6124                 else {
6125                         tsbond( botleft, botrshelle );
6126                 }
6127                 if ( toprshelle.sh == dummysh ) {
6128                         tsdissolve( botright );
6129                 }
6130                 else {
6131                         tsbond( botright, toprshelle );
6132                 }
6133         }
6134
6135         /* New point assignments for the rotated quadrilateral. */
6136         setorg( *flipedge, farpoint );
6137         setdest( *flipedge, botpoint );
6138         setapex( *flipedge, rightpoint );
6139         setorg( top, botpoint );
6140         setdest( top, farpoint );
6141         setapex( top, leftpoint );
6142         if ( verbose > 2 ) {
6143                 printf( "  Edge flip results in left " );
6144                 lnextself( topleft );
6145                 printtriangle( &topleft );
6146                 printf( "  and right " );
6147                 printtriangle( flipedge );
6148         }
6149 }
6150
6151 /*****************************************************************************/
6152 /*                                                                           */
6153 /*  insertsite()   Insert a vertex into a Delaunay triangulation,            */
6154 /*                 performing flips as necessary to maintain the Delaunay    */
6155 /*                 property.                                                 */
6156 /*                                                                           */
6157 /*  The point `insertpoint' is located.  If `searchtri.tri' is not NULL,     */
6158 /*  the search for the containing triangle begins from `searchtri'.  If      */
6159 /*  `searchtri.tri' is NULL, a full point location procedure is called.      */
6160 /*  If `insertpoint' is found inside a triangle, the triangle is split into  */
6161 /*  three; if `insertpoint' lies on an edge, the edge is split in two,       */
6162 /*  thereby splitting the two adjacent triangles into four.  Edge flips are  */
6163 /*  used to restore the Delaunay property.  If `insertpoint' lies on an      */
6164 /*  existing vertex, no action is taken, and the value DUPLICATEPOINT is     */
6165 /*  returned.  On return, `searchtri' is set to a handle whose origin is the */
6166 /*  existing vertex.                                                         */
6167 /*                                                                           */
6168 /*  Normally, the parameter `splitedge' is set to NULL, implying that no     */
6169 /*  segment should be split.  In this case, if `insertpoint' is found to     */
6170 /*  lie on a segment, no action is taken, and the value VIOLATINGPOINT is    */
6171 /*  returned.  On return, `searchtri' is set to a handle whose primary edge  */
6172 /*  is the violated segment.                                                 */
6173 /*                                                                           */
6174 /*  If the calling routine wishes to split a segment by inserting a point in */
6175 /*  it, the parameter `splitedge' should be that segment.  In this case,     */
6176 /*  `searchtri' MUST be the triangle handle reached by pivoting from that    */
6177 /*  segment; no point location is done.                                      */
6178 /*                                                                           */
6179 /*  `segmentflaws' and `triflaws' are flags that indicate whether or not     */
6180 /*  there should be checks for the creation of encroached segments or bad    */
6181 /*  quality faces.  If a newly inserted point encroaches upon segments,      */
6182 /*  these segments are added to the list of segments to be split if          */
6183 /*  `segmentflaws' is set.  If bad triangles are created, these are added    */
6184 /*  to the queue if `triflaws' is set.                                       */
6185 /*                                                                           */
6186 /*  If a duplicate point or violated segment does not prevent the point      */
6187 /*  from being inserted, the return value will be ENCROACHINGPOINT if the    */
6188 /*  point encroaches upon a segment (and checking is enabled), or            */
6189 /*  SUCCESSFULPOINT otherwise.  In either case, `searchtri' is set to a      */
6190 /*  handle whose origin is the newly inserted vertex.                        */
6191 /*                                                                           */
6192 /*  insertsite() does not use flip() for reasons of speed; some              */
6193 /*  information can be reused from edge flip to edge flip, like the          */
6194 /*  locations of shell edges.                                                */
6195 /*                                                                           */
6196 /*****************************************************************************/
6197
6198 enum insertsiteresult insertsite( insertpoint, searchtri, splitedge,
6199                                                                   segmentflaws, triflaws )
6200 point insertpoint;
6201 struct triedge *searchtri;
6202 struct edge *splitedge;
6203 int segmentflaws;
6204 int triflaws;
6205 {
6206         struct triedge horiz;
6207         struct triedge top;
6208         struct triedge botleft, botright;
6209         struct triedge topleft, topright;
6210         struct triedge newbotleft, newbotright;
6211         struct triedge newtopright;
6212         struct triedge botlcasing, botrcasing;
6213         struct triedge toplcasing, toprcasing;
6214         struct triedge testtri;
6215         struct edge botlshelle, botrshelle;
6216         struct edge toplshelle, toprshelle;
6217         struct edge brokenshelle;
6218         struct edge checkshelle;
6219         struct edge rightedge;
6220         struct edge newedge;
6221         struct edge *encroached;
6222         point first;
6223         point leftpoint, rightpoint, botpoint, toppoint, farpoint;
6224         REAL attrib;
6225         REAL area;
6226         enum insertsiteresult success;
6227         enum locateresult intersect;
6228         int doflip;
6229         int mirrorflag;
6230         int i;
6231         triangle ptr;                       /* Temporary variable used by sym(). */
6232         shelle sptr;       /* Temporary variable used by spivot() and tspivot(). */
6233
6234         if ( verbose > 1 ) {
6235                 printf( "  Inserting (%.12g, %.12g).\n", insertpoint[0], insertpoint[1] );
6236         }
6237         if ( splitedge == (struct edge *) NULL ) {
6238                 /* Find the location of the point to be inserted.  Check if a good */
6239                 /*   starting triangle has already been provided by the caller.    */
6240                 if ( searchtri->tri == (triangle *) NULL ) {
6241                         /* Find a boundary triangle. */
6242                         horiz.tri = dummytri;
6243                         horiz.orient = 0;
6244                         symself( horiz );
6245                         /* Search for a triangle containing `insertpoint'. */
6246                         intersect = locate( insertpoint, &horiz );
6247                 }
6248                 else {
6249                         /* Start searching from the triangle provided by the caller. */
6250                         triedgecopy( *searchtri, horiz );
6251                         intersect = preciselocate( insertpoint, &horiz );
6252                 }
6253         }
6254         else {
6255                 /* The calling routine provides the edge in which the point is inserted. */
6256                 triedgecopy( *searchtri, horiz );
6257                 intersect = ONEDGE;
6258         }
6259         if ( intersect == ONVERTEX ) {
6260                 /* There's already a vertex there.  Return in `searchtri' a triangle */
6261                 /*   whose origin is the existing vertex.                            */
6262                 triedgecopy( horiz, *searchtri );
6263                 triedgecopy( horiz, recenttri );
6264                 return DUPLICATEPOINT;
6265         }
6266         if ( ( intersect == ONEDGE ) || ( intersect == OUTSIDE ) ) {
6267                 /* The vertex falls on an edge or boundary. */
6268                 if ( checksegments && ( splitedge == (struct edge *) NULL ) ) {
6269                         /* Check whether the vertex falls on a shell edge. */
6270                         tspivot( horiz, brokenshelle );
6271                         if ( brokenshelle.sh != dummysh ) {
6272                                 /* The vertex falls on a shell edge. */
6273                                 if ( segmentflaws ) {
6274                                         if ( nobisect == 0 ) {
6275                                                 /* Add the shell edge to the list of encroached segments. */
6276                                                 encroached = (struct edge *) poolalloc( &badsegments );
6277                                                 shellecopy( brokenshelle, *encroached );
6278                                         }
6279                                         else if ( ( nobisect == 1 ) && ( intersect == ONEDGE ) ) {
6280                                                 /* This segment may be split only if it is an internal boundary. */
6281                                                 sym( horiz, testtri );
6282                                                 if ( testtri.tri != dummytri ) {
6283                                                         /* Add the shell edge to the list of encroached segments. */
6284                                                         encroached = (struct edge *) poolalloc( &badsegments );
6285                                                         shellecopy( brokenshelle, *encroached );
6286                                                 }
6287                                         }
6288                                 }
6289                                 /* Return a handle whose primary edge contains the point, */
6290                                 /*   which has not been inserted.                         */
6291                                 triedgecopy( horiz, *searchtri );
6292                                 triedgecopy( horiz, recenttri );
6293                                 return VIOLATINGPOINT;
6294                         }
6295                 }
6296                 /* Insert the point on an edge, dividing one triangle into two (if */
6297                 /*   the edge lies on a boundary) or two triangles into four.      */
6298                 lprev( horiz, botright );
6299                 sym( botright, botrcasing );
6300                 sym( horiz, topright );
6301                 /* Is there a second triangle?  (Or does this edge lie on a boundary?) */
6302                 mirrorflag = topright.tri != dummytri;
6303                 if ( mirrorflag ) {
6304                         lnextself( topright );
6305                         sym( topright, toprcasing );
6306                         maketriangle( &newtopright );
6307                 }
6308                 else {
6309                         /* Splitting the boundary edge increases the number of boundary edges. */
6310                         hullsize++;
6311                 }
6312                 maketriangle( &newbotright );
6313
6314                 /* Set the vertices of changed and new triangles. */
6315                 org( horiz, rightpoint );
6316                 dest( horiz, leftpoint );
6317                 apex( horiz, botpoint );
6318                 setorg( newbotright, botpoint );
6319                 setdest( newbotright, rightpoint );
6320                 setapex( newbotright, insertpoint );
6321                 setorg( horiz, insertpoint );
6322                 for ( i = 0; i < eextras; i++ ) {
6323                         /* Set the element attributes of a new triangle. */
6324                         setelemattribute( newbotright, i, elemattribute( botright, i ) );
6325                 }
6326                 if ( vararea ) {
6327                         /* Set the area constraint of a new triangle. */
6328                         setareabound( newbotright, areabound( botright ) );
6329                 }
6330                 if ( mirrorflag ) {
6331                         dest( topright, toppoint );
6332                         setorg( newtopright, rightpoint );
6333                         setdest( newtopright, toppoint );
6334                         setapex( newtopright, insertpoint );
6335                         setorg( topright, insertpoint );
6336                         for ( i = 0; i < eextras; i++ ) {
6337                                 /* Set the element attributes of another new triangle. */
6338                                 setelemattribute( newtopright, i, elemattribute( topright, i ) );
6339                         }
6340                         if ( vararea ) {
6341                                 /* Set the area constraint of another new triangle. */
6342                                 setareabound( newtopright, areabound( topright ) );
6343                         }
6344                 }
6345
6346                 /* There may be shell edges that need to be bonded */
6347                 /*   to the new triangle(s).                       */
6348                 if ( checksegments ) {
6349                         tspivot( botright, botrshelle );
6350                         if ( botrshelle.sh != dummysh ) {
6351                                 tsdissolve( botright );
6352                                 tsbond( newbotright, botrshelle );
6353                         }
6354                         if ( mirrorflag ) {
6355                                 tspivot( topright, toprshelle );
6356                                 if ( toprshelle.sh != dummysh ) {
6357                                         tsdissolve( topright );
6358                                         tsbond( newtopright, toprshelle );
6359                                 }
6360                         }
6361                 }
6362
6363                 /* Bond the new triangle(s) to the surrounding triangles. */
6364                 bond( newbotright, botrcasing );
6365                 lprevself( newbotright );
6366                 bond( newbotright, botright );
6367                 lprevself( newbotright );
6368                 if ( mirrorflag ) {
6369                         bond( newtopright, toprcasing );
6370                         lnextself( newtopright );
6371                         bond( newtopright, topright );
6372                         lnextself( newtopright );
6373                         bond( newtopright, newbotright );
6374                 }
6375
6376                 if ( splitedge != (struct edge *) NULL ) {
6377                         /* Split the shell edge into two. */
6378                         setsdest( *splitedge, insertpoint );
6379                         ssymself( *splitedge );
6380                         spivot( *splitedge, rightedge );
6381                         insertshelle( &newbotright, mark( *splitedge ) );
6382                         tspivot( newbotright, newedge );
6383                         sbond( *splitedge, newedge );
6384                         ssymself( newedge );
6385                         sbond( newedge, rightedge );
6386                         ssymself( *splitedge );
6387                 }
6388
6389 #ifdef SELF_CHECK
6390                 if ( counterclockwise( rightpoint, leftpoint, botpoint ) < 0.0 ) {
6391                         printf( "Internal error in insertsite():\n" );
6392                         printf( "  Clockwise triangle prior to edge point insertion (bottom).\n" );
6393                 }
6394                 if ( mirrorflag ) {
6395                         if ( counterclockwise( leftpoint, rightpoint, toppoint ) < 0.0 ) {
6396                                 printf( "Internal error in insertsite():\n" );
6397                                 printf( "  Clockwise triangle prior to edge point insertion (top).\n" );
6398                         }
6399                         if ( counterclockwise( rightpoint, toppoint, insertpoint ) < 0.0 ) {
6400                                 printf( "Internal error in insertsite():\n" );
6401                                 printf( "  Clockwise triangle after edge point insertion (top right).\n"
6402                                                 );
6403                         }
6404                         if ( counterclockwise( toppoint, leftpoint, insertpoint ) < 0.0 ) {
6405                                 printf( "Internal error in insertsite():\n" );
6406                                 printf( "  Clockwise triangle after edge point insertion (top left).\n"
6407                                                 );
6408                         }
6409                 }
6410                 if ( counterclockwise( leftpoint, botpoint, insertpoint ) < 0.0 ) {
6411                         printf( "Internal error in insertsite():\n" );
6412                         printf( "  Clockwise triangle after edge point insertion (bottom left).\n"
6413                                         );
6414                 }
6415                 if ( counterclockwise( botpoint, rightpoint, insertpoint ) < 0.0 ) {
6416                         printf( "Internal error in insertsite():\n" );
6417                         printf(
6418                                 "  Clockwise triangle after edge point insertion (bottom right).\n" );
6419                 }
6420 #endif /* SELF_CHECK */
6421                 if ( verbose > 2 ) {
6422                         printf( "  Updating bottom left " );
6423                         printtriangle( &botright );
6424                         if ( mirrorflag ) {
6425                                 printf( "  Updating top left " );
6426                                 printtriangle( &topright );
6427                                 printf( "  Creating top right " );
6428                                 printtriangle( &newtopright );
6429                         }
6430                         printf( "  Creating bottom right " );
6431                         printtriangle( &newbotright );
6432                 }
6433
6434                 /* Position `horiz' on the first edge to check for */
6435                 /*   the Delaunay property.                        */
6436                 lnextself( horiz );
6437         }
6438         else {
6439                 /* Insert the point in a triangle, splitting it into three. */
6440                 lnext( horiz, botleft );
6441                 lprev( horiz, botright );
6442                 sym( botleft, botlcasing );
6443                 sym( botright, botrcasing );
6444                 maketriangle( &newbotleft );
6445                 maketriangle( &newbotright );
6446
6447                 /* Set the vertices of changed and new triangles. */
6448                 org( horiz, rightpoint );
6449                 dest( horiz, leftpoint );
6450                 apex( horiz, botpoint );
6451                 setorg( newbotleft, leftpoint );
6452                 setdest( newbotleft, botpoint );
6453                 setapex( newbotleft, insertpoint );
6454                 setorg( newbotright, botpoint );
6455                 setdest( newbotright, rightpoint );
6456                 setapex( newbotright, insertpoint );
6457                 setapex( horiz, insertpoint );
6458                 for ( i = 0; i < eextras; i++ ) {
6459                         /* Set the element attributes of the new triangles. */
6460                         attrib = elemattribute( horiz, i );
6461                         setelemattribute( newbotleft, i, attrib );
6462                         setelemattribute( newbotright, i, attrib );
6463                 }
6464                 if ( vararea ) {
6465                         /* Set the area constraint of the new triangles. */
6466                         area = areabound( horiz );
6467                         setareabound( newbotleft, area );
6468                         setareabound( newbotright, area );
6469                 }
6470
6471                 /* There may be shell edges that need to be bonded */
6472                 /*   to the new triangles.                         */
6473                 if ( checksegments ) {
6474                         tspivot( botleft, botlshelle );
6475                         if ( botlshelle.sh != dummysh ) {
6476                                 tsdissolve( botleft );
6477                                 tsbond( newbotleft, botlshelle );
6478                         }
6479                         tspivot( botright, botrshelle );
6480                         if ( botrshelle.sh != dummysh ) {
6481                                 tsdissolve( botright );
6482                                 tsbond( newbotright, botrshelle );
6483                         }
6484                 }
6485
6486                 /* Bond the new triangles to the surrounding triangles. */
6487                 bond( newbotleft, botlcasing );
6488                 bond( newbotright, botrcasing );
6489                 lnextself( newbotleft );
6490                 lprevself( newbotright );
6491                 bond( newbotleft, newbotright );
6492                 lnextself( newbotleft );
6493                 bond( botleft, newbotleft );
6494                 lprevself( newbotright );
6495                 bond( botright, newbotright );
6496
6497 #ifdef SELF_CHECK
6498                 if ( counterclockwise( rightpoint, leftpoint, botpoint ) < 0.0 ) {
6499                         printf( "Internal error in insertsite():\n" );
6500                         printf( "  Clockwise triangle prior to point insertion.\n" );
6501                 }
6502                 if ( counterclockwise( rightpoint, leftpoint, insertpoint ) < 0.0 ) {
6503                         printf( "Internal error in insertsite():\n" );
6504                         printf( "  Clockwise triangle after point insertion (top).\n" );
6505                 }
6506                 if ( counterclockwise( leftpoint, botpoint, insertpoint ) < 0.0 ) {
6507                         printf( "Internal error in insertsite():\n" );
6508                         printf( "  Clockwise triangle after point insertion (left).\n" );
6509                 }
6510                 if ( counterclockwise( botpoint, rightpoint, insertpoint ) < 0.0 ) {
6511                         printf( "Internal error in insertsite():\n" );
6512                         printf( "  Clockwise triangle after point insertion (right).\n" );
6513                 }
6514 #endif /* SELF_CHECK */
6515                 if ( verbose > 2 ) {
6516                         printf( "  Updating top " );
6517                         printtriangle( &horiz );
6518                         printf( "  Creating left " );
6519                         printtriangle( &newbotleft );
6520                         printf( "  Creating right " );
6521                         printtriangle( &newbotright );
6522                 }
6523         }
6524
6525         /* The insertion is successful by default, unless an encroached */
6526         /*   edge is found.                                             */
6527         success = SUCCESSFULPOINT;
6528         /* Circle around the newly inserted vertex, checking each edge opposite */
6529         /*   it for the Delaunay property.  Non-Delaunay edges are flipped.     */
6530         /*   `horiz' is always the edge being checked.  `first' marks where to  */
6531         /*   stop circling.                                                     */
6532         org( horiz, first );
6533         rightpoint = first;
6534         dest( horiz, leftpoint );
6535         /* Circle until finished. */
6536         while ( 1 ) {
6537                 /* By default, the edge will be flipped. */
6538                 doflip = 1;
6539                 if ( checksegments ) {
6540                         /* Check for a segment, which cannot be flipped. */
6541                         tspivot( horiz, checkshelle );
6542                         if ( checkshelle.sh != dummysh ) {
6543                                 /* The edge is a segment and cannot be flipped. */
6544                                 doflip = 0;
6545 #ifndef CDT_ONLY
6546                                 if ( segmentflaws ) {
6547                                         /* Does the new point encroach upon this segment? */
6548                                         if ( checkedge4encroach( &checkshelle ) ) {
6549                                                 success = ENCROACHINGPOINT;
6550                                         }
6551                                 }
6552 #endif /* not CDT_ONLY */
6553                         }
6554                 }
6555                 if ( doflip ) {
6556                         /* Check if the edge is a boundary edge. */
6557                         sym( horiz, top );
6558                         if ( top.tri == dummytri ) {
6559                                 /* The edge is a boundary edge and cannot be flipped. */
6560                                 doflip = 0;
6561                         }
6562                         else {
6563                                 /* Find the point on the other side of the edge. */
6564                                 apex( top, farpoint );
6565                                 /* In the incremental Delaunay triangulation algorithm, any of    */
6566                                 /*   `leftpoint', `rightpoint', and `farpoint' could be vertices  */
6567                                 /*   of the triangular bounding box.  These vertices must be      */
6568                                 /*   treated as if they are infinitely distant, even though their */
6569                                 /*   "coordinates" are not.                                       */
6570                                 if ( ( leftpoint == infpoint1 ) || ( leftpoint == infpoint2 )
6571                                          || ( leftpoint == infpoint3 ) ) {
6572                                         /* `leftpoint' is infinitely distant.  Check the convexity of */
6573                                         /*   the boundary of the triangulation.  'farpoint' might be  */
6574                                         /*   infinite as well, but trust me, this same condition      */
6575                                         /*   should be applied.                                       */
6576                                         doflip = counterclockwise( insertpoint, rightpoint, farpoint ) > 0.0;
6577                                 }
6578                                 else if ( ( rightpoint == infpoint1 ) || ( rightpoint == infpoint2 )
6579                                                   || ( rightpoint == infpoint3 ) ) {
6580                                         /* `rightpoint' is infinitely distant.  Check the convexity of */
6581                                         /*   the boundary of the triangulation.  'farpoint' might be  */
6582                                         /*   infinite as well, but trust me, this same condition      */
6583                                         /*   should be applied.                                       */
6584                                         doflip = counterclockwise( farpoint, leftpoint, insertpoint ) > 0.0;
6585                                 }
6586                                 else if ( ( farpoint == infpoint1 ) || ( farpoint == infpoint2 )
6587                                                   || ( farpoint == infpoint3 ) ) {
6588                                         /* `farpoint' is infinitely distant and cannot be inside */
6589                                         /*   the circumcircle of the triangle `horiz'.           */
6590                                         doflip = 0;
6591                                 }
6592                                 else {
6593                                         /* Test whether the edge is locally Delaunay. */
6594                                         doflip = incircle( leftpoint, insertpoint, rightpoint, farpoint )
6595                                                          > 0.0;
6596                                 }
6597                                 if ( doflip ) {
6598                                         /* We made it!  Flip the edge `horiz' by rotating its containing */
6599                                         /*   quadrilateral (the two triangles adjacent to `horiz').      */
6600                                         /* Identify the casing of the quadrilateral. */
6601                                         lprev( top, topleft );
6602                                         sym( topleft, toplcasing );
6603                                         lnext( top, topright );
6604                                         sym( topright, toprcasing );
6605                                         lnext( horiz, botleft );
6606                                         sym( botleft, botlcasing );
6607                                         lprev( horiz, botright );
6608                                         sym( botright, botrcasing );
6609                                         /* Rotate the quadrilateral one-quarter turn counterclockwise. */
6610                                         bond( topleft, botlcasing );
6611                                         bond( botleft, botrcasing );
6612                                         bond( botright, toprcasing );
6613                                         bond( topright, toplcasing );
6614                                         if ( checksegments ) {
6615                                                 /* Check for shell edges and rebond them to the quadrilateral. */
6616                                                 tspivot( topleft, toplshelle );
6617                                                 tspivot( botleft, botlshelle );
6618                                                 tspivot( botright, botrshelle );
6619                                                 tspivot( topright, toprshelle );
6620                                                 if ( toplshelle.sh == dummysh ) {
6621                                                         tsdissolve( topright );
6622                                                 }
6623                                                 else {
6624                                                         tsbond( topright, toplshelle );
6625                                                 }
6626                                                 if ( botlshelle.sh == dummysh ) {
6627                                                         tsdissolve( topleft );
6628                                                 }
6629                                                 else {
6630                                                         tsbond( topleft, botlshelle );
6631                                                 }
6632                                                 if ( botrshelle.sh == dummysh ) {
6633                                                         tsdissolve( botleft );
6634                                                 }
6635                                                 else {
6636                                                         tsbond( botleft, botrshelle );
6637                                                 }
6638                                                 if ( toprshelle.sh == dummysh ) {
6639                                                         tsdissolve( botright );
6640                                                 }
6641                                                 else {
6642                                                         tsbond( botright, toprshelle );
6643                                                 }
6644                                         }
6645                                         /* New point assignments for the rotated quadrilateral. */
6646                                         setorg( horiz, farpoint );
6647                                         setdest( horiz, insertpoint );
6648                                         setapex( horiz, rightpoint );
6649                                         setorg( top, insertpoint );
6650                                         setdest( top, farpoint );
6651                                         setapex( top, leftpoint );
6652                                         for ( i = 0; i < eextras; i++ ) {
6653                                                 /* Take the average of the two triangles' attributes. */
6654                                                 attrib = (REAL)( 0.5 * ( elemattribute( top, i ) + elemattribute( horiz, i ) ) );
6655                                                 setelemattribute( top, i, attrib );
6656                                                 setelemattribute( horiz, i, attrib );
6657                                         }
6658                                         if ( vararea ) {
6659                                                 if ( ( areabound( top ) <= 0.0 ) || ( areabound( horiz ) <= 0.0 ) ) {
6660                                                         area = -1.0;
6661                                                 }
6662                                                 else {
6663                                                         /* Take the average of the two triangles' area constraints.    */
6664                                                         /*   This prevents small area constraints from migrating a     */
6665                                                         /*   long, long way from their original location due to flips. */
6666                                                         area = (REAL)( 0.5 * ( areabound( top ) + areabound( horiz ) ) );
6667                                                 }
6668                                                 setareabound( top, area );
6669                                                 setareabound( horiz, area );
6670                                         }
6671 #ifdef SELF_CHECK
6672                                         if ( insertpoint != (point) NULL ) {
6673                                                 if ( counterclockwise( leftpoint, insertpoint, rightpoint ) < 0.0 ) {
6674                                                         printf( "Internal error in insertsite():\n" );
6675                                                         printf( "  Clockwise triangle prior to edge flip (bottom).\n" );
6676                                                 }
6677                                                 /* The following test has been removed because constrainededge() */
6678                                                 /*   sometimes generates inverted triangles that insertsite()    */
6679                                                 /*   removes.                                                    */
6680 /*
6681             if (counterclockwise(rightpoint, farpoint, leftpoint) < 0.0) {
6682               printf("Internal error in insertsite():\n");
6683               printf("  Clockwise triangle prior to edge flip (top).\n");
6684             }
6685  */
6686                                                 if ( counterclockwise( farpoint, leftpoint, insertpoint ) < 0.0 ) {
6687                                                         printf( "Internal error in insertsite():\n" );
6688                                                         printf( "  Clockwise triangle after edge flip (left).\n" );
6689                                                 }
6690                                                 if ( counterclockwise( insertpoint, rightpoint, farpoint ) < 0.0 ) {
6691                                                         printf( "Internal error in insertsite():\n" );
6692                                                         printf( "  Clockwise triangle after edge flip (right).\n" );
6693                                                 }
6694                                         }
6695 #endif /* SELF_CHECK */
6696                                         if ( verbose > 2 ) {
6697                                                 printf( "  Edge flip results in left " );
6698                                                 lnextself( topleft );
6699                                                 printtriangle( &topleft );
6700                                                 printf( "  and right " );
6701                                                 printtriangle( &horiz );
6702                                         }
6703                                         /* On the next iterations, consider the two edges that were  */
6704                                         /*   exposed (this is, are now visible to the newly inserted */
6705                                         /*   point) by the edge flip.                                */
6706                                         lprevself( horiz );
6707                                         leftpoint = farpoint;
6708                                 }
6709                         }
6710                 }
6711                 if ( !doflip ) {
6712                         /* The handle `horiz' is accepted as locally Delaunay. */
6713 #ifndef CDT_ONLY
6714                         if ( triflaws ) {
6715                                 /* Check the triangle `horiz' for quality. */
6716                                 testtriangle( &horiz );
6717                         }
6718 #endif /* not CDT_ONLY */
6719                         /* Look for the next edge around the newly inserted point. */
6720                         lnextself( horiz );
6721                         sym( horiz, testtri );
6722                         /* Check for finishing a complete revolution about the new point, or */
6723                         /*   falling off the edge of the triangulation.  The latter will     */
6724                         /*   happen when a point is inserted at a boundary.                  */
6725                         if ( ( leftpoint == first ) || ( testtri.tri == dummytri ) ) {
6726                                 /* We're done.  Return a triangle whose origin is the new point. */
6727                                 lnext( horiz, *searchtri );
6728                                 lnext( horiz, recenttri );
6729                                 return success;
6730                         }
6731                         /* Finish finding the next edge around the newly inserted point. */
6732                         lnext( testtri, horiz );
6733                         rightpoint = leftpoint;
6734                         dest( horiz, leftpoint );
6735                 }
6736         }
6737 }
6738
6739 /*****************************************************************************/
6740 /*                                                                           */
6741 /*  triangulatepolygon()   Find the Delaunay triangulation of a polygon that */
6742 /*                         has a certain "nice" shape.  This includes the    */
6743 /*                         polygons that result from deletion of a point or  */
6744 /*                         insertion of a segment.                           */
6745 /*                                                                           */
6746 /*  This is a conceptually difficult routine.  The starting assumption is    */
6747 /*  that we have a polygon with n sides.  n - 1 of these sides are currently */
6748 /*  represented as edges in the mesh.  One side, called the "base", need not */
6749 /*  be.                                                                      */
6750 /*                                                                           */
6751 /*  Inside the polygon is a structure I call a "fan", consisting of n - 1    */
6752 /*  triangles that share a common origin.  For each of these triangles, the  */
6753 /*  edge opposite the origin is one of the sides of the polygon.  The        */
6754 /*  primary edge of each triangle is the edge directed from the origin to    */
6755 /*  the destination; note that this is not the same edge that is a side of   */
6756 /*  the polygon.  `firstedge' is the primary edge of the first triangle.     */
6757 /*  From there, the triangles follow in counterclockwise order about the     */
6758 /*  polygon, until `lastedge', the primary edge of the last triangle.        */
6759 /*  `firstedge' and `lastedge' are probably connected to other triangles     */
6760 /*  beyond the extremes of the fan, but their identity is not important, as  */
6761 /*  long as the fan remains connected to them.                               */
6762 /*                                                                           */
6763 /*  Imagine the polygon oriented so that its base is at the bottom.  This    */
6764 /*  puts `firstedge' on the far right, and `lastedge' on the far left.       */
6765 /*  The right vertex of the base is the destination of `firstedge', and the  */
6766 /*  left vertex of the base is the apex of `lastedge'.                       */
6767 /*                                                                           */
6768 /*  The challenge now is to find the right sequence of edge flips to         */
6769 /*  transform the fan into a Delaunay triangulation of the polygon.  Each    */
6770 /*  edge flip effectively removes one triangle from the fan, committing it   */
6771 /*  to the polygon.  The resulting polygon has one fewer edge.  If `doflip'  */
6772 /*  is set, the final flip will be performed, resulting in a fan of one      */
6773 /*  (useless?) triangle.  If `doflip' is not set, the final flip is not      */
6774 /*  performed, resulting in a fan of two triangles, and an unfinished        */
6775 /*  triangular polygon that is not yet filled out with a single triangle.    */
6776 /*  On completion of the routine, `lastedge' is the last remaining triangle, */
6777 /*  or the leftmost of the last two.                                         */
6778 /*                                                                           */
6779 /*  Although the flips are performed in the order described above, the       */
6780 /*  decisions about what flips to perform are made in precisely the reverse  */
6781 /*  order.  The recursive triangulatepolygon() procedure makes a decision,   */
6782 /*  uses up to two recursive calls to triangulate the "subproblems"          */
6783 /*  (polygons with fewer edges), and then performs an edge flip.             */
6784 /*                                                                           */
6785 /*  The "decision" it makes is which vertex of the polygon should be         */
6786 /*  connected to the base.  This decision is made by testing every possible  */
6787 /*  vertex.  Once the best vertex is found, the two edges that connect this  */
6788 /*  vertex to the base become the bases for two smaller polygons.  These     */
6789 /*  are triangulated recursively.  Unfortunately, this approach can take     */
6790 /*  O(n^2) time not only in the worst case, but in many common cases.  It's  */
6791 /*  rarely a big deal for point deletion, where n is rarely larger than ten, */
6792 /*  but it could be a big deal for segment insertion, especially if there's  */
6793 /*  a lot of long segments that each cut many triangles.  I ought to code    */
6794 /*  a faster algorithm some time.                                            */
6795 /*                                                                           */
6796 /*  The `edgecount' parameter is the number of sides of the polygon,         */
6797 /*  including its base.  `triflaws' is a flag that determines whether the    */
6798 /*  new triangles should be tested for quality, and enqueued if they are     */
6799 /*  bad.                                                                     */
6800 /*                                                                           */
6801 /*****************************************************************************/
6802
6803 void triangulatepolygon( firstedge, lastedge, edgecount, doflip, triflaws )
6804 struct triedge *firstedge;
6805 struct triedge *lastedge;
6806 int edgecount;
6807 int doflip;
6808 int triflaws;
6809 {
6810         struct triedge testtri;
6811         struct triedge besttri;
6812         struct triedge tempedge;
6813         point leftbasepoint, rightbasepoint;
6814         point testpoint;
6815         point bestpoint;
6816         int bestnumber;
6817         int i;
6818         triangle ptr; /* Temporary variable used by sym(), onext(), and oprev(). */
6819
6820         /* Identify the base vertices. */
6821         apex( *lastedge, leftbasepoint );
6822         dest( *firstedge, rightbasepoint );
6823         if ( verbose > 2 ) {
6824                 printf( "  Triangulating interior polygon at edge\n" );
6825                 printf( "    (%.12g, %.12g) (%.12g, %.12g)\n", leftbasepoint[0],
6826                                 leftbasepoint[1], rightbasepoint[0], rightbasepoint[1] );
6827         }
6828         /* Find the best vertex to connect the base to. */
6829         onext( *firstedge, besttri );
6830         dest( besttri, bestpoint );
6831         triedgecopy( besttri, testtri );
6832         bestnumber = 1;
6833         for ( i = 2; i <= edgecount - 2; i++ ) {
6834                 onextself( testtri );
6835                 dest( testtri, testpoint );
6836                 /* Is this a better vertex? */
6837                 if ( incircle( leftbasepoint, rightbasepoint, bestpoint, testpoint ) > 0.0 ) {
6838                         triedgecopy( testtri, besttri );
6839                         bestpoint = testpoint;
6840                         bestnumber = i;
6841                 }
6842         }
6843         if ( verbose > 2 ) {
6844                 printf( "    Connecting edge to (%.12g, %.12g)\n", bestpoint[0],
6845                                 bestpoint[1] );
6846         }
6847         if ( bestnumber > 1 ) {
6848                 /* Recursively triangulate the smaller polygon on the right. */
6849                 oprev( besttri, tempedge );
6850                 triangulatepolygon( firstedge, &tempedge, bestnumber + 1, 1, triflaws );
6851         }
6852         if ( bestnumber < edgecount - 2 ) {
6853                 /* Recursively triangulate the smaller polygon on the left. */
6854                 sym( besttri, tempedge );
6855                 triangulatepolygon( &besttri, lastedge, edgecount - bestnumber, 1,
6856                                                         triflaws );
6857                 /* Find `besttri' again; it may have been lost to edge flips. */
6858                 sym( tempedge, besttri );
6859         }
6860         if ( doflip ) {
6861                 /* Do one final edge flip. */
6862                 flip( &besttri );
6863 #ifndef CDT_ONLY
6864                 if ( triflaws ) {
6865                         /* Check the quality of the newly committed triangle. */
6866                         sym( besttri, testtri );
6867                         testtriangle( &testtri );
6868                 }
6869 #endif /* not CDT_ONLY */
6870         }
6871         /* Return the base triangle. */
6872         triedgecopy( besttri, *lastedge );
6873 }
6874
6875 /*****************************************************************************/
6876 /*                                                                           */
6877 /*  deletesite()   Delete a vertex from a Delaunay triangulation, ensuring   */
6878 /*                 that the triangulation remains Delaunay.                  */
6879 /*                                                                           */
6880 /*  The origin of `deltri' is deleted.  The union of the triangles adjacent  */
6881 /*  to this point is a polygon, for which the Delaunay triangulation is      */
6882 /*  found.  Two triangles are removed from the mesh.                         */
6883 /*                                                                           */
6884 /*  Only interior points that do not lie on segments (shell edges) or        */
6885 /*  boundaries may be deleted.                                               */
6886 /*                                                                           */
6887 /*****************************************************************************/
6888
6889 #ifndef CDT_ONLY
6890
6891 void deletesite( deltri )
6892 struct triedge *deltri;
6893 {
6894         struct triedge countingtri;
6895         struct triedge firstedge, lastedge;
6896         struct triedge deltriright;
6897         struct triedge lefttri, righttri;
6898         struct triedge leftcasing, rightcasing;
6899         struct edge leftshelle, rightshelle;
6900         point delpoint;
6901         point neworg;
6902         int edgecount;
6903         triangle ptr; /* Temporary variable used by sym(), onext(), and oprev(). */
6904         shelle sptr;                    /* Temporary variable used by tspivot(). */
6905
6906         org( *deltri, delpoint );
6907         if ( verbose > 1 ) {
6908                 printf( "  Deleting (%.12g, %.12g).\n", delpoint[0], delpoint[1] );
6909         }
6910         pointdealloc( delpoint );
6911
6912         /* Count the degree of the point being deleted. */
6913         onext( *deltri, countingtri );
6914         edgecount = 1;
6915         while ( !triedgeequal( *deltri, countingtri ) ) {
6916 #ifdef SELF_CHECK
6917                 if ( countingtri.tri == dummytri ) {
6918                         printf( "Internal error in deletesite():\n" );
6919                         printf( "  Attempt to delete boundary point.\n" );
6920                         internalerror();
6921                 }
6922 #endif /* SELF_CHECK */
6923                 edgecount++;
6924                 onextself( countingtri );
6925         }
6926
6927 #ifdef SELF_CHECK
6928         if ( edgecount < 3 ) {
6929                 printf( "Internal error in deletesite():\n  Point has degree %d.\n",
6930                                 edgecount );
6931                 internalerror();
6932         }
6933 #endif /* SELF_CHECK */
6934         if ( edgecount > 3 ) {
6935                 /* Triangulate the polygon defined by the union of all triangles */
6936                 /*   adjacent to the point being deleted.  Check the quality of  */
6937                 /*   the resulting triangles.                                    */
6938                 onext( *deltri, firstedge );
6939                 oprev( *deltri, lastedge );
6940                 triangulatepolygon( &firstedge, &lastedge, edgecount, 0, !nobisect );
6941         }
6942         /* Splice out two triangles. */
6943         lprev( *deltri, deltriright );
6944         dnext( *deltri, lefttri );
6945         sym( lefttri, leftcasing );
6946         oprev( deltriright, righttri );
6947         sym( righttri, rightcasing );
6948         bond( *deltri, leftcasing );
6949         bond( deltriright, rightcasing );
6950         tspivot( lefttri, leftshelle );
6951         if ( leftshelle.sh != dummysh ) {
6952                 tsbond( *deltri, leftshelle );
6953         }
6954         tspivot( righttri, rightshelle );
6955         if ( rightshelle.sh != dummysh ) {
6956                 tsbond( deltriright, rightshelle );
6957         }
6958
6959         /* Set the new origin of `deltri' and check its quality. */
6960         org( lefttri, neworg );
6961         setorg( *deltri, neworg );
6962         if ( !nobisect ) {
6963                 testtriangle( deltri );
6964         }
6965
6966         /* Delete the two spliced-out triangles. */
6967         triangledealloc( lefttri.tri );
6968         triangledealloc( righttri.tri );
6969 }
6970
6971 #endif /* not CDT_ONLY */
6972
6973 /**                                                                         **/
6974 /**                                                                         **/
6975 /********* Mesh transformation routines end here                     *********/
6976
6977 /********* Divide-and-conquer Delaunay triangulation begins here     *********/
6978 /**                                                                         **/
6979 /**                                                                         **/
6980
6981 /*****************************************************************************/
6982 /*                                                                           */
6983 /*  The divide-and-conquer bounding box                                      */
6984 /*                                                                           */
6985 /*  I originally implemented the divide-and-conquer and incremental Delaunay */
6986 /*  triangulations using the edge-based data structure presented by Guibas   */
6987 /*  and Stolfi.  Switching to a triangle-based data structure doubled the    */
6988 /*  speed.  However, I had to think of a few extra tricks to maintain the    */
6989 /*  elegance of the original algorithms.                                     */
6990 /*                                                                           */
6991 /*  The "bounding box" used by my variant of the divide-and-conquer          */
6992 /*  algorithm uses one triangle for each edge of the convex hull of the      */
6993 /*  triangulation.  These bounding triangles all share a common apical       */
6994 /*  vertex, which is represented by NULL and which represents nothing.       */
6995 /*  The bounding triangles are linked in a circular fan about this NULL      */
6996 /*  vertex, and the edges on the convex hull of the triangulation appear     */
6997 /*  opposite the NULL vertex.  You might find it easiest to imagine that     */
6998 /*  the NULL vertex is a point in 3D space behind the center of the          */
6999 /*  triangulation, and that the bounding triangles form a sort of cone.      */
7000 /*                                                                           */
7001 /*  This bounding box makes it easy to represent degenerate cases.  For      */
7002 /*  instance, the triangulation of two vertices is a single edge.  This edge */
7003 /*  is represented by two bounding box triangles, one on each "side" of the  */
7004 /*  edge.  These triangles are also linked together in a fan about the NULL  */
7005 /*  vertex.                                                                  */
7006 /*                                                                           */
7007 /*  The bounding box also makes it easy to traverse the convex hull, as the  */
7008 /*  divide-and-conquer algorithm needs to do.                                */
7009 /*                                                                           */
7010 /*****************************************************************************/
7011
7012 /*****************************************************************************/
7013 /*                                                                           */
7014 /*  pointsort()   Sort an array of points by x-coordinate, using the         */
7015 /*                y-coordinate as a secondary key.                           */
7016 /*                                                                           */
7017 /*  Uses quicksort.  Randomized O(n log n) time.  No, I did not make any of  */
7018 /*  the usual quicksort mistakes.                                            */
7019 /*                                                                           */
7020 /*****************************************************************************/
7021
7022 void pointsort( sortarray, arraysize )
7023 point * sortarray;
7024 int arraysize;
7025 {
7026         int left, right;
7027         int pivot;
7028         REAL pivotx, pivoty;
7029         point temp;
7030
7031         if ( arraysize == 2 ) {
7032                 /* Recursive base case. */
7033                 if ( ( sortarray[0][0] > sortarray[1][0] ) ||
7034                          ( ( sortarray[0][0] == sortarray[1][0] ) &&
7035                            ( sortarray[0][1] > sortarray[1][1] ) ) ) {
7036                         temp = sortarray[1];
7037                         sortarray[1] = sortarray[0];
7038                         sortarray[0] = temp;
7039                 }
7040                 return;
7041         }
7042         /* Choose a random pivot to split the array. */
7043         pivot = (int) randomnation( arraysize );
7044         pivotx = sortarray[pivot][0];
7045         pivoty = sortarray[pivot][1];
7046         /* Split the array. */
7047         left = -1;
7048         right = arraysize;
7049         while ( left < right ) {
7050                 /* Search for a point whose x-coordinate is too large for the left. */
7051                 do {
7052                         left++;
7053                 } while ( ( left <= right ) && ( ( sortarray[left][0] < pivotx ) ||
7054                                                                                  ( ( sortarray[left][0] == pivotx ) &&
7055                                                                                    ( sortarray[left][1] < pivoty ) ) ) );
7056                 /* Search for a point whose x-coordinate is too small for the right. */
7057                 do {
7058                         right--;
7059                 } while ( ( left <= right ) && ( ( sortarray[right][0] > pivotx ) ||
7060                                                                                  ( ( sortarray[right][0] == pivotx ) &&
7061                                                                                    ( sortarray[right][1] > pivoty ) ) ) );
7062                 if ( left < right ) {
7063                         /* Swap the left and right points. */
7064                         temp = sortarray[left];
7065                         sortarray[left] = sortarray[right];
7066                         sortarray[right] = temp;
7067                 }
7068         }
7069         if ( left > 1 ) {
7070                 /* Recursively sort the left subset. */
7071                 pointsort( sortarray, left );
7072         }
7073         if ( right < arraysize - 2 ) {
7074                 /* Recursively sort the right subset. */
7075                 pointsort( &sortarray[right + 1], arraysize - right - 1 );
7076         }
7077 }
7078
7079 /*****************************************************************************/
7080 /*                                                                           */
7081 /*  pointmedian()   An order statistic algorithm, almost.  Shuffles an array */
7082 /*                  of points so that the first `median' points occur        */
7083 /*                  lexicographically before the remaining points.           */
7084 /*                                                                           */
7085 /*  Uses the x-coordinate as the primary key if axis == 0; the y-coordinate  */
7086 /*  if axis == 1.  Very similar to the pointsort() procedure, but runs in    */
7087 /*  randomized linear time.                                                  */
7088 /*                                                                           */
7089 /*****************************************************************************/
7090
7091 void pointmedian( sortarray, arraysize, median, axis )
7092 point * sortarray;
7093 int arraysize;
7094 int median;
7095 int axis;
7096 {
7097         int left, right;
7098         int pivot;
7099         REAL pivot1, pivot2;
7100         point temp;
7101
7102         if ( arraysize == 2 ) {
7103                 /* Recursive base case. */
7104                 if ( ( sortarray[0][axis] > sortarray[1][axis] ) ||
7105                          ( ( sortarray[0][axis] == sortarray[1][axis] ) &&
7106                            ( sortarray[0][1 - axis] > sortarray[1][1 - axis] ) ) ) {
7107                         temp = sortarray[1];
7108                         sortarray[1] = sortarray[0];
7109                         sortarray[0] = temp;
7110                 }
7111                 return;
7112         }
7113         /* Choose a random pivot to split the array. */
7114         pivot = (int) randomnation( arraysize );
7115         pivot1 = sortarray[pivot][axis];
7116         pivot2 = sortarray[pivot][1 - axis];
7117         /* Split the array. */
7118         left = -1;
7119         right = arraysize;
7120         while ( left < right ) {
7121                 /* Search for a point whose x-coordinate is too large for the left. */
7122                 do {
7123                         left++;
7124                 } while ( ( left <= right ) && ( ( sortarray[left][axis] < pivot1 ) ||
7125                                                                                  ( ( sortarray[left][axis] == pivot1 ) &&
7126                                                                                    ( sortarray[left][1 - axis] < pivot2 ) ) ) );
7127                 /* Search for a point whose x-coordinate is too small for the right. */
7128                 do {
7129                         right--;
7130                 } while ( ( left <= right ) && ( ( sortarray[right][axis] > pivot1 ) ||
7131                                                                                  ( ( sortarray[right][axis] == pivot1 ) &&
7132                                                                                    ( sortarray[right][1 - axis] > pivot2 ) ) ) );
7133                 if ( left < right ) {
7134                         /* Swap the left and right points. */
7135                         temp = sortarray[left];
7136                         sortarray[left] = sortarray[right];
7137                         sortarray[right] = temp;
7138                 }
7139         }
7140         /* Unlike in pointsort(), at most one of the following */
7141         /*   conditionals is true.                             */
7142         if ( left > median ) {
7143                 /* Recursively shuffle the left subset. */
7144                 pointmedian( sortarray, left, median, axis );
7145         }
7146         if ( right < median - 1 ) {
7147                 /* Recursively shuffle the right subset. */
7148                 pointmedian( &sortarray[right + 1], arraysize - right - 1,
7149                                          median - right - 1, axis );
7150         }
7151 }
7152
7153 /*****************************************************************************/
7154 /*                                                                           */
7155 /*  alternateaxes()   Sorts the points as appropriate for the divide-and-    */
7156 /*                    conquer algorithm with alternating cuts.               */
7157 /*                                                                           */
7158 /*  Partitions by x-coordinate if axis == 0; by y-coordinate if axis == 1.   */
7159 /*  For the base case, subsets containing only two or three points are       */
7160 /*  always sorted by x-coordinate.                                           */
7161 /*                                                                           */
7162 /*****************************************************************************/
7163
7164 void alternateaxes( sortarray, arraysize, axis )
7165 point * sortarray;
7166 int arraysize;
7167 int axis;
7168 {
7169         int divider;
7170
7171         divider = arraysize >> 1;
7172         if ( arraysize <= 3 ) {
7173                 /* Recursive base case:  subsets of two or three points will be      */
7174                 /*   handled specially, and should always be sorted by x-coordinate. */
7175                 axis = 0;
7176         }
7177         /* Partition with a horizontal or vertical cut. */
7178         pointmedian( sortarray, arraysize, divider, axis );
7179         /* Recursively partition the subsets with a cross cut. */
7180         if ( arraysize - divider >= 2 ) {
7181                 if ( divider >= 2 ) {
7182                         alternateaxes( sortarray, divider, 1 - axis );
7183                 }
7184                 alternateaxes( &sortarray[divider], arraysize - divider, 1 - axis );
7185         }
7186 }
7187
7188 /*****************************************************************************/
7189 /*                                                                           */
7190 /*  mergehulls()   Merge two adjacent Delaunay triangulations into a         */
7191 /*                 single Delaunay triangulation.                            */
7192 /*                                                                           */
7193 /*  This is similar to the algorithm given by Guibas and Stolfi, but uses    */
7194 /*  a triangle-based, rather than edge-based, data structure.                */
7195 /*                                                                           */
7196 /*  The algorithm walks up the gap between the two triangulations, knitting  */
7197 /*  them together.  As they are merged, some of their bounding triangles     */
7198 /*  are converted into real triangles of the triangulation.  The procedure   */
7199 /*  pulls each hull's bounding triangles apart, then knits them together     */
7200 /*  like the teeth of two gears.  The Delaunay property determines, at each  */
7201 /*  step, whether the next "tooth" is a bounding triangle of the left hull   */
7202 /*  or the right.  When a bounding triangle becomes real, its apex is        */
7203 /*  changed from NULL to a real point.                                       */
7204 /*                                                                           */
7205 /*  Only two new triangles need to be allocated.  These become new bounding  */
7206 /*  triangles at the top and bottom of the seam.  They are used to connect   */
7207 /*  the remaining bounding triangles (those that have not been converted     */
7208 /*  into real triangles) into a single fan.                                  */
7209 /*                                                                           */
7210 /*  On entry, `farleft' and `innerleft' are bounding triangles of the left   */
7211 /*  triangulation.  The origin of `farleft' is the leftmost vertex, and      */
7212 /*  the destination of `innerleft' is the rightmost vertex of the            */
7213 /*  triangulation.  Similarly, `innerright' and `farright' are bounding      */
7214 /*  triangles of the right triangulation.  The origin of `innerright' and    */
7215 /*  destination of `farright' are the leftmost and rightmost vertices.       */
7216 /*                                                                           */
7217 /*  On completion, the origin of `farleft' is the leftmost vertex of the     */
7218 /*  merged triangulation, and the destination of `farright' is the rightmost */
7219 /*  vertex.                                                                  */
7220 /*                                                                           */
7221 /*****************************************************************************/
7222
7223 void mergehulls( farleft, innerleft, innerright, farright, axis )
7224 struct triedge *farleft;
7225 struct triedge *innerleft;
7226 struct triedge *innerright;
7227 struct triedge *farright;
7228 int axis;
7229 {
7230         struct triedge leftcand, rightcand;
7231         struct triedge baseedge;
7232         struct triedge nextedge;
7233         struct triedge sidecasing, topcasing, outercasing;
7234         struct triedge checkedge;
7235         point innerleftdest;
7236         point innerrightorg;
7237         point innerleftapex, innerrightapex;
7238         point farleftpt, farrightpt;
7239         point farleftapex, farrightapex;
7240         point lowerleft, lowerright;
7241         point upperleft, upperright;
7242         point nextapex;
7243         point checkvertex;
7244         int changemade;
7245         int badedge;
7246         int leftfinished, rightfinished;
7247         triangle ptr;                       /* Temporary variable used by sym(). */
7248
7249         dest( *innerleft, innerleftdest );
7250         apex( *innerleft, innerleftapex );
7251         org( *innerright, innerrightorg );
7252         apex( *innerright, innerrightapex );
7253         /* Special treatment for horizontal cuts. */
7254         if ( dwyer && ( axis == 1 ) ) {
7255                 org( *farleft, farleftpt );
7256                 apex( *farleft, farleftapex );
7257                 dest( *farright, farrightpt );
7258                 apex( *farright, farrightapex );
7259                 /* The pointers to the extremal points are shifted to point to the */
7260                 /*   topmost and bottommost point of each hull, rather than the    */
7261                 /*   leftmost and rightmost points.                                */
7262                 while ( farleftapex[1] < farleftpt[1] ) {
7263                         lnextself( *farleft );
7264                         symself( *farleft );
7265                         farleftpt = farleftapex;
7266                         apex( *farleft, farleftapex );
7267                 }
7268                 sym( *innerleft, checkedge );
7269                 apex( checkedge, checkvertex );
7270                 while ( checkvertex[1] > innerleftdest[1] ) {
7271                         lnext( checkedge, *innerleft );
7272                         innerleftapex = innerleftdest;
7273                         innerleftdest = checkvertex;
7274                         sym( *innerleft, checkedge );
7275                         apex( checkedge, checkvertex );
7276                 }
7277                 while ( innerrightapex[1] < innerrightorg[1] ) {
7278                         lnextself( *innerright );
7279                         symself( *innerright );
7280                         innerrightorg = innerrightapex;
7281                         apex( *innerright, innerrightapex );
7282                 }
7283                 sym( *farright, checkedge );
7284                 apex( checkedge, checkvertex );
7285                 while ( checkvertex[1] > farrightpt[1] ) {
7286                         lnext( checkedge, *farright );
7287                         farrightapex = farrightpt;
7288                         farrightpt = checkvertex;
7289                         sym( *farright, checkedge );
7290                         apex( checkedge, checkvertex );
7291                 }
7292         }
7293         /* Find a line tangent to and below both hulls. */
7294         do {
7295                 changemade = 0;
7296                 /* Make innerleftdest the "bottommost" point of the left hull. */
7297                 if ( counterclockwise( innerleftdest, innerleftapex, innerrightorg ) > 0.0 ) {
7298                         lprevself( *innerleft );
7299                         symself( *innerleft );
7300                         innerleftdest = innerleftapex;
7301                         apex( *innerleft, innerleftapex );
7302                         changemade = 1;
7303                 }
7304                 /* Make innerrightorg the "bottommost" point of the right hull. */
7305                 if ( counterclockwise( innerrightapex, innerrightorg, innerleftdest ) > 0.0 ) {
7306                         lnextself( *innerright );
7307                         symself( *innerright );
7308                         innerrightorg = innerrightapex;
7309                         apex( *innerright, innerrightapex );
7310                         changemade = 1;
7311                 }
7312         } while ( changemade );
7313         /* Find the two candidates to be the next "gear tooth". */
7314         sym( *innerleft, leftcand );
7315         sym( *innerright, rightcand );
7316         /* Create the bottom new bounding triangle. */
7317         maketriangle( &baseedge );
7318         /* Connect it to the bounding boxes of the left and right triangulations. */
7319         bond( baseedge, *innerleft );
7320         lnextself( baseedge );
7321         bond( baseedge, *innerright );
7322         lnextself( baseedge );
7323         setorg( baseedge, innerrightorg );
7324         setdest( baseedge, innerleftdest );
7325         /* Apex is intentionally left NULL. */
7326         if ( verbose > 2 ) {
7327                 printf( "  Creating base bounding " );
7328                 printtriangle( &baseedge );
7329         }
7330         /* Fix the extreme triangles if necessary. */
7331         org( *farleft, farleftpt );
7332         if ( innerleftdest == farleftpt ) {
7333                 lnext( baseedge, *farleft );
7334         }
7335         dest( *farright, farrightpt );
7336         if ( innerrightorg == farrightpt ) {
7337                 lprev( baseedge, *farright );
7338         }
7339         /* The vertices of the current knitting edge. */
7340         lowerleft = innerleftdest;
7341         lowerright = innerrightorg;
7342         /* The candidate vertices for knitting. */
7343         apex( leftcand, upperleft );
7344         apex( rightcand, upperright );
7345         /* Walk up the gap between the two triangulations, knitting them together. */
7346         while ( 1 ) {
7347                 /* Have we reached the top?  (This isn't quite the right question,       */
7348                 /*   because even though the left triangulation might seem finished now, */
7349                 /*   moving up on the right triangulation might reveal a new point of    */
7350                 /*   the left triangulation.  And vice-versa.)                           */
7351                 leftfinished = counterclockwise( upperleft, lowerleft, lowerright ) <= 0.0;
7352                 rightfinished = counterclockwise( upperright, lowerleft, lowerright ) <= 0.0;
7353                 if ( leftfinished && rightfinished ) {
7354                         /* Create the top new bounding triangle. */
7355                         maketriangle( &nextedge );
7356                         setorg( nextedge, lowerleft );
7357                         setdest( nextedge, lowerright );
7358                         /* Apex is intentionally left NULL. */
7359                         /* Connect it to the bounding boxes of the two triangulations. */
7360                         bond( nextedge, baseedge );
7361                         lnextself( nextedge );
7362                         bond( nextedge, rightcand );
7363                         lnextself( nextedge );
7364                         bond( nextedge, leftcand );
7365                         if ( verbose > 2 ) {
7366                                 printf( "  Creating top bounding " );
7367                                 printtriangle( &baseedge );
7368                         }
7369                         /* Special treatment for horizontal cuts. */
7370                         if ( dwyer && ( axis == 1 ) ) {
7371                                 org( *farleft, farleftpt );
7372                                 apex( *farleft, farleftapex );
7373                                 dest( *farright, farrightpt );
7374                                 apex( *farright, farrightapex );
7375                                 sym( *farleft, checkedge );
7376                                 apex( checkedge, checkvertex );
7377                                 /* The pointers to the extremal points are restored to the leftmost */
7378                                 /*   and rightmost points (rather than topmost and bottommost).     */
7379                                 while ( checkvertex[0] < farleftpt[0] ) {
7380                                         lprev( checkedge, *farleft );
7381                                         farleftapex = farleftpt;
7382                                         farleftpt = checkvertex;
7383                                         sym( *farleft, checkedge );
7384                                         apex( checkedge, checkvertex );
7385                                 }
7386                                 while ( farrightapex[0] > farrightpt[0] ) {
7387                                         lprevself( *farright );
7388                                         symself( *farright );
7389                                         farrightpt = farrightapex;
7390                                         apex( *farright, farrightapex );
7391                                 }
7392                         }
7393                         return;
7394                 }
7395                 /* Consider eliminating edges from the left triangulation. */
7396                 if ( !leftfinished ) {
7397                         /* What vertex would be exposed if an edge were deleted? */
7398                         lprev( leftcand, nextedge );
7399                         symself( nextedge );
7400                         apex( nextedge, nextapex );
7401                         /* If nextapex is NULL, then no vertex would be exposed; the */
7402                         /*   triangulation would have been eaten right through.      */
7403                         if ( nextapex != (point) NULL ) {
7404                                 /* Check whether the edge is Delaunay. */
7405                                 badedge = incircle( lowerleft, lowerright, upperleft, nextapex ) > 0.0;
7406                                 while ( badedge ) {
7407                                         /* Eliminate the edge with an edge flip.  As a result, the    */
7408                                         /*   left triangulation will have one more boundary triangle. */
7409                                         lnextself( nextedge );
7410                                         sym( nextedge, topcasing );
7411                                         lnextself( nextedge );
7412                                         sym( nextedge, sidecasing );
7413                                         bond( nextedge, topcasing );
7414                                         bond( leftcand, sidecasing );
7415                                         lnextself( leftcand );
7416                                         sym( leftcand, outercasing );
7417                                         lprevself( nextedge );
7418                                         bond( nextedge, outercasing );
7419                                         /* Correct the vertices to reflect the edge flip. */
7420                                         setorg( leftcand, lowerleft );
7421                                         setdest( leftcand, NULL );
7422                                         setapex( leftcand, nextapex );
7423                                         setorg( nextedge, NULL );
7424                                         setdest( nextedge, upperleft );
7425                                         setapex( nextedge, nextapex );
7426                                         /* Consider the newly exposed vertex. */
7427                                         upperleft = nextapex;
7428                                         /* What vertex would be exposed if another edge were deleted? */
7429                                         triedgecopy( sidecasing, nextedge );
7430                                         apex( nextedge, nextapex );
7431                                         if ( nextapex != (point) NULL ) {
7432                                                 /* Check whether the edge is Delaunay. */
7433                                                 badedge = incircle( lowerleft, lowerright, upperleft, nextapex )
7434                                                                   > 0.0;
7435                                         }
7436                                         else {
7437                                                 /* Avoid eating right through the triangulation. */
7438                                                 badedge = 0;
7439                                         }
7440                                 }
7441                         }
7442                 }
7443                 /* Consider eliminating edges from the right triangulation. */
7444                 if ( !rightfinished ) {
7445                         /* What vertex would be exposed if an edge were deleted? */
7446                         lnext( rightcand, nextedge );
7447                         symself( nextedge );
7448                         apex( nextedge, nextapex );
7449                         /* If nextapex is NULL, then no vertex would be exposed; the */
7450                         /*   triangulation would have been eaten right through.      */
7451                         if ( nextapex != (point) NULL ) {
7452                                 /* Check whether the edge is Delaunay. */
7453                                 badedge = incircle( lowerleft, lowerright, upperright, nextapex ) > 0.0;
7454                                 while ( badedge ) {
7455                                         /* Eliminate the edge with an edge flip.  As a result, the     */
7456                                         /*   right triangulation will have one more boundary triangle. */
7457                                         lprevself( nextedge );
7458                                         sym( nextedge, topcasing );
7459                                         lprevself( nextedge );
7460                                         sym( nextedge, sidecasing );
7461                                         bond( nextedge, topcasing );
7462                                         bond( rightcand, sidecasing );
7463                                         lprevself( rightcand );
7464                                         sym( rightcand, outercasing );
7465                                         lnextself( nextedge );
7466                                         bond( nextedge, outercasing );
7467                                         /* Correct the vertices to reflect the edge flip. */
7468                                         setorg( rightcand, NULL );
7469                                         setdest( rightcand, lowerright );
7470                                         setapex( rightcand, nextapex );
7471                                         setorg( nextedge, upperright );
7472                                         setdest( nextedge, NULL );
7473                                         setapex( nextedge, nextapex );
7474                                         /* Consider the newly exposed vertex. */
7475                                         upperright = nextapex;
7476                                         /* What vertex would be exposed if another edge were deleted? */
7477                                         triedgecopy( sidecasing, nextedge );
7478                                         apex( nextedge, nextapex );
7479                                         if ( nextapex != (point) NULL ) {
7480                                                 /* Check whether the edge is Delaunay. */
7481                                                 badedge = incircle( lowerleft, lowerright, upperright, nextapex )
7482                                                                   > 0.0;
7483                                         }
7484                                         else {
7485                                                 /* Avoid eating right through the triangulation. */
7486                                                 badedge = 0;
7487                                         }
7488                                 }
7489                         }
7490                 }
7491                 if ( leftfinished || ( !rightfinished &&
7492                                                            ( incircle( upperleft, lowerleft, lowerright, upperright ) > 0.0 ) ) ) {
7493                         /* Knit the triangulations, adding an edge from `lowerleft' */
7494                         /*   to `upperright'.                                       */
7495                         bond( baseedge, rightcand );
7496                         lprev( rightcand, baseedge );
7497                         setdest( baseedge, lowerleft );
7498                         lowerright = upperright;
7499                         sym( baseedge, rightcand );
7500                         apex( rightcand, upperright );
7501                 }
7502                 else {
7503                         /* Knit the triangulations, adding an edge from `upperleft' */
7504                         /*   to `lowerright'.                                       */
7505                         bond( baseedge, leftcand );
7506                         lnext( leftcand, baseedge );
7507                         setorg( baseedge, lowerright );
7508                         lowerleft = upperleft;
7509                         sym( baseedge, leftcand );
7510                         apex( leftcand, upperleft );
7511                 }
7512                 if ( verbose > 2 ) {
7513                         printf( "  Connecting " );
7514                         printtriangle( &baseedge );
7515                 }
7516         }
7517 }
7518
7519 /*****************************************************************************/
7520 /*                                                                           */
7521 /*  divconqrecurse()   Recursively form a Delaunay triangulation by the      */
7522 /*                     divide-and-conquer method.                            */
7523 /*                                                                           */
7524 /*  Recursively breaks down the problem into smaller pieces, which are       */
7525 /*  knitted together by mergehulls().  The base cases (problems of two or    */
7526 /*  three points) are handled specially here.                                */
7527 /*                                                                           */
7528 /*  On completion, `farleft' and `farright' are bounding triangles such that */
7529 /*  the origin of `farleft' is the leftmost vertex (breaking ties by         */
7530 /*  choosing the highest leftmost vertex), and the destination of            */
7531 /*  `farright' is the rightmost vertex (breaking ties by choosing the        */
7532 /*  lowest rightmost vertex).                                                */
7533 /*                                                                           */
7534 /*****************************************************************************/
7535
7536 void divconqrecurse( sortarray, vertices, axis, farleft, farright )
7537 point * sortarray;
7538 int vertices;
7539 int axis;
7540 struct triedge *farleft;
7541 struct triedge *farright;
7542 {
7543         struct triedge midtri, tri1, tri2, tri3;
7544         struct triedge innerleft, innerright;
7545         REAL area;
7546         int divider;
7547
7548         if ( verbose > 2 ) {
7549                 printf( "  Triangulating %d points.\n", vertices );
7550         }
7551         if ( vertices == 2 ) {
7552                 /* The triangulation of two vertices is an edge.  An edge is */
7553                 /*   represented by two bounding triangles.                  */
7554                 maketriangle( farleft );
7555                 setorg( *farleft, sortarray[0] );
7556                 setdest( *farleft, sortarray[1] );
7557                 /* The apex is intentionally left NULL. */
7558                 maketriangle( farright );
7559                 setorg( *farright, sortarray[1] );
7560                 setdest( *farright, sortarray[0] );
7561                 /* The apex is intentionally left NULL. */
7562                 bond( *farleft, *farright );
7563                 lprevself( *farleft );
7564                 lnextself( *farright );
7565                 bond( *farleft, *farright );
7566                 lprevself( *farleft );
7567                 lnextself( *farright );
7568                 bond( *farleft, *farright );
7569                 if ( verbose > 2 ) {
7570                         printf( "  Creating " );
7571                         printtriangle( farleft );
7572                         printf( "  Creating " );
7573                         printtriangle( farright );
7574                 }
7575                 /* Ensure that the origin of `farleft' is sortarray[0]. */
7576                 lprev( *farright, *farleft );
7577                 return;
7578         }
7579         else if ( vertices == 3 ) {
7580                 /* The triangulation of three vertices is either a triangle (with */
7581                 /*   three bounding triangles) or two edges (with four bounding   */
7582                 /*   triangles).  In either case, four triangles are created.     */
7583                 maketriangle( &midtri );
7584                 maketriangle( &tri1 );
7585                 maketriangle( &tri2 );
7586                 maketriangle( &tri3 );
7587                 area = counterclockwise( sortarray[0], sortarray[1], sortarray[2] );
7588                 if ( area == 0.0 ) {
7589                         /* Three collinear points; the triangulation is two edges. */
7590                         setorg( midtri, sortarray[0] );
7591                         setdest( midtri, sortarray[1] );
7592                         setorg( tri1, sortarray[1] );
7593                         setdest( tri1, sortarray[0] );
7594                         setorg( tri2, sortarray[2] );
7595                         setdest( tri2, sortarray[1] );
7596                         setorg( tri3, sortarray[1] );
7597                         setdest( tri3, sortarray[2] );
7598                         /* All apices are intentionally left NULL. */
7599                         bond( midtri, tri1 );
7600                         bond( tri2, tri3 );
7601                         lnextself( midtri );
7602                         lprevself( tri1 );
7603                         lnextself( tri2 );
7604                         lprevself( tri3 );
7605                         bond( midtri, tri3 );
7606                         bond( tri1, tri2 );
7607                         lnextself( midtri );
7608                         lprevself( tri1 );
7609                         lnextself( tri2 );
7610                         lprevself( tri3 );
7611                         bond( midtri, tri1 );
7612                         bond( tri2, tri3 );
7613                         /* Ensure that the origin of `farleft' is sortarray[0]. */
7614                         triedgecopy( tri1, *farleft );
7615                         /* Ensure that the destination of `farright' is sortarray[2]. */
7616                         triedgecopy( tri2, *farright );
7617                 }
7618                 else {
7619                         /* The three points are not collinear; the triangulation is one */
7620                         /*   triangle, namely `midtri'.                                 */
7621                         setorg( midtri, sortarray[0] );
7622                         setdest( tri1, sortarray[0] );
7623                         setorg( tri3, sortarray[0] );
7624                         /* Apices of tri1, tri2, and tri3 are left NULL. */
7625                         if ( area > 0.0 ) {
7626                                 /* The vertices are in counterclockwise order. */
7627                                 setdest( midtri, sortarray[1] );
7628                                 setorg( tri1, sortarray[1] );
7629                                 setdest( tri2, sortarray[1] );
7630                                 setapex( midtri, sortarray[2] );
7631                                 setorg( tri2, sortarray[2] );
7632                                 setdest( tri3, sortarray[2] );
7633                         }
7634                         else {
7635                                 /* The vertices are in clockwise order. */
7636                                 setdest( midtri, sortarray[2] );
7637                                 setorg( tri1, sortarray[2] );
7638                                 setdest( tri2, sortarray[2] );
7639                                 setapex( midtri, sortarray[1] );
7640                                 setorg( tri2, sortarray[1] );
7641                                 setdest( tri3, sortarray[1] );
7642                         }
7643                         /* The topology does not depend on how the vertices are ordered. */
7644                         bond( midtri, tri1 );
7645                         lnextself( midtri );
7646                         bond( midtri, tri2 );
7647                         lnextself( midtri );
7648                         bond( midtri, tri3 );
7649                         lprevself( tri1 );
7650                         lnextself( tri2 );
7651                         bond( tri1, tri2 );
7652                         lprevself( tri1 );
7653                         lprevself( tri3 );
7654                         bond( tri1, tri3 );
7655                         lnextself( tri2 );
7656                         lprevself( tri3 );
7657                         bond( tri2, tri3 );
7658                         /* Ensure that the origin of `farleft' is sortarray[0]. */
7659                         triedgecopy( tri1, *farleft );
7660                         /* Ensure that the destination of `farright' is sortarray[2]. */
7661                         if ( area > 0.0 ) {
7662                                 triedgecopy( tri2, *farright );
7663                         }
7664                         else {
7665                                 lnext( *farleft, *farright );
7666                         }
7667                 }
7668                 if ( verbose > 2 ) {
7669                         printf( "  Creating " );
7670                         printtriangle( &midtri );
7671                         printf( "  Creating " );
7672                         printtriangle( &tri1 );
7673                         printf( "  Creating " );
7674                         printtriangle( &tri2 );
7675                         printf( "  Creating " );
7676                         printtriangle( &tri3 );
7677                 }
7678                 return;
7679         }
7680         else {
7681                 /* Split the vertices in half. */
7682                 divider = vertices >> 1;
7683                 /* Recursively triangulate each half. */
7684                 divconqrecurse( sortarray, divider, 1 - axis, farleft, &innerleft );
7685                 divconqrecurse( &sortarray[divider], vertices - divider, 1 - axis,
7686                                                 &innerright, farright );
7687                 if ( verbose > 1 ) {
7688                         printf( "  Joining triangulations with %d and %d vertices.\n", divider,
7689                                         vertices - divider );
7690                 }
7691                 /* Merge the two triangulations into one. */
7692                 mergehulls( farleft, &innerleft, &innerright, farright, axis );
7693         }
7694 }
7695
7696 long removeghosts( startghost )
7697 struct triedge *startghost;
7698 {
7699         struct triedge searchedge;
7700         struct triedge dissolveedge;
7701         struct triedge deadtri;
7702         point markorg;
7703         long hullsize;
7704         triangle ptr;                       /* Temporary variable used by sym(). */
7705
7706         if ( verbose ) {
7707                 printf( "  Removing ghost triangles.\n" );
7708         }
7709         /* Find an edge on the convex hull to start point location from. */
7710         lprev( *startghost, searchedge );
7711         symself( searchedge );
7712         dummytri[0] = encode( searchedge );
7713         /* Remove the bounding box and count the convex hull edges. */
7714         triedgecopy( *startghost, dissolveedge );
7715         hullsize = 0;
7716         do {
7717                 hullsize++;
7718                 lnext( dissolveedge, deadtri );
7719                 lprevself( dissolveedge );
7720                 symself( dissolveedge );
7721                 /* If no PSLG is involved, set the boundary markers of all the points */
7722                 /*   on the convex hull.  If a PSLG is used, this step is done later. */
7723                 if ( !poly ) {
7724                         /* Watch out for the case where all the input points are collinear. */
7725                         if ( dissolveedge.tri != dummytri ) {
7726                                 org( dissolveedge, markorg );
7727                                 if ( pointmark( markorg ) == 0 ) {
7728                                         setpointmark( markorg, 1 );
7729                                 }
7730                         }
7731                 }
7732                 /* Remove a bounding triangle from a convex hull triangle. */
7733                 dissolve( dissolveedge );
7734                 /* Find the next bounding triangle. */
7735                 sym( deadtri, dissolveedge );
7736                 /* Delete the bounding triangle. */
7737                 triangledealloc( deadtri.tri );
7738         } while ( !triedgeequal( dissolveedge, *startghost ) );
7739         return hullsize;
7740 }
7741
7742 /*****************************************************************************/
7743 /*                                                                           */
7744 /*  divconqdelaunay()   Form a Delaunay triangulation by the divide-and-     */
7745 /*                      conquer method.                                      */
7746 /*                                                                           */
7747 /*  Sorts the points, calls a recursive procedure to triangulate them, and   */
7748 /*  removes the bounding box, setting boundary markers as appropriate.       */
7749 /*                                                                           */
7750 /*****************************************************************************/
7751
7752 long divconqdelaunay(){
7753         point *sortarray;
7754         struct triedge hullleft, hullright;
7755         int divider;
7756         int i, j;
7757
7758         /* Allocate an array of pointers to points for sorting. */
7759         sortarray = (point *) malloc( inpoints * sizeof( point ) );
7760         if ( sortarray == (point *) NULL ) {
7761                 printf( "Error:  Out of memory.\n" );
7762                 exit( 1 );
7763         }
7764         traversalinit( &points );
7765         for ( i = 0; i < inpoints; i++ ) {
7766                 sortarray[i] = pointtraverse();
7767         }
7768         if ( verbose ) {
7769                 printf( "  Sorting points.\n" );
7770         }
7771         /* Sort the points. */
7772         pointsort( sortarray, inpoints );
7773         /* Discard duplicate points, which can really mess up the algorithm. */
7774         i = 0;
7775         for ( j = 1; j < inpoints; j++ ) {
7776                 if ( ( sortarray[i][0] == sortarray[j][0] )
7777                          && ( sortarray[i][1] == sortarray[j][1] ) ) {
7778                         if ( !quiet ) {
7779                                 printf(
7780                                         "Warning:  A duplicate point at (%.12g, %.12g) appeared and was ignored.\n",
7781                                         sortarray[j][0], sortarray[j][1] );
7782                         }
7783 /*  Commented out - would eliminate point from output .node file, but causes
7784     a failure if some segment has this point as an endpoint.
7785       setpointmark(sortarray[j], DEADPOINT);
7786  */
7787                 }
7788                 else {
7789                         i++;
7790                         sortarray[i] = sortarray[j];
7791                 }
7792         }
7793         i++;
7794         if ( dwyer ) {
7795                 /* Re-sort the array of points to accommodate alternating cuts. */
7796                 divider = i >> 1;
7797                 if ( i - divider >= 2 ) {
7798                         if ( divider >= 2 ) {
7799                                 alternateaxes( sortarray, divider, 1 );
7800                         }
7801                         alternateaxes( &sortarray[divider], i - divider, 1 );
7802                 }
7803         }
7804         if ( verbose ) {
7805                 printf( "  Forming triangulation.\n" );
7806         }
7807         /* Form the Delaunay triangulation. */
7808         divconqrecurse( sortarray, i, 0, &hullleft, &hullright );
7809         free( sortarray );
7810
7811         return removeghosts( &hullleft );
7812 }
7813
7814 /**                                                                         **/
7815 /**                                                                         **/
7816 /********* Divide-and-conquer Delaunay triangulation ends here       *********/
7817
7818 /********* Incremental Delaunay triangulation begins here            *********/
7819 /**                                                                         **/
7820 /**                                                                         **/
7821
7822 /*****************************************************************************/
7823 /*                                                                           */
7824 /*  boundingbox()   Form an "infinite" bounding triangle to insert points    */
7825 /*                  into.                                                    */
7826 /*                                                                           */
7827 /*  The points at "infinity" are assigned finite coordinates, which are used */
7828 /*  by the point location routines, but (mostly) ignored by the Delaunay     */
7829 /*  edge flip routines.                                                      */
7830 /*                                                                           */
7831 /*****************************************************************************/
7832
7833 #ifndef REDUCED
7834
7835 void boundingbox(){
7836         struct triedge inftri;        /* Handle for the triangular bounding box. */
7837         REAL width;
7838
7839         if ( verbose ) {
7840                 printf( "  Creating triangular bounding box.\n" );
7841         }
7842         /* Find the width (or height, whichever is larger) of the triangulation. */
7843         width = xmax - xmin;
7844         if ( ymax - ymin > width ) {
7845                 width = ymax - ymin;
7846         }
7847         if ( width == 0.0 ) {
7848                 width = 1.0;
7849         }
7850         /* Create the vertices of the bounding box. */
7851         infpoint1 = (point) malloc( points.itembytes );
7852         infpoint2 = (point) malloc( points.itembytes );
7853         infpoint3 = (point) malloc( points.itembytes );
7854         if ( ( infpoint1 == (point) NULL ) || ( infpoint2 == (point) NULL )
7855                  || ( infpoint3 == (point) NULL ) ) {
7856                 printf( "Error:  Out of memory.\n" );
7857                 exit( 1 );
7858         }
7859         infpoint1[0] = xmin - 50.0 * width;
7860         infpoint1[1] = ymin - 40.0 * width;
7861         infpoint2[0] = xmax + 50.0 * width;
7862         infpoint2[1] = ymin - 40.0 * width;
7863         infpoint3[0] = 0.5 * ( xmin + xmax );
7864         infpoint3[1] = ymax + 60.0 * width;
7865
7866         /* Create the bounding box. */
7867         maketriangle( &inftri );
7868         setorg( inftri, infpoint1 );
7869         setdest( inftri, infpoint2 );
7870         setapex( inftri, infpoint3 );
7871         /* Link dummytri to the bounding box so we can always find an */
7872         /*   edge to begin searching (point location) from.           */
7873         dummytri[0] = (triangle) inftri.tri;
7874         if ( verbose > 2 ) {
7875                 printf( "  Creating " );
7876                 printtriangle( &inftri );
7877         }
7878 }
7879
7880 #endif /* not REDUCED */
7881
7882 /*****************************************************************************/
7883 /*                                                                           */
7884 /*  removebox()   Remove the "infinite" bounding triangle, setting boundary  */
7885 /*                markers as appropriate.                                    */
7886 /*                                                                           */
7887 /*  The triangular bounding box has three boundary triangles (one for each   */
7888 /*  side of the bounding box), and a bunch of triangles fanning out from     */
7889 /*  the three bounding box vertices (one triangle for each edge of the       */
7890 /*  convex hull of the inner mesh).  This routine removes these triangles.   */
7891 /*                                                                           */
7892 /*****************************************************************************/
7893
7894 #ifndef REDUCED
7895
7896 long removebox(){
7897         struct triedge deadtri;
7898         struct triedge searchedge;
7899         struct triedge checkedge;
7900         struct triedge nextedge, finaledge, dissolveedge;
7901         point markorg;
7902         long hullsize;
7903         triangle ptr;                       /* Temporary variable used by sym(). */
7904
7905         if ( verbose ) {
7906                 printf( "  Removing triangular bounding box.\n" );
7907         }
7908         /* Find a boundary triangle. */
7909         nextedge.tri = dummytri;
7910         nextedge.orient = 0;
7911         symself( nextedge );
7912         /* Mark a place to stop. */
7913         lprev( nextedge, finaledge );
7914         lnextself( nextedge );
7915         symself( nextedge );
7916         /* Find a triangle (on the boundary of the point set) that isn't */
7917         /*   a bounding box triangle.                                    */
7918         lprev( nextedge, searchedge );
7919         symself( searchedge );
7920         /* Check whether nextedge is another boundary triangle */
7921         /*   adjacent to the first one.                        */
7922         lnext( nextedge, checkedge );
7923         symself( checkedge );
7924         if ( checkedge.tri == dummytri ) {
7925                 /* Go on to the next triangle.  There are only three boundary   */
7926                 /*   triangles, and this next triangle cannot be the third one, */
7927                 /*   so it's safe to stop here.                                 */
7928                 lprevself( searchedge );
7929                 symself( searchedge );
7930         }
7931         /* Find a new boundary edge to search from, as the current search */
7932         /*   edge lies on a bounding box triangle and will be deleted.    */
7933         dummytri[0] = encode( searchedge );
7934         hullsize = -2l;
7935         while ( !triedgeequal( nextedge, finaledge ) ) {
7936                 hullsize++;
7937                 lprev( nextedge, dissolveedge );
7938                 symself( dissolveedge );
7939                 /* If not using a PSLG, the vertices should be marked now. */
7940                 /*   (If using a PSLG, markhull() will do the job.)        */
7941                 if ( !poly ) {
7942                         /* Be careful!  One must check for the case where all the input   */
7943                         /*   points are collinear, and thus all the triangles are part of */
7944                         /*   the bounding box.  Otherwise, the setpointmark() call below  */
7945                         /*   will cause a bad pointer reference.                          */
7946                         if ( dissolveedge.tri != dummytri ) {
7947                                 org( dissolveedge, markorg );
7948                                 if ( pointmark( markorg ) == 0 ) {
7949                                         setpointmark( markorg, 1 );
7950                                 }
7951                         }
7952                 }
7953                 /* Disconnect the bounding box triangle from the mesh triangle. */
7954                 dissolve( dissolveedge );
7955                 lnext( nextedge, deadtri );
7956                 sym( deadtri, nextedge );
7957                 /* Get rid of the bounding box triangle. */
7958                 triangledealloc( deadtri.tri );
7959                 /* Do we need to turn the corner? */
7960                 if ( nextedge.tri == dummytri ) {
7961                         /* Turn the corner. */
7962                         triedgecopy( dissolveedge, nextedge );
7963                 }
7964         }
7965         triangledealloc( finaledge.tri );
7966
7967         free( infpoint1 );              /* Deallocate the bounding box vertices. */
7968         free( infpoint2 );
7969         free( infpoint3 );
7970
7971         return hullsize;
7972 }
7973
7974 #endif /* not REDUCED */
7975
7976 /*****************************************************************************/
7977 /*                                                                           */
7978 /*  incrementaldelaunay()   Form a Delaunay triangulation by incrementally   */
7979 /*                          adding vertices.                                 */
7980 /*                                                                           */
7981 /*****************************************************************************/
7982
7983 #ifndef REDUCED
7984
7985 long incrementaldelaunay(){
7986         struct triedge starttri;
7987         point pointloop;
7988         int i;
7989
7990         /* Create a triangular bounding box. */
7991         boundingbox();
7992         if ( verbose ) {
7993                 printf( "  Incrementally inserting points.\n" );
7994         }
7995         traversalinit( &points );
7996         pointloop = pointtraverse();
7997         i = 1;
7998         while ( pointloop != (point) NULL ) {
7999                 /* Find a boundary triangle to search from. */
8000                 starttri.tri = (triangle *) NULL;
8001                 if ( insertsite( pointloop, &starttri, (struct edge *) NULL, 0, 0 ) ==
8002                          DUPLICATEPOINT ) {
8003                         if ( !quiet ) {
8004                                 printf(
8005                                         "Warning:  A duplicate point at (%.12g, %.12g) appeared and was ignored.\n",
8006                                         pointloop[0], pointloop[1] );
8007                         }
8008 /*  Commented out - would eliminate point from output .node file.
8009       setpointmark(pointloop, DEADPOINT);
8010  */
8011                 }
8012                 pointloop = pointtraverse();
8013                 i++;
8014         }
8015         /* Remove the bounding box. */
8016         return removebox();
8017 }
8018
8019 #endif /* not REDUCED */
8020
8021 /**                                                                         **/
8022 /**                                                                         **/
8023 /********* Incremental Delaunay triangulation ends here              *********/
8024
8025 /********* Sweepline Delaunay triangulation begins here              *********/
8026 /**                                                                         **/
8027 /**                                                                         **/
8028
8029 #ifndef REDUCED
8030
8031 void eventheapinsert( heap, heapsize, newevent )
8032 struct event **heap;
8033 int heapsize;
8034 struct event *newevent;
8035 {
8036         REAL eventx, eventy;
8037         int eventnum;
8038         int parent;
8039         int notdone;
8040
8041         eventx = newevent->xkey;
8042         eventy = newevent->ykey;
8043         eventnum = heapsize;
8044         notdone = eventnum > 0;
8045         while ( notdone ) {
8046                 parent = ( eventnum - 1 ) >> 1;
8047                 if ( ( heap[parent]->ykey < eventy ) ||
8048                          ( ( heap[parent]->ykey == eventy )
8049                            && ( heap[parent]->xkey <= eventx ) ) ) {
8050                         notdone = 0;
8051                 }
8052                 else {
8053                         heap[eventnum] = heap[parent];
8054                         heap[eventnum]->heapposition = eventnum;
8055
8056                         eventnum = parent;
8057                         notdone = eventnum > 0;
8058                 }
8059         }
8060         heap[eventnum] = newevent;
8061         newevent->heapposition = eventnum;
8062 }
8063
8064 #endif /* not REDUCED */
8065
8066 #ifndef REDUCED
8067
8068 void eventheapify( heap, heapsize, eventnum )
8069 struct event **heap;
8070 int heapsize;
8071 int eventnum;
8072 {
8073         struct event *thisevent;
8074         REAL eventx, eventy;
8075         int leftchild, rightchild;
8076         int smallest;
8077         int notdone;
8078
8079         thisevent = heap[eventnum];
8080         eventx = thisevent->xkey;
8081         eventy = thisevent->ykey;
8082         leftchild = 2 * eventnum + 1;
8083         notdone = leftchild < heapsize;
8084         while ( notdone ) {
8085                 if ( ( heap[leftchild]->ykey < eventy ) ||
8086                          ( ( heap[leftchild]->ykey == eventy )
8087                            && ( heap[leftchild]->xkey < eventx ) ) ) {
8088                         smallest = leftchild;
8089                 }
8090                 else {
8091                         smallest = eventnum;
8092                 }
8093                 rightchild = leftchild + 1;
8094                 if ( rightchild < heapsize ) {
8095                         if ( ( heap[rightchild]->ykey < heap[smallest]->ykey ) ||
8096                                  ( ( heap[rightchild]->ykey == heap[smallest]->ykey )
8097                                    && ( heap[rightchild]->xkey < heap[smallest]->xkey ) ) ) {
8098                                 smallest = rightchild;
8099                         }
8100                 }
8101                 if ( smallest == eventnum ) {
8102                         notdone = 0;
8103                 }
8104                 else {
8105                         heap[eventnum] = heap[smallest];
8106                         heap[eventnum]->heapposition = eventnum;
8107                         heap[smallest] = thisevent;
8108                         thisevent->heapposition = smallest;
8109
8110                         eventnum = smallest;
8111                         leftchild = 2 * eventnum + 1;
8112                         notdone = leftchild < heapsize;
8113                 }
8114         }
8115 }
8116
8117 #endif /* not REDUCED */
8118
8119 #ifndef REDUCED
8120
8121 void eventheapdelete( heap, heapsize, eventnum )
8122 struct event **heap;
8123 int heapsize;
8124 int eventnum;
8125 {
8126         struct event *moveevent;
8127         REAL eventx, eventy;
8128         int parent;
8129         int notdone;
8130
8131         moveevent = heap[heapsize - 1];
8132         if ( eventnum > 0 ) {
8133                 eventx = moveevent->xkey;
8134                 eventy = moveevent->ykey;
8135                 do {
8136                         parent = ( eventnum - 1 ) >> 1;
8137                         if ( ( heap[parent]->ykey < eventy ) ||
8138                                  ( ( heap[parent]->ykey == eventy )
8139                                    && ( heap[parent]->xkey <= eventx ) ) ) {
8140                                 notdone = 0;
8141                         }
8142                         else {
8143                                 heap[eventnum] = heap[parent];
8144                                 heap[eventnum]->heapposition = eventnum;
8145
8146                                 eventnum = parent;
8147                                 notdone = eventnum > 0;
8148                         }
8149                 } while ( notdone );
8150         }
8151         heap[eventnum] = moveevent;
8152         moveevent->heapposition = eventnum;
8153         eventheapify( heap, heapsize - 1, eventnum );
8154 }
8155
8156 #endif /* not REDUCED */
8157
8158 #ifndef REDUCED
8159
8160 void createeventheap( eventheap, events, freeevents )
8161 struct event ***eventheap;
8162 struct event **events;
8163 struct event **freeevents;
8164 {
8165         point thispoint;
8166         int maxevents;
8167         int i;
8168
8169         maxevents = ( 3 * inpoints ) / 2;
8170         *eventheap = (struct event **) malloc( maxevents * sizeof( struct event * ) );
8171         if ( *eventheap == (struct event **) NULL ) {
8172                 printf( "Error:  Out of memory.\n" );
8173                 exit( 1 );
8174         }
8175         *events = (struct event *) malloc( maxevents * sizeof( struct event ) );
8176         if ( *events == (struct event *) NULL ) {
8177                 printf( "Error:  Out of memory.\n" );
8178                 exit( 1 );
8179         }
8180         traversalinit( &points );
8181         for ( i = 0; i < inpoints; i++ ) {
8182                 thispoint = pointtraverse();
8183                 ( *events )[i].eventptr = (VOID *) thispoint;
8184                 ( *events )[i].xkey = thispoint[0];
8185                 ( *events )[i].ykey = thispoint[1];
8186                 eventheapinsert( *eventheap, i, *events + i );
8187         }
8188         *freeevents = (struct event *) NULL;
8189         for ( i = maxevents - 1; i >= inpoints; i-- ) {
8190                 ( *events )[i].eventptr = (VOID *) *freeevents;
8191                 *freeevents = *events + i;
8192         }
8193 }
8194
8195 #endif /* not REDUCED */
8196
8197 #ifndef REDUCED
8198
8199 int rightofhyperbola( fronttri, newsite )
8200 struct triedge *fronttri;
8201 point newsite;
8202 {
8203         point leftpoint, rightpoint;
8204         REAL dxa, dya, dxb, dyb;
8205
8206         hyperbolacount++;
8207
8208         dest( *fronttri, leftpoint );
8209         apex( *fronttri, rightpoint );
8210         if ( ( leftpoint[1] < rightpoint[1] )
8211                  || ( ( leftpoint[1] == rightpoint[1] ) && ( leftpoint[0] < rightpoint[0] ) ) ) {
8212                 if ( newsite[0] >= rightpoint[0] ) {
8213                         return 1;
8214                 }
8215         }
8216         else {
8217                 if ( newsite[0] <= leftpoint[0] ) {
8218                         return 0;
8219                 }
8220         }
8221         dxa = leftpoint[0] - newsite[0];
8222         dya = leftpoint[1] - newsite[1];
8223         dxb = rightpoint[0] - newsite[0];
8224         dyb = rightpoint[1] - newsite[1];
8225         return dya * ( dxb * dxb + dyb * dyb ) > dyb * ( dxa * dxa + dya * dya );
8226 }
8227
8228 #endif /* not REDUCED */
8229
8230 #ifndef REDUCED
8231
8232 REAL circletop( pa, pb, pc, ccwabc )
8233 point pa;
8234 point pb;
8235 point pc;
8236 REAL ccwabc;
8237 {
8238         REAL xac, yac, xbc, ybc, xab, yab;
8239         REAL aclen2, bclen2, ablen2;
8240
8241         circletopcount++;
8242
8243         xac = pa[0] - pc[0];
8244         yac = pa[1] - pc[1];
8245         xbc = pb[0] - pc[0];
8246         ybc = pb[1] - pc[1];
8247         xab = pa[0] - pb[0];
8248         yab = pa[1] - pb[1];
8249         aclen2 = xac * xac + yac * yac;
8250         bclen2 = xbc * xbc + ybc * ybc;
8251         ablen2 = xab * xab + yab * yab;
8252         return pc[1] + ( xac * bclen2 - xbc * aclen2 + sqrt( aclen2 * bclen2 * ablen2 ) )
8253                    / ( 2.0 * ccwabc );
8254 }
8255
8256 #endif /* not REDUCED */
8257
8258 #ifndef REDUCED
8259
8260 void check4deadevent( checktri, freeevents, eventheap, heapsize )
8261 struct triedge *checktri;
8262 struct event **freeevents;
8263 struct event **eventheap;
8264 int *heapsize;
8265 {
8266         struct event *deadevent;
8267         point eventpoint;
8268         int eventnum;
8269
8270         org( *checktri, eventpoint );
8271         if ( eventpoint != (point) NULL ) {
8272                 deadevent = (struct event *) eventpoint;
8273                 eventnum = deadevent->heapposition;
8274                 deadevent->eventptr = (VOID *) *freeevents;
8275                 *freeevents = deadevent;
8276                 eventheapdelete( eventheap, *heapsize, eventnum );
8277                 ( *heapsize )--;
8278                 setorg( *checktri, NULL );
8279         }
8280 }
8281
8282 #endif /* not REDUCED */
8283
8284 #ifndef REDUCED
8285
8286 struct splaynode *splay( splaytree, searchpoint, searchtri )
8287 struct splaynode *splaytree;
8288 point searchpoint;
8289 struct triedge *searchtri;
8290 {
8291         struct splaynode *child, *grandchild;
8292         struct splaynode *lefttree, *righttree;
8293         struct splaynode *leftright;
8294         point checkpoint;
8295         int rightofroot, rightofchild;
8296
8297         if ( splaytree == (struct splaynode *) NULL ) {
8298                 return (struct splaynode *) NULL;
8299         }
8300         dest( splaytree->keyedge, checkpoint );
8301         if ( checkpoint == splaytree->keydest ) {
8302                 rightofroot = rightofhyperbola( &splaytree->keyedge, searchpoint );
8303                 if ( rightofroot ) {
8304                         triedgecopy( splaytree->keyedge, *searchtri );
8305                         child = splaytree->rchild;
8306                 }
8307                 else {
8308                         child = splaytree->lchild;
8309                 }
8310                 if ( child == (struct splaynode *) NULL ) {
8311                         return splaytree;
8312                 }
8313                 dest( child->keyedge, checkpoint );
8314                 if ( checkpoint != child->keydest ) {
8315                         child = splay( child, searchpoint, searchtri );
8316                         if ( child == (struct splaynode *) NULL ) {
8317                                 if ( rightofroot ) {
8318                                         splaytree->rchild = (struct splaynode *) NULL;
8319                                 }
8320                                 else {
8321                                         splaytree->lchild = (struct splaynode *) NULL;
8322                                 }
8323                                 return splaytree;
8324                         }
8325                 }
8326                 rightofchild = rightofhyperbola( &child->keyedge, searchpoint );
8327                 if ( rightofchild ) {
8328                         triedgecopy( child->keyedge, *searchtri );
8329                         grandchild = splay( child->rchild, searchpoint, searchtri );
8330                         child->rchild = grandchild;
8331                 }
8332                 else {
8333                         grandchild = splay( child->lchild, searchpoint, searchtri );
8334                         child->lchild = grandchild;
8335                 }
8336                 if ( grandchild == (struct splaynode *) NULL ) {
8337                         if ( rightofroot ) {
8338                                 splaytree->rchild = child->lchild;
8339                                 child->lchild = splaytree;
8340                         }
8341                         else {
8342                                 splaytree->lchild = child->rchild;
8343                                 child->rchild = splaytree;
8344                         }
8345                         return child;
8346                 }
8347                 if ( rightofchild ) {
8348                         if ( rightofroot ) {
8349                                 splaytree->rchild = child->lchild;
8350                                 child->lchild = splaytree;
8351                         }
8352                         else {
8353                                 splaytree->lchild = grandchild->rchild;
8354                                 grandchild->rchild = splaytree;
8355                         }
8356                         child->rchild = grandchild->lchild;
8357                         grandchild->lchild = child;
8358                 }
8359                 else {
8360                         if ( rightofroot ) {
8361                                 splaytree->rchild = grandchild->lchild;
8362                                 grandchild->lchild = splaytree;
8363                         }
8364                         else {
8365                                 splaytree->lchild = child->rchild;
8366                                 child->rchild = splaytree;
8367                         }
8368                         child->lchild = grandchild->rchild;
8369                         grandchild->rchild = child;
8370                 }
8371                 return grandchild;
8372         }
8373         else {
8374                 lefttree = splay( splaytree->lchild, searchpoint, searchtri );
8375                 righttree = splay( splaytree->rchild, searchpoint, searchtri );
8376
8377                 pooldealloc( &splaynodes, (VOID *) splaytree );
8378                 if ( lefttree == (struct splaynode *) NULL ) {
8379                         return righttree;
8380                 }
8381                 else if ( righttree == (struct splaynode *) NULL ) {
8382                         return lefttree;
8383                 }
8384                 else if ( lefttree->rchild == (struct splaynode *) NULL ) {
8385                         lefttree->rchild = righttree->lchild;
8386                         righttree->lchild = lefttree;
8387                         return righttree;
8388                 }
8389                 else if ( righttree->lchild == (struct splaynode *) NULL ) {
8390                         righttree->lchild = lefttree->rchild;
8391                         lefttree->rchild = righttree;
8392                         return lefttree;
8393                 }
8394                 else {
8395 /*      printf("Holy Toledo!!!\n"); */
8396                         leftright = lefttree->rchild;
8397                         while ( leftright->rchild != (struct splaynode *) NULL ) {
8398                                 leftright = leftright->rchild;
8399                         }
8400                         leftright->rchild = righttree;
8401                         return lefttree;
8402                 }
8403         }
8404 }
8405
8406 #endif /* not REDUCED */
8407
8408 #ifndef REDUCED
8409
8410 struct splaynode *splayinsert( splayroot, newkey, searchpoint )
8411 struct splaynode *splayroot;
8412 struct triedge *newkey;
8413 point searchpoint;
8414 {
8415         struct splaynode *newsplaynode;
8416
8417         newsplaynode = (struct splaynode *) poolalloc( &splaynodes );
8418         triedgecopy( *newkey, newsplaynode->keyedge );
8419         dest( *newkey, newsplaynode->keydest );
8420         if ( splayroot == (struct splaynode *) NULL ) {
8421                 newsplaynode->lchild = (struct splaynode *) NULL;
8422                 newsplaynode->rchild = (struct splaynode *) NULL;
8423         }
8424         else if ( rightofhyperbola( &splayroot->keyedge, searchpoint ) ) {
8425                 newsplaynode->lchild = splayroot;
8426                 newsplaynode->rchild = splayroot->rchild;
8427                 splayroot->rchild = (struct splaynode *) NULL;
8428         }
8429         else {
8430                 newsplaynode->lchild = splayroot->lchild;
8431                 newsplaynode->rchild = splayroot;
8432                 splayroot->lchild = (struct splaynode *) NULL;
8433         }
8434         return newsplaynode;
8435 }
8436
8437 #endif /* not REDUCED */
8438
8439 #ifndef REDUCED
8440
8441 struct splaynode *circletopinsert( splayroot, newkey, pa, pb, pc, topy )
8442 struct splaynode *splayroot;
8443 struct triedge *newkey;
8444 point pa;
8445 point pb;
8446 point pc;
8447 REAL topy;
8448 {
8449         REAL ccwabc;
8450         REAL xac, yac, xbc, ybc;
8451         REAL aclen2, bclen2;
8452         REAL searchpoint[2];
8453         struct triedge dummytri;
8454
8455         ccwabc = counterclockwise( pa, pb, pc );
8456         xac = pa[0] - pc[0];
8457         yac = pa[1] - pc[1];
8458         xbc = pb[0] - pc[0];
8459         ybc = pb[1] - pc[1];
8460         aclen2 = xac * xac + yac * yac;
8461         bclen2 = xbc * xbc + ybc * ybc;
8462         searchpoint[0] = pc[0] - ( yac * bclen2 - ybc * aclen2 ) / ( 2.0 * ccwabc );
8463         searchpoint[1] = topy;
8464         return splayinsert( splay( splayroot, (point) searchpoint, &dummytri ), newkey,
8465                                                 (point) searchpoint );
8466 }
8467
8468 #endif /* not REDUCED */
8469
8470 #ifndef REDUCED
8471
8472 struct splaynode *frontlocate( splayroot, bottommost, searchpoint, searchtri,
8473                                                            farright )
8474 struct splaynode *splayroot;
8475 struct triedge *bottommost;
8476 point searchpoint;
8477 struct triedge *searchtri;
8478 int *farright;
8479 {
8480         int farrightflag;
8481         triangle ptr;                     /* Temporary variable used by onext(). */
8482
8483         triedgecopy( *bottommost, *searchtri );
8484         splayroot = splay( splayroot, searchpoint, searchtri );
8485
8486         farrightflag = 0;
8487         while ( !farrightflag && rightofhyperbola( searchtri, searchpoint ) ) {
8488                 onextself( *searchtri );
8489                 farrightflag = triedgeequal( *searchtri, *bottommost );
8490         }
8491         *farright = farrightflag;
8492         return splayroot;
8493 }
8494
8495 #endif /* not REDUCED */
8496
8497 #ifndef REDUCED
8498
8499 long sweeplinedelaunay(){
8500         struct event **eventheap;
8501         struct event *events;
8502         struct event *freeevents;
8503         struct event *nextevent;
8504         struct event *newevent;
8505         struct splaynode *splayroot;
8506         struct triedge bottommost;
8507         struct triedge searchtri;
8508         struct triedge fliptri;
8509         struct triedge lefttri, righttri, farlefttri, farrighttri;
8510         struct triedge inserttri;
8511         point firstpoint, secondpoint;
8512         point nextpoint, lastpoint;
8513         point connectpoint;
8514         point leftpoint, midpoint, rightpoint;
8515         REAL lefttest, righttest;
8516         int heapsize;
8517         int check4events, farrightflag;
8518         triangle ptr; /* Temporary variable used by sym(), onext(), and oprev(). */
8519
8520         poolinit( &splaynodes, sizeof( struct splaynode ), SPLAYNODEPERBLOCK, POINTER,
8521                           0 );
8522         splayroot = (struct splaynode *) NULL;
8523
8524         if ( verbose ) {
8525                 printf( "  Placing points in event heap.\n" );
8526         }
8527         createeventheap( &eventheap, &events, &freeevents );
8528         heapsize = inpoints;
8529
8530         if ( verbose ) {
8531                 printf( "  Forming triangulation.\n" );
8532         }
8533         maketriangle( &lefttri );
8534         maketriangle( &righttri );
8535         bond( lefttri, righttri );
8536         lnextself( lefttri );
8537         lprevself( righttri );
8538         bond( lefttri, righttri );
8539         lnextself( lefttri );
8540         lprevself( righttri );
8541         bond( lefttri, righttri );
8542         firstpoint = (point) eventheap[0]->eventptr;
8543         eventheap[0]->eventptr = (VOID *) freeevents;
8544         freeevents = eventheap[0];
8545         eventheapdelete( eventheap, heapsize, 0 );
8546         heapsize--;
8547         do {
8548                 if ( heapsize == 0 ) {
8549                         printf( "Error:  Input points are all identical.\n" );
8550                         exit( 1 );
8551                 }
8552                 secondpoint = (point) eventheap[0]->eventptr;
8553                 eventheap[0]->eventptr = (VOID *) freeevents;
8554                 freeevents = eventheap[0];
8555                 eventheapdelete( eventheap, heapsize, 0 );
8556                 heapsize--;
8557                 if ( ( firstpoint[0] == secondpoint[0] )
8558                          && ( firstpoint[1] == secondpoint[1] ) ) {
8559                         printf(
8560                                 "Warning:  A duplicate point at (%.12g, %.12g) appeared and was ignored.\n",
8561                                 secondpoint[0], secondpoint[1] );
8562 /*  Commented out - would eliminate point from output .node file.
8563       setpointmark(secondpoint, DEADPOINT);
8564  */
8565                 }
8566         } while ( ( firstpoint[0] == secondpoint[0] )
8567                           && ( firstpoint[1] == secondpoint[1] ) );
8568         setorg( lefttri, firstpoint );
8569         setdest( lefttri, secondpoint );
8570         setorg( righttri, secondpoint );
8571         setdest( righttri, firstpoint );
8572         lprev( lefttri, bottommost );
8573         lastpoint = secondpoint;
8574         while ( heapsize > 0 ) {
8575                 nextevent = eventheap[0];
8576                 eventheapdelete( eventheap, heapsize, 0 );
8577                 heapsize--;
8578                 check4events = 1;
8579                 if ( nextevent->xkey < xmin ) {
8580                         decode( nextevent->eventptr, fliptri );
8581                         oprev( fliptri, farlefttri );
8582                         check4deadevent( &farlefttri, &freeevents, eventheap, &heapsize );
8583                         onext( fliptri, farrighttri );
8584                         check4deadevent( &farrighttri, &freeevents, eventheap, &heapsize );
8585
8586                         if ( triedgeequal( farlefttri, bottommost ) ) {
8587                                 lprev( fliptri, bottommost );
8588                         }
8589                         flip( &fliptri );
8590                         setapex( fliptri, NULL );
8591                         lprev( fliptri, lefttri );
8592                         lnext( fliptri, righttri );
8593                         sym( lefttri, farlefttri );
8594
8595                         if ( randomnation( SAMPLERATE ) == 0 ) {
8596                                 symself( fliptri );
8597                                 dest( fliptri, leftpoint );
8598                                 apex( fliptri, midpoint );
8599                                 org( fliptri, rightpoint );
8600                                 splayroot = circletopinsert( splayroot, &lefttri, leftpoint, midpoint,
8601                                                                                          rightpoint, nextevent->ykey );
8602                         }
8603                 }
8604                 else {
8605                         nextpoint = (point) nextevent->eventptr;
8606                         if ( ( nextpoint[0] == lastpoint[0] ) && ( nextpoint[1] == lastpoint[1] ) ) {
8607                                 printf(
8608                                         "Warning:  A duplicate point at (%.12g, %.12g) appeared and was ignored.\n",
8609                                         nextpoint[0], nextpoint[1] );
8610 /*  Commented out - would eliminate point from output .node file.
8611         setpointmark(nextpoint, DEADPOINT);
8612  */
8613                                 check4events = 0;
8614                         }
8615                         else {
8616                                 lastpoint = nextpoint;
8617
8618                                 splayroot = frontlocate( splayroot, &bottommost, nextpoint, &searchtri,
8619                                                                                  &farrightflag );
8620 /*
8621         triedgecopy(bottommost, searchtri);
8622         farrightflag = 0;
8623         while (!farrightflag && rightofhyperbola(&searchtri, nextpoint)) {
8624           onextself(searchtri);
8625           farrightflag = triedgeequal(searchtri, bottommost);
8626         }
8627  */
8628
8629                                 check4deadevent( &searchtri, &freeevents, eventheap, &heapsize );
8630
8631                                 triedgecopy( searchtri, farrighttri );
8632                                 sym( searchtri, farlefttri );
8633                                 maketriangle( &lefttri );
8634                                 maketriangle( &righttri );
8635                                 dest( farrighttri, connectpoint );
8636                                 setorg( lefttri, connectpoint );
8637                                 setdest( lefttri, nextpoint );
8638                                 setorg( righttri, nextpoint );
8639                                 setdest( righttri, connectpoint );
8640                                 bond( lefttri, righttri );
8641                                 lnextself( lefttri );
8642                                 lprevself( righttri );
8643                                 bond( lefttri, righttri );
8644                                 lnextself( lefttri );
8645                                 lprevself( righttri );
8646                                 bond( lefttri, farlefttri );
8647                                 bond( righttri, farrighttri );
8648                                 if ( !farrightflag && triedgeequal( farrighttri, bottommost ) ) {
8649                                         triedgecopy( lefttri, bottommost );
8650                                 }
8651
8652                                 if ( randomnation( SAMPLERATE ) == 0 ) {
8653                                         splayroot = splayinsert( splayroot, &lefttri, nextpoint );
8654                                 }
8655                                 else if ( randomnation( SAMPLERATE ) == 0 ) {
8656                                         lnext( righttri, inserttri );
8657                                         splayroot = splayinsert( splayroot, &inserttri, nextpoint );
8658                                 }
8659                         }
8660                 }
8661                 nextevent->eventptr = (VOID *) freeevents;
8662                 freeevents = nextevent;
8663
8664                 if ( check4events ) {
8665                         apex( farlefttri, leftpoint );
8666                         dest( lefttri, midpoint );
8667                         apex( lefttri, rightpoint );
8668                         lefttest = counterclockwise( leftpoint, midpoint, rightpoint );
8669                         if ( lefttest > 0.0 ) {
8670                                 newevent = freeevents;
8671                                 freeevents = (struct event *) freeevents->eventptr;
8672                                 newevent->xkey = xminextreme;
8673                                 newevent->ykey = circletop( leftpoint, midpoint, rightpoint,
8674                                                                                         lefttest );
8675                                 newevent->eventptr = (VOID *) encode( lefttri );
8676                                 eventheapinsert( eventheap, heapsize, newevent );
8677                                 heapsize++;
8678                                 setorg( lefttri, newevent );
8679                         }
8680                         apex( righttri, leftpoint );
8681                         org( righttri, midpoint );
8682                         apex( farrighttri, rightpoint );
8683                         righttest = counterclockwise( leftpoint, midpoint, rightpoint );
8684                         if ( righttest > 0.0 ) {
8685                                 newevent = freeevents;
8686                                 freeevents = (struct event *) freeevents->eventptr;
8687                                 newevent->xkey = xminextreme;
8688                                 newevent->ykey = circletop( leftpoint, midpoint, rightpoint,
8689                                                                                         righttest );
8690                                 newevent->eventptr = (VOID *) encode( farrighttri );
8691                                 eventheapinsert( eventheap, heapsize, newevent );
8692                                 heapsize++;
8693                                 setorg( farrighttri, newevent );
8694                         }
8695                 }
8696         }
8697
8698         pooldeinit( &splaynodes );
8699         lprevself( bottommost );
8700         return removeghosts( &bottommost );
8701 }
8702
8703 #endif /* not REDUCED */
8704
8705 /**                                                                         **/
8706 /**                                                                         **/
8707 /********* Sweepline Delaunay triangulation ends here                *********/
8708
8709 /********* General mesh construction routines begin here             *********/
8710 /**                                                                         **/
8711 /**                                                                         **/
8712
8713 /*****************************************************************************/
8714 /*                                                                           */
8715 /*  delaunay()   Form a Delaunay triangulation.                              */
8716 /*                                                                           */
8717 /*****************************************************************************/
8718
8719 long delaunay(){
8720         eextras = 0;
8721         initializetrisegpools();
8722
8723 #ifdef REDUCED
8724         if ( !quiet ) {
8725                 printf(
8726                         "Constructing Delaunay triangulation by divide-and-conquer method.\n" );
8727         }
8728         return divconqdelaunay();
8729 #else /* not REDUCED */
8730         if ( !quiet ) {
8731                 printf( "Constructing Delaunay triangulation " );
8732                 if ( incremental ) {
8733                         printf( "by incremental method.\n" );
8734                 }
8735                 else if ( sweepline ) {
8736                         printf( "by sweepline method.\n" );
8737                 }
8738                 else {
8739                         printf( "by divide-and-conquer method.\n" );
8740                 }
8741         }
8742         if ( incremental ) {
8743                 return incrementaldelaunay();
8744         }
8745         else if ( sweepline ) {
8746                 return sweeplinedelaunay();
8747         }
8748         else {
8749                 return divconqdelaunay();
8750         }
8751 #endif /* not REDUCED */
8752 }
8753
8754 /*****************************************************************************/
8755 /*                                                                           */
8756 /*  reconstruct()   Reconstruct a triangulation from its .ele (and possibly  */
8757 /*                  .poly) file.  Used when the -r switch is used.           */
8758 /*                                                                           */
8759 /*  Reads an .ele file and reconstructs the original mesh.  If the -p switch */
8760 /*  is used, this procedure will also read a .poly file and reconstruct the  */
8761 /*  shell edges of the original mesh.  If the -a switch is used, this        */
8762 /*  procedure will also read an .area file and set a maximum area constraint */
8763 /*  on each triangle.                                                        */
8764 /*                                                                           */
8765 /*  Points that are not corners of triangles, such as nodes on edges of      */
8766 /*  subparametric elements, are discarded.                                   */
8767 /*                                                                           */
8768 /*  This routine finds the adjacencies between triangles (and shell edges)   */
8769 /*  by forming one stack of triangles for each vertex.  Each triangle is on  */
8770 /*  three different stacks simultaneously.  Each triangle's shell edge       */
8771 /*  pointers are used to link the items in each stack.  This memory-saving   */
8772 /*  feature makes the code harder to read.  The most important thing to keep */
8773 /*  in mind is that each triangle is removed from a stack precisely when     */
8774 /*  the corresponding pointer is adjusted to refer to a shell edge rather    */
8775 /*  than the next triangle of the stack.                                     */
8776 /*                                                                           */
8777 /*****************************************************************************/
8778
8779 #ifndef CDT_ONLY
8780
8781 #ifdef TRILIBRARY
8782
8783 int reconstruct( trianglelist, triangleattriblist, trianglearealist, elements,
8784                                  corners, attribs, segmentlist, segmentmarkerlist,
8785                                  numberofsegments )
8786 int *trianglelist;
8787 REAL *triangleattriblist;
8788 REAL *trianglearealist;
8789 int elements;
8790 int corners;
8791 int attribs;
8792 int *segmentlist;
8793 int *segmentmarkerlist;
8794 int numberofsegments;
8795
8796 #else /* not TRILIBRARY */
8797
8798 long reconstruct( elefilename, areafilename, polyfilename, polyfile )
8799 char *elefilename;
8800 char *areafilename;
8801 char *polyfilename;
8802 FILE *polyfile;
8803
8804 #endif /* not TRILIBRARY */
8805
8806 {
8807 #ifdef TRILIBRARY
8808         int pointindex;
8809         int attribindex;
8810 #else /* not TRILIBRARY */
8811         FILE *elefile;
8812         FILE *areafile;
8813         char inputline[INPUTLINESIZE];
8814         char *stringptr;
8815         int areaelements;
8816 #endif /* not TRILIBRARY */
8817         struct triedge triangleloop;
8818         struct triedge triangleleft;
8819         struct triedge checktri;
8820         struct triedge checkleft;
8821         struct triedge checkneighbor;
8822         struct edge shelleloop;
8823         triangle *vertexarray;
8824         triangle *prevlink;
8825         triangle nexttri;
8826         point tdest, tapex;
8827         point checkdest, checkapex;
8828         point shorg;
8829         point killpoint;
8830         REAL area;
8831         int corner[3];
8832         int end[2];
8833         int killpointindex;
8834         int incorners;
8835         int segmentmarkers;
8836         int boundmarker;
8837         int aroundpoint;
8838         long hullsize;
8839         int notfound;
8840         int elementnumber, segmentnumber;
8841         int i, j;
8842         triangle ptr;                       /* Temporary variable used by sym(). */
8843
8844 #ifdef TRILIBRARY
8845         inelements = elements;
8846         incorners = corners;
8847         if ( incorners < 3 ) {
8848                 printf( "Error:  Triangles must have at least 3 points.\n" );
8849                 exit( 1 );
8850         }
8851         eextras = attribs;
8852 #else /* not TRILIBRARY */
8853         /* Read the triangles from an .ele file. */
8854         if ( !quiet ) {
8855                 printf( "Opening %s.\n", elefilename );
8856         }
8857         elefile = fopen( elefilename, "r" );
8858         if ( elefile == (FILE *) NULL ) {
8859                 printf( "  Error:  Cannot access file %s.\n", elefilename );
8860                 exit( 1 );
8861         }
8862         /* Read number of triangles, number of points per triangle, and */
8863         /*   number of triangle attributes from .ele file.              */
8864         stringptr = readline( inputline, elefile, elefilename );
8865         inelements = (int) strtol( stringptr, &stringptr, 0 );
8866         stringptr = findfield( stringptr );
8867         if ( *stringptr == '\0' ) {
8868                 incorners = 3;
8869         }
8870         else {
8871                 incorners = (int) strtol( stringptr, &stringptr, 0 );
8872                 if ( incorners < 3 ) {
8873                         printf( "Error:  Triangles in %s must have at least 3 points.\n",
8874                                         elefilename );
8875                         exit( 1 );
8876                 }
8877         }
8878         stringptr = findfield( stringptr );
8879         if ( *stringptr == '\0' ) {
8880                 eextras = 0;
8881         }
8882         else {
8883                 eextras = (int) strtol( stringptr, &stringptr, 0 );
8884         }
8885 #endif /* not TRILIBRARY */
8886
8887         initializetrisegpools();
8888
8889         /* Create the triangles. */
8890         for ( elementnumber = 1; elementnumber <= inelements; elementnumber++ ) {
8891                 maketriangle( &triangleloop );
8892                 /* Mark the triangle as living. */
8893                 triangleloop.tri[3] = (triangle) triangleloop.tri;
8894         }
8895
8896         if ( poly ) {
8897 #ifdef TRILIBRARY
8898                 insegments = numberofsegments;
8899                 segmentmarkers = segmentmarkerlist != (int *) NULL;
8900 #else /* not TRILIBRARY */
8901                 /* Read number of segments and number of segment */
8902                 /*   boundary markers from .poly file.           */
8903                 stringptr = readline( inputline, polyfile, inpolyfilename );
8904                 insegments = (int) strtol( stringptr, &stringptr, 0 );
8905                 stringptr = findfield( stringptr );
8906                 if ( *stringptr == '\0' ) {
8907                         segmentmarkers = 0;
8908                 }
8909                 else {
8910                         segmentmarkers = (int) strtol( stringptr, &stringptr, 0 );
8911                 }
8912 #endif /* not TRILIBRARY */
8913
8914                 /* Create the shell edges. */
8915                 for ( segmentnumber = 1; segmentnumber <= insegments; segmentnumber++ ) {
8916                         makeshelle( &shelleloop );
8917                         /* Mark the shell edge as living. */
8918                         shelleloop.sh[2] = (shelle) shelleloop.sh;
8919                 }
8920         }
8921
8922 #ifdef TRILIBRARY
8923         pointindex = 0;
8924         attribindex = 0;
8925 #else /* not TRILIBRARY */
8926         if ( vararea ) {
8927                 /* Open an .area file, check for consistency with the .ele file. */
8928                 if ( !quiet ) {
8929                         printf( "Opening %s.\n", areafilename );
8930                 }
8931                 areafile = fopen( areafilename, "r" );
8932                 if ( areafile == (FILE *) NULL ) {
8933                         printf( "  Error:  Cannot access file %s.\n", areafilename );
8934                         exit( 1 );
8935                 }
8936                 stringptr = readline( inputline, areafile, areafilename );
8937                 areaelements = (int) strtol( stringptr, &stringptr, 0 );
8938                 if ( areaelements != inelements ) {
8939                         printf( "Error:  %s and %s disagree on number of triangles.\n",
8940                                         elefilename, areafilename );
8941                         exit( 1 );
8942                 }
8943         }
8944 #endif /* not TRILIBRARY */
8945
8946         if ( !quiet ) {
8947                 printf( "Reconstructing mesh.\n" );
8948         }
8949         /* Allocate a temporary array that maps each point to some adjacent  */
8950         /*   triangle.  I took care to allocate all the permanent memory for */
8951         /*   triangles and shell edges first.                                */
8952         vertexarray = (triangle *) malloc( points.items * sizeof( triangle ) );
8953         if ( vertexarray == (triangle *) NULL ) {
8954                 printf( "Error:  Out of memory.\n" );
8955                 exit( 1 );
8956         }
8957         /* Each point is initially unrepresented. */
8958         for ( i = 0; i < points.items; i++ ) {
8959                 vertexarray[i] = (triangle) dummytri;
8960         }
8961
8962         if ( verbose ) {
8963                 printf( "  Assembling triangles.\n" );
8964         }
8965         /* Read the triangles from the .ele file, and link */
8966         /*   together those that share an edge.            */
8967         traversalinit( &triangles );
8968         triangleloop.tri = triangletraverse();
8969         elementnumber = firstnumber;
8970         while ( triangleloop.tri != (triangle *) NULL ) {
8971 #ifdef TRILIBRARY
8972                 /* Copy the triangle's three corners. */
8973                 for ( j = 0; j < 3; j++ ) {
8974                         corner[j] = trianglelist[pointindex++];
8975                         if ( ( corner[j] < firstnumber ) || ( corner[j] >= firstnumber + inpoints ) ) {
8976                                 printf( "Error:  Triangle %d has an invalid vertex index.\n",
8977                                                 elementnumber );
8978                                 exit( 1 );
8979                         }
8980                 }
8981 #else /* not TRILIBRARY */
8982                 /* Read triangle number and the triangle's three corners. */
8983                 stringptr = readline( inputline, elefile, elefilename );
8984                 for ( j = 0; j < 3; j++ ) {
8985                         stringptr = findfield( stringptr );
8986                         if ( *stringptr == '\0' ) {
8987                                 printf( "Error:  Triangle %d is missing point %d in %s.\n",
8988                                                 elementnumber, j + 1, elefilename );
8989                                 exit( 1 );
8990                         }
8991                         else {
8992                                 corner[j] = (int) strtol( stringptr, &stringptr, 0 );
8993                                 if ( ( corner[j] < firstnumber ) ||
8994                                          ( corner[j] >= firstnumber + inpoints ) ) {
8995                                         printf( "Error:  Triangle %d has an invalid vertex index.\n",
8996                                                         elementnumber );
8997                                         exit( 1 );
8998                                 }
8999                         }
9000                 }
9001 #endif /* not TRILIBRARY */
9002
9003                 /* Find out about (and throw away) extra nodes. */
9004                 for ( j = 3; j < incorners; j++ ) {
9005 #ifdef TRILIBRARY
9006                         killpointindex = trianglelist[pointindex++];
9007 #else /* not TRILIBRARY */
9008                         stringptr = findfield( stringptr );
9009                         if ( *stringptr != '\0' ) {
9010                                 killpointindex = (int) strtol( stringptr, &stringptr, 0 );
9011 #endif /* not TRILIBRARY */
9012                         if ( ( killpointindex >= firstnumber ) &&
9013                                  ( killpointindex < firstnumber + inpoints ) ) {
9014                                 /* Delete the non-corner point if it's not already deleted. */
9015                                 killpoint = getpoint( killpointindex );
9016                                 if ( pointmark( killpoint ) != DEADPOINT ) {
9017                                         pointdealloc( killpoint );
9018                                 }
9019                         }
9020 #ifndef TRILIBRARY
9021                 }
9022 #endif /* not TRILIBRARY */
9023                 }
9024
9025                 /* Read the triangle's attributes. */
9026                 for ( j = 0; j < eextras; j++ ) {
9027 #ifdef TRILIBRARY
9028                         setelemattribute( triangleloop, j, triangleattriblist[attribindex++] );
9029 #else /* not TRILIBRARY */
9030                         stringptr = findfield( stringptr );
9031                         if ( *stringptr == '\0' ) {
9032                                 setelemattribute( triangleloop, j, 0 );
9033                         }
9034                         else {
9035                                 setelemattribute( triangleloop, j,
9036                                                                   (REAL) strtod( stringptr, &stringptr ) );
9037                         }
9038 #endif /* not TRILIBRARY */
9039                 }
9040
9041                 if ( vararea ) {
9042 #ifdef TRILIBRARY
9043                         area = trianglearealist[elementnumber - firstnumber];
9044 #else /* not TRILIBRARY */
9045                         /* Read an area constraint from the .area file. */
9046                         stringptr = readline( inputline, areafile, areafilename );
9047                         stringptr = findfield( stringptr );
9048                         if ( *stringptr == '\0' ) {
9049                                 area = -1.0;              /* No constraint on this triangle. */
9050                         }
9051                         else {
9052                                 area = (REAL) strtod( stringptr, &stringptr );
9053                         }
9054 #endif /* not TRILIBRARY */
9055                         setareabound( triangleloop, area );
9056                 }
9057
9058                 /* Set the triangle's vertices. */
9059                 triangleloop.orient = 0;
9060                 setorg( triangleloop, getpoint( corner[0] ) );
9061                 setdest( triangleloop, getpoint( corner[1] ) );
9062                 setapex( triangleloop, getpoint( corner[2] ) );
9063                 /* Try linking the triangle to others that share these vertices. */
9064                 for ( triangleloop.orient = 0; triangleloop.orient < 3;
9065                           triangleloop.orient++ ) {
9066                         /* Take the number for the origin of triangleloop. */
9067                         aroundpoint = corner[triangleloop.orient];
9068                         /* Look for other triangles having this vertex. */
9069                         nexttri = vertexarray[aroundpoint - firstnumber];
9070                         /* Link the current triangle to the next one in the stack. */
9071                         triangleloop.tri[6 + triangleloop.orient] = nexttri;
9072                         /* Push the current triangle onto the stack. */
9073                         vertexarray[aroundpoint - firstnumber] = encode( triangleloop );
9074                         decode( nexttri, checktri );
9075                         if ( checktri.tri != dummytri ) {
9076                                 dest( triangleloop, tdest );
9077                                 apex( triangleloop, tapex );
9078                                 /* Look for other triangles that share an edge. */
9079                                 do {
9080                                         dest( checktri, checkdest );
9081                                         apex( checktri, checkapex );
9082                                         if ( tapex == checkdest ) {
9083                                                 /* The two triangles share an edge; bond them together. */
9084                                                 lprev( triangleloop, triangleleft );
9085                                                 bond( triangleleft, checktri );
9086                                         }
9087                                         if ( tdest == checkapex ) {
9088                                                 /* The two triangles share an edge; bond them together. */
9089                                                 lprev( checktri, checkleft );
9090                                                 bond( triangleloop, checkleft );
9091                                         }
9092                                         /* Find the next triangle in the stack. */
9093                                         nexttri = checktri.tri[6 + checktri.orient];
9094                                         decode( nexttri, checktri );
9095                                 } while ( checktri.tri != dummytri );
9096                         }
9097                 }
9098                 triangleloop.tri = triangletraverse();
9099                 elementnumber++;
9100         }
9101
9102 #ifdef TRILIBRARY
9103         pointindex = 0;
9104 #else /* not TRILIBRARY */
9105         fclose( elefile );
9106         if ( vararea ) {
9107                 fclose( areafile );
9108         }
9109 #endif /* not TRILIBRARY */
9110
9111         hullsize = 0;                    /* Prepare to count the boundary edges. */
9112         if ( poly ) {
9113                 if ( verbose ) {
9114                         printf( "  Marking segments in triangulation.\n" );
9115                 }
9116                 /* Read the segments from the .poly file, and link them */
9117                 /*   to their neighboring triangles.                    */
9118                 boundmarker = 0;
9119                 traversalinit( &shelles );
9120                 shelleloop.sh = shelletraverse();
9121                 segmentnumber = firstnumber;
9122                 while ( shelleloop.sh != (shelle *) NULL ) {
9123 #ifdef TRILIBRARY
9124                         end[0] = segmentlist[pointindex++];
9125                         end[1] = segmentlist[pointindex++];
9126                         if ( segmentmarkers ) {
9127                                 boundmarker = segmentmarkerlist[segmentnumber - firstnumber];
9128                         }
9129 #else /* not TRILIBRARY */
9130                         /* Read the endpoints of each segment, and possibly a boundary marker. */
9131                         stringptr = readline( inputline, polyfile, inpolyfilename );
9132                         /* Skip the first (segment number) field. */
9133                         stringptr = findfield( stringptr );
9134                         if ( *stringptr == '\0' ) {
9135                                 printf( "Error:  Segment %d has no endpoints in %s.\n", segmentnumber,
9136                                                 polyfilename );
9137                                 exit( 1 );
9138                         }
9139                         else {
9140                                 end[0] = (int) strtol( stringptr, &stringptr, 0 );
9141                         }
9142                         stringptr = findfield( stringptr );
9143                         if ( *stringptr == '\0' ) {
9144                                 printf( "Error:  Segment %d is missing its second endpoint in %s.\n",
9145                                                 segmentnumber, polyfilename );
9146                                 exit( 1 );
9147                         }
9148                         else {
9149                                 end[1] = (int) strtol( stringptr, &stringptr, 0 );
9150                         }
9151                         if ( segmentmarkers ) {
9152                                 stringptr = findfield( stringptr );
9153                                 if ( *stringptr == '\0' ) {
9154                                         boundmarker = 0;
9155                                 }
9156                                 else {
9157                                         boundmarker = (int) strtol( stringptr, &stringptr, 0 );
9158                                 }
9159                         }
9160 #endif /* not TRILIBRARY */
9161                         for ( j = 0; j < 2; j++ ) {
9162                                 if ( ( end[j] < firstnumber ) || ( end[j] >= firstnumber + inpoints ) ) {
9163                                         printf( "Error:  Segment %d has an invalid vertex index.\n",
9164                                                         segmentnumber );
9165                                         exit( 1 );
9166                                 }
9167                         }
9168
9169                         /* set the shell edge's vertices. */
9170                         shelleloop.shorient = 0;
9171                         setsorg( shelleloop, getpoint( end[0] ) );
9172                         setsdest( shelleloop, getpoint( end[1] ) );
9173                         setmark( shelleloop, boundmarker );
9174                         /* Try linking the shell edge to triangles that share these vertices. */
9175                         for ( shelleloop.shorient = 0; shelleloop.shorient < 2;
9176                                   shelleloop.shorient++ ) {
9177                                 /* Take the number for the destination of shelleloop. */
9178                                 aroundpoint = end[1 - shelleloop.shorient];
9179                                 /* Look for triangles having this vertex. */
9180                                 prevlink = &vertexarray[aroundpoint - firstnumber];
9181                                 nexttri = vertexarray[aroundpoint - firstnumber];
9182                                 decode( nexttri, checktri );
9183                                 sorg( shelleloop, shorg );
9184                                 notfound = 1;
9185                                 /* Look for triangles having this edge.  Note that I'm only       */
9186                                 /*   comparing each triangle's destination with the shell edge;   */
9187                                 /*   each triangle's apex is handled through a different vertex.  */
9188                                 /*   Because each triangle appears on three vertices' lists, each */
9189                                 /*   occurrence of a triangle on a list can (and does) represent  */
9190                                 /*   an edge.  In this way, most edges are represented twice, and */
9191                                 /*   every triangle-segment bond is represented once.             */
9192                                 while ( notfound && ( checktri.tri != dummytri ) ) {
9193                                         dest( checktri, checkdest );
9194                                         if ( shorg == checkdest ) {
9195                                                 /* We have a match.  Remove this triangle from the list. */
9196                                                 *prevlink = checktri.tri[6 + checktri.orient];
9197                                                 /* Bond the shell edge to the triangle. */
9198                                                 tsbond( checktri, shelleloop );
9199                                                 /* Check if this is a boundary edge. */
9200                                                 sym( checktri, checkneighbor );
9201                                                 if ( checkneighbor.tri == dummytri ) {
9202                                                         /* The next line doesn't insert a shell edge (because there's */
9203                                                         /*   already one there), but it sets the boundary markers of  */
9204                                                         /*   the existing shell edge and its vertices.                */
9205                                                         insertshelle( &checktri, 1 );
9206                                                         hullsize++;
9207                                                 }
9208                                                 notfound = 0;
9209                                         }
9210                                         /* Find the next triangle in the stack. */
9211                                         prevlink = &checktri.tri[6 + checktri.orient];
9212                                         nexttri = checktri.tri[6 + checktri.orient];
9213                                         decode( nexttri, checktri );
9214                                 }
9215                         }
9216                         shelleloop.sh = shelletraverse();
9217                         segmentnumber++;
9218                 }
9219         }
9220
9221         /* Mark the remaining edges as not being attached to any shell edge. */
9222         /* Also, count the (yet uncounted) boundary edges.                   */
9223         for ( i = 0; i < points.items; i++ ) {
9224                 /* Search the stack of triangles adjacent to a point. */
9225                 nexttri = vertexarray[i];
9226                 decode( nexttri, checktri );
9227                 while ( checktri.tri != dummytri ) {
9228                         /* Find the next triangle in the stack before this */
9229                         /*   information gets overwritten.                 */
9230                         nexttri = checktri.tri[6 + checktri.orient];
9231                         /* No adjacent shell edge.  (This overwrites the stack info.) */
9232                         tsdissolve( checktri );
9233                         sym( checktri, checkneighbor );
9234                         if ( checkneighbor.tri == dummytri ) {
9235                                 insertshelle( &checktri, 1 );
9236                                 hullsize++;
9237                         }
9238                         decode( nexttri, checktri );
9239                 }
9240         }
9241
9242         free( vertexarray );
9243         return hullsize;
9244 }
9245
9246 #endif /* not CDT_ONLY */
9247
9248 /**                                                                         **/
9249 /**                                                                         **/
9250 /********* General mesh construction routines end here               *********/
9251
9252 /********* Segment (shell edge) insertion begins here                *********/
9253 /**                                                                         **/
9254 /**                                                                         **/
9255
9256 /*****************************************************************************/
9257 /*                                                                           */
9258 /*  finddirection()   Find the first triangle on the path from one point     */
9259 /*                    to another.                                            */
9260 /*                                                                           */
9261 /*  Finds the triangle that intersects a line segment drawn from the         */
9262 /*  origin of `searchtri' to the point `endpoint', and returns the result    */
9263 /*  in `searchtri'.  The origin of `searchtri' does not change, even though  */
9264 /*  the triangle returned may differ from the one passed in.  This routine   */
9265 /*  is used to find the direction to move in to get from one point to        */
9266 /*  another.                                                                 */
9267 /*                                                                           */
9268 /*  The return value notes whether the destination or apex of the found      */
9269 /*  triangle is collinear with the two points in question.                   */
9270 /*                                                                           */
9271 /*****************************************************************************/
9272
9273 enum finddirectionresult finddirection( searchtri, endpoint )
9274 struct triedge *searchtri;
9275 point endpoint;
9276 {
9277         struct triedge checktri;
9278         point startpoint;
9279         point leftpoint, rightpoint;
9280         REAL leftccw, rightccw;
9281         int leftflag, rightflag;
9282         triangle ptr;         /* Temporary variable used by onext() and oprev(). */
9283
9284         org( *searchtri, startpoint );
9285         dest( *searchtri, rightpoint );
9286         apex( *searchtri, leftpoint );
9287         /* Is `endpoint' to the left? */
9288         leftccw = counterclockwise( endpoint, startpoint, leftpoint );
9289         leftflag = leftccw > 0.0;
9290         /* Is `endpoint' to the right? */
9291         rightccw = counterclockwise( startpoint, endpoint, rightpoint );
9292         rightflag = rightccw > 0.0;
9293         if ( leftflag && rightflag ) {
9294                 /* `searchtri' faces directly away from `endpoint'.  We could go */
9295                 /*   left or right.  Ask whether it's a triangle or a boundary   */
9296                 /*   on the left.                                                */
9297                 onext( *searchtri, checktri );
9298                 if ( checktri.tri == dummytri ) {
9299                         leftflag = 0;
9300                 }
9301                 else {
9302                         rightflag = 0;
9303                 }
9304         }
9305         while ( leftflag ) {
9306                 /* Turn left until satisfied. */
9307                 onextself( *searchtri );
9308                 if ( searchtri->tri == dummytri ) {
9309                         printf( "Internal error in finddirection():  Unable to find a\n" );
9310                         printf( "  triangle leading from (%.12g, %.12g) to", startpoint[0],
9311                                         startpoint[1] );
9312                         printf( "  (%.12g, %.12g).\n", endpoint[0], endpoint[1] );
9313                         internalerror();
9314                 }
9315                 apex( *searchtri, leftpoint );
9316                 rightccw = leftccw;
9317                 leftccw = counterclockwise( endpoint, startpoint, leftpoint );
9318                 leftflag = leftccw > 0.0;
9319         }
9320         while ( rightflag ) {
9321                 /* Turn right until satisfied. */
9322                 oprevself( *searchtri );
9323                 if ( searchtri->tri == dummytri ) {
9324                         printf( "Internal error in finddirection():  Unable to find a\n" );
9325                         printf( "  triangle leading from (%.12g, %.12g) to", startpoint[0],
9326                                         startpoint[1] );
9327                         printf( "  (%.12g, %.12g).\n", endpoint[0], endpoint[1] );
9328                         internalerror();
9329                 }
9330                 dest( *searchtri, rightpoint );
9331                 leftccw = rightccw;
9332                 rightccw = counterclockwise( startpoint, endpoint, rightpoint );
9333                 rightflag = rightccw > 0.0;
9334         }
9335         if ( leftccw == 0.0 ) {
9336                 return LEFTCOLLINEAR;
9337         }
9338         else if ( rightccw == 0.0 ) {
9339                 return RIGHTCOLLINEAR;
9340         }
9341         else {
9342                 return WITHIN;
9343         }
9344 }
9345
9346 /*****************************************************************************/
9347 /*                                                                           */
9348 /*  segmentintersection()   Find the intersection of an existing segment     */
9349 /*                          and a segment that is being inserted.  Insert    */
9350 /*                          a point at the intersection, splitting an        */
9351 /*                          existing shell edge.                             */
9352 /*                                                                           */
9353 /*  The segment being inserted connects the apex of splittri to endpoint2.   */
9354 /*  splitshelle is the shell edge being split, and MUST be opposite          */
9355 /*  splittri.  Hence, the edge being split connects the origin and           */
9356 /*  destination of splittri.                                                 */
9357 /*                                                                           */
9358 /*  On completion, splittri is a handle having the newly inserted            */
9359 /*  intersection point as its origin, and endpoint1 as its destination.      */
9360 /*                                                                           */
9361 /*****************************************************************************/
9362
9363 void segmentintersection( splittri, splitshelle, endpoint2 )
9364 struct triedge *splittri;
9365 struct edge *splitshelle;
9366 point endpoint2;
9367 {
9368         point endpoint1;
9369         point torg, tdest;
9370         point leftpoint, rightpoint;
9371         point newpoint;
9372         enum insertsiteresult success;
9373         enum finddirectionresult collinear;
9374         REAL ex, ey;
9375         REAL tx, ty;
9376         REAL etx, ety;
9377         REAL split, denom;
9378         int i;
9379         triangle ptr;                     /* Temporary variable used by onext(). */
9380
9381         /* Find the other three segment endpoints. */
9382         apex( *splittri, endpoint1 );
9383         org( *splittri, torg );
9384         dest( *splittri, tdest );
9385         /* Segment intersection formulae; see the Antonio reference. */
9386         tx = tdest[0] - torg[0];
9387         ty = tdest[1] - torg[1];
9388         ex = endpoint2[0] - endpoint1[0];
9389         ey = endpoint2[1] - endpoint1[1];
9390         etx = torg[0] - endpoint2[0];
9391         ety = torg[1] - endpoint2[1];
9392         denom = ty * ex - tx * ey;
9393         if ( denom == 0.0 ) {
9394                 printf( "Internal error in segmentintersection():" );
9395                 printf( "  Attempt to find intersection of parallel segments.\n" );
9396                 internalerror();
9397         }
9398         split = ( ey * etx - ex * ety ) / denom;
9399         /* Create the new point. */
9400         newpoint = (point) poolalloc( &points );
9401         /* Interpolate its coordinate and attributes. */
9402         for ( i = 0; i < 2 + nextras; i++ ) {
9403                 newpoint[i] = torg[i] + split * ( tdest[i] - torg[i] );
9404         }
9405         setpointmark( newpoint, mark( *splitshelle ) );
9406         if ( verbose > 1 ) {
9407                 printf(
9408                         "  Splitting edge (%.12g, %.12g) (%.12g, %.12g) at (%.12g, %.12g).\n",
9409                         torg[0], torg[1], tdest[0], tdest[1], newpoint[0], newpoint[1] );
9410         }
9411         /* Insert the intersection point.  This should always succeed. */
9412         success = insertsite( newpoint, splittri, splitshelle, 0, 0 );
9413         if ( success != SUCCESSFULPOINT ) {
9414                 printf( "Internal error in segmentintersection():\n" );
9415                 printf( "  Failure to split a segment.\n" );
9416                 internalerror();
9417         }
9418         if ( steinerleft > 0 ) {
9419                 steinerleft--;
9420         }
9421         /* Inserting the point may have caused edge flips.  We wish to rediscover */
9422         /*   the edge connecting endpoint1 to the new intersection point.         */
9423         collinear = finddirection( splittri, endpoint1 );
9424         dest( *splittri, rightpoint );
9425         apex( *splittri, leftpoint );
9426         if ( ( leftpoint[0] == endpoint1[0] ) && ( leftpoint[1] == endpoint1[1] ) ) {
9427                 onextself( *splittri );
9428         }
9429         else if ( ( rightpoint[0] != endpoint1[0] ) ||
9430                           ( rightpoint[1] != endpoint1[1] ) ) {
9431                 printf( "Internal error in segmentintersection():\n" );
9432                 printf( "  Topological inconsistency after splitting a segment.\n" );
9433                 internalerror();
9434         }
9435         /* `splittri' should have destination endpoint1. */
9436 }
9437
9438 /*****************************************************************************/
9439 /*                                                                           */
9440 /*  scoutsegment()   Scout the first triangle on the path from one endpoint  */
9441 /*                   to another, and check for completion (reaching the      */
9442 /*                   second endpoint), a collinear point, and the            */
9443 /*                   intersection of two segments.                           */
9444 /*                                                                           */
9445 /*  Returns one if the entire segment is successfully inserted, and zero if  */
9446 /*  the job must be finished by conformingedge() or constrainededge().       */
9447 /*                                                                           */
9448 /*  If the first triangle on the path has the second endpoint as its         */
9449 /*  destination or apex, a shell edge is inserted and the job is done.       */
9450 /*                                                                           */
9451 /*  If the first triangle on the path has a destination or apex that lies on */
9452 /*  the segment, a shell edge is inserted connecting the first endpoint to   */
9453 /*  the collinear point, and the search is continued from the collinear      */
9454 /*  point.                                                                   */
9455 /*                                                                           */
9456 /*  If the first triangle on the path has a shell edge opposite its origin,  */
9457 /*  then there is a segment that intersects the segment being inserted.      */
9458 /*  Their intersection point is inserted, splitting the shell edge.          */
9459 /*                                                                           */
9460 /*  Otherwise, return zero.                                                  */
9461 /*                                                                           */
9462 /*****************************************************************************/
9463
9464 int scoutsegment( searchtri, endpoint2, newmark )
9465 struct triedge *searchtri;
9466 point endpoint2;
9467 int newmark;
9468 {
9469         struct triedge crosstri;
9470         struct edge crossedge;
9471         point leftpoint, rightpoint;
9472         point endpoint1;
9473         enum finddirectionresult collinear;
9474         shelle sptr;                    /* Temporary variable used by tspivot(). */
9475
9476         collinear = finddirection( searchtri, endpoint2 );
9477         dest( *searchtri, rightpoint );
9478         apex( *searchtri, leftpoint );
9479         if ( ( ( leftpoint[0] == endpoint2[0] ) && ( leftpoint[1] == endpoint2[1] ) ) ||
9480                  ( ( rightpoint[0] == endpoint2[0] ) && ( rightpoint[1] == endpoint2[1] ) ) ) {
9481                 /* The segment is already an edge in the mesh. */
9482                 if ( ( leftpoint[0] == endpoint2[0] ) && ( leftpoint[1] == endpoint2[1] ) ) {
9483                         lprevself( *searchtri );
9484                 }
9485                 /* Insert a shell edge, if there isn't already one there. */
9486                 insertshelle( searchtri, newmark );
9487                 return 1;
9488         }
9489         else if ( collinear == LEFTCOLLINEAR ) {
9490                 /* We've collided with a point between the segment's endpoints. */
9491                 /* Make the collinear point be the triangle's origin. */
9492                 lprevself( *searchtri );
9493                 insertshelle( searchtri, newmark );
9494                 /* Insert the remainder of the segment. */
9495                 return scoutsegment( searchtri, endpoint2, newmark );
9496         }
9497         else if ( collinear == RIGHTCOLLINEAR ) {
9498                 /* We've collided with a point between the segment's endpoints. */
9499                 insertshelle( searchtri, newmark );
9500                 /* Make the collinear point be the triangle's origin. */
9501                 lnextself( *searchtri );
9502                 /* Insert the remainder of the segment. */
9503                 return scoutsegment( searchtri, endpoint2, newmark );
9504         }
9505         else {
9506                 lnext( *searchtri, crosstri );
9507                 tspivot( crosstri, crossedge );
9508                 /* Check for a crossing segment. */
9509                 if ( crossedge.sh == dummysh ) {
9510                         return 0;
9511                 }
9512                 else {
9513                         org( *searchtri, endpoint1 );
9514                         /* Insert a point at the intersection. */
9515                         segmentintersection( &crosstri, &crossedge, endpoint2 );
9516                         triedgecopy( crosstri, *searchtri );
9517                         insertshelle( searchtri, newmark );
9518                         /* Insert the remainder of the segment. */
9519                         return scoutsegment( searchtri, endpoint2, newmark );
9520                 }
9521         }
9522 }
9523
9524 /*****************************************************************************/
9525 /*                                                                           */
9526 /*  conformingedge()   Force a segment into a conforming Delaunay            */
9527 /*                     triangulation by inserting a point at its midpoint,   */
9528 /*                     and recursively forcing in the two half-segments if   */
9529 /*                     necessary.                                            */
9530 /*                                                                           */
9531 /*  Generates a sequence of edges connecting `endpoint1' to `endpoint2'.     */
9532 /*  `newmark' is the boundary marker of the segment, assigned to each new    */
9533 /*  splitting point and shell edge.                                          */
9534 /*                                                                           */
9535 /*  Note that conformingedge() does not always maintain the conforming       */
9536 /*  Delaunay property.  Once inserted, segments are locked into place;       */
9537 /*  points inserted later (to force other segments in) may render these      */
9538 /*  fixed segments non-Delaunay.  The conforming Delaunay property will be   */
9539 /*  restored by enforcequality() by splitting encroached segments.           */
9540 /*                                                                           */
9541 /*****************************************************************************/
9542
9543 #ifndef REDUCED
9544 #ifndef CDT_ONLY
9545
9546 void conformingedge( endpoint1, endpoint2, newmark )
9547 point endpoint1;
9548 point endpoint2;
9549 int newmark;
9550 {
9551         struct triedge searchtri1, searchtri2;
9552         struct edge brokenshelle;
9553         point newpoint;
9554         point midpoint1, midpoint2;
9555         enum insertsiteresult success;
9556         int result1, result2;
9557         int i;
9558         shelle sptr;                    /* Temporary variable used by tspivot(). */
9559
9560         if ( verbose > 2 ) {
9561                 printf( "Forcing segment into triangulation by recursive splitting:\n" );
9562                 printf( "  (%.12g, %.12g) (%.12g, %.12g)\n", endpoint1[0], endpoint1[1],
9563                                 endpoint2[0], endpoint2[1] );
9564         }
9565         /* Create a new point to insert in the middle of the segment. */
9566         newpoint = (point) poolalloc( &points );
9567         /* Interpolate coordinates and attributes. */
9568         for ( i = 0; i < 2 + nextras; i++ ) {
9569                 newpoint[i] = 0.5 * ( endpoint1[i] + endpoint2[i] );
9570         }
9571         setpointmark( newpoint, newmark );
9572         /* Find a boundary triangle to search from. */
9573         searchtri1.tri = (triangle *) NULL;
9574         /* Attempt to insert the new point. */
9575         success = insertsite( newpoint, &searchtri1, (struct edge *) NULL, 0, 0 );
9576         if ( success == DUPLICATEPOINT ) {
9577                 if ( verbose > 2 ) {
9578                         printf( "  Segment intersects existing point (%.12g, %.12g).\n",
9579                                         newpoint[0], newpoint[1] );
9580                 }
9581                 /* Use the point that's already there. */
9582                 pointdealloc( newpoint );
9583                 org( searchtri1, newpoint );
9584         }
9585         else {
9586                 if ( success == VIOLATINGPOINT ) {
9587                         if ( verbose > 2 ) {
9588                                 printf( "  Two segments intersect at (%.12g, %.12g).\n",
9589                                                 newpoint[0], newpoint[1] );
9590                         }
9591                         /* By fluke, we've landed right on another segment.  Split it. */
9592                         tspivot( searchtri1, brokenshelle );
9593                         success = insertsite( newpoint, &searchtri1, &brokenshelle, 0, 0 );
9594                         if ( success != SUCCESSFULPOINT ) {
9595                                 printf( "Internal error in conformingedge():\n" );
9596                                 printf( "  Failure to split a segment.\n" );
9597                                 internalerror();
9598                         }
9599                 }
9600                 /* The point has been inserted successfully. */
9601                 if ( steinerleft > 0 ) {
9602                         steinerleft--;
9603                 }
9604         }
9605         triedgecopy( searchtri1, searchtri2 );
9606         result1 = scoutsegment( &searchtri1, endpoint1, newmark );
9607         result2 = scoutsegment( &searchtri2, endpoint2, newmark );
9608         if ( !result1 ) {
9609                 /* The origin of searchtri1 may have changed if a collision with an */
9610                 /*   intervening vertex on the segment occurred.                    */
9611                 org( searchtri1, midpoint1 );
9612                 conformingedge( midpoint1, endpoint1, newmark );
9613         }
9614         if ( !result2 ) {
9615                 /* The origin of searchtri2 may have changed if a collision with an */
9616                 /*   intervening vertex on the segment occurred.                    */
9617                 org( searchtri2, midpoint2 );
9618                 conformingedge( midpoint2, endpoint2, newmark );
9619         }
9620 }
9621
9622 #endif /* not CDT_ONLY */
9623 #endif /* not REDUCED */
9624
9625 /*****************************************************************************/
9626 /*                                                                           */
9627 /*  delaunayfixup()   Enforce the Delaunay condition at an edge, fanning out */
9628 /*                    recursively from an existing point.  Pay special       */
9629 /*                    attention to stacking inverted triangles.              */
9630 /*                                                                           */
9631 /*  This is a support routine for inserting segments into a constrained      */
9632 /*  Delaunay triangulation.                                                  */
9633 /*                                                                           */
9634 /*  The origin of fixuptri is treated as if it has just been inserted, and   */
9635 /*  the local Delaunay condition needs to be enforced.  It is only enforced  */
9636 /*  in one sector, however, that being the angular range defined by          */
9637 /*  fixuptri.                                                                */
9638 /*                                                                           */
9639 /*  This routine also needs to make decisions regarding the "stacking" of    */
9640 /*  triangles.  (Read the description of constrainededge() below before      */
9641 /*  reading on here, so you understand the algorithm.)  If the position of   */
9642 /*  the new point (the origin of fixuptri) indicates that the vertex before  */
9643 /*  it on the polygon is a reflex vertex, then "stack" the triangle by       */
9644 /*  doing nothing.  (fixuptri is an inverted triangle, which is how stacked  */
9645 /*  triangles are identified.)                                               */
9646 /*                                                                           */
9647 /*  Otherwise, check whether the vertex before that was a reflex vertex.     */
9648 /*  If so, perform an edge flip, thereby eliminating an inverted triangle    */
9649 /*  (popping it off the stack).  The edge flip may result in the creation    */
9650 /*  of a new inverted triangle, depending on whether or not the new vertex   */
9651 /*  is visible to the vertex three edges behind on the polygon.              */
9652 /*                                                                           */
9653 /*  If neither of the two vertices behind the new vertex are reflex          */
9654 /*  vertices, fixuptri and fartri, the triangle opposite it, are not         */
9655 /*  inverted; hence, ensure that the edge between them is locally Delaunay.  */
9656 /*                                                                           */
9657 /*  `leftside' indicates whether or not fixuptri is to the left of the       */
9658 /*  segment being inserted.  (Imagine that the segment is pointing up from   */
9659 /*  endpoint1 to endpoint2.)                                                 */
9660 /*                                                                           */
9661 /*****************************************************************************/
9662
9663 void delaunayfixup( fixuptri, leftside )
9664 struct triedge *fixuptri;
9665 int leftside;
9666 {
9667         struct triedge neartri;
9668         struct triedge fartri;
9669         struct edge faredge;
9670         point nearpoint, leftpoint, rightpoint, farpoint;
9671         triangle ptr;                       /* Temporary variable used by sym(). */
9672         shelle sptr;                    /* Temporary variable used by tspivot(). */
9673
9674         lnext( *fixuptri, neartri );
9675         sym( neartri, fartri );
9676         /* Check if the edge opposite the origin of fixuptri can be flipped. */
9677         if ( fartri.tri == dummytri ) {
9678                 return;
9679         }
9680         tspivot( neartri, faredge );
9681         if ( faredge.sh != dummysh ) {
9682                 return;
9683         }
9684         /* Find all the relevant vertices. */
9685         apex( neartri, nearpoint );
9686         org( neartri, leftpoint );
9687         dest( neartri, rightpoint );
9688         apex( fartri, farpoint );
9689         /* Check whether the previous polygon vertex is a reflex vertex. */
9690         if ( leftside ) {
9691                 if ( counterclockwise( nearpoint, leftpoint, farpoint ) <= 0.0 ) {
9692                         /* leftpoint is a reflex vertex too.  Nothing can */
9693                         /*   be done until a convex section is found.     */
9694                         return;
9695                 }
9696         }
9697         else {
9698                 if ( counterclockwise( farpoint, rightpoint, nearpoint ) <= 0.0 ) {
9699                         /* rightpoint is a reflex vertex too.  Nothing can */
9700                         /*   be done until a convex section is found.      */
9701                         return;
9702                 }
9703         }
9704         if ( counterclockwise( rightpoint, leftpoint, farpoint ) > 0.0 ) {
9705                 /* fartri is not an inverted triangle, and farpoint is not a reflex */
9706                 /*   vertex.  As there are no reflex vertices, fixuptri isn't an    */
9707                 /*   inverted triangle, either.  Hence, test the edge between the   */
9708                 /*   triangles to ensure it is locally Delaunay.                    */
9709                 if ( incircle( leftpoint, farpoint, rightpoint, nearpoint ) <= 0.0 ) {
9710                         return;
9711                 }
9712                 /* Not locally Delaunay; go on to an edge flip. */
9713         }      /* else fartri is inverted; remove it from the stack by flipping. */
9714         flip( &neartri );
9715         lprevself( *fixuptri ); /* Restore the origin of fixuptri after the flip. */
9716         /* Recursively process the two triangles that result from the flip. */
9717         delaunayfixup( fixuptri, leftside );
9718         delaunayfixup( &fartri, leftside );
9719 }
9720
9721 /*****************************************************************************/
9722 /*                                                                           */
9723 /*  constrainededge()   Force a segment into a constrained Delaunay          */
9724 /*                      triangulation by deleting the triangles it           */
9725 /*                      intersects, and triangulating the polygons that      */
9726 /*                      form on each side of it.                             */
9727 /*                                                                           */
9728 /*  Generates a single edge connecting `endpoint1' to `endpoint2'.  The      */
9729 /*  triangle `starttri' has `endpoint1' as its origin.  `newmark' is the     */
9730 /*  boundary marker of the segment.                                          */
9731 /*                                                                           */
9732 /*  To insert a segment, every triangle whose interior intersects the        */
9733 /*  segment is deleted.  The union of these deleted triangles is a polygon   */
9734 /*  (which is not necessarily monotone, but is close enough), which is       */
9735 /*  divided into two polygons by the new segment.  This routine's task is    */
9736 /*  to generate the Delaunay triangulation of these two polygons.            */
9737 /*                                                                           */
9738 /*  You might think of this routine's behavior as a two-step process.  The   */
9739 /*  first step is to walk from endpoint1 to endpoint2, flipping each edge    */
9740 /*  encountered.  This step creates a fan of edges connected to endpoint1,   */
9741 /*  including the desired edge to endpoint2.  The second step enforces the   */
9742 /*  Delaunay condition on each side of the segment in an incremental manner: */
9743 /*  proceeding along the polygon from endpoint1 to endpoint2 (this is done   */
9744 /*  independently on each side of the segment), each vertex is "enforced"    */
9745 /*  as if it had just been inserted, but affecting only the previous         */
9746 /*  vertices.  The result is the same as if the vertices had been inserted   */
9747 /*  in the order they appear on the polygon, so the result is Delaunay.      */
9748 /*                                                                           */
9749 /*  In truth, constrainededge() interleaves these two steps.  The procedure  */
9750 /*  walks from endpoint1 to endpoint2, and each time an edge is encountered  */
9751 /*  and flipped, the newly exposed vertex (at the far end of the flipped     */
9752 /*  edge) is "enforced" upon the previously flipped edges, usually affecting */
9753 /*  only one side of the polygon (depending upon which side of the segment   */
9754 /*  the vertex falls on).                                                    */
9755 /*                                                                           */
9756 /*  The algorithm is complicated by the need to handle polygons that are not */
9757 /*  convex.  Although the polygon is not necessarily monotone, it can be     */
9758 /*  triangulated in a manner similar to the stack-based algorithms for       */
9759 /*  monotone polygons.  For each reflex vertex (local concavity) of the      */
9760 /*  polygon, there will be an inverted triangle formed by one of the edge    */
9761 /*  flips.  (An inverted triangle is one with negative area - that is, its   */
9762 /*  vertices are arranged in clockwise order - and is best thought of as a   */
9763 /*  wrinkle in the fabric of the mesh.)  Each inverted triangle can be       */
9764 /*  thought of as a reflex vertex pushed on the stack, waiting to be fixed   */
9765 /*  later.                                                                   */
9766 /*                                                                           */
9767 /*  A reflex vertex is popped from the stack when a vertex is inserted that  */
9768 /*  is visible to the reflex vertex.  (However, if the vertex behind the     */
9769 /*  reflex vertex is not visible to the reflex vertex, a new inverted        */
9770 /*  triangle will take its place on the stack.)  These details are handled   */
9771 /*  by the delaunayfixup() routine above.                                    */
9772 /*                                                                           */
9773 /*****************************************************************************/
9774
9775 void constrainededge( starttri, endpoint2, newmark )
9776 struct triedge *starttri;
9777 point endpoint2;
9778 int newmark;
9779 {
9780         struct triedge fixuptri, fixuptri2;
9781         struct edge fixupedge;
9782         point endpoint1;
9783         point farpoint;
9784         REAL area;
9785         int collision;
9786         int done;
9787         triangle ptr;           /* Temporary variable used by sym() and oprev(). */
9788         shelle sptr;                    /* Temporary variable used by tspivot(). */
9789
9790         org( *starttri, endpoint1 );
9791         lnext( *starttri, fixuptri );
9792         flip( &fixuptri );
9793         /* `collision' indicates whether we have found a point directly */
9794         /*   between endpoint1 and endpoint2.                           */
9795         collision = 0;
9796         done = 0;
9797         do {
9798                 org( fixuptri, farpoint );
9799                 /* `farpoint' is the extreme point of the polygon we are "digging" */
9800                 /*   to get from endpoint1 to endpoint2.                           */
9801                 if ( ( farpoint[0] == endpoint2[0] ) && ( farpoint[1] == endpoint2[1] ) ) {
9802                         oprev( fixuptri, fixuptri2 );
9803                         /* Enforce the Delaunay condition around endpoint2. */
9804                         delaunayfixup( &fixuptri, 0 );
9805                         delaunayfixup( &fixuptri2, 1 );
9806                         done = 1;
9807                 }
9808                 else {
9809                         /* Check whether farpoint is to the left or right of the segment */
9810                         /*   being inserted, to decide which edge of fixuptri to dig     */
9811                         /*   through next.                                               */
9812                         area = counterclockwise( endpoint1, endpoint2, farpoint );
9813                         if ( area == 0.0 ) {
9814                                 /* We've collided with a point between endpoint1 and endpoint2. */
9815                                 collision = 1;
9816                                 oprev( fixuptri, fixuptri2 );
9817                                 /* Enforce the Delaunay condition around farpoint. */
9818                                 delaunayfixup( &fixuptri, 0 );
9819                                 delaunayfixup( &fixuptri2, 1 );
9820                                 done = 1;
9821                         }
9822                         else {
9823                                 if ( area > 0.0 ) { /* farpoint is to the left of the segment. */
9824                                         oprev( fixuptri, fixuptri2 );
9825                                         /* Enforce the Delaunay condition around farpoint, on the */
9826                                         /*   left side of the segment only.                       */
9827                                         delaunayfixup( &fixuptri2, 1 );
9828                                         /* Flip the edge that crosses the segment.  After the edge is */
9829                                         /*   flipped, one of its endpoints is the fan vertex, and the */
9830                                         /*   destination of fixuptri is the fan vertex.               */
9831                                         lprevself( fixuptri );
9832                                 }
9833                                 else {           /* farpoint is to the right of the segment. */
9834                                         delaunayfixup( &fixuptri, 0 );
9835                                         /* Flip the edge that crosses the segment.  After the edge is */
9836                                         /*   flipped, one of its endpoints is the fan vertex, and the */
9837                                         /*   destination of fixuptri is the fan vertex.               */
9838                                         oprevself( fixuptri );
9839                                 }
9840                                 /* Check for two intersecting segments. */
9841                                 tspivot( fixuptri, fixupedge );
9842                                 if ( fixupedge.sh == dummysh ) {
9843                                         flip( &fixuptri ); /* May create an inverted triangle on the left. */
9844                                 }
9845                                 else {
9846                                         /* We've collided with a segment between endpoint1 and endpoint2. */
9847                                         collision = 1;
9848                                         /* Insert a point at the intersection. */
9849                                         segmentintersection( &fixuptri, &fixupedge, endpoint2 );
9850                                         done = 1;
9851                                 }
9852                         }
9853                 }
9854         } while ( !done );
9855         /* Insert a shell edge to make the segment permanent. */
9856         insertshelle( &fixuptri, newmark );
9857         /* If there was a collision with an interceding vertex, install another */
9858         /*   segment connecting that vertex with endpoint2.                     */
9859         if ( collision ) {
9860                 /* Insert the remainder of the segment. */
9861                 if ( !scoutsegment( &fixuptri, endpoint2, newmark ) ) {
9862                         constrainededge( &fixuptri, endpoint2, newmark );
9863                 }
9864         }
9865 }
9866
9867 /*****************************************************************************/
9868 /*                                                                           */
9869 /*  insertsegment()   Insert a PSLG segment into a triangulation.            */
9870 /*                                                                           */
9871 /*****************************************************************************/
9872
9873 void insertsegment( endpoint1, endpoint2, newmark )
9874 point endpoint1;
9875 point endpoint2;
9876 int newmark;
9877 {
9878         struct triedge searchtri1, searchtri2;
9879         triangle encodedtri;
9880         point checkpoint;
9881         triangle ptr;                       /* Temporary variable used by sym(). */
9882
9883         if ( verbose > 1 ) {
9884                 printf( "  Connecting (%.12g, %.12g) to (%.12g, %.12g).\n",
9885                                 endpoint1[0], endpoint1[1], endpoint2[0], endpoint2[1] );
9886         }
9887
9888         /* Find a triangle whose origin is the segment's first endpoint. */
9889         checkpoint = (point) NULL;
9890         encodedtri = point2tri( endpoint1 );
9891         if ( encodedtri != (triangle) NULL ) {
9892                 decode( encodedtri, searchtri1 );
9893                 org( searchtri1, checkpoint );
9894         }
9895         if ( checkpoint != endpoint1 ) {
9896                 /* Find a boundary triangle to search from. */
9897                 searchtri1.tri = dummytri;
9898                 searchtri1.orient = 0;
9899                 symself( searchtri1 );
9900                 /* Search for the segment's first endpoint by point location. */
9901                 if ( locate( endpoint1, &searchtri1 ) != ONVERTEX ) {
9902                         printf(
9903                                 "Internal error in insertsegment():  Unable to locate PSLG point\n" );
9904                         printf( "  (%.12g, %.12g) in triangulation.\n",
9905                                         endpoint1[0], endpoint1[1] );
9906                         internalerror();
9907                 }
9908         }
9909         /* Remember this triangle to improve subsequent point location. */
9910         triedgecopy( searchtri1, recenttri );
9911         /* Scout the beginnings of a path from the first endpoint */
9912         /*   toward the second.                                   */
9913         if ( scoutsegment( &searchtri1, endpoint2, newmark ) ) {
9914                 /* The segment was easily inserted. */
9915                 return;
9916         }
9917         /* The first endpoint may have changed if a collision with an intervening */
9918         /*   vertex on the segment occurred.                                      */
9919         org( searchtri1, endpoint1 );
9920
9921         /* Find a triangle whose origin is the segment's second endpoint. */
9922         checkpoint = (point) NULL;
9923         encodedtri = point2tri( endpoint2 );
9924         if ( encodedtri != (triangle) NULL ) {
9925                 decode( encodedtri, searchtri2 );
9926                 org( searchtri2, checkpoint );
9927         }
9928         if ( checkpoint != endpoint2 ) {
9929                 /* Find a boundary triangle to search from. */
9930                 searchtri2.tri = dummytri;
9931                 searchtri2.orient = 0;
9932                 symself( searchtri2 );
9933                 /* Search for the segment's second endpoint by point location. */
9934                 if ( locate( endpoint2, &searchtri2 ) != ONVERTEX ) {
9935                         printf(
9936                                 "Internal error in insertsegment():  Unable to locate PSLG point\n" );
9937                         printf( "  (%.12g, %.12g) in triangulation.\n",
9938                                         endpoint2[0], endpoint2[1] );
9939                         internalerror();
9940                 }
9941         }
9942         /* Remember this triangle to improve subsequent point location. */
9943         triedgecopy( searchtri2, recenttri );
9944         /* Scout the beginnings of a path from the second endpoint */
9945         /*   toward the first.                                     */
9946         if ( scoutsegment( &searchtri2, endpoint1, newmark ) ) {
9947                 /* The segment was easily inserted. */
9948                 return;
9949         }
9950         /* The second endpoint may have changed if a collision with an intervening */
9951         /*   vertex on the segment occurred.                                       */
9952         org( searchtri2, endpoint2 );
9953
9954 #ifndef REDUCED
9955 #ifndef CDT_ONLY
9956         if ( splitseg ) {
9957                 /* Insert vertices to force the segment into the triangulation. */
9958                 conformingedge( endpoint1, endpoint2, newmark );
9959         }
9960         else {
9961 #endif /* not CDT_ONLY */
9962 #endif /* not REDUCED */
9963            /* Insert the segment directly into the triangulation. */
9964         constrainededge( &searchtri1, endpoint2, newmark );
9965 #ifndef REDUCED
9966 #ifndef CDT_ONLY
9967 }
9968 #endif /* not CDT_ONLY */
9969 #endif /* not REDUCED */
9970 }
9971
9972 /*****************************************************************************/
9973 /*                                                                           */
9974 /*  markhull()   Cover the convex hull of a triangulation with shell edges.  */
9975 /*                                                                           */
9976 /*****************************************************************************/
9977
9978 void markhull(){
9979         struct triedge hulltri;
9980         struct triedge nexttri;
9981         struct triedge starttri;
9982         triangle ptr;           /* Temporary variable used by sym() and oprev(). */
9983
9984         /* Find a triangle handle on the hull. */
9985         hulltri.tri = dummytri;
9986         hulltri.orient = 0;
9987         symself( hulltri );
9988         /* Remember where we started so we know when to stop. */
9989         triedgecopy( hulltri, starttri );
9990         /* Go once counterclockwise around the convex hull. */
9991         do {
9992                 /* Create a shell edge if there isn't already one here. */
9993                 insertshelle( &hulltri, 1 );
9994                 /* To find the next hull edge, go clockwise around the next vertex. */
9995                 lnextself( hulltri );
9996                 oprev( hulltri, nexttri );
9997                 while ( nexttri.tri != dummytri ) {
9998                         triedgecopy( nexttri, hulltri );
9999                         oprev( hulltri, nexttri );
10000                 }
10001         } while ( !triedgeequal( hulltri, starttri ) );
10002 }
10003
10004 /*****************************************************************************/
10005 /*                                                                           */
10006 /*  formskeleton()   Create the shell edges of a triangulation, including    */
10007 /*                   PSLG edges and edges on the convex hull.                */
10008 /*                                                                           */
10009 /*  The PSLG edges are read from a .poly file.  The return value is the      */
10010 /*  number of segments in the file.                                          */
10011 /*                                                                           */
10012 /*****************************************************************************/
10013
10014 #ifdef TRILIBRARY
10015
10016 int formskeleton( segmentlist, segmentmarkerlist, numberofsegments )
10017 int *segmentlist;
10018 int *segmentmarkerlist;
10019 int numberofsegments;
10020
10021 #else /* not TRILIBRARY */
10022
10023 int formskeleton( polyfile, polyfilename )
10024 FILE * polyfile;
10025 char *polyfilename;
10026
10027 #endif /* not TRILIBRARY */
10028
10029 {
10030 #ifdef TRILIBRARY
10031         char polyfilename[6];
10032         int index;
10033 #else /* not TRILIBRARY */
10034         char inputline[INPUTLINESIZE];
10035         char *stringptr;
10036 #endif /* not TRILIBRARY */
10037         point endpoint1, endpoint2;
10038         int segments;
10039         int segmentmarkers;
10040         int end1, end2;
10041         int boundmarker;
10042         int i;
10043
10044         if ( poly ) {
10045                 if ( !quiet ) {
10046                         printf( "Inserting segments into Delaunay triangulation.\n" );
10047                 }
10048 #ifdef TRILIBRARY
10049                 strcpy( polyfilename, "input" );
10050                 segments = numberofsegments;
10051                 segmentmarkers = segmentmarkerlist != (int *) NULL;
10052                 index = 0;
10053 #else /* not TRILIBRARY */
10054                 /* Read the segments from a .poly file. */
10055                 /* Read number of segments and number of boundary markers. */
10056                 stringptr = readline( inputline, polyfile, polyfilename );
10057                 segments = (int) strtol( stringptr, &stringptr, 0 );
10058                 stringptr = findfield( stringptr );
10059                 if ( *stringptr == '\0' ) {
10060                         segmentmarkers = 0;
10061                 }
10062                 else {
10063                         segmentmarkers = (int) strtol( stringptr, &stringptr, 0 );
10064                 }
10065 #endif /* not TRILIBRARY */
10066                 /* If segments are to be inserted, compute a mapping */
10067                 /*   from points to triangles.                       */
10068                 if ( segments > 0 ) {
10069                         if ( verbose ) {
10070                                 printf( "  Inserting PSLG segments.\n" );
10071                         }
10072                         makepointmap();
10073                 }
10074
10075                 boundmarker = 0;
10076                 /* Read and insert the segments. */
10077                 for ( i = 1; i <= segments; i++ ) {
10078 #ifdef TRILIBRARY
10079                         end1 = segmentlist[index++];
10080                         end2 = segmentlist[index++];
10081                         if ( segmentmarkers ) {
10082                                 boundmarker = segmentmarkerlist[i - 1];
10083                         }
10084 #else /* not TRILIBRARY */
10085                         stringptr = readline( inputline, polyfile, inpolyfilename );
10086                         stringptr = findfield( stringptr );
10087                         if ( *stringptr == '\0' ) {
10088                                 printf( "Error:  Segment %d has no endpoints in %s.\n", i,
10089                                                 polyfilename );
10090                                 exit( 1 );
10091                         }
10092                         else {
10093                                 end1 = (int) strtol( stringptr, &stringptr, 0 );
10094                         }
10095                         stringptr = findfield( stringptr );
10096                         if ( *stringptr == '\0' ) {
10097                                 printf( "Error:  Segment %d is missing its second endpoint in %s.\n", i,
10098                                                 polyfilename );
10099                                 exit( 1 );
10100                         }
10101                         else {
10102                                 end2 = (int) strtol( stringptr, &stringptr, 0 );
10103                         }
10104                         if ( segmentmarkers ) {
10105                                 stringptr = findfield( stringptr );
10106                                 if ( *stringptr == '\0' ) {
10107                                         boundmarker = 0;
10108                                 }
10109                                 else {
10110                                         boundmarker = (int) strtol( stringptr, &stringptr, 0 );
10111                                 }
10112                         }
10113 #endif /* not TRILIBRARY */
10114                         if ( ( end1 < firstnumber ) || ( end1 >= firstnumber + inpoints ) ) {
10115                                 if ( !quiet ) {
10116                                         printf( "Warning:  Invalid first endpoint of segment %d in %s.\n", i,
10117                                                         polyfilename );
10118                                 }
10119                         }
10120                         else if ( ( end2 < firstnumber ) || ( end2 >= firstnumber + inpoints ) ) {
10121                                 if ( !quiet ) {
10122                                         printf( "Warning:  Invalid second endpoint of segment %d in %s.\n", i,
10123                                                         polyfilename );
10124                                 }
10125                         }
10126                         else {
10127                                 endpoint1 = getpoint( end1 );
10128                                 endpoint2 = getpoint( end2 );
10129                                 if ( ( endpoint1[0] == endpoint2[0] ) && ( endpoint1[1] == endpoint2[1] ) ) {
10130                                         if ( !quiet ) {
10131                                                 printf( "Warning:  Endpoints of segment %d are coincident in %s.\n",
10132                                                                 i, polyfilename );
10133                                         }
10134                                 }
10135                                 else {
10136                                         insertsegment( endpoint1, endpoint2, boundmarker );
10137                                 }
10138                         }
10139                 }
10140         }
10141         else {
10142                 segments = 0;
10143         }
10144         if ( convex || !poly ) {
10145                 /* Enclose the convex hull with shell edges. */
10146                 if ( verbose ) {
10147                         printf( "  Enclosing convex hull with segments.\n" );
10148                 }
10149                 markhull();
10150         }
10151         return segments;
10152 }
10153
10154 /**                                                                         **/
10155 /**                                                                         **/
10156 /********* Segment (shell edge) insertion ends here                  *********/
10157
10158 /********* Carving out holes and concavities begins here             *********/
10159 /**                                                                         **/
10160 /**                                                                         **/
10161
10162 /*****************************************************************************/
10163 /*                                                                           */
10164 /*  infecthull()   Virally infect all of the triangles of the convex hull    */
10165 /*                 that are not protected by shell edges.  Where there are   */
10166 /*                 shell edges, set boundary markers as appropriate.         */
10167 /*                                                                           */
10168 /*****************************************************************************/
10169
10170 void infecthull(){
10171         struct triedge hulltri;
10172         struct triedge nexttri;
10173         struct triedge starttri;
10174         struct edge hulledge;
10175         triangle **deadtri;
10176         point horg, hdest;
10177         triangle ptr;                       /* Temporary variable used by sym(). */
10178         shelle sptr;                    /* Temporary variable used by tspivot(). */
10179
10180         if ( verbose ) {
10181                 printf( "  Marking concavities (external triangles) for elimination.\n" );
10182         }
10183         /* Find a triangle handle on the hull. */
10184         hulltri.tri = dummytri;
10185         hulltri.orient = 0;
10186         symself( hulltri );
10187         /* Remember where we started so we know when to stop. */
10188         triedgecopy( hulltri, starttri );
10189         /* Go once counterclockwise around the convex hull. */
10190         do {
10191                 /* Ignore triangles that are already infected. */
10192                 if ( !infected( hulltri ) ) {
10193                         /* Is the triangle protected by a shell edge? */
10194                         tspivot( hulltri, hulledge );
10195                         if ( hulledge.sh == dummysh ) {
10196                                 /* The triangle is not protected; infect it. */
10197                                 infect( hulltri );
10198                                 deadtri = (triangle **) poolalloc( &viri );
10199                                 *deadtri = hulltri.tri;
10200                         }
10201                         else {
10202                                 /* The triangle is protected; set boundary markers if appropriate. */
10203                                 if ( mark( hulledge ) == 0 ) {
10204                                         setmark( hulledge, 1 );
10205                                         org( hulltri, horg );
10206                                         dest( hulltri, hdest );
10207                                         if ( pointmark( horg ) == 0 ) {
10208                                                 setpointmark( horg, 1 );
10209                                         }
10210                                         if ( pointmark( hdest ) == 0 ) {
10211                                                 setpointmark( hdest, 1 );
10212                                         }
10213                                 }
10214                         }
10215                 }
10216                 /* To find the next hull edge, go clockwise around the next vertex. */
10217                 lnextself( hulltri );
10218                 oprev( hulltri, nexttri );
10219                 while ( nexttri.tri != dummytri ) {
10220                         triedgecopy( nexttri, hulltri );
10221                         oprev( hulltri, nexttri );
10222                 }
10223         } while ( !triedgeequal( hulltri, starttri ) );
10224 }
10225
10226 /*****************************************************************************/
10227 /*                                                                           */
10228 /*  plague()   Spread the virus from all infected triangles to any neighbors */
10229 /*             not protected by shell edges.  Delete all infected triangles. */
10230 /*                                                                           */
10231 /*  This is the procedure that actually creates holes and concavities.       */
10232 /*                                                                           */
10233 /*  This procedure operates in two phases.  The first phase identifies all   */
10234 /*  the triangles that will die, and marks them as infected.  They are       */
10235 /*  marked to ensure that each triangle is added to the virus pool only      */
10236 /*  once, so the procedure will terminate.                                   */
10237 /*                                                                           */
10238 /*  The second phase actually eliminates the infected triangles.  It also    */
10239 /*  eliminates orphaned points.                                              */
10240 /*                                                                           */
10241 /*****************************************************************************/
10242
10243 void plague(){
10244         struct triedge testtri;
10245         struct triedge neighbor;
10246         triangle **virusloop;
10247         triangle **deadtri;
10248         struct edge neighborshelle;
10249         point testpoint;
10250         point norg, ndest;
10251         point deadorg, deaddest, deadapex;
10252         int killorg;
10253         triangle ptr;           /* Temporary variable used by sym() and onext(). */
10254         shelle sptr;                    /* Temporary variable used by tspivot(). */
10255
10256         if ( verbose ) {
10257                 printf( "  Marking neighbors of marked triangles.\n" );
10258         }
10259         /* Loop through all the infected triangles, spreading the virus to */
10260         /*   their neighbors, then to their neighbors' neighbors.          */
10261         traversalinit( &viri );
10262         virusloop = (triangle **) traverse( &viri );
10263         while ( virusloop != (triangle **) NULL ) {
10264                 testtri.tri = *virusloop;
10265                 /* A triangle is marked as infected by messing with one of its shell */
10266                 /*   edges, setting it to an illegal value.  Hence, we have to       */
10267                 /*   temporarily uninfect this triangle so that we can examine its   */
10268                 /*   adjacent shell edges.                                           */
10269                 uninfect( testtri );
10270                 if ( verbose > 2 ) {
10271                         /* Assign the triangle an orientation for convenience in */
10272                         /*   checking its points.                                */
10273                         testtri.orient = 0;
10274                         org( testtri, deadorg );
10275                         dest( testtri, deaddest );
10276                         apex( testtri, deadapex );
10277                         printf( "    Checking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
10278                                         deadorg[0], deadorg[1], deaddest[0], deaddest[1],
10279                                         deadapex[0], deadapex[1] );
10280                 }
10281                 /* Check each of the triangle's three neighbors. */
10282                 for ( testtri.orient = 0; testtri.orient < 3; testtri.orient++ ) {
10283                         /* Find the neighbor. */
10284                         sym( testtri, neighbor );
10285                         /* Check for a shell between the triangle and its neighbor. */
10286                         tspivot( testtri, neighborshelle );
10287                         /* Check if the neighbor is nonexistent or already infected. */
10288                         if ( ( neighbor.tri == dummytri ) || infected( neighbor ) ) {
10289                                 if ( neighborshelle.sh != dummysh ) {
10290                                         /* There is a shell edge separating the triangle from its */
10291                                         /*   neighbor, but both triangles are dying, so the shell */
10292                                         /*   edge dies too.                                       */
10293                                         shelledealloc( neighborshelle.sh );
10294                                         if ( neighbor.tri != dummytri ) {
10295                                                 /* Make sure the shell edge doesn't get deallocated again */
10296                                                 /*   later when the infected neighbor is visited.         */
10297                                                 uninfect( neighbor );
10298                                                 tsdissolve( neighbor );
10299                                                 infect( neighbor );
10300                                         }
10301                                 }
10302                         }
10303                         else {               /* The neighbor exists and is not infected. */
10304                                 if ( neighborshelle.sh == dummysh ) {
10305                                         /* There is no shell edge protecting the neighbor, so */
10306                                         /*   the neighbor becomes infected.                   */
10307                                         if ( verbose > 2 ) {
10308                                                 org( neighbor, deadorg );
10309                                                 dest( neighbor, deaddest );
10310                                                 apex( neighbor, deadapex );
10311                                                 printf(
10312                                                         "    Marking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
10313                                                         deadorg[0], deadorg[1], deaddest[0], deaddest[1],
10314                                                         deadapex[0], deadapex[1] );
10315                                         }
10316                                         infect( neighbor );
10317                                         /* Ensure that the neighbor's neighbors will be infected. */
10318                                         deadtri = (triangle **) poolalloc( &viri );
10319                                         *deadtri = neighbor.tri;
10320                                 }
10321                                 else {         /* The neighbor is protected by a shell edge. */
10322                                         /* Remove this triangle from the shell edge. */
10323                                         stdissolve( neighborshelle );
10324                                         /* The shell edge becomes a boundary.  Set markers accordingly. */
10325                                         if ( mark( neighborshelle ) == 0 ) {
10326                                                 setmark( neighborshelle, 1 );
10327                                         }
10328                                         org( neighbor, norg );
10329                                         dest( neighbor, ndest );
10330                                         if ( pointmark( norg ) == 0 ) {
10331                                                 setpointmark( norg, 1 );
10332                                         }
10333                                         if ( pointmark( ndest ) == 0 ) {
10334                                                 setpointmark( ndest, 1 );
10335                                         }
10336                                 }
10337                         }
10338                 }
10339                 /* Remark the triangle as infected, so it doesn't get added to the */
10340                 /*   virus pool again.                                             */
10341                 infect( testtri );
10342                 virusloop = (triangle **) traverse( &viri );
10343         }
10344
10345         if ( verbose ) {
10346                 printf( "  Deleting marked triangles.\n" );
10347         }
10348         traversalinit( &viri );
10349         virusloop = (triangle **) traverse( &viri );
10350         while ( virusloop != (triangle **) NULL ) {
10351                 testtri.tri = *virusloop;
10352
10353                 /* Check each of the three corners of the triangle for elimination. */
10354                 /*   This is done by walking around each point, checking if it is   */
10355                 /*   still connected to at least one live triangle.                 */
10356                 for ( testtri.orient = 0; testtri.orient < 3; testtri.orient++ ) {
10357                         org( testtri, testpoint );
10358                         /* Check if the point has already been tested. */
10359                         if ( testpoint != (point) NULL ) {
10360                                 killorg = 1;
10361                                 /* Mark the corner of the triangle as having been tested. */
10362                                 setorg( testtri, NULL );
10363                                 /* Walk counterclockwise about the point. */
10364                                 onext( testtri, neighbor );
10365                                 /* Stop upon reaching a boundary or the starting triangle. */
10366                                 while ( ( neighbor.tri != dummytri )
10367                                                 && ( !triedgeequal( neighbor, testtri ) ) ) {
10368                                         if ( infected( neighbor ) ) {
10369                                                 /* Mark the corner of this triangle as having been tested. */
10370                                                 setorg( neighbor, NULL );
10371                                         }
10372                                         else {
10373                                                 /* A live triangle.  The point survives. */
10374                                                 killorg = 0;
10375                                         }
10376                                         /* Walk counterclockwise about the point. */
10377                                         onextself( neighbor );
10378                                 }
10379                                 /* If we reached a boundary, we must walk clockwise as well. */
10380                                 if ( neighbor.tri == dummytri ) {
10381                                         /* Walk clockwise about the point. */
10382                                         oprev( testtri, neighbor );
10383                                         /* Stop upon reaching a boundary. */
10384                                         while ( neighbor.tri != dummytri ) {
10385                                                 if ( infected( neighbor ) ) {
10386                                                         /* Mark the corner of this triangle as having been tested. */
10387                                                         setorg( neighbor, NULL );
10388                                                 }
10389                                                 else {
10390                                                         /* A live triangle.  The point survives. */
10391                                                         killorg = 0;
10392                                                 }
10393                                                 /* Walk clockwise about the point. */
10394                                                 oprevself( neighbor );
10395                                         }
10396                                 }
10397                                 if ( killorg ) {
10398                                         if ( verbose > 1 ) {
10399                                                 printf( "    Deleting point (%.12g, %.12g)\n",
10400                                                                 testpoint[0], testpoint[1] );
10401                                         }
10402                                         pointdealloc( testpoint );
10403                                 }
10404                         }
10405                 }
10406
10407                 /* Record changes in the number of boundary edges, and disconnect */
10408                 /*   dead triangles from their neighbors.                         */
10409                 for ( testtri.orient = 0; testtri.orient < 3; testtri.orient++ ) {
10410                         sym( testtri, neighbor );
10411                         if ( neighbor.tri == dummytri ) {
10412                                 /* There is no neighboring triangle on this edge, so this edge    */
10413                                 /*   is a boundary edge.  This triangle is being deleted, so this */
10414                                 /*   boundary edge is deleted.                                    */
10415                                 hullsize--;
10416                         }
10417                         else {
10418                                 /* Disconnect the triangle from its neighbor. */
10419                                 dissolve( neighbor );
10420                                 /* There is a neighboring triangle on this edge, so this edge */
10421                                 /*   becomes a boundary edge when this triangle is deleted.   */
10422                                 hullsize++;
10423                         }
10424                 }
10425                 /* Return the dead triangle to the pool of triangles. */
10426                 triangledealloc( testtri.tri );
10427                 virusloop = (triangle **) traverse( &viri );
10428         }
10429         /* Empty the virus pool. */
10430         poolrestart( &viri );
10431 }
10432
10433 /*****************************************************************************/
10434 /*                                                                           */
10435 /*  regionplague()   Spread regional attributes and/or area constraints      */
10436 /*                   (from a .poly file) throughout the mesh.                */
10437 /*                                                                           */
10438 /*  This procedure operates in two phases.  The first phase spreads an       */
10439 /*  attribute and/or an area constraint through a (segment-bounded) region.  */
10440 /*  The triangles are marked to ensure that each triangle is added to the    */
10441 /*  virus pool only once, so the procedure will terminate.                   */
10442 /*                                                                           */
10443 /*  The second phase uninfects all infected triangles, returning them to     */
10444 /*  normal.                                                                  */
10445 /*                                                                           */
10446 /*****************************************************************************/
10447
10448 void regionplague( attribute, area )
10449 REAL attribute;
10450 REAL area;
10451 {
10452         struct triedge testtri;
10453         struct triedge neighbor;
10454         triangle **virusloop;
10455         triangle **regiontri;
10456         struct edge neighborshelle;
10457         point regionorg, regiondest, regionapex;
10458         triangle ptr;           /* Temporary variable used by sym() and onext(). */
10459         shelle sptr;                    /* Temporary variable used by tspivot(). */
10460
10461         if ( verbose > 1 ) {
10462                 printf( "  Marking neighbors of marked triangles.\n" );
10463         }
10464         /* Loop through all the infected triangles, spreading the attribute      */
10465         /*   and/or area constraint to their neighbors, then to their neighbors' */
10466         /*   neighbors.                                                          */
10467         traversalinit( &viri );
10468         virusloop = (triangle **) traverse( &viri );
10469         while ( virusloop != (triangle **) NULL ) {
10470                 testtri.tri = *virusloop;
10471                 /* A triangle is marked as infected by messing with one of its shell */
10472                 /*   edges, setting it to an illegal value.  Hence, we have to       */
10473                 /*   temporarily uninfect this triangle so that we can examine its   */
10474                 /*   adjacent shell edges.                                           */
10475                 uninfect( testtri );
10476                 if ( regionattrib ) {
10477                         /* Set an attribute. */
10478                         setelemattribute( testtri, eextras, attribute );
10479                 }
10480                 if ( vararea ) {
10481                         /* Set an area constraint. */
10482                         setareabound( testtri, area );
10483                 }
10484                 if ( verbose > 2 ) {
10485                         /* Assign the triangle an orientation for convenience in */
10486                         /*   checking its points.                                */
10487                         testtri.orient = 0;
10488                         org( testtri, regionorg );
10489                         dest( testtri, regiondest );
10490                         apex( testtri, regionapex );
10491                         printf( "    Checking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
10492                                         regionorg[0], regionorg[1], regiondest[0], regiondest[1],
10493                                         regionapex[0], regionapex[1] );
10494                 }
10495                 /* Check each of the triangle's three neighbors. */
10496                 for ( testtri.orient = 0; testtri.orient < 3; testtri.orient++ ) {
10497                         /* Find the neighbor. */
10498                         sym( testtri, neighbor );
10499                         /* Check for a shell between the triangle and its neighbor. */
10500                         tspivot( testtri, neighborshelle );
10501                         /* Make sure the neighbor exists, is not already infected, and */
10502                         /*   isn't protected by a shell edge.                          */
10503                         if ( ( neighbor.tri != dummytri ) && !infected( neighbor )
10504                                  && ( neighborshelle.sh == dummysh ) ) {
10505                                 if ( verbose > 2 ) {
10506                                         org( neighbor, regionorg );
10507                                         dest( neighbor, regiondest );
10508                                         apex( neighbor, regionapex );
10509                                         printf( "    Marking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
10510                                                         regionorg[0], regionorg[1], regiondest[0], regiondest[1],
10511                                                         regionapex[0], regionapex[1] );
10512                                 }
10513                                 /* Infect the neighbor. */
10514                                 infect( neighbor );
10515                                 /* Ensure that the neighbor's neighbors will be infected. */
10516                                 regiontri = (triangle **) poolalloc( &viri );
10517                                 *regiontri = neighbor.tri;
10518                         }
10519                 }
10520                 /* Remark the triangle as infected, so it doesn't get added to the */
10521                 /*   virus pool again.                                             */
10522                 infect( testtri );
10523                 virusloop = (triangle **) traverse( &viri );
10524         }
10525
10526         /* Uninfect all triangles. */
10527         if ( verbose > 1 ) {
10528                 printf( "  Unmarking marked triangles.\n" );
10529         }
10530         traversalinit( &viri );
10531         virusloop = (triangle **) traverse( &viri );
10532         while ( virusloop != (triangle **) NULL ) {
10533                 testtri.tri = *virusloop;
10534                 uninfect( testtri );
10535                 virusloop = (triangle **) traverse( &viri );
10536         }
10537         /* Empty the virus pool. */
10538         poolrestart( &viri );
10539 }
10540
10541 /*****************************************************************************/
10542 /*                                                                           */
10543 /*  carveholes()   Find the holes and infect them.  Find the area            */
10544 /*                 constraints and infect them.  Infect the convex hull.     */
10545 /*                 Spread the infection and kill triangles.  Spread the      */
10546 /*                 area constraints.                                         */
10547 /*                                                                           */
10548 /*  This routine mainly calls other routines to carry out all these          */
10549 /*  functions.                                                               */
10550 /*                                                                           */
10551 /*****************************************************************************/
10552
10553 void carveholes( holelist, holes, regionlist, regions )
10554 REAL * holelist;
10555 int holes;
10556 REAL *regionlist;
10557 int regions;
10558 {
10559         struct triedge searchtri;
10560         struct triedge triangleloop;
10561         struct triedge *regiontris;
10562         triangle **holetri;
10563         triangle **regiontri;
10564         point searchorg, searchdest;
10565         enum locateresult intersect;
10566         int i;
10567         triangle ptr;                       /* Temporary variable used by sym(). */
10568
10569         if ( !( quiet || ( noholes && convex ) ) ) {
10570                 printf( "Removing unwanted triangles.\n" );
10571                 if ( verbose && ( holes > 0 ) ) {
10572                         printf( "  Marking holes for elimination.\n" );
10573                 }
10574         }
10575
10576         if ( regions > 0 ) {
10577                 /* Allocate storage for the triangles in which region points fall. */
10578                 regiontris = (struct triedge *) malloc( regions * sizeof( struct triedge ) );
10579                 if ( regiontris == (struct triedge *) NULL ) {
10580                         printf( "Error:  Out of memory.\n" );
10581                         exit( 1 );
10582                 }
10583         }
10584
10585         if ( ( ( holes > 0 ) && !noholes ) || !convex || ( regions > 0 ) ) {
10586                 /* Initialize a pool of viri to be used for holes, concavities, */
10587                 /*   regional attributes, and/or regional area constraints.     */
10588                 poolinit( &viri, sizeof( triangle * ), VIRUSPERBLOCK, POINTER, 0 );
10589         }
10590
10591         if ( !convex ) {
10592                 /* Mark as infected any unprotected triangles on the boundary. */
10593                 /*   This is one way by which concavities are created.         */
10594                 infecthull();
10595         }
10596
10597         if ( ( holes > 0 ) && !noholes ) {
10598                 /* Infect each triangle in which a hole lies. */
10599                 for ( i = 0; i < 2 * holes; i += 2 ) {
10600                         /* Ignore holes that aren't within the bounds of the mesh. */
10601                         if ( ( holelist[i] >= xmin ) && ( holelist[i] <= xmax )
10602                                  && ( holelist[i + 1] >= ymin ) && ( holelist[i + 1] <= ymax ) ) {
10603                                 /* Start searching from some triangle on the outer boundary. */
10604                                 searchtri.tri = dummytri;
10605                                 searchtri.orient = 0;
10606                                 symself( searchtri );
10607                                 /* Ensure that the hole is to the left of this boundary edge; */
10608                                 /*   otherwise, locate() will falsely report that the hole    */
10609                                 /*   falls within the starting triangle.                      */
10610                                 org( searchtri, searchorg );
10611                                 dest( searchtri, searchdest );
10612                                 if ( counterclockwise( searchorg, searchdest, &holelist[i] ) > 0.0 ) {
10613                                         /* Find a triangle that contains the hole. */
10614                                         intersect = locate( &holelist[i], &searchtri );
10615                                         if ( ( intersect != OUTSIDE ) && ( !infected( searchtri ) ) ) {
10616                                                 /* Infect the triangle.  This is done by marking the triangle */
10617                                                 /*   as infect and including the triangle in the virus pool.  */
10618                                                 infect( searchtri );
10619                                                 holetri = (triangle **) poolalloc( &viri );
10620                                                 *holetri = searchtri.tri;
10621                                         }
10622                                 }
10623                         }
10624                 }
10625         }
10626
10627         /* Now, we have to find all the regions BEFORE we carve the holes, because */
10628         /*   locate() won't work when the triangulation is no longer convex.       */
10629         /*   (Incidentally, this is the reason why regional attributes and area    */
10630         /*   constraints can't be used when refining a preexisting mesh, which     */
10631         /*   might not be convex; they can only be used with a freshly             */
10632         /*   triangulated PSLG.)                                                   */
10633         if ( regions > 0 ) {
10634                 /* Find the starting triangle for each region. */
10635                 for ( i = 0; i < regions; i++ ) {
10636                         regiontris[i].tri = dummytri;
10637                         /* Ignore region points that aren't within the bounds of the mesh. */
10638                         if ( ( regionlist[4 * i] >= xmin ) && ( regionlist[4 * i] <= xmax ) &&
10639                                  ( regionlist[4 * i + 1] >= ymin ) && ( regionlist[4 * i + 1] <= ymax ) ) {
10640                                 /* Start searching from some triangle on the outer boundary. */
10641                                 searchtri.tri = dummytri;
10642                                 searchtri.orient = 0;
10643                                 symself( searchtri );
10644                                 /* Ensure that the region point is to the left of this boundary */
10645                                 /*   edge; otherwise, locate() will falsely report that the     */
10646                                 /*   region point falls within the starting triangle.           */
10647                                 org( searchtri, searchorg );
10648                                 dest( searchtri, searchdest );
10649                                 if ( counterclockwise( searchorg, searchdest, &regionlist[4 * i] ) >
10650                                          0.0 ) {
10651                                         /* Find a triangle that contains the region point. */
10652                                         intersect = locate( &regionlist[4 * i], &searchtri );
10653                                         if ( ( intersect != OUTSIDE ) && ( !infected( searchtri ) ) ) {
10654                                                 /* Record the triangle for processing after the */
10655                                                 /*   holes have been carved.                    */
10656                                                 triedgecopy( searchtri, regiontris[i] );
10657                                         }
10658                                 }
10659                         }
10660                 }
10661         }
10662
10663         if ( viri.items > 0 ) {
10664                 /* Carve the holes and concavities. */
10665                 plague();
10666         }
10667         /* The virus pool should be empty now. */
10668
10669         if ( regions > 0 ) {
10670                 if ( !quiet ) {
10671                         if ( regionattrib ) {
10672                                 if ( vararea ) {
10673                                         printf( "Spreading regional attributes and area constraints.\n" );
10674                                 }
10675                                 else {
10676                                         printf( "Spreading regional attributes.\n" );
10677                                 }
10678                         }
10679                         else {
10680                                 printf( "Spreading regional area constraints.\n" );
10681                         }
10682                 }
10683                 if ( regionattrib && !refine ) {
10684                         /* Assign every triangle a regional attribute of zero. */
10685                         traversalinit( &triangles );
10686                         triangleloop.orient = 0;
10687                         triangleloop.tri = triangletraverse();
10688                         while ( triangleloop.tri != (triangle *) NULL ) {
10689                                 setelemattribute( triangleloop, eextras, 0.0 );
10690                                 triangleloop.tri = triangletraverse();
10691                         }
10692                 }
10693                 for ( i = 0; i < regions; i++ ) {
10694                         if ( regiontris[i].tri != dummytri ) {
10695                                 /* Make sure the triangle under consideration still exists. */
10696                                 /*   It may have been eaten by the virus.                   */
10697                                 if ( regiontris[i].tri[3] != (triangle) NULL ) {
10698                                         /* Put one triangle in the virus pool. */
10699                                         infect( regiontris[i] );
10700                                         regiontri = (triangle **) poolalloc( &viri );
10701                                         *regiontri = regiontris[i].tri;
10702                                         /* Apply one region's attribute and/or area constraint. */
10703                                         regionplague( regionlist[4 * i + 2], regionlist[4 * i + 3] );
10704                                         /* The virus pool should be empty now. */
10705                                 }
10706                         }
10707                 }
10708                 if ( regionattrib && !refine ) {
10709                         /* Note the fact that each triangle has an additional attribute. */
10710                         eextras++;
10711                 }
10712         }
10713
10714         /* Free up memory. */
10715         if ( ( ( holes > 0 ) && !noholes ) || !convex || ( regions > 0 ) ) {
10716                 pooldeinit( &viri );
10717         }
10718         if ( regions > 0 ) {
10719                 free( regiontris );
10720         }
10721 }
10722
10723 /**                                                                         **/
10724 /**                                                                         **/
10725 /********* Carving out holes and concavities ends here               *********/
10726
10727 /********* Mesh quality maintenance begins here                      *********/
10728 /**                                                                         **/
10729 /**                                                                         **/
10730
10731 /*****************************************************************************/
10732 /*                                                                           */
10733 /*  tallyencs()   Traverse the entire list of shell edges, check each edge   */
10734 /*                to see if it is encroached.  If so, add it to the list.    */
10735 /*                                                                           */
10736 /*****************************************************************************/
10737
10738 #ifndef CDT_ONLY
10739
10740 void tallyencs(){
10741         struct edge edgeloop;
10742         int dummy;
10743
10744         traversalinit( &shelles );
10745         edgeloop.shorient = 0;
10746         edgeloop.sh = shelletraverse();
10747         while ( edgeloop.sh != (shelle *) NULL ) {
10748                 /* If the segment is encroached, add it to the list. */
10749                 dummy = checkedge4encroach( &edgeloop );
10750                 edgeloop.sh = shelletraverse();
10751         }
10752 }
10753
10754 #endif /* not CDT_ONLY */
10755
10756 /*****************************************************************************/
10757 /*                                                                           */
10758 /*  precisionerror()  Print an error message for precision problems.         */
10759 /*                                                                           */
10760 /*****************************************************************************/
10761
10762 #ifndef CDT_ONLY
10763
10764 void precisionerror(){
10765         printf( "Try increasing the area criterion and/or reducing the minimum\n" );
10766         printf( "  allowable angle so that tiny triangles are not created.\n" );
10767 #ifdef SINGLE
10768         printf( "Alternatively, try recompiling me with double precision\n" );
10769         printf( "  arithmetic (by removing \"#define SINGLE\" from the\n" );
10770         printf( "  source file or \"-DSINGLE\" from the makefile).\n" );
10771 #endif /* SINGLE */
10772 }
10773
10774 #endif /* not CDT_ONLY */
10775
10776 /*****************************************************************************/
10777 /*                                                                           */
10778 /*  repairencs()   Find and repair all the encroached segments.              */
10779 /*                                                                           */
10780 /*  Encroached segments are repaired by splitting them by inserting a point  */
10781 /*  at or near their centers.                                                */
10782 /*                                                                           */
10783 /*  `flaws' is a flag that specifies whether one should take note of new     */
10784 /*  encroached segments and bad triangles that result from inserting points  */
10785 /*  to repair existing encroached segments.                                  */
10786 /*                                                                           */
10787 /*  When a segment is split, the two resulting subsegments are always        */
10788 /*  tested to see if they are encroached upon, regardless of the value       */
10789 /*  of `flaws'.                                                              */
10790 /*                                                                           */
10791 /*****************************************************************************/
10792
10793 #ifndef CDT_ONLY
10794
10795 void repairencs( flaws )
10796 int flaws;
10797 {
10798         struct triedge enctri;
10799         struct triedge testtri;
10800         struct edge *encloop;
10801         struct edge testsh;
10802         point eorg, edest;
10803         point newpoint;
10804         enum insertsiteresult success;
10805         REAL segmentlength, nearestpoweroftwo;
10806         REAL split;
10807         int acuteorg, acutedest;
10808         int dummy;
10809         int i;
10810         triangle ptr;                   /* Temporary variable used by stpivot(). */
10811         shelle sptr;                      /* Temporary variable used by snext(). */
10812
10813         while ( ( badsegments.items > 0 ) && ( steinerleft != 0 ) ) {
10814                 traversalinit( &badsegments );
10815                 encloop = badsegmenttraverse();
10816                 while ( ( encloop != (struct edge *) NULL ) && ( steinerleft != 0 ) ) {
10817                         /* To decide where to split a segment, we need to know if the  */
10818                         /*   segment shares an endpoint with an adjacent segment.      */
10819                         /*   The concern is that, if we simply split every encroached  */
10820                         /*   segment in its center, two adjacent segments with a small */
10821                         /*   angle between them might lead to an infinite loop; each   */
10822                         /*   point added to split one segment will encroach upon the   */
10823                         /*   other segment, which must then be split with a point that */
10824                         /*   will encroach upon the first segment, and so on forever.  */
10825                         /* To avoid this, imagine a set of concentric circles, whose   */
10826                         /*   radii are powers of two, about each segment endpoint.     */
10827                         /*   These concentric circles determine where the segment is   */
10828                         /*   split.  (If both endpoints are shared with adjacent       */
10829                         /*   segments, split the segment in the middle, and apply the  */
10830                         /*   concentric shells for later splittings.)                  */
10831
10832                         /* Is the origin shared with another segment? */
10833                         stpivot( *encloop, enctri );
10834                         lnext( enctri, testtri );
10835                         tspivot( testtri, testsh );
10836                         acuteorg = testsh.sh != dummysh;
10837                         /* Is the destination shared with another segment? */
10838                         lnextself( testtri );
10839                         tspivot( testtri, testsh );
10840                         acutedest = testsh.sh != dummysh;
10841                         /* Now, check the other side of the segment, if there's a triangle */
10842                         /*   there.                                                        */
10843                         sym( enctri, testtri );
10844                         if ( testtri.tri != dummytri ) {
10845                                 /* Is the destination shared with another segment? */
10846                                 lnextself( testtri );
10847                                 tspivot( testtri, testsh );
10848                                 acutedest = acutedest || ( testsh.sh != dummysh );
10849                                 /* Is the origin shared with another segment? */
10850                                 lnextself( testtri );
10851                                 tspivot( testtri, testsh );
10852                                 acuteorg = acuteorg || ( testsh.sh != dummysh );
10853                         }
10854
10855                         sorg( *encloop, eorg );
10856                         sdest( *encloop, edest );
10857                         /* Use the concentric circles if exactly one endpoint is shared */
10858                         /*   with another adjacent segment.                             */
10859                         if ( acuteorg ^ acutedest ) {
10860                                 segmentlength = sqrt( ( edest[0] - eorg[0] ) * ( edest[0] - eorg[0] )
10861                                                                           + ( edest[1] - eorg[1] ) * ( edest[1] - eorg[1] ) );
10862                                 /* Find the power of two nearest the segment's length. */
10863                                 nearestpoweroftwo = 1.0;
10864                                 while ( segmentlength > SQUAREROOTTWO * nearestpoweroftwo ) {
10865                                         nearestpoweroftwo *= 2.0;
10866                                 }
10867                                 while ( segmentlength < ( 0.5 * SQUAREROOTTWO ) * nearestpoweroftwo ) {
10868                                         nearestpoweroftwo *= 0.5;
10869                                 }
10870                                 /* Where do we split the segment? */
10871                                 split = 0.5 * nearestpoweroftwo / segmentlength;
10872                                 if ( acutedest ) {
10873                                         split = 1.0 - split;
10874                                 }
10875                         }
10876                         else {
10877                                 /* If we're not worried about adjacent segments, split */
10878                                 /*   this segment in the middle.                       */
10879                                 split = 0.5;
10880                         }
10881
10882                         /* Create the new point. */
10883                         newpoint = (point) poolalloc( &points );
10884                         /* Interpolate its coordinate and attributes. */
10885                         for ( i = 0; i < 2 + nextras; i++ ) {
10886                                 newpoint[i] = ( 1.0 - split ) * eorg[i] + split * edest[i];
10887                         }
10888                         setpointmark( newpoint, mark( *encloop ) );
10889                         if ( verbose > 1 ) {
10890                                 printf(
10891                                         "  Splitting edge (%.12g, %.12g) (%.12g, %.12g) at (%.12g, %.12g).\n",
10892                                         eorg[0], eorg[1], edest[0], edest[1], newpoint[0], newpoint[1] );
10893                         }
10894                         /* Check whether the new point lies on an endpoint. */
10895                         if ( ( ( newpoint[0] == eorg[0] ) && ( newpoint[1] == eorg[1] ) )
10896                                  || ( ( newpoint[0] == edest[0] ) && ( newpoint[1] == edest[1] ) ) ) {
10897                                 printf( "Error:  Ran out of precision at (%.12g, %.12g).\n",
10898                                                 newpoint[0], newpoint[1] );
10899                                 printf( "I attempted to split a segment to a smaller size than can\n" );
10900                                 printf( "  be accommodated by the finite precision of floating point\n"
10901                                                 );
10902                                 printf( "  arithmetic.\n" );
10903                                 precisionerror();
10904                                 exit( 1 );
10905                         }
10906                         /* Insert the splitting point.  This should always succeed. */
10907                         success = insertsite( newpoint, &enctri, encloop, flaws, flaws );
10908                         if ( ( success != SUCCESSFULPOINT ) && ( success != ENCROACHINGPOINT ) ) {
10909                                 printf( "Internal error in repairencs():\n" );
10910                                 printf( "  Failure to split a segment.\n" );
10911                                 internalerror();
10912                         }
10913                         if ( steinerleft > 0 ) {
10914                                 steinerleft--;
10915                         }
10916                         /* Check the two new subsegments to see if they're encroached. */
10917                         dummy = checkedge4encroach( encloop );
10918                         snextself( *encloop );
10919                         dummy = checkedge4encroach( encloop );
10920
10921                         badsegmentdealloc( encloop );
10922                         encloop = badsegmenttraverse();
10923                 }
10924         }
10925 }
10926
10927 #endif /* not CDT_ONLY */
10928
10929 /*****************************************************************************/
10930 /*                                                                           */
10931 /*  tallyfaces()   Test every triangle in the mesh for quality measures.     */
10932 /*                                                                           */
10933 /*****************************************************************************/
10934
10935 #ifndef CDT_ONLY
10936
10937 void tallyfaces(){
10938         struct triedge triangleloop;
10939
10940         if ( verbose ) {
10941                 printf( "  Making a list of bad triangles.\n" );
10942         }
10943         traversalinit( &triangles );
10944         triangleloop.orient = 0;
10945         triangleloop.tri = triangletraverse();
10946         while ( triangleloop.tri != (triangle *) NULL ) {
10947                 /* If the triangle is bad, enqueue it. */
10948                 testtriangle( &triangleloop );
10949                 triangleloop.tri = triangletraverse();
10950         }
10951 }
10952
10953 #endif /* not CDT_ONLY */
10954
10955 /*****************************************************************************/
10956 /*                                                                           */
10957 /*  findcircumcenter()   Find the circumcenter of a triangle.                */
10958 /*                                                                           */
10959 /*  The result is returned both in terms of x-y coordinates and xi-eta       */
10960 /*  coordinates.  The xi-eta coordinate system is defined in terms of the    */
10961 /*  triangle:  the origin of the triangle is the origin of the coordinate    */
10962 /*  system; the destination of the triangle is one unit along the xi axis;   */
10963 /*  and the apex of the triangle is one unit along the eta axis.             */
10964 /*                                                                           */
10965 /*  The return value indicates which edge of the triangle is shortest.       */
10966 /*                                                                           */
10967 /*****************************************************************************/
10968
10969 enum circumcenterresult findcircumcenter( torg, tdest, tapex, circumcenter,
10970                                                                                   xi, eta )
10971 point torg;
10972 point tdest;
10973 point tapex;
10974 point circumcenter;
10975 REAL *xi;
10976 REAL *eta;
10977 {
10978         REAL xdo, ydo, xao, yao, xad, yad;
10979         REAL dodist, aodist, addist;
10980         REAL denominator;
10981         REAL dx, dy;
10982
10983         circumcentercount++;
10984
10985         /* Compute the circumcenter of the triangle. */
10986         xdo = tdest[0] - torg[0];
10987         ydo = tdest[1] - torg[1];
10988         xao = tapex[0] - torg[0];
10989         yao = tapex[1] - torg[1];
10990         dodist = xdo * xdo + ydo * ydo;
10991         aodist = xao * xao + yao * yao;
10992         if ( noexact ) {
10993                 denominator = (REAL)( 0.5 / ( xdo * yao - xao * ydo ) );
10994         }
10995         else {
10996                 /* Use the counterclockwise() routine to ensure a positive (and */
10997                 /*   reasonably accurate) result, avoiding any possibility of   */
10998                 /*   division by zero.                                          */
10999                 denominator = (REAL)( 0.5 / counterclockwise( tdest, tapex, torg ) );
11000                 /* Don't count the above as an orientation test. */
11001                 counterclockcount--;
11002         }
11003         circumcenter[0] = torg[0] - ( ydo * aodist - yao * dodist ) * denominator;
11004         circumcenter[1] = torg[1] + ( xdo * aodist - xao * dodist ) * denominator;
11005
11006         /* To interpolate point attributes for the new point inserted at  */
11007         /*   the circumcenter, define a coordinate system with a xi-axis, */
11008         /*   directed from the triangle's origin to its destination, and  */
11009         /*   an eta-axis, directed from its origin to its apex.           */
11010         /*   Calculate the xi and eta coordinates of the circumcenter.    */
11011         dx = circumcenter[0] - torg[0];
11012         dy = circumcenter[1] - torg[1];
11013         *xi = (REAL)( ( dx * yao - xao * dy ) * ( 2.0 * denominator ) );
11014         *eta = (REAL)( ( xdo * dy - dx * ydo ) * ( 2.0 * denominator ) );
11015
11016         xad = tapex[0] - tdest[0];
11017         yad = tapex[1] - tdest[1];
11018         addist = xad * xad + yad * yad;
11019         if ( ( addist < dodist ) && ( addist < aodist ) ) {
11020                 return OPPOSITEORG;
11021         }
11022         else if ( dodist < aodist ) {
11023                 return OPPOSITEAPEX;
11024         }
11025         else {
11026                 return OPPOSITEDEST;
11027         }
11028 }
11029
11030 /*****************************************************************************/
11031 /*                                                                           */
11032 /*  splittriangle()   Inserts a point at the circumcenter of a triangle.     */
11033 /*                    Deletes the newly inserted point if it encroaches upon */
11034 /*                    a segment.                                             */
11035 /*                                                                           */
11036 /*****************************************************************************/
11037
11038 #ifndef CDT_ONLY
11039
11040 void splittriangle( badtri )
11041 struct badface *badtri;
11042 {
11043         point borg, bdest, bapex;
11044         point newpoint;
11045         REAL xi, eta;
11046         enum insertsiteresult success;
11047         enum circumcenterresult shortedge;
11048         int errorflag;
11049         int i;
11050
11051         org( badtri->badfacetri, borg );
11052         dest( badtri->badfacetri, bdest );
11053         apex( badtri->badfacetri, bapex );
11054         /* Make sure that this triangle is still the same triangle it was      */
11055         /*   when it was tested and determined to be of bad quality.           */
11056         /*   Subsequent transformations may have made it a different triangle. */
11057         if ( ( borg == badtri->faceorg ) && ( bdest == badtri->facedest ) &&
11058                  ( bapex == badtri->faceapex ) ) {
11059                 if ( verbose > 1 ) {
11060                         printf( "  Splitting this triangle at its circumcenter:\n" );
11061                         printf( "    (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n", borg[0],
11062                                         borg[1], bdest[0], bdest[1], bapex[0], bapex[1] );
11063                 }
11064                 errorflag = 0;
11065                 /* Create a new point at the triangle's circumcenter. */
11066                 newpoint = (point) poolalloc( &points );
11067                 shortedge = findcircumcenter( borg, bdest, bapex, newpoint, &xi, &eta );
11068                 /* Check whether the new point lies on a triangle vertex. */
11069                 if ( ( ( newpoint[0] == borg[0] ) && ( newpoint[1] == borg[1] ) )
11070                          || ( ( newpoint[0] == bdest[0] ) && ( newpoint[1] == bdest[1] ) )
11071                          || ( ( newpoint[0] == bapex[0] ) && ( newpoint[1] == bapex[1] ) ) ) {
11072                         if ( !quiet ) {
11073                                 printf( "Warning:  New point (%.12g, %.12g) falls on existing vertex.\n"
11074                                                 , newpoint[0], newpoint[1] );
11075                                 errorflag = 1;
11076                         }
11077                         pointdealloc( newpoint );
11078                 }
11079                 else {
11080                         for ( i = 2; i < 2 + nextras; i++ ) {
11081                                 /* Interpolate the point attributes at the circumcenter. */
11082                                 newpoint[i] = borg[i] + xi * ( bdest[i] - borg[i] )
11083                                                           + eta * ( bapex[i] - borg[i] );
11084                         }
11085                         /* The new point must be in the interior, and have a marker of zero. */
11086                         setpointmark( newpoint, 0 );
11087                         /* Ensure that the handle `badtri->badfacetri' represents the shortest */
11088                         /*   edge of the triangle.  This ensures that the circumcenter must    */
11089                         /*   fall to the left of this edge, so point location will work.       */
11090                         if ( shortedge == OPPOSITEORG ) {
11091                                 lnextself( badtri->badfacetri );
11092                         }
11093                         else if ( shortedge == OPPOSITEDEST ) {
11094                                 lprevself( badtri->badfacetri );
11095                         }
11096                         /* Insert the circumcenter, searching from the edge of the triangle, */
11097                         /*   and maintain the Delaunay property of the triangulation.        */
11098                         success = insertsite( newpoint, &( badtri->badfacetri ),
11099                                                                   (struct edge *) NULL, 1, 1 );
11100                         if ( success == SUCCESSFULPOINT ) {
11101                                 if ( steinerleft > 0 ) {
11102                                         steinerleft--;
11103                                 }
11104                         }
11105                         else if ( success == ENCROACHINGPOINT ) {
11106                                 /* If the newly inserted point encroaches upon a segment, delete it. */
11107                                 deletesite( &( badtri->badfacetri ) );
11108                         }
11109                         else if ( success == VIOLATINGPOINT ) {
11110                                 /* Failed to insert the new point, but some segment was */
11111                                 /*   marked as being encroached.                        */
11112                                 pointdealloc( newpoint );
11113                         }
11114                         else {                              /* success == DUPLICATEPOINT */
11115                                 /* Failed to insert the new point because a vertex is already there. */
11116                                 if ( !quiet ) {
11117                                         printf(
11118                                                 "Warning:  New point (%.12g, %.12g) falls on existing vertex.\n"
11119                                                 , newpoint[0], newpoint[1] );
11120                                         errorflag = 1;
11121                                 }
11122                                 pointdealloc( newpoint );
11123                         }
11124                 }
11125                 if ( errorflag ) {
11126                         if ( verbose ) {
11127                                 printf( "  The new point is at the circumcenter of triangle\n" );
11128                                 printf( "    (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
11129                                                 borg[0], borg[1], bdest[0], bdest[1], bapex[0], bapex[1] );
11130                         }
11131                         printf( "This probably means that I am trying to refine triangles\n" );
11132                         printf( "  to a smaller size than can be accommodated by the finite\n" );
11133                         printf( "  precision of floating point arithmetic.  (You can be\n" );
11134                         printf( "  sure of this if I fail to terminate.)\n" );
11135                         precisionerror();
11136                 }
11137         }
11138         /* Return the bad triangle to the pool. */
11139         pooldealloc( &badtriangles, (VOID *) badtri );
11140 }
11141
11142 #endif /* not CDT_ONLY */
11143
11144 /*****************************************************************************/
11145 /*                                                                           */
11146 /*  enforcequality()   Remove all the encroached edges and bad triangles     */
11147 /*                     from the triangulation.                               */
11148 /*                                                                           */
11149 /*****************************************************************************/
11150
11151 #ifndef CDT_ONLY
11152
11153 void enforcequality(){
11154         int i;
11155
11156         if ( !quiet ) {
11157                 printf( "Adding Steiner points to enforce quality.\n" );
11158         }
11159         /* Initialize the pool of encroached segments. */
11160         poolinit( &badsegments, sizeof( struct edge ), BADSEGMENTPERBLOCK, POINTER, 0 );
11161         if ( verbose ) {
11162                 printf( "  Looking for encroached segments.\n" );
11163         }
11164         /* Test all segments to see if they're encroached. */
11165         tallyencs();
11166         if ( verbose && ( badsegments.items > 0 ) ) {
11167                 printf( "  Splitting encroached segments.\n" );
11168         }
11169         /* Note that steinerleft == -1 if an unlimited number */
11170         /*   of Steiner points is allowed.                    */
11171         while ( ( badsegments.items > 0 ) && ( steinerleft != 0 ) ) {
11172                 /* Fix the segments without noting newly encroached segments or   */
11173                 /*   bad triangles.  The reason we don't want to note newly       */
11174                 /*   encroached segments is because some encroached segments are  */
11175                 /*   likely to be noted multiple times, and would then be blindly */
11176                 /*   split multiple times.  I should fix that some time.          */
11177                 repairencs( 0 );
11178                 /* Now, find all the segments that became encroached while adding */
11179                 /*   points to split encroached segments.                         */
11180                 tallyencs();
11181         }
11182         /* At this point, if we haven't run out of Steiner points, the */
11183         /*   triangulation should be (conforming) Delaunay.            */
11184
11185         /* Next, we worry about enforcing triangle quality. */
11186         if ( ( minangle > 0.0 ) || vararea || fixedarea ) {
11187                 /* Initialize the pool of bad triangles. */
11188                 poolinit( &badtriangles, sizeof( struct badface ), BADTRIPERBLOCK, POINTER,
11189                                   0 );
11190                 /* Initialize the queues of bad triangles. */
11191                 for ( i = 0; i < 64; i++ ) {
11192                         queuefront[i] = (struct badface *) NULL;
11193                         queuetail[i] = &queuefront[i];
11194                 }
11195                 /* Test all triangles to see if they're bad. */
11196                 tallyfaces();
11197                 if ( verbose ) {
11198                         printf( "  Splitting bad triangles.\n" );
11199                 }
11200                 while ( ( badtriangles.items > 0 ) && ( steinerleft != 0 ) ) {
11201                         /* Fix one bad triangle by inserting a point at its circumcenter. */
11202                         splittriangle( dequeuebadtri() );
11203                         /* Fix any encroached segments that may have resulted.  Record */
11204                         /*   any new bad triangles or encroached segments that result. */
11205                         if ( badsegments.items > 0 ) {
11206                                 repairencs( 1 );
11207                         }
11208                 }
11209         }
11210         /* At this point, if we haven't run out of Steiner points, the */
11211         /*   triangulation should be (conforming) Delaunay and have no */
11212         /*   low-quality triangles.                                    */
11213
11214         /* Might we have run out of Steiner points too soon? */
11215         if ( !quiet && ( badsegments.items > 0 ) && ( steinerleft == 0 ) ) {
11216                 printf( "\nWarning:  I ran out of Steiner points, but the mesh has\n" );
11217                 if ( badsegments.items == 1 ) {
11218                         printf( "  an encroached segment, and therefore might not be truly\n" );
11219                 }
11220                 else {
11221                         printf( "  %ld encroached segments, and therefore might not be truly\n",
11222                                         badsegments.items );
11223                 }
11224                 printf( "  Delaunay.  If the Delaunay property is important to you,\n" );
11225                 printf( "  try increasing the number of Steiner points (controlled by\n" );
11226                 printf( "  the -S switch) slightly and try again.\n\n" );
11227         }
11228 }
11229
11230 #endif /* not CDT_ONLY */
11231
11232 /**                                                                         **/
11233 /**                                                                         **/
11234 /********* Mesh quality maintenance ends here                        *********/
11235
11236 /*****************************************************************************/
11237 /*                                                                           */
11238 /*  highorder()   Create extra nodes for quadratic subparametric elements.   */
11239 /*                                                                           */
11240 /*****************************************************************************/
11241
11242 void highorder(){
11243         struct triedge triangleloop, trisym;
11244         struct edge checkmark;
11245         point newpoint;
11246         point torg, tdest;
11247         int i;
11248         triangle ptr;                       /* Temporary variable used by sym(). */
11249         shelle sptr;                    /* Temporary variable used by tspivot(). */
11250
11251         if ( !quiet ) {
11252                 printf( "Adding vertices for second-order triangles.\n" );
11253         }
11254         /* The following line ensures that dead items in the pool of nodes    */
11255         /*   cannot be allocated for the extra nodes associated with high     */
11256         /*   order elements.  This ensures that the primary nodes (at the     */
11257         /*   corners of elements) will occur earlier in the output files, and */
11258         /*   have lower indices, than the extra nodes.                        */
11259         points.deaditemstack = (VOID *) NULL;
11260
11261         traversalinit( &triangles );
11262         triangleloop.tri = triangletraverse();
11263         /* To loop over the set of edges, loop over all triangles, and look at   */
11264         /*   the three edges of each triangle.  If there isn't another triangle  */
11265         /*   adjacent to the edge, operate on the edge.  If there is another     */
11266         /*   adjacent triangle, operate on the edge only if the current triangle */
11267         /*   has a smaller pointer than its neighbor.  This way, each edge is    */
11268         /*   considered only once.                                               */
11269         while ( triangleloop.tri != (triangle *) NULL ) {
11270                 for ( triangleloop.orient = 0; triangleloop.orient < 3;
11271                           triangleloop.orient++ ) {
11272                         sym( triangleloop, trisym );
11273                         if ( ( triangleloop.tri < trisym.tri ) || ( trisym.tri == dummytri ) ) {
11274                                 org( triangleloop, torg );
11275                                 dest( triangleloop, tdest );
11276                                 /* Create a new node in the middle of the edge.  Interpolate */
11277                                 /*   its attributes.                                         */
11278                                 newpoint = (point) poolalloc( &points );
11279                                 for ( i = 0; i < 2 + nextras; i++ ) {
11280                                         newpoint[i] = (REAL)( 0.5 * ( torg[i] + tdest[i] ) );
11281                                 }
11282                                 /* Set the new node's marker to zero or one, depending on */
11283                                 /*   whether it lies on a boundary.                       */
11284                                 setpointmark( newpoint, trisym.tri == dummytri );
11285                                 if ( useshelles ) {
11286                                         tspivot( triangleloop, checkmark );
11287                                         /* If this edge is a segment, transfer the marker to the new node. */
11288                                         if ( checkmark.sh != dummysh ) {
11289                                                 setpointmark( newpoint, mark( checkmark ) );
11290                                         }
11291                                 }
11292                                 if ( verbose > 1 ) {
11293                                         printf( "  Creating (%.12g, %.12g).\n", newpoint[0], newpoint[1] );
11294                                 }
11295                                 /* Record the new node in the (one or two) adjacent elements. */
11296                                 triangleloop.tri[highorderindex + triangleloop.orient] =
11297                                         (triangle) newpoint;
11298                                 if ( trisym.tri != dummytri ) {
11299                                         trisym.tri[highorderindex + trisym.orient] = (triangle) newpoint;
11300                                 }
11301                         }
11302                 }
11303                 triangleloop.tri = triangletraverse();
11304         }
11305 }
11306
11307 /********* File I/O routines begin here                              *********/
11308 /**                                                                         **/
11309 /**                                                                         **/
11310
11311 /*****************************************************************************/
11312 /*                                                                           */
11313 /*  readline()   Read a nonempty line from a file.                           */
11314 /*                                                                           */
11315 /*  A line is considered "nonempty" if it contains something that looks like */
11316 /*  a number.                                                                */
11317 /*                                                                           */
11318 /*****************************************************************************/
11319
11320 #ifndef TRILIBRARY
11321
11322 char *readline( string, infile, infilename )
11323 char *string;
11324 FILE *infile;
11325 char *infilename;
11326 {
11327         char *result;
11328
11329         /* Search for something that looks like a number. */
11330         do {
11331                 result = fgets( string, INPUTLINESIZE, infile );
11332                 if ( result == (char *) NULL ) {
11333                         printf( "  Error:  Unexpected end of file in %s.\n", infilename );
11334                         exit( 1 );
11335                 }
11336                 /* Skip anything that doesn't look like a number, a comment, */
11337                 /*   or the end of a line.                                   */
11338                 while ( ( *result != '\0' ) && ( *result != '#' )
11339                                 && ( *result != '.' ) && ( *result != '+' ) && ( *result != '-' )
11340                                 && ( ( *result < '0' ) || ( *result > '9' ) ) ) {
11341                         result++;
11342                 }
11343                 /* If it's a comment or end of line, read another line and try again. */
11344         } while ( ( *result == '#' ) || ( *result == '\0' ) );
11345         return result;
11346 }
11347
11348 #endif /* not TRILIBRARY */
11349
11350 /*****************************************************************************/
11351 /*                                                                           */
11352 /*  findfield()   Find the next field of a string.                           */
11353 /*                                                                           */
11354 /*  Jumps past the current field by searching for whitespace, then jumps     */
11355 /*  past the whitespace to find the next field.                              */
11356 /*                                                                           */
11357 /*****************************************************************************/
11358
11359 #ifndef TRILIBRARY
11360
11361 char *findfield( string )
11362 char *string;
11363 {
11364         char *result;
11365
11366         result = string;
11367         /* Skip the current field.  Stop upon reaching whitespace. */
11368         while ( ( *result != '\0' ) && ( *result != '#' )
11369                         && ( *result != ' ' ) && ( *result != '\t' ) ) {
11370                 result++;
11371         }
11372         /* Now skip the whitespace and anything else that doesn't look like a */
11373         /*   number, a comment, or the end of a line.                         */
11374         while ( ( *result != '\0' ) && ( *result != '#' )
11375                         && ( *result != '.' ) && ( *result != '+' ) && ( *result != '-' )
11376                         && ( ( *result < '0' ) || ( *result > '9' ) ) ) {
11377                 result++;
11378         }
11379         /* Check for a comment (prefixed with `#'). */
11380         if ( *result == '#' ) {
11381                 *result = '\0';
11382         }
11383         return result;
11384 }
11385
11386 #endif /* not TRILIBRARY */
11387
11388 /*****************************************************************************/
11389 /*                                                                           */
11390 /*  readnodes()   Read the points from a file, which may be a .node or .poly */
11391 /*                file.                                                      */
11392 /*                                                                           */
11393 /*****************************************************************************/
11394
11395 #ifndef TRILIBRARY
11396
11397 void readnodes( nodefilename, polyfilename, polyfile )
11398 char *nodefilename;
11399 char *polyfilename;
11400 FILE **polyfile;
11401 {
11402         FILE *infile;
11403         point pointloop;
11404         char inputline[INPUTLINESIZE];
11405         char *stringptr;
11406         char *infilename;
11407         REAL x, y;
11408         int firstnode;
11409         int nodemarkers;
11410         int currentmarker;
11411         int i, j;
11412
11413         if ( poly ) {
11414                 /* Read the points from a .poly file. */
11415                 if ( !quiet ) {
11416                         printf( "Opening %s.\n", polyfilename );
11417                 }
11418                 *polyfile = fopen( polyfilename, "r" );
11419                 if ( *polyfile == (FILE *) NULL ) {
11420                         printf( "  Error:  Cannot access file %s.\n", polyfilename );
11421                         exit( 1 );
11422                 }
11423                 /* Read number of points, number of dimensions, number of point */
11424                 /*   attributes, and number of boundary markers.                */
11425                 stringptr = readline( inputline, *polyfile, polyfilename );
11426                 inpoints = (int) strtol( stringptr, &stringptr, 0 );
11427                 stringptr = findfield( stringptr );
11428                 if ( *stringptr == '\0' ) {
11429                         mesh_dim = 2;
11430                 }
11431                 else {
11432                         mesh_dim = (int) strtol( stringptr, &stringptr, 0 );
11433                 }
11434                 stringptr = findfield( stringptr );
11435                 if ( *stringptr == '\0' ) {
11436                         nextras = 0;
11437                 }
11438                 else {
11439                         nextras = (int) strtol( stringptr, &stringptr, 0 );
11440                 }
11441                 stringptr = findfield( stringptr );
11442                 if ( *stringptr == '\0' ) {
11443                         nodemarkers = 0;
11444                 }
11445                 else {
11446                         nodemarkers = (int) strtol( stringptr, &stringptr, 0 );
11447                 }
11448                 if ( inpoints > 0 ) {
11449                         infile = *polyfile;
11450                         infilename = polyfilename;
11451                         readnodefile = 0;
11452                 }
11453                 else {
11454                         /* If the .poly file claims there are zero points, that means that */
11455                         /*   the points should be read from a separate .node file.         */
11456                         readnodefile = 1;
11457                         infilename = innodefilename;
11458                 }
11459         }
11460         else {
11461                 readnodefile = 1;
11462                 infilename = innodefilename;
11463                 *polyfile = (FILE *) NULL;
11464         }
11465
11466         if ( readnodefile ) {
11467                 /* Read the points from a .node file. */
11468                 if ( !quiet ) {
11469                         printf( "Opening %s.\n", innodefilename );
11470                 }
11471                 infile = fopen( innodefilename, "r" );
11472                 if ( infile == (FILE *) NULL ) {
11473                         printf( "  Error:  Cannot access file %s.\n", innodefilename );
11474                         exit( 1 );
11475                 }
11476                 /* Read number of points, number of dimensions, number of point */
11477                 /*   attributes, and number of boundary markers.                */
11478                 stringptr = readline( inputline, infile, innodefilename );
11479                 inpoints = (int) strtol( stringptr, &stringptr, 0 );
11480                 stringptr = findfield( stringptr );
11481                 if ( *stringptr == '\0' ) {
11482                         mesh_dim = 2;
11483                 }
11484                 else {
11485                         mesh_dim = (int) strtol( stringptr, &stringptr, 0 );
11486                 }
11487                 stringptr = findfield( stringptr );
11488                 if ( *stringptr == '\0' ) {
11489                         nextras = 0;
11490                 }
11491                 else {
11492                         nextras = (int) strtol( stringptr, &stringptr, 0 );
11493                 }
11494                 stringptr = findfield( stringptr );
11495                 if ( *stringptr == '\0' ) {
11496                         nodemarkers = 0;
11497                 }
11498                 else {
11499                         nodemarkers = (int) strtol( stringptr, &stringptr, 0 );
11500                 }
11501         }
11502
11503         if ( inpoints < 3 ) {
11504                 printf( "Error:  Input must have at least three input points.\n" );
11505                 exit( 1 );
11506         }
11507         if ( mesh_dim != 2 ) {
11508                 printf( "Error:  Triangle only works with two-dimensional meshes.\n" );
11509                 exit( 1 );
11510         }
11511
11512         initializepointpool();
11513
11514         /* Read the points. */
11515         for ( i = 0; i < inpoints; i++ ) {
11516                 pointloop = (point) poolalloc( &points );
11517                 stringptr = readline( inputline, infile, infilename );
11518                 if ( i == 0 ) {
11519                         firstnode = (int) strtol( stringptr, &stringptr, 0 );
11520                         if ( ( firstnode == 0 ) || ( firstnode == 1 ) ) {
11521                                 firstnumber = firstnode;
11522                         }
11523                 }
11524                 stringptr = findfield( stringptr );
11525                 if ( *stringptr == '\0' ) {
11526                         printf( "Error:  Point %d has no x coordinate.\n", firstnumber + i );
11527                         exit( 1 );
11528                 }
11529                 x = (REAL) strtod( stringptr, &stringptr );
11530                 stringptr = findfield( stringptr );
11531                 if ( *stringptr == '\0' ) {
11532                         printf( "Error:  Point %d has no y coordinate.\n", firstnumber + i );
11533                         exit( 1 );
11534                 }
11535                 y = (REAL) strtod( stringptr, &stringptr );
11536                 pointloop[0] = x;
11537                 pointloop[1] = y;
11538                 /* Read the point attributes. */
11539                 for ( j = 2; j < 2 + nextras; j++ ) {
11540                         stringptr = findfield( stringptr );
11541                         if ( *stringptr == '\0' ) {
11542                                 pointloop[j] = 0.0;
11543                         }
11544                         else {
11545                                 pointloop[j] = (REAL) strtod( stringptr, &stringptr );
11546                         }
11547                 }
11548                 if ( nodemarkers ) {
11549                         /* Read a point marker. */
11550                         stringptr = findfield( stringptr );
11551                         if ( *stringptr == '\0' ) {
11552                                 setpointmark( pointloop, 0 );
11553                         }
11554                         else {
11555                                 currentmarker = (int) strtol( stringptr, &stringptr, 0 );
11556                                 setpointmark( pointloop, currentmarker );
11557                         }
11558                 }
11559                 else {
11560                         /* If no markers are specified in the file, they default to zero. */
11561                         setpointmark( pointloop, 0 );
11562                 }
11563                 /* Determine the smallest and largest x and y coordinates. */
11564                 if ( i == 0 ) {
11565                         xmin = xmax = x;
11566                         ymin = ymax = y;
11567                 }
11568                 else {
11569                         xmin = ( x < xmin ) ? x : xmin;
11570                         xmax = ( x > xmax ) ? x : xmax;
11571                         ymin = ( y < ymin ) ? y : ymin;
11572                         ymax = ( y > ymax ) ? y : ymax;
11573                 }
11574         }
11575         if ( readnodefile ) {
11576                 fclose( infile );
11577         }
11578
11579         /* Nonexistent x value used as a flag to mark circle events in sweepline */
11580         /*   Delaunay algorithm.                                                 */
11581         xminextreme = 10 * xmin - 9 * xmax;
11582 }
11583
11584 #endif /* not TRILIBRARY */
11585
11586 /*****************************************************************************/
11587 /*                                                                           */
11588 /*  transfernodes()   Read the points from memory.                           */
11589 /*                                                                           */
11590 /*****************************************************************************/
11591
11592 #ifdef TRILIBRARY
11593
11594 void transfernodes( pointlist, pointattriblist, pointmarkerlist, numberofpoints,
11595                                         numberofpointattribs )
11596 REAL * pointlist;
11597 REAL *pointattriblist;
11598 int *pointmarkerlist;
11599 int numberofpoints;
11600 int numberofpointattribs;
11601 {
11602         point pointloop;
11603         REAL x, y;
11604         int i, j;
11605         int coordindex;
11606         int attribindex;
11607
11608         inpoints = numberofpoints;
11609         mesh_dim = 2;
11610         nextras = numberofpointattribs;
11611         readnodefile = 0;
11612         if ( inpoints < 3 ) {
11613                 printf( "Error:  Input must have at least three input points.\n" );
11614                 exit( 1 );
11615         }
11616
11617         initializepointpool();
11618
11619         /* Read the points. */
11620         coordindex = 0;
11621         attribindex = 0;
11622         for ( i = 0; i < inpoints; i++ ) {
11623                 pointloop = (point) poolalloc( &points );
11624                 /* Read the point coordinates. */
11625                 x = pointloop[0] = pointlist[coordindex++];
11626                 y = pointloop[1] = pointlist[coordindex++];
11627                 /* Read the point attributes. */
11628                 for ( j = 0; j < numberofpointattribs; j++ ) {
11629                         pointloop[2 + j] = pointattriblist[attribindex++];
11630                 }
11631                 if ( pointmarkerlist != (int *) NULL ) {
11632                         /* Read a point marker. */
11633                         setpointmark( pointloop, pointmarkerlist[i] );
11634                 }
11635                 else {
11636                         /* If no markers are specified, they default to zero. */
11637                         setpointmark( pointloop, 0 );
11638                 }
11639                 x = pointloop[0];
11640                 y = pointloop[1];
11641                 /* Determine the smallest and largest x and y coordinates. */
11642                 if ( i == 0 ) {
11643                         xmin = xmax = x;
11644                         ymin = ymax = y;
11645                 }
11646                 else {
11647                         xmin = ( x < xmin ) ? x : xmin;
11648                         xmax = ( x > xmax ) ? x : xmax;
11649                         ymin = ( y < ymin ) ? y : ymin;
11650                         ymax = ( y > ymax ) ? y : ymax;
11651                 }
11652         }
11653
11654         /* Nonexistent x value used as a flag to mark circle events in sweepline */
11655         /*   Delaunay algorithm.                                                 */
11656         xminextreme = 10 * xmin - 9 * xmax;
11657 }
11658
11659 #endif /* TRILIBRARY */
11660
11661 /*****************************************************************************/
11662 /*                                                                           */
11663 /*  readholes()   Read the holes, and possibly regional attributes and area  */
11664 /*                constraints, from a .poly file.                            */
11665 /*                                                                           */
11666 /*****************************************************************************/
11667
11668 #ifndef TRILIBRARY
11669
11670 void readholes( polyfile, polyfilename, hlist, holes, rlist, regions )
11671 FILE * polyfile;
11672 char *polyfilename;
11673 REAL **hlist;
11674 int *holes;
11675 REAL **rlist;
11676 int *regions;
11677 {
11678         REAL *holelist;
11679         REAL *regionlist;
11680         char inputline[INPUTLINESIZE];
11681         char *stringptr;
11682         int index;
11683         int i;
11684
11685         /* Read the holes. */
11686         stringptr = readline( inputline, polyfile, polyfilename );
11687         *holes = (int) strtol( stringptr, &stringptr, 0 );
11688         if ( *holes > 0 ) {
11689                 holelist = (REAL *) malloc( 2 * *holes * sizeof( REAL ) );
11690                 *hlist = holelist;
11691                 if ( holelist == (REAL *) NULL ) {
11692                         printf( "Error:  Out of memory.\n" );
11693                         exit( 1 );
11694                 }
11695                 for ( i = 0; i < 2 * *holes; i += 2 ) {
11696                         stringptr = readline( inputline, polyfile, polyfilename );
11697                         stringptr = findfield( stringptr );
11698                         if ( *stringptr == '\0' ) {
11699                                 printf( "Error:  Hole %d has no x coordinate.\n",
11700                                                 firstnumber + ( i >> 1 ) );
11701                                 exit( 1 );
11702                         }
11703                         else {
11704                                 holelist[i] = (REAL) strtod( stringptr, &stringptr );
11705                         }
11706                         stringptr = findfield( stringptr );
11707                         if ( *stringptr == '\0' ) {
11708                                 printf( "Error:  Hole %d has no y coordinate.\n",
11709                                                 firstnumber + ( i >> 1 ) );
11710                                 exit( 1 );
11711                         }
11712                         else {
11713                                 holelist[i + 1] = (REAL) strtod( stringptr, &stringptr );
11714                         }
11715                 }
11716         }
11717         else {
11718                 *hlist = (REAL *) NULL;
11719         }
11720
11721 #ifndef CDT_ONLY
11722         if ( ( regionattrib || vararea ) && !refine ) {
11723                 /* Read the area constraints. */
11724                 stringptr = readline( inputline, polyfile, polyfilename );
11725                 *regions = (int) strtol( stringptr, &stringptr, 0 );
11726                 if ( *regions > 0 ) {
11727                         regionlist = (REAL *) malloc( 4 * *regions * sizeof( REAL ) );
11728                         *rlist = regionlist;
11729                         if ( regionlist == (REAL *) NULL ) {
11730                                 printf( "Error:  Out of memory.\n" );
11731                                 exit( 1 );
11732                         }
11733                         index = 0;
11734                         for ( i = 0; i < *regions; i++ ) {
11735                                 stringptr = readline( inputline, polyfile, polyfilename );
11736                                 stringptr = findfield( stringptr );
11737                                 if ( *stringptr == '\0' ) {
11738                                         printf( "Error:  Region %d has no x coordinate.\n",
11739                                                         firstnumber + i );
11740                                         exit( 1 );
11741                                 }
11742                                 else {
11743                                         regionlist[index++] = (REAL) strtod( stringptr, &stringptr );
11744                                 }
11745                                 stringptr = findfield( stringptr );
11746                                 if ( *stringptr == '\0' ) {
11747                                         printf( "Error:  Region %d has no y coordinate.\n",
11748                                                         firstnumber + i );
11749                                         exit( 1 );
11750                                 }
11751                                 else {
11752                                         regionlist[index++] = (REAL) strtod( stringptr, &stringptr );
11753                                 }
11754                                 stringptr = findfield( stringptr );
11755                                 if ( *stringptr == '\0' ) {
11756                                         printf(
11757                                                 "Error:  Region %d has no region attribute or area constraint.\n",
11758                                                 firstnumber + i );
11759                                         exit( 1 );
11760                                 }
11761                                 else {
11762                                         regionlist[index++] = (REAL) strtod( stringptr, &stringptr );
11763                                 }
11764                                 stringptr = findfield( stringptr );
11765                                 if ( *stringptr == '\0' ) {
11766                                         regionlist[index] = regionlist[index - 1];
11767                                 }
11768                                 else {
11769                                         regionlist[index] = (REAL) strtod( stringptr, &stringptr );
11770                                 }
11771                                 index++;
11772                         }
11773                 }
11774         }
11775         else {
11776                 /* Set `*regions' to zero to avoid an accidental free() later. */
11777                 *regions = 0;
11778                 *rlist = (REAL *) NULL;
11779         }
11780 #endif /* not CDT_ONLY */
11781
11782         fclose( polyfile );
11783 }
11784
11785 #endif /* not TRILIBRARY */
11786
11787 /*****************************************************************************/
11788 /*                                                                           */
11789 /*  finishfile()   Write the command line to the output file so the user     */
11790 /*                 can remember how the file was generated.  Close the file. */
11791 /*                                                                           */
11792 /*****************************************************************************/
11793
11794 #ifndef TRILIBRARY
11795
11796 void finishfile( outfile, argc, argv )
11797 FILE * outfile;
11798 int argc;
11799 char **argv;
11800 {
11801         int i;
11802
11803         fprintf( outfile, "# Generated by" );
11804         for ( i = 0; i < argc; i++ ) {
11805                 fprintf( outfile, " " );
11806                 fputs( argv[i], outfile );
11807         }
11808         fprintf( outfile, "\n" );
11809         fclose( outfile );
11810 }
11811
11812 #endif /* not TRILIBRARY */
11813
11814 /*****************************************************************************/
11815 /*                                                                           */
11816 /*  writenodes()   Number the points and write them to a .node file.         */
11817 /*                                                                           */
11818 /*  To save memory, the point numbers are written over the shell markers     */
11819 /*  after the points are written to a file.                                  */
11820 /*                                                                           */
11821 /*****************************************************************************/
11822
11823 #ifdef TRILIBRARY
11824
11825 void writenodes( pointlist, pointattriblist, pointmarkerlist )
11826 REAL * *pointlist;
11827 REAL **pointattriblist;
11828 int **pointmarkerlist;
11829
11830 #else /* not TRILIBRARY */
11831
11832 void writenodes( nodefilename, argc, argv )
11833 char *nodefilename;
11834 int argc;
11835 char **argv;
11836
11837 #endif /* not TRILIBRARY */
11838
11839 {
11840 #ifdef TRILIBRARY
11841         REAL *plist;
11842         REAL *palist;
11843         int *pmlist;
11844         int coordindex;
11845         int attribindex;
11846 #else /* not TRILIBRARY */
11847         FILE *outfile;
11848 #endif /* not TRILIBRARY */
11849         point pointloop;
11850         int pointnumber;
11851         int i;
11852
11853 #ifdef TRILIBRARY
11854         if ( !quiet ) {
11855                 printf( "Writing points.\n" );
11856         }
11857         /* Allocate memory for output points if necessary. */
11858         if ( *pointlist == (REAL *) NULL ) {
11859                 *pointlist = (REAL *) malloc( points.items * 2 * sizeof( REAL ) );
11860                 if ( *pointlist == (REAL *) NULL ) {
11861                         printf( "Error:  Out of memory.\n" );
11862                         exit( 1 );
11863                 }
11864         }
11865         /* Allocate memory for output point attributes if necessary. */
11866         if ( ( nextras > 0 ) && ( *pointattriblist == (REAL *) NULL ) ) {
11867                 *pointattriblist = (REAL *) malloc( points.items * nextras * sizeof( REAL ) );
11868                 if ( *pointattriblist == (REAL *) NULL ) {
11869                         printf( "Error:  Out of memory.\n" );
11870                         exit( 1 );
11871                 }
11872         }
11873         /* Allocate memory for output point markers if necessary. */
11874         if ( !nobound && ( *pointmarkerlist == (int *) NULL ) ) {
11875                 *pointmarkerlist = (int *) malloc( points.items * sizeof( int ) );
11876                 if ( *pointmarkerlist == (int *) NULL ) {
11877                         printf( "Error:  Out of memory.\n" );
11878                         exit( 1 );
11879                 }
11880         }
11881         plist = *pointlist;
11882         palist = *pointattriblist;
11883         pmlist = *pointmarkerlist;
11884         coordindex = 0;
11885         attribindex = 0;
11886 #else /* not TRILIBRARY */
11887         if ( !quiet ) {
11888                 printf( "Writing %s.\n", nodefilename );
11889         }
11890         outfile = fopen( nodefilename, "w" );
11891         if ( outfile == (FILE *) NULL ) {
11892                 printf( "  Error:  Cannot create file %s.\n", nodefilename );
11893                 exit( 1 );
11894         }
11895         /* Number of points, number of dimensions, number of point attributes, */
11896         /*   and number of boundary markers (zero or one).                     */
11897         fprintf( outfile, "%ld  %d  %d  %d\n", points.items, mesh_dim, nextras,
11898                          1 - nobound );
11899 #endif /* not TRILIBRARY */
11900
11901         traversalinit( &points );
11902         pointloop = pointtraverse();
11903         pointnumber = firstnumber;
11904         while ( pointloop != (point) NULL ) {
11905 #ifdef TRILIBRARY
11906                 /* X and y coordinates. */
11907                 plist[coordindex++] = pointloop[0];
11908                 plist[coordindex++] = pointloop[1];
11909                 /* Point attributes. */
11910                 for ( i = 0; i < nextras; i++ ) {
11911                         palist[attribindex++] = pointloop[2 + i];
11912                 }
11913                 if ( !nobound ) {
11914                         /* Copy the boundary marker. */
11915                         pmlist[pointnumber - firstnumber] = pointmark( pointloop );
11916                 }
11917 #else /* not TRILIBRARY */
11918                 /* Point number, x and y coordinates. */
11919                 fprintf( outfile, "%4d    %.17g  %.17g", pointnumber, pointloop[0],
11920                                  pointloop[1] );
11921                 for ( i = 0; i < nextras; i++ ) {
11922                         /* Write an attribute. */
11923                         fprintf( outfile, "  %.17g", pointloop[i + 2] );
11924                 }
11925                 if ( nobound ) {
11926                         fprintf( outfile, "\n" );
11927                 }
11928                 else {
11929                         /* Write the boundary marker. */
11930                         fprintf( outfile, "    %d\n", pointmark( pointloop ) );
11931                 }
11932 #endif /* not TRILIBRARY */
11933
11934                 setpointmark( pointloop, pointnumber );
11935                 pointloop = pointtraverse();
11936                 pointnumber++;
11937         }
11938
11939 #ifndef TRILIBRARY
11940         finishfile( outfile, argc, argv );
11941 #endif /* not TRILIBRARY */
11942 }
11943
11944 /*****************************************************************************/
11945 /*                                                                           */
11946 /*  numbernodes()   Number the points.                                       */
11947 /*                                                                           */
11948 /*  Each point is assigned a marker equal to its number.                     */
11949 /*                                                                           */
11950 /*  Used when writenodes() is not called because no .node file is written.   */
11951 /*                                                                           */
11952 /*****************************************************************************/
11953
11954 void numbernodes(){
11955         point pointloop;
11956         int pointnumber;
11957
11958         traversalinit( &points );
11959         pointloop = pointtraverse();
11960         pointnumber = firstnumber;
11961         while ( pointloop != (point) NULL ) {
11962                 setpointmark( pointloop, pointnumber );
11963                 pointloop = pointtraverse();
11964                 pointnumber++;
11965         }
11966 }
11967
11968 /*****************************************************************************/
11969 /*                                                                           */
11970 /*  writeelements()   Write the triangles to an .ele file.                   */
11971 /*                                                                           */
11972 /*****************************************************************************/
11973
11974 #ifdef TRILIBRARY
11975
11976 void writeelements( trianglelist, triangleattriblist )
11977 int **trianglelist;
11978 REAL **triangleattriblist;
11979
11980 #else /* not TRILIBRARY */
11981
11982 void writeelements( elefilename, argc, argv )
11983 char *elefilename;
11984 int argc;
11985 char **argv;
11986
11987 #endif /* not TRILIBRARY */
11988
11989 {
11990 #ifdef TRILIBRARY
11991         int *tlist;
11992         REAL *talist;
11993         int pointindex;
11994         int attribindex;
11995 #else /* not TRILIBRARY */
11996         FILE *outfile;
11997 #endif /* not TRILIBRARY */
11998         struct triedge triangleloop;
11999         point p1, p2, p3;
12000         point mid1, mid2, mid3;
12001         int elementnumber;
12002         int i;
12003
12004 #ifdef TRILIBRARY
12005         if ( !quiet ) {
12006                 printf( "Writing triangles.\n" );
12007         }
12008         /* Allocate memory for output triangles if necessary. */
12009         if ( *trianglelist == (int *) NULL ) {
12010                 *trianglelist = (int *) malloc( triangles.items *
12011                                                                                 ( ( order + 1 ) * ( order + 2 ) / 2 ) * sizeof( int ) );
12012                 if ( *trianglelist == (int *) NULL ) {
12013                         printf( "Error:  Out of memory.\n" );
12014                         exit( 1 );
12015                 }
12016         }
12017         /* Allocate memory for output triangle attributes if necessary. */
12018         if ( ( eextras > 0 ) && ( *triangleattriblist == (REAL *) NULL ) ) {
12019                 *triangleattriblist = (REAL *) malloc( triangles.items * eextras *
12020                                                                                            sizeof( REAL ) );
12021                 if ( *triangleattriblist == (REAL *) NULL ) {
12022                         printf( "Error:  Out of memory.\n" );
12023                         exit( 1 );
12024                 }
12025         }
12026         tlist = *trianglelist;
12027         talist = *triangleattriblist;
12028         pointindex = 0;
12029         attribindex = 0;
12030 #else /* not TRILIBRARY */
12031         if ( !quiet ) {
12032                 printf( "Writing %s.\n", elefilename );
12033         }
12034         outfile = fopen( elefilename, "w" );
12035         if ( outfile == (FILE *) NULL ) {
12036                 printf( "  Error:  Cannot create file %s.\n", elefilename );
12037                 exit( 1 );
12038         }
12039         /* Number of triangles, points per triangle, attributes per triangle. */
12040         fprintf( outfile, "%ld  %d  %d\n", triangles.items,
12041                          ( order + 1 ) * ( order + 2 ) / 2, eextras );
12042 #endif /* not TRILIBRARY */
12043
12044         traversalinit( &triangles );
12045         triangleloop.tri = triangletraverse();
12046         triangleloop.orient = 0;
12047         elementnumber = firstnumber;
12048         while ( triangleloop.tri != (triangle *) NULL ) {
12049                 org( triangleloop, p1 );
12050                 dest( triangleloop, p2 );
12051                 apex( triangleloop, p3 );
12052                 if ( order == 1 ) {
12053 #ifdef TRILIBRARY
12054                         tlist[pointindex++] = pointmark( p1 );
12055                         tlist[pointindex++] = pointmark( p2 );
12056                         tlist[pointindex++] = pointmark( p3 );
12057 #else /* not TRILIBRARY */
12058                         /* Triangle number, indices for three points. */
12059                         fprintf( outfile, "%4d    %4d  %4d  %4d", elementnumber,
12060                                          pointmark( p1 ), pointmark( p2 ), pointmark( p3 ) );
12061 #endif /* not TRILIBRARY */
12062                 }
12063                 else {
12064                         mid1 = (point) triangleloop.tri[highorderindex + 1];
12065                         mid2 = (point) triangleloop.tri[highorderindex + 2];
12066                         mid3 = (point) triangleloop.tri[highorderindex];
12067 #ifdef TRILIBRARY
12068                         tlist[pointindex++] = pointmark( p1 );
12069                         tlist[pointindex++] = pointmark( p2 );
12070                         tlist[pointindex++] = pointmark( p3 );
12071                         tlist[pointindex++] = pointmark( mid1 );
12072                         tlist[pointindex++] = pointmark( mid2 );
12073                         tlist[pointindex++] = pointmark( mid3 );
12074 #else /* not TRILIBRARY */
12075                         /* Triangle number, indices for six points. */
12076                         fprintf( outfile, "%4d    %4d  %4d  %4d  %4d  %4d  %4d", elementnumber,
12077                                          pointmark( p1 ), pointmark( p2 ), pointmark( p3 ), pointmark( mid1 ),
12078                                          pointmark( mid2 ), pointmark( mid3 ) );
12079 #endif /* not TRILIBRARY */
12080                 }
12081
12082 #ifdef TRILIBRARY
12083                 for ( i = 0; i < eextras; i++ ) {
12084                         talist[attribindex++] = elemattribute( triangleloop, i );
12085                 }
12086 #else /* not TRILIBRARY */
12087                 for ( i = 0; i < eextras; i++ ) {
12088                         fprintf( outfile, "  %.17g", elemattribute( triangleloop, i ) );
12089                 }
12090                 fprintf( outfile, "\n" );
12091 #endif /* not TRILIBRARY */
12092
12093                 triangleloop.tri = triangletraverse();
12094                 elementnumber++;
12095         }
12096
12097 #ifndef TRILIBRARY
12098         finishfile( outfile, argc, argv );
12099 #endif /* not TRILIBRARY */
12100 }
12101
12102 /*****************************************************************************/
12103 /*                                                                           */
12104 /*  writepoly()   Write the segments and holes to a .poly file.              */
12105 /*                                                                           */
12106 /*****************************************************************************/
12107
12108 #ifdef TRILIBRARY
12109
12110 void writepoly( segmentlist, segmentmarkerlist )
12111 int **segmentlist;
12112 int **segmentmarkerlist;
12113
12114 #else /* not TRILIBRARY */
12115
12116 void writepoly( polyfilename, holelist, holes, regionlist, regions, argc, argv )
12117 char *polyfilename;
12118 REAL *holelist;
12119 int holes;
12120 REAL *regionlist;
12121 int regions;
12122 int argc;
12123 char **argv;
12124
12125 #endif /* not TRILIBRARY */
12126
12127 {
12128 #ifdef TRILIBRARY
12129         int *slist;
12130         int *smlist;
12131         int index;
12132 #else /* not TRILIBRARY */
12133         FILE *outfile;
12134         int i;
12135 #endif /* not TRILIBRARY */
12136         struct edge shelleloop;
12137         point endpoint1, endpoint2;
12138         int shellenumber;
12139
12140 #ifdef TRILIBRARY
12141         if ( !quiet ) {
12142                 printf( "Writing segments.\n" );
12143         }
12144         /* Allocate memory for output segments if necessary. */
12145         if ( *segmentlist == (int *) NULL ) {
12146                 *segmentlist = (int *) malloc( shelles.items * 2 * sizeof( int ) );
12147                 if ( *segmentlist == (int *) NULL ) {
12148                         printf( "Error:  Out of memory.\n" );
12149                         exit( 1 );
12150                 }
12151         }
12152         /* Allocate memory for output segment markers if necessary. */
12153         if ( !nobound && ( *segmentmarkerlist == (int *) NULL ) ) {
12154                 *segmentmarkerlist = (int *) malloc( shelles.items * sizeof( int ) );
12155                 if ( *segmentmarkerlist == (int *) NULL ) {
12156                         printf( "Error:  Out of memory.\n" );
12157                         exit( 1 );
12158                 }
12159         }
12160         slist = *segmentlist;
12161         smlist = *segmentmarkerlist;
12162         index = 0;
12163 #else /* not TRILIBRARY */
12164         if ( !quiet ) {
12165                 printf( "Writing %s.\n", polyfilename );
12166         }
12167         outfile = fopen( polyfilename, "w" );
12168         if ( outfile == (FILE *) NULL ) {
12169                 printf( "  Error:  Cannot create file %s.\n", polyfilename );
12170                 exit( 1 );
12171         }
12172         /* The zero indicates that the points are in a separate .node file. */
12173         /*   Followed by number of dimensions, number of point attributes,  */
12174         /*   and number of boundary markers (zero or one).                  */
12175         fprintf( outfile, "%d  %d  %d  %d\n", 0, mesh_dim, nextras, 1 - nobound );
12176         /* Number of segments, number of boundary markers (zero or one). */
12177         fprintf( outfile, "%ld  %d\n", shelles.items, 1 - nobound );
12178 #endif /* not TRILIBRARY */
12179
12180         traversalinit( &shelles );
12181         shelleloop.sh = shelletraverse();
12182         shelleloop.shorient = 0;
12183         shellenumber = firstnumber;
12184         while ( shelleloop.sh != (shelle *) NULL ) {
12185                 sorg( shelleloop, endpoint1 );
12186                 sdest( shelleloop, endpoint2 );
12187 #ifdef TRILIBRARY
12188                 /* Copy indices of the segment's two endpoints. */
12189                 slist[index++] = pointmark( endpoint1 );
12190                 slist[index++] = pointmark( endpoint2 );
12191                 if ( !nobound ) {
12192                         /* Copy the boundary marker. */
12193                         smlist[shellenumber - firstnumber] = mark( shelleloop );
12194                 }
12195 #else /* not TRILIBRARY */
12196                 /* Segment number, indices of its two endpoints, and possibly a marker. */
12197                 if ( nobound ) {
12198                         fprintf( outfile, "%4d    %4d  %4d\n", shellenumber,
12199                                          pointmark( endpoint1 ), pointmark( endpoint2 ) );
12200                 }
12201                 else {
12202                         fprintf( outfile, "%4d    %4d  %4d    %4d\n", shellenumber,
12203                                          pointmark( endpoint1 ), pointmark( endpoint2 ), mark( shelleloop ) );
12204                 }
12205 #endif /* not TRILIBRARY */
12206
12207                 shelleloop.sh = shelletraverse();
12208                 shellenumber++;
12209         }
12210
12211 #ifndef TRILIBRARY
12212 #ifndef CDT_ONLY
12213         fprintf( outfile, "%d\n", holes );
12214         if ( holes > 0 ) {
12215                 for ( i = 0; i < holes; i++ ) {
12216                         /* Hole number, x and y coordinates. */
12217                         fprintf( outfile, "%4d   %.17g  %.17g\n", firstnumber + i,
12218                                          holelist[2 * i], holelist[2 * i + 1] );
12219                 }
12220         }
12221         if ( regions > 0 ) {
12222                 fprintf( outfile, "%d\n", regions );
12223                 for ( i = 0; i < regions; i++ ) {
12224                         /* Region number, x and y coordinates, attribute, maximum area. */
12225                         fprintf( outfile, "%4d   %.17g  %.17g  %.17g  %.17g\n", firstnumber + i,
12226                                          regionlist[4 * i], regionlist[4 * i + 1],
12227                                          regionlist[4 * i + 2], regionlist[4 * i + 3] );
12228                 }
12229         }
12230 #endif /* not CDT_ONLY */
12231
12232         finishfile( outfile, argc, argv );
12233 #endif /* not TRILIBRARY */
12234 }
12235
12236 /*****************************************************************************/
12237 /*                                                                           */
12238 /*  writeedges()   Write the edges to a .edge file.                          */
12239 /*                                                                           */
12240 /*****************************************************************************/
12241
12242 #ifdef TRILIBRARY
12243
12244 void writeedges( edgelist, edgemarkerlist )
12245 int **edgelist;
12246 int **edgemarkerlist;
12247
12248 #else /* not TRILIBRARY */
12249
12250 void writeedges( edgefilename, argc, argv )
12251 char *edgefilename;
12252 int argc;
12253 char **argv;
12254
12255 #endif /* not TRILIBRARY */
12256
12257 {
12258 #ifdef TRILIBRARY
12259         int *elist;
12260         int *emlist;
12261         int index;
12262 #else /* not TRILIBRARY */
12263         FILE *outfile;
12264 #endif /* not TRILIBRARY */
12265         struct triedge triangleloop, trisym;
12266         struct edge checkmark;
12267         point p1, p2;
12268         int edgenumber;
12269         triangle ptr;                       /* Temporary variable used by sym(). */
12270         shelle sptr;                    /* Temporary variable used by tspivot(). */
12271
12272 #ifdef TRILIBRARY
12273         if ( !quiet ) {
12274                 printf( "Writing edges.\n" );
12275         }
12276         /* Allocate memory for edges if necessary. */
12277         if ( *edgelist == (int *) NULL ) {
12278                 *edgelist = (int *) malloc( edges * 2 * sizeof( int ) );
12279                 if ( *edgelist == (int *) NULL ) {
12280                         printf( "Error:  Out of memory.\n" );
12281                         exit( 1 );
12282                 }
12283         }
12284         /* Allocate memory for edge markers if necessary. */
12285         if ( !nobound && ( *edgemarkerlist == (int *) NULL ) ) {
12286                 *edgemarkerlist = (int *) malloc( edges * sizeof( int ) );
12287                 if ( *edgemarkerlist == (int *) NULL ) {
12288                         printf( "Error:  Out of memory.\n" );
12289                         exit( 1 );
12290                 }
12291         }
12292         elist = *edgelist;
12293         emlist = *edgemarkerlist;
12294         index = 0;
12295 #else /* not TRILIBRARY */
12296         if ( !quiet ) {
12297                 printf( "Writing %s.\n", edgefilename );
12298         }
12299         outfile = fopen( edgefilename, "w" );
12300         if ( outfile == (FILE *) NULL ) {
12301                 printf( "  Error:  Cannot create file %s.\n", edgefilename );
12302                 exit( 1 );
12303         }
12304         /* Number of edges, number of boundary markers (zero or one). */
12305         fprintf( outfile, "%ld  %d\n", edges, 1 - nobound );
12306 #endif /* not TRILIBRARY */
12307
12308         traversalinit( &triangles );
12309         triangleloop.tri = triangletraverse();
12310         edgenumber = firstnumber;
12311         /* To loop over the set of edges, loop over all triangles, and look at   */
12312         /*   the three edges of each triangle.  If there isn't another triangle  */
12313         /*   adjacent to the edge, operate on the edge.  If there is another     */
12314         /*   adjacent triangle, operate on the edge only if the current triangle */
12315         /*   has a smaller pointer than its neighbor.  This way, each edge is    */
12316         /*   considered only once.                                               */
12317         while ( triangleloop.tri != (triangle *) NULL ) {
12318                 for ( triangleloop.orient = 0; triangleloop.orient < 3;
12319                           triangleloop.orient++ ) {
12320                         sym( triangleloop, trisym );
12321                         if ( ( triangleloop.tri < trisym.tri ) || ( trisym.tri == dummytri ) ) {
12322                                 org( triangleloop, p1 );
12323                                 dest( triangleloop, p2 );
12324 #ifdef TRILIBRARY
12325                                 elist[index++] = pointmark( p1 );
12326                                 elist[index++] = pointmark( p2 );
12327 #endif /* TRILIBRARY */
12328                                 if ( nobound ) {
12329 #ifndef TRILIBRARY
12330                                         /* Edge number, indices of two endpoints. */
12331                                         fprintf( outfile, "%4d   %d  %d\n", edgenumber,
12332                                                          pointmark( p1 ), pointmark( p2 ) );
12333 #endif /* not TRILIBRARY */
12334                                 }
12335                                 else {
12336                                         /* Edge number, indices of two endpoints, and a boundary marker. */
12337                                         /*   If there's no shell edge, the boundary marker is zero.      */
12338                                         if ( useshelles ) {
12339                                                 tspivot( triangleloop, checkmark );
12340                                                 if ( checkmark.sh == dummysh ) {
12341 #ifdef TRILIBRARY
12342                                                         emlist[edgenumber - firstnumber] = 0;
12343 #else /* not TRILIBRARY */
12344                                                         fprintf( outfile, "%4d   %d  %d  %d\n", edgenumber,
12345                                                                          pointmark( p1 ), pointmark( p2 ), 0 );
12346 #endif /* not TRILIBRARY */
12347                                                 }
12348                                                 else {
12349 #ifdef TRILIBRARY
12350                                                         emlist[edgenumber - firstnumber] = mark( checkmark );
12351 #else /* not TRILIBRARY */
12352                                                         fprintf( outfile, "%4d   %d  %d  %d\n", edgenumber,
12353                                                                          pointmark( p1 ), pointmark( p2 ), mark( checkmark ) );
12354 #endif /* not TRILIBRARY */
12355                                                 }
12356                                         }
12357                                         else {
12358 #ifdef TRILIBRARY
12359                                                 emlist[edgenumber - firstnumber] = trisym.tri == dummytri;
12360 #else /* not TRILIBRARY */
12361                                                 fprintf( outfile, "%4d   %d  %d  %d\n", edgenumber,
12362                                                                  pointmark( p1 ), pointmark( p2 ), trisym.tri == dummytri );
12363 #endif /* not TRILIBRARY */
12364                                         }
12365                                 }
12366                                 edgenumber++;
12367                         }
12368                 }
12369                 triangleloop.tri = triangletraverse();
12370         }
12371
12372 #ifndef TRILIBRARY
12373         finishfile( outfile, argc, argv );
12374 #endif /* not TRILIBRARY */
12375 }
12376
12377 /*****************************************************************************/
12378 /*                                                                           */
12379 /*  writevoronoi()   Write the Voronoi diagram to a .v.node and .v.edge      */
12380 /*                   file.                                                   */
12381 /*                                                                           */
12382 /*  The Voronoi diagram is the geometric dual of the Delaunay triangulation. */
12383 /*  Hence, the Voronoi vertices are listed by traversing the Delaunay        */
12384 /*  triangles, and the Voronoi edges are listed by traversing the Delaunay   */
12385 /*  edges.                                                                   */
12386 /*                                                                           */
12387 /*  WARNING:  In order to assign numbers to the Voronoi vertices, this       */
12388 /*  procedure messes up the shell edges or the extra nodes of every          */
12389 /*  element.  Hence, you should call this procedure last.                    */
12390 /*                                                                           */
12391 /*****************************************************************************/
12392
12393 #ifdef TRILIBRARY
12394
12395 void writevoronoi( vpointlist, vpointattriblist, vpointmarkerlist, vedgelist,
12396                                    vedgemarkerlist, vnormlist )
12397 REAL * *vpointlist;
12398 REAL **vpointattriblist;
12399 int **vpointmarkerlist;
12400 int **vedgelist;
12401 int **vedgemarkerlist;
12402 REAL **vnormlist;
12403
12404 #else /* not TRILIBRARY */
12405
12406 void writevoronoi( vnodefilename, vedgefilename, argc, argv )
12407 char *vnodefilename;
12408 char *vedgefilename;
12409 int argc;
12410 char **argv;
12411
12412 #endif /* not TRILIBRARY */
12413
12414 {
12415 #ifdef TRILIBRARY
12416         REAL *plist;
12417         REAL *palist;
12418         int *elist;
12419         REAL *normlist;
12420         int coordindex;
12421         int attribindex;
12422 #else /* not TRILIBRARY */
12423         FILE *outfile;
12424 #endif /* not TRILIBRARY */
12425         struct triedge triangleloop, trisym;
12426         point torg, tdest, tapex;
12427         REAL circumcenter[2];
12428         REAL xi, eta;
12429         int vnodenumber, vedgenumber;
12430         int p1, p2;
12431         int i;
12432         triangle ptr;                       /* Temporary variable used by sym(). */
12433
12434 #ifdef TRILIBRARY
12435         if ( !quiet ) {
12436                 printf( "Writing Voronoi vertices.\n" );
12437         }
12438         /* Allocate memory for Voronoi vertices if necessary. */
12439         if ( *vpointlist == (REAL *) NULL ) {
12440                 *vpointlist = (REAL *) malloc( triangles.items * 2 * sizeof( REAL ) );
12441                 if ( *vpointlist == (REAL *) NULL ) {
12442                         printf( "Error:  Out of memory.\n" );
12443                         exit( 1 );
12444                 }
12445         }
12446         /* Allocate memory for Voronoi vertex attributes if necessary. */
12447         if ( *vpointattriblist == (REAL *) NULL ) {
12448                 *vpointattriblist = (REAL *) malloc( triangles.items * nextras *
12449                                                                                          sizeof( REAL ) );
12450                 if ( *vpointattriblist == (REAL *) NULL ) {
12451                         printf( "Error:  Out of memory.\n" );
12452                         exit( 1 );
12453                 }
12454         }
12455         *vpointmarkerlist = (int *) NULL;
12456         plist = *vpointlist;
12457         palist = *vpointattriblist;
12458         coordindex = 0;
12459         attribindex = 0;
12460 #else /* not TRILIBRARY */
12461         if ( !quiet ) {
12462                 printf( "Writing %s.\n", vnodefilename );
12463         }
12464         outfile = fopen( vnodefilename, "w" );
12465         if ( outfile == (FILE *) NULL ) {
12466                 printf( "  Error:  Cannot create file %s.\n", vnodefilename );
12467                 exit( 1 );
12468         }
12469         /* Number of triangles, two dimensions, number of point attributes, */
12470         /*   zero markers.                                                  */
12471         fprintf( outfile, "%ld  %d  %d  %d\n", triangles.items, 2, nextras, 0 );
12472 #endif /* not TRILIBRARY */
12473
12474         traversalinit( &triangles );
12475         triangleloop.tri = triangletraverse();
12476         triangleloop.orient = 0;
12477         vnodenumber = firstnumber;
12478         while ( triangleloop.tri != (triangle *) NULL ) {
12479                 org( triangleloop, torg );
12480                 dest( triangleloop, tdest );
12481                 apex( triangleloop, tapex );
12482                 findcircumcenter( torg, tdest, tapex, circumcenter, &xi, &eta );
12483 #ifdef TRILIBRARY
12484                 /* X and y coordinates. */
12485                 plist[coordindex++] = circumcenter[0];
12486                 plist[coordindex++] = circumcenter[1];
12487                 for ( i = 2; i < 2 + nextras; i++ ) {
12488                         /* Interpolate the point attributes at the circumcenter. */
12489                         palist[attribindex++] = torg[i] + xi * ( tdest[i] - torg[i] )
12490                                                                         + eta * ( tapex[i] - torg[i] );
12491                 }
12492 #else /* not TRILIBRARY */
12493                 /* Voronoi vertex number, x and y coordinates. */
12494                 fprintf( outfile, "%4d    %.17g  %.17g", vnodenumber, circumcenter[0],
12495                                  circumcenter[1] );
12496                 for ( i = 2; i < 2 + nextras; i++ ) {
12497                         /* Interpolate the point attributes at the circumcenter. */
12498                         fprintf( outfile, "  %.17g", torg[i] + xi * ( tdest[i] - torg[i] )
12499                                          + eta * ( tapex[i] - torg[i] ) );
12500                 }
12501                 fprintf( outfile, "\n" );
12502 #endif /* not TRILIBRARY */
12503
12504                 *(int *) ( triangleloop.tri + 6 ) = vnodenumber;
12505                 triangleloop.tri = triangletraverse();
12506                 vnodenumber++;
12507         }
12508
12509 #ifndef TRILIBRARY
12510         finishfile( outfile, argc, argv );
12511 #endif /* not TRILIBRARY */
12512
12513 #ifdef TRILIBRARY
12514         if ( !quiet ) {
12515                 printf( "Writing Voronoi edges.\n" );
12516         }
12517         /* Allocate memory for output Voronoi edges if necessary. */
12518         if ( *vedgelist == (int *) NULL ) {
12519                 *vedgelist = (int *) malloc( edges * 2 * sizeof( int ) );
12520                 if ( *vedgelist == (int *) NULL ) {
12521                         printf( "Error:  Out of memory.\n" );
12522                         exit( 1 );
12523                 }
12524         }
12525         *vedgemarkerlist = (int *) NULL;
12526         /* Allocate memory for output Voronoi norms if necessary. */
12527         if ( *vnormlist == (REAL *) NULL ) {
12528                 *vnormlist = (REAL *) malloc( edges * 2 * sizeof( REAL ) );
12529                 if ( *vnormlist == (REAL *) NULL ) {
12530                         printf( "Error:  Out of memory.\n" );
12531                         exit( 1 );
12532                 }
12533         }
12534         elist = *vedgelist;
12535         normlist = *vnormlist;
12536         coordindex = 0;
12537 #else /* not TRILIBRARY */
12538         if ( !quiet ) {
12539                 printf( "Writing %s.\n", vedgefilename );
12540         }
12541         outfile = fopen( vedgefilename, "w" );
12542         if ( outfile == (FILE *) NULL ) {
12543                 printf( "  Error:  Cannot create file %s.\n", vedgefilename );
12544                 exit( 1 );
12545         }
12546         /* Number of edges, zero boundary markers. */
12547         fprintf( outfile, "%ld  %d\n", edges, 0 );
12548 #endif /* not TRILIBRARY */
12549
12550         traversalinit( &triangles );
12551         triangleloop.tri = triangletraverse();
12552         vedgenumber = firstnumber;
12553         /* To loop over the set of edges, loop over all triangles, and look at   */
12554         /*   the three edges of each triangle.  If there isn't another triangle  */
12555         /*   adjacent to the edge, operate on the edge.  If there is another     */
12556         /*   adjacent triangle, operate on the edge only if the current triangle */
12557         /*   has a smaller pointer than its neighbor.  This way, each edge is    */
12558         /*   considered only once.                                               */
12559         while ( triangleloop.tri != (triangle *) NULL ) {
12560                 for ( triangleloop.orient = 0; triangleloop.orient < 3;
12561                           triangleloop.orient++ ) {
12562                         sym( triangleloop, trisym );
12563                         if ( ( triangleloop.tri < trisym.tri ) || ( trisym.tri == dummytri ) ) {
12564                                 /* Find the number of this triangle (and Voronoi vertex). */
12565                                 p1 = *(int *) ( triangleloop.tri + 6 );
12566                                 if ( trisym.tri == dummytri ) {
12567                                         org( triangleloop, torg );
12568                                         dest( triangleloop, tdest );
12569 #ifdef TRILIBRARY
12570                                         /* Copy an infinite ray.  Index of one endpoint, and -1. */
12571                                         elist[coordindex] = p1;
12572                                         normlist[coordindex++] = tdest[1] - torg[1];
12573                                         elist[coordindex] = -1;
12574                                         normlist[coordindex++] = torg[0] - tdest[0];
12575 #else /* not TRILIBRARY */
12576                                         /* Write an infinite ray.  Edge number, index of one endpoint, -1, */
12577                                         /*   and x and y coordinates of a vector representing the          */
12578                                         /*   direction of the ray.                                         */
12579                                         fprintf( outfile, "%4d   %d  %d   %.17g  %.17g\n", vedgenumber,
12580                                                          p1, -1, tdest[1] - torg[1], torg[0] - tdest[0] );
12581 #endif /* not TRILIBRARY */
12582                                 }
12583                                 else {
12584                                         /* Find the number of the adjacent triangle (and Voronoi vertex). */
12585                                         p2 = *(int *) ( trisym.tri + 6 );
12586                                         /* Finite edge.  Write indices of two endpoints. */
12587 #ifdef TRILIBRARY
12588                                         elist[coordindex] = p1;
12589                                         normlist[coordindex++] = 0.0;
12590                                         elist[coordindex] = p2;
12591                                         normlist[coordindex++] = 0.0;
12592 #else /* not TRILIBRARY */
12593                                         fprintf( outfile, "%4d   %d  %d\n", vedgenumber, p1, p2 );
12594 #endif /* not TRILIBRARY */
12595                                 }
12596                                 vedgenumber++;
12597                         }
12598                 }
12599                 triangleloop.tri = triangletraverse();
12600         }
12601
12602 #ifndef TRILIBRARY
12603         finishfile( outfile, argc, argv );
12604 #endif /* not TRILIBRARY */
12605 }
12606
12607 #ifdef TRILIBRARY
12608
12609 void writeneighbors( neighborlist )
12610 int **neighborlist;
12611
12612 #else /* not TRILIBRARY */
12613
12614 void writeneighbors( neighborfilename, argc, argv )
12615 char *neighborfilename;
12616 int argc;
12617 char **argv;
12618
12619 #endif /* not TRILIBRARY */
12620
12621 {
12622 #ifdef TRILIBRARY
12623         int *nlist;
12624         int index;
12625 #else /* not TRILIBRARY */
12626         FILE *outfile;
12627 #endif /* not TRILIBRARY */
12628         struct triedge triangleloop, trisym;
12629         int elementnumber;
12630         int neighbor1, neighbor2, neighbor3;
12631         triangle ptr;                       /* Temporary variable used by sym(). */
12632
12633 #ifdef TRILIBRARY
12634         if ( !quiet ) {
12635                 printf( "Writing neighbors.\n" );
12636         }
12637         /* Allocate memory for neighbors if necessary. */
12638         if ( *neighborlist == (int *) NULL ) {
12639                 *neighborlist = (int *) malloc( triangles.items * 3 * sizeof( int ) );
12640                 if ( *neighborlist == (int *) NULL ) {
12641                         printf( "Error:  Out of memory.\n" );
12642                         exit( 1 );
12643                 }
12644         }
12645         nlist = *neighborlist;
12646         index = 0;
12647 #else /* not TRILIBRARY */
12648         if ( !quiet ) {
12649                 printf( "Writing %s.\n", neighborfilename );
12650         }
12651         outfile = fopen( neighborfilename, "w" );
12652         if ( outfile == (FILE *) NULL ) {
12653                 printf( "  Error:  Cannot create file %s.\n", neighborfilename );
12654                 exit( 1 );
12655         }
12656         /* Number of triangles, three edges per triangle. */
12657         fprintf( outfile, "%ld  %d\n", triangles.items, 3 );
12658 #endif /* not TRILIBRARY */
12659
12660         traversalinit( &triangles );
12661         triangleloop.tri = triangletraverse();
12662         triangleloop.orient = 0;
12663         elementnumber = firstnumber;
12664         while ( triangleloop.tri != (triangle *) NULL ) {
12665                 *(int *) ( triangleloop.tri + 6 ) = elementnumber;
12666                 triangleloop.tri = triangletraverse();
12667                 elementnumber++;
12668         }
12669         *(int *) ( dummytri + 6 ) = -1;
12670
12671         traversalinit( &triangles );
12672         triangleloop.tri = triangletraverse();
12673         elementnumber = firstnumber;
12674         while ( triangleloop.tri != (triangle *) NULL ) {
12675                 triangleloop.orient = 1;
12676                 sym( triangleloop, trisym );
12677                 neighbor1 = *(int *) ( trisym.tri + 6 );
12678                 triangleloop.orient = 2;
12679                 sym( triangleloop, trisym );
12680                 neighbor2 = *(int *) ( trisym.tri + 6 );
12681                 triangleloop.orient = 0;
12682                 sym( triangleloop, trisym );
12683                 neighbor3 = *(int *) ( trisym.tri + 6 );
12684 #ifdef TRILIBRARY
12685                 nlist[index++] = neighbor1;
12686                 nlist[index++] = neighbor2;
12687                 nlist[index++] = neighbor3;
12688 #else /* not TRILIBRARY */
12689                 /* Triangle number, neighboring triangle numbers. */
12690                 fprintf( outfile, "%4d    %d  %d  %d\n", elementnumber,
12691                                  neighbor1, neighbor2, neighbor3 );
12692 #endif /* not TRILIBRARY */
12693
12694                 triangleloop.tri = triangletraverse();
12695                 elementnumber++;
12696         }
12697
12698 #ifndef TRILIBRARY
12699         finishfile( outfile, argc, argv );
12700 #endif /* TRILIBRARY */
12701 }
12702
12703 /*****************************************************************************/
12704 /*                                                                           */
12705 /*  writeoff()   Write the triangulation to an .off file.                    */
12706 /*                                                                           */
12707 /*  OFF stands for the Object File Format, a format used by the Geometry     */
12708 /*  Center's Geomview package.                                               */
12709 /*                                                                           */
12710 /*****************************************************************************/
12711
12712 #ifndef TRILIBRARY
12713
12714 void writeoff( offfilename, argc, argv )
12715 char *offfilename;
12716 int argc;
12717 char **argv;
12718 {
12719         FILE *outfile;
12720         struct triedge triangleloop;
12721         point pointloop;
12722         point p1, p2, p3;
12723
12724         if ( !quiet ) {
12725                 printf( "Writing %s.\n", offfilename );
12726         }
12727         outfile = fopen( offfilename, "w" );
12728         if ( outfile == (FILE *) NULL ) {
12729                 printf( "  Error:  Cannot create file %s.\n", offfilename );
12730                 exit( 1 );
12731         }
12732         /* Number of points, triangles, and edges. */
12733         fprintf( outfile, "OFF\n%ld  %ld  %ld\n", points.items, triangles.items,
12734                          edges );
12735
12736         /* Write the points. */
12737         traversalinit( &points );
12738         pointloop = pointtraverse();
12739         while ( pointloop != (point) NULL ) {
12740                 /* The "0.0" is here because the OFF format uses 3D coordinates. */
12741                 fprintf( outfile, " %.17g  %.17g  %.17g\n", pointloop[0],
12742                                  pointloop[1], 0.0 );
12743                 pointloop = pointtraverse();
12744         }
12745
12746         /* Write the triangles. */
12747         traversalinit( &triangles );
12748         triangleloop.tri = triangletraverse();
12749         triangleloop.orient = 0;
12750         while ( triangleloop.tri != (triangle *) NULL ) {
12751                 org( triangleloop, p1 );
12752                 dest( triangleloop, p2 );
12753                 apex( triangleloop, p3 );
12754                 /* The "3" means a three-vertex polygon. */
12755                 fprintf( outfile, " 3   %4d  %4d  %4d\n", pointmark( p1 ) - 1,
12756                                  pointmark( p2 ) - 1, pointmark( p3 ) - 1 );
12757                 triangleloop.tri = triangletraverse();
12758         }
12759         finishfile( outfile, argc, argv );
12760 }
12761
12762 #endif /* not TRILIBRARY */
12763
12764 /**                                                                         **/
12765 /**                                                                         **/
12766 /********* File I/O routines end here                                *********/
12767
12768 /*****************************************************************************/
12769 /*                                                                           */
12770 /*  quality_statistics()   Print statistics about the quality of the mesh.   */
12771 /*                                                                           */
12772 /*****************************************************************************/
12773
12774 void quality_statistics(){
12775         struct triedge triangleloop;
12776         point p[3];
12777         REAL cossquaretable[8];
12778         REAL ratiotable[16];
12779         REAL dx[3], dy[3];
12780         REAL edgelength[3];
12781         REAL dotproduct;
12782         REAL cossquare;
12783         REAL triarea;
12784         REAL shortest, longest;
12785         REAL trilongest2;
12786         REAL smallestarea, biggestarea;
12787         REAL triminaltitude2;
12788         REAL minaltitude;
12789         REAL triaspect2;
12790         REAL worstaspect;
12791         REAL smallestangle, biggestangle;
12792         REAL radconst, degconst;
12793         int angletable[18];
12794         int aspecttable[16];
12795         int aspectindex;
12796         int tendegree;
12797         int acutebiggest;
12798         int i, ii, j, k;
12799
12800         printf( "Mesh quality statistics:\n\n" );
12801         radconst = (REAL)( PI / 18.0 );
12802         degconst = (REAL)( 180.0 / PI );
12803         for ( i = 0; i < 8; i++ ) {
12804                 cossquaretable[i] = (REAL)( cos( radconst * (REAL) ( i + 1 ) ) );
12805                 cossquaretable[i] = cossquaretable[i] * cossquaretable[i];
12806         }
12807         for ( i = 0; i < 18; i++ ) {
12808                 angletable[i] = 0;
12809         }
12810
12811         ratiotable[0]  =      1.5;      ratiotable[1]  =     2.0;
12812         ratiotable[2]  =      2.5;      ratiotable[3]  =     3.0;
12813         ratiotable[4]  =      4.0;      ratiotable[5]  =     6.0;
12814         ratiotable[6]  =     10.0;      ratiotable[7]  =    15.0;
12815         ratiotable[8]  =     25.0;      ratiotable[9]  =    50.0;
12816         ratiotable[10] =    100.0;      ratiotable[11] =   300.0;
12817         ratiotable[12] =   1000.0;      ratiotable[13] = 10000.0;
12818         ratiotable[14] = 100000.0;      ratiotable[15] =     0.0;
12819         for ( i = 0; i < 16; i++ ) {
12820                 aspecttable[i] = 0;
12821         }
12822
12823         worstaspect = 0.0;
12824         minaltitude = xmax - xmin + ymax - ymin;
12825         minaltitude = minaltitude * minaltitude;
12826         shortest = minaltitude;
12827         longest = 0.0;
12828         smallestarea = minaltitude;
12829         biggestarea = 0.0;
12830         worstaspect = 0.0;
12831         smallestangle = 0.0;
12832         biggestangle = 2.0;
12833         acutebiggest = 1;
12834
12835         traversalinit( &triangles );
12836         triangleloop.tri = triangletraverse();
12837         triangleloop.orient = 0;
12838         while ( triangleloop.tri != (triangle *) NULL ) {
12839                 org( triangleloop, p[0] );
12840                 dest( triangleloop, p[1] );
12841                 apex( triangleloop, p[2] );
12842                 trilongest2 = 0.0;
12843
12844                 for ( i = 0; i < 3; i++ ) {
12845                         j = plus1mod3[i];
12846                         k = minus1mod3[i];
12847                         dx[i] = p[j][0] - p[k][0];
12848                         dy[i] = p[j][1] - p[k][1];
12849                         edgelength[i] = dx[i] * dx[i] + dy[i] * dy[i];
12850                         if ( edgelength[i] > trilongest2 ) {
12851                                 trilongest2 = edgelength[i];
12852                         }
12853                         if ( edgelength[i] > longest ) {
12854                                 longest = edgelength[i];
12855                         }
12856                         if ( edgelength[i] < shortest ) {
12857                                 shortest = edgelength[i];
12858                         }
12859                 }
12860
12861                 triarea = counterclockwise( p[0], p[1], p[2] );
12862                 if ( triarea < smallestarea ) {
12863                         smallestarea = triarea;
12864                 }
12865                 if ( triarea > biggestarea ) {
12866                         biggestarea = triarea;
12867                 }
12868                 triminaltitude2 = triarea * triarea / trilongest2;
12869                 if ( triminaltitude2 < minaltitude ) {
12870                         minaltitude = triminaltitude2;
12871                 }
12872                 triaspect2 = trilongest2 / triminaltitude2;
12873                 if ( triaspect2 > worstaspect ) {
12874                         worstaspect = triaspect2;
12875                 }
12876                 aspectindex = 0;
12877                 while ( ( triaspect2 > ratiotable[aspectindex] * ratiotable[aspectindex] )
12878                                 && ( aspectindex < 15 ) ) {
12879                         aspectindex++;
12880                 }
12881                 aspecttable[aspectindex]++;
12882
12883                 for ( i = 0; i < 3; i++ ) {
12884                         j = plus1mod3[i];
12885                         k = minus1mod3[i];
12886                         dotproduct = dx[j] * dx[k] + dy[j] * dy[k];
12887                         cossquare = dotproduct * dotproduct / ( edgelength[j] * edgelength[k] );
12888                         tendegree = 8;
12889                         for ( ii = 7; ii >= 0; ii-- ) {
12890                                 if ( cossquare > cossquaretable[ii] ) {
12891                                         tendegree = ii;
12892                                 }
12893                         }
12894                         if ( dotproduct <= 0.0 ) {
12895                                 angletable[tendegree]++;
12896                                 if ( cossquare > smallestangle ) {
12897                                         smallestangle = cossquare;
12898                                 }
12899                                 if ( acutebiggest && ( cossquare < biggestangle ) ) {
12900                                         biggestangle = cossquare;
12901                                 }
12902                         }
12903                         else {
12904                                 angletable[17 - tendegree]++;
12905                                 if ( acutebiggest || ( cossquare > biggestangle ) ) {
12906                                         biggestangle = cossquare;
12907                                         acutebiggest = 0;
12908                                 }
12909                         }
12910                 }
12911                 triangleloop.tri = triangletraverse();
12912         }
12913
12914         shortest = (REAL)sqrt( shortest );
12915         longest = (REAL)sqrt( longest );
12916         minaltitude = (REAL)sqrt( minaltitude );
12917         worstaspect = (REAL)sqrt( worstaspect );
12918         smallestarea *= 2.0;
12919         biggestarea *= 2.0;
12920         if ( smallestangle >= 1.0 ) {
12921                 smallestangle = 0.0;
12922         }
12923         else {
12924                 smallestangle = (REAL)( degconst * acos( sqrt( smallestangle ) ) );
12925         }
12926         if ( biggestangle >= 1.0 ) {
12927                 biggestangle = 180.0;
12928         }
12929         else {
12930                 if ( acutebiggest ) {
12931                         biggestangle = (REAL)( degconst * acos( sqrt( biggestangle ) ) );
12932                 }
12933                 else {
12934                         biggestangle = (REAL)( 180.0 - degconst * acos( sqrt( biggestangle ) ) );
12935                 }
12936         }
12937
12938         printf( "  Smallest area: %16.5g   |  Largest area: %16.5g\n",
12939                         smallestarea, biggestarea );
12940         printf( "  Shortest edge: %16.5g   |  Longest edge: %16.5g\n",
12941                         shortest, longest );
12942         printf( "  Shortest altitude: %12.5g   |  Largest aspect ratio: %8.5g\n\n",
12943                         minaltitude, worstaspect );
12944         printf( "  Aspect ratio histogram:\n" );
12945         printf( "  1.1547 - %-6.6g    :  %8d    | %6.6g - %-6.6g     :  %8d\n",
12946                         ratiotable[0], aspecttable[0], ratiotable[7], ratiotable[8],
12947                         aspecttable[8] );
12948         for ( i = 1; i < 7; i++ ) {
12949                 printf( "  %6.6g - %-6.6g    :  %8d    | %6.6g - %-6.6g     :  %8d\n",
12950                                 ratiotable[i - 1], ratiotable[i], aspecttable[i],
12951                                 ratiotable[i + 7], ratiotable[i + 8], aspecttable[i + 8] );
12952         }
12953         printf( "  %6.6g - %-6.6g    :  %8d    | %6.6g -            :  %8d\n",
12954                         ratiotable[6], ratiotable[7], aspecttable[7], ratiotable[14],
12955                         aspecttable[15] );
12956         printf(
12957                 "  (Triangle aspect ratio is longest edge divided by shortest altitude)\n\n" );
12958         printf( "  Smallest angle: %15.5g   |  Largest angle: %15.5g\n\n",
12959                         smallestangle, biggestangle );
12960         printf( "  Angle histogram:\n" );
12961         for ( i = 0; i < 9; i++ ) {
12962                 printf( "    %3d - %3d degrees:  %8d    |    %3d - %3d degrees:  %8d\n",
12963                                 i * 10, i * 10 + 10, angletable[i],
12964                                 i * 10 + 90, i * 10 + 100, angletable[i + 9] );
12965         }
12966         printf( "\n" );
12967 }
12968
12969 /*****************************************************************************/
12970 /*                                                                           */
12971 /*  statistics()   Print all sorts of cool facts.                            */
12972 /*                                                                           */
12973 /*****************************************************************************/
12974
12975 void statistics(){
12976         printf( "\nStatistics:\n\n" );
12977         printf( "  Input points: %d\n", inpoints );
12978         if ( refine ) {
12979                 printf( "  Input triangles: %d\n", inelements );
12980         }
12981         if ( poly ) {
12982                 printf( "  Input segments: %d\n", insegments );
12983                 if ( !refine ) {
12984                         printf( "  Input holes: %d\n", holes );
12985                 }
12986         }
12987
12988         printf( "\n  Mesh points: %ld\n", points.items );
12989         printf( "  Mesh triangles: %ld\n", triangles.items );
12990         printf( "  Mesh edges: %ld\n", edges );
12991         if ( poly || refine ) {
12992                 printf( "  Mesh boundary edges: %ld\n", hullsize );
12993                 printf( "  Mesh segments: %ld\n\n", shelles.items );
12994         }
12995         else {
12996                 printf( "  Mesh convex hull edges: %ld\n\n", hullsize );
12997         }
12998         if ( verbose ) {
12999                 quality_statistics();
13000                 printf( "Memory allocation statistics:\n\n" );
13001                 printf( "  Maximum number of points: %ld\n", points.maxitems );
13002                 printf( "  Maximum number of triangles: %ld\n", triangles.maxitems );
13003                 if ( shelles.maxitems > 0 ) {
13004                         printf( "  Maximum number of segments: %ld\n", shelles.maxitems );
13005                 }
13006                 if ( viri.maxitems > 0 ) {
13007                         printf( "  Maximum number of viri: %ld\n", viri.maxitems );
13008                 }
13009                 if ( badsegments.maxitems > 0 ) {
13010                         printf( "  Maximum number of encroached segments: %ld\n",
13011                                         badsegments.maxitems );
13012                 }
13013                 if ( badtriangles.maxitems > 0 ) {
13014                         printf( "  Maximum number of bad triangles: %ld\n",
13015                                         badtriangles.maxitems );
13016                 }
13017                 if ( splaynodes.maxitems > 0 ) {
13018                         printf( "  Maximum number of splay tree nodes: %ld\n",
13019                                         splaynodes.maxitems );
13020                 }
13021                 printf( "  Approximate heap memory use (bytes): %ld\n\n",
13022                                 points.maxitems * points.itembytes
13023                                 + triangles.maxitems * triangles.itembytes
13024                                 + shelles.maxitems * shelles.itembytes
13025                                 + viri.maxitems * viri.itembytes
13026                                 + badsegments.maxitems * badsegments.itembytes
13027                                 + badtriangles.maxitems * badtriangles.itembytes
13028                                 + splaynodes.maxitems * splaynodes.itembytes );
13029
13030                 printf( "Algorithmic statistics:\n\n" );
13031                 printf( "  Number of incircle tests: %ld\n", incirclecount );
13032                 printf( "  Number of orientation tests: %ld\n", counterclockcount );
13033                 if ( hyperbolacount > 0 ) {
13034                         printf( "  Number of right-of-hyperbola tests: %ld\n",
13035                                         hyperbolacount );
13036                 }
13037                 if ( circumcentercount > 0 ) {
13038                         printf( "  Number of circumcenter computations: %ld\n",
13039                                         circumcentercount );
13040                 }
13041                 if ( circletopcount > 0 ) {
13042                         printf( "  Number of circle top computations: %ld\n",
13043                                         circletopcount );
13044                 }
13045                 printf( "\n" );
13046         }
13047 }
13048
13049 /*****************************************************************************/
13050 /*                                                                           */
13051 /*  main() or triangulate()   Gosh, do everything.                           */
13052 /*                                                                           */
13053 /*  The sequence is roughly as follows.  Many of these steps can be skipped, */
13054 /*  depending on the command line switches.                                  */
13055 /*                                                                           */
13056 /*  - Initialize constants and parse the command line.                       */
13057 /*  - Read the points from a file and either                                 */
13058 /*    - triangulate them (no -r), or                                         */
13059 /*    - read an old mesh from files and reconstruct it (-r).                 */
13060 /*  - Insert the PSLG segments (-p), and possibly segments on the convex     */
13061 /*      hull (-c).                                                           */
13062 /*  - Read the holes (-p), regional attributes (-pA), and regional area      */
13063 /*      constraints (-pa).  Carve the holes and concavities, and spread the  */
13064 /*      regional attributes and area constraints.                            */
13065 /*  - Enforce the constraints on minimum angle (-q) and maximum area (-a).   */
13066 /*      Also enforce the conforming Delaunay property (-q and -a).           */
13067 /*  - Compute the number of edges in the resulting mesh.                     */
13068 /*  - Promote the mesh's linear triangles to higher order elements (-o).     */
13069 /*  - Write the output files and print the statistics.                       */
13070 /*  - Check the consistency and Delaunay property of the mesh (-C).          */
13071 /*                                                                           */
13072 /*****************************************************************************/
13073
13074 #ifdef TRILIBRARY
13075
13076 void triangulate( triswitches, in, out, vorout )
13077 char *triswitches;
13078 struct triangulateio *in;
13079 struct triangulateio *out;
13080 struct triangulateio *vorout;
13081
13082 #else /* not TRILIBRARY */
13083
13084 int main( argc, argv )
13085 int argc;
13086 char **argv;
13087
13088 #endif /* not TRILIBRARY */
13089
13090 {
13091         REAL *holearray;                                      /* Array of holes. */
13092         REAL *regionarray; /* Array of regional attributes and area constraints. */
13093 #ifndef TRILIBRARY
13094         FILE *polyfile;
13095 #endif /* not TRILIBRARY */
13096 #ifndef NO_TIMER
13097         /* Variables for timing the performance of Triangle.  The types are */
13098         /*   defined in sys/time.h.                                         */
13099         struct timeval tv0, tv1, tv2, tv3, tv4, tv5, tv6;
13100         struct timezone tz;
13101 #endif /* NO_TIMER */
13102
13103 #ifndef NO_TIMER
13104         gettimeofday( &tv0, &tz );
13105 #endif /* NO_TIMER */
13106
13107         triangleinit();
13108 #ifdef TRILIBRARY
13109         parsecommandline( 1, &triswitches );
13110 #else /* not TRILIBRARY */
13111         parsecommandline( argc, argv );
13112 #endif /* not TRILIBRARY */
13113
13114 #ifdef TRILIBRARY
13115         transfernodes( in->pointlist, in->pointattributelist, in->pointmarkerlist,
13116                                    in->numberofpoints, in->numberofpointattributes );
13117 #else /* not TRILIBRARY */
13118         readnodes( innodefilename, inpolyfilename, &polyfile );
13119 #endif /* not TRILIBRARY */
13120
13121 #ifndef NO_TIMER
13122         if ( !quiet ) {
13123                 gettimeofday( &tv1, &tz );
13124         }
13125 #endif /* NO_TIMER */
13126
13127 #ifdef CDT_ONLY
13128         hullsize = delaunay();                        /* Triangulate the points. */
13129 #else /* not CDT_ONLY */
13130         if ( refine ) {
13131                 /* Read and reconstruct a mesh. */
13132 #ifdef TRILIBRARY
13133                 hullsize = reconstruct( in->trianglelist, in->triangleattributelist,
13134                                                                 in->trianglearealist, in->numberoftriangles,
13135                                                                 in->numberofcorners, in->numberoftriangleattributes,
13136                                                                 in->segmentlist, in->segmentmarkerlist,
13137                                                                 in->numberofsegments );
13138 #else /* not TRILIBRARY */
13139                 hullsize = reconstruct( inelefilename, areafilename, inpolyfilename,
13140                                                                 polyfile );
13141 #endif /* not TRILIBRARY */
13142         }
13143         else {
13144                 hullsize = delaunay();                    /* Triangulate the points. */
13145         }
13146 #endif /* not CDT_ONLY */
13147
13148 #ifndef NO_TIMER
13149         if ( !quiet ) {
13150                 gettimeofday( &tv2, &tz );
13151                 if ( refine ) {
13152                         printf( "Mesh reconstruction" );
13153                 }
13154                 else {
13155                         printf( "Delaunay" );
13156                 }
13157                 printf( " milliseconds:  %ld\n", 1000l * ( tv2.tv_sec - tv1.tv_sec )
13158                                 + ( tv2.tv_usec - tv1.tv_usec ) / 1000l );
13159         }
13160 #endif /* NO_TIMER */
13161
13162         /* Ensure that no point can be mistaken for a triangular bounding */
13163         /*   box point in insertsite().                                   */
13164         infpoint1 = (point) NULL;
13165         infpoint2 = (point) NULL;
13166         infpoint3 = (point) NULL;
13167
13168         if ( useshelles ) {
13169                 checksegments = 1;              /* Segments will be introduced next. */
13170                 if ( !refine ) {
13171                         /* Insert PSLG segments and/or convex hull segments. */
13172 #ifdef TRILIBRARY
13173                         insegments = formskeleton( in->segmentlist, in->segmentmarkerlist,
13174                                                                            in->numberofsegments );
13175 #else /* not TRILIBRARY */
13176                         insegments = formskeleton( polyfile, inpolyfilename );
13177 #endif /* not TRILIBRARY */
13178                 }
13179         }
13180
13181 #ifndef NO_TIMER
13182         if ( !quiet ) {
13183                 gettimeofday( &tv3, &tz );
13184                 if ( useshelles && !refine ) {
13185                         printf( "Segment milliseconds:  %ld\n",
13186                                         1000l * ( tv3.tv_sec - tv2.tv_sec )
13187                                         + ( tv3.tv_usec - tv2.tv_usec ) / 1000l );
13188                 }
13189         }
13190 #endif /* NO_TIMER */
13191
13192         if ( poly ) {
13193 #ifdef TRILIBRARY
13194                 holearray = in->holelist;
13195                 holes = in->numberofholes;
13196                 regionarray = in->regionlist;
13197                 regions = in->numberofregions;
13198 #else /* not TRILIBRARY */
13199                 readholes( polyfile, inpolyfilename, &holearray, &holes,
13200                                    &regionarray, &regions );
13201 #endif /* not TRILIBRARY */
13202                 if ( !refine ) {
13203                         /* Carve out holes and concavities. */
13204                         carveholes( holearray, holes, regionarray, regions );
13205                 }
13206         }
13207         else {
13208                 /* Without a PSLG, there can be no holes or regional attributes   */
13209                 /*   or area constraints.  The following are set to zero to avoid */
13210                 /*   an accidental free() later.                                  */
13211                 holes = 0;
13212                 regions = 0;
13213         }
13214
13215 #ifndef NO_TIMER
13216         if ( !quiet ) {
13217                 gettimeofday( &tv4, &tz );
13218                 if ( poly && !refine ) {
13219                         printf( "Hole milliseconds:  %ld\n", 1000l * ( tv4.tv_sec - tv3.tv_sec )
13220                                         + ( tv4.tv_usec - tv3.tv_usec ) / 1000l );
13221                 }
13222         }
13223 #endif /* NO_TIMER */
13224
13225 #ifndef CDT_ONLY
13226         if ( quality ) {
13227                 enforcequality();             /* Enforce angle and area constraints. */
13228         }
13229 #endif /* not CDT_ONLY */
13230
13231 #ifndef NO_TIMER
13232         if ( !quiet ) {
13233                 gettimeofday( &tv5, &tz );
13234 #ifndef CDT_ONLY
13235                 if ( quality ) {
13236                         printf( "Quality milliseconds:  %ld\n",
13237                                         1000l * ( tv5.tv_sec - tv4.tv_sec )
13238                                         + ( tv5.tv_usec - tv4.tv_usec ) / 1000l );
13239                 }
13240 #endif /* not CDT_ONLY */
13241         }
13242 #endif /* NO_TIMER */
13243
13244         /* Compute the number of edges. */
13245         edges = ( 3l * triangles.items + hullsize ) / 2l;
13246
13247         if ( order > 1 ) {
13248                 highorder();         /* Promote elements to higher polynomial order. */
13249         }
13250         if ( !quiet ) {
13251                 printf( "\n" );
13252         }
13253
13254 #ifdef TRILIBRARY
13255         out->numberofpoints = points.items;
13256         out->numberofpointattributes = nextras;
13257         out->numberoftriangles = triangles.items;
13258         out->numberofcorners = ( order + 1 ) * ( order + 2 ) / 2;
13259         out->numberoftriangleattributes = eextras;
13260         out->numberofedges = edges;
13261         if ( useshelles ) {
13262                 out->numberofsegments = shelles.items;
13263         }
13264         else {
13265                 out->numberofsegments = hullsize;
13266         }
13267         if ( vorout != (struct triangulateio *) NULL ) {
13268                 vorout->numberofpoints = triangles.items;
13269                 vorout->numberofpointattributes = nextras;
13270                 vorout->numberofedges = edges;
13271         }
13272 #endif /* TRILIBRARY */
13273         /* If not using iteration numbers, don't write a .node file if one was */
13274         /*   read, because the original one would be overwritten!              */
13275         if ( nonodewritten || ( noiterationnum && readnodefile ) ) {
13276                 if ( !quiet ) {
13277 #ifdef TRILIBRARY
13278                         printf( "NOT writing points.\n" );
13279 #else /* not TRILIBRARY */
13280                         printf( "NOT writing a .node file.\n" );
13281 #endif /* not TRILIBRARY */
13282                 }
13283                 numbernodes();             /* We must remember to number the points. */
13284         }
13285         else {
13286 #ifdef TRILIBRARY
13287                 writenodes( &out->pointlist, &out->pointattributelist,
13288                                         &out->pointmarkerlist );
13289 #else /* not TRILIBRARY */
13290                 writenodes( outnodefilename, argc, argv ); /* Numbers the points too. */
13291 #endif /* TRILIBRARY */
13292         }
13293         if ( noelewritten ) {
13294                 if ( !quiet ) {
13295 #ifdef TRILIBRARY
13296                         printf( "NOT writing triangles.\n" );
13297 #else /* not TRILIBRARY */
13298                         printf( "NOT writing an .ele file.\n" );
13299 #endif /* not TRILIBRARY */
13300                 }
13301         }
13302         else {
13303 #ifdef TRILIBRARY
13304                 writeelements( &out->trianglelist, &out->triangleattributelist );
13305 #else /* not TRILIBRARY */
13306                 writeelements( outelefilename, argc, argv );
13307 #endif /* not TRILIBRARY */
13308         }
13309         /* The -c switch (convex switch) causes a PSLG to be written */
13310         /*   even if none was read.                                  */
13311         if ( poly || convex ) {
13312                 /* If not using iteration numbers, don't overwrite the .poly file. */
13313                 if ( nopolywritten || noiterationnum ) {
13314                         if ( !quiet ) {
13315 #ifdef TRILIBRARY
13316                                 printf( "NOT writing segments.\n" );
13317 #else /* not TRILIBRARY */
13318                                 printf( "NOT writing a .poly file.\n" );
13319 #endif /* not TRILIBRARY */
13320                         }
13321                 }
13322                 else {
13323 #ifdef TRILIBRARY
13324                         writepoly( &out->segmentlist, &out->segmentmarkerlist );
13325                         out->numberofholes = holes;
13326                         out->numberofregions = regions;
13327                         if ( poly ) {
13328                                 out->holelist = in->holelist;
13329                                 out->regionlist = in->regionlist;
13330                         }
13331                         else {
13332                                 out->holelist = (REAL *) NULL;
13333                                 out->regionlist = (REAL *) NULL;
13334                         }
13335 #else /* not TRILIBRARY */
13336                         writepoly( outpolyfilename, holearray, holes, regionarray, regions,
13337                                            argc, argv );
13338 #endif /* not TRILIBRARY */
13339                 }
13340         }
13341 #ifndef TRILIBRARY
13342 #ifndef CDT_ONLY
13343         if ( regions > 0 ) {
13344                 free( regionarray );
13345         }
13346 #endif /* not CDT_ONLY */
13347         if ( holes > 0 ) {
13348                 free( holearray );
13349         }
13350         if ( geomview ) {
13351                 writeoff( offfilename, argc, argv );
13352         }
13353 #endif /* not TRILIBRARY */
13354         if ( edgesout ) {
13355 #ifdef TRILIBRARY
13356                 writeedges( &out->edgelist, &out->edgemarkerlist );
13357 #else /* not TRILIBRARY */
13358                 writeedges( edgefilename, argc, argv );
13359 #endif /* not TRILIBRARY */
13360         }
13361         if ( voronoi ) {
13362 #ifdef TRILIBRARY
13363                 writevoronoi( &vorout->pointlist, &vorout->pointattributelist,
13364                                           &vorout->pointmarkerlist, &vorout->edgelist,
13365                                           &vorout->edgemarkerlist, &vorout->normlist );
13366 #else /* not TRILIBRARY */
13367                 writevoronoi( vnodefilename, vedgefilename, argc, argv );
13368 #endif /* not TRILIBRARY */
13369         }
13370         if ( neighbors ) {
13371 #ifdef TRILIBRARY
13372                 writeneighbors( &out->neighborlist );
13373 #else /* not TRILIBRARY */
13374                 writeneighbors( neighborfilename, argc, argv );
13375 #endif /* not TRILIBRARY */
13376         }
13377
13378         if ( !quiet ) {
13379 #ifndef NO_TIMER
13380                 gettimeofday( &tv6, &tz );
13381                 printf( "\nOutput milliseconds:  %ld\n",
13382                                 1000l * ( tv6.tv_sec - tv5.tv_sec )
13383                                 + ( tv6.tv_usec - tv5.tv_usec ) / 1000l );
13384                 printf( "Total running milliseconds:  %ld\n",
13385                                 1000l * ( tv6.tv_sec - tv0.tv_sec )
13386                                 + ( tv6.tv_usec - tv0.tv_usec ) / 1000l );
13387 #endif /* NO_TIMER */
13388
13389                 statistics();
13390         }
13391
13392 #ifndef REDUCED
13393         if ( docheck ) {
13394                 checkmesh();
13395                 checkdelaunay();
13396         }
13397 #endif /* not REDUCED */
13398
13399         triangledeinit();
13400 #ifndef TRILIBRARY
13401         return 0;
13402 #endif /* not TRILIBRARY */
13403 }