]> git.xonotic.org Git - xonotic/netradiant.git/blob - contrib/gtkgensurf/triangle.c
reformat code! now the code is only ugly on the *inside*
[xonotic/netradiant.git] / contrib / gtkgensurf / triangle.c
1 #define
2 ANSI_DECLARATORS
3 /*****************************************************************************/
4 /*                                                                           */
5 /*      888888888        ,o,                          / 888                  */
6 /*         888    88o88o  "    o8888o  88o8888o o88888o 888  o88888o         */
7 /*         888    888    888       88b 888  888 888 888 888 d888  88b        */
8 /*         888    888    888  o88^o888 888  888 "88888" 888 8888oo888        */
9 /*         888    888    888 C888  888 888  888  /      888 q888             */
10 /*         888    888    888  "88o^888 888  888 Cb      888  "88oooo"        */
11 /*                                              "8oo8D                       */
12 /*                                                                           */
13 /*  A Two-Dimensional Quality Mesh Generator and Delaunay Triangulator.      */
14 /*  (triangle.c)                                                             */
15 /*                                                                           */
16 /*  Version 1.3                                                              */
17 /*  July 19, 1996                                                            */
18 /*                                                                           */
19 /*  Copyright 1996                                                           */
20 /*  Jonathan Richard Shewchuk                                                */
21 /*  School of Computer Science                                               */
22 /*  Carnegie Mellon University                                               */
23 /*  5000 Forbes Avenue                                                       */
24 /*  Pittsburgh, Pennsylvania  15213-3891                                     */
25 /*  jrs@cs.cmu.edu                                                           */
26 /*                                                                           */
27 /*  This program may be freely redistributed under the condition that the    */
28 /*    copyright notices (including this entire header and the copyright      */
29 /*    notice printed when the `-h' switch is selected) are not removed, and  */
30 /*    no compensation is received.  Private, research, and institutional     */
31 /*    use is free.  You may distribute modified versions of this code UNDER  */
32 /*    THE CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE TO IT IN THE   */
33 /*    SAME FILE REMAIN UNDER COPYRIGHT OF THE ORIGINAL AUTHOR, BOTH SOURCE   */
34 /*    AND OBJECT CODE ARE MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR    */
35 /*    NOTICE IS GIVEN OF THE MODIFICATIONS.  Distribution of this code as    */
36 /*    part of a commercial system is permissible ONLY BY DIRECT ARRANGEMENT  */
37 /*    WITH THE AUTHOR.  (If you are not directly supplying this code to a    */
38 /*    customer, and you are instead telling them how they can obtain it for  */
39 /*    free, then you are not required to make any arrangement with me.)      */
40 /*                                                                           */
41 /*  Hypertext instructions for Triangle are available on the Web at          */
42 /*                                                                           */
43 /*      http://www.cs.cmu.edu/~quake/triangle.html                           */
44 /*                                                                           */
45 /*  Some of the references listed below are marked [*].  These are available */
46 /*    for downloading from the Web page                                      */
47 /*                                                                           */
48 /*      http://www.cs.cmu.edu/~quake/triangle.research.html                  */
49 /*                                                                           */
50 /*  A paper discussing some aspects of Triangle is available.  See Jonathan  */
51 /*    Richard Shewchuk, "Triangle:  Engineering a 2D Quality Mesh Generator  */
52 /*    and Delaunay Triangulator," First Workshop on Applied Computational    */
53 /*    Geometry, ACM, May 1996.  [*]                                          */
54 /*                                                                           */
55 /*  Triangle was created as part of the Archimedes project in the School of  */
56 /*    Computer Science at Carnegie Mellon University.  Archimedes is a       */
57 /*    system for compiling parallel finite element solvers.  For further     */
58 /*    information, see Anja Feldmann, Omar Ghattas, John R. Gilbert, Gary L. */
59 /*    Miller, David R. O'Hallaron, Eric J. Schwabe, Jonathan R. Shewchuk,    */
60 /*    and Shang-Hua Teng, "Automated Parallel Solution of Unstructured PDE   */
61 /*    Problems."  To appear in Communications of the ACM, we hope.           */
62 /*                                                                           */
63 /*  The quality mesh generation algorithm is due to Jim Ruppert, "A          */
64 /*    Delaunay Refinement Algorithm for Quality 2-Dimensional Mesh           */
65 /*    Generation," Journal of Algorithms 18(3):548-585, May 1995.  [*]       */
66 /*                                                                           */
67 /*  My implementation of the divide-and-conquer and incremental Delaunay     */
68 /*    triangulation algorithms follows closely the presentation of Guibas    */
69 /*    and Stolfi, even though I use a triangle-based data structure instead  */
70 /*    of their quad-edge data structure.  (In fact, I originally implemented */
71 /*    Triangle using the quad-edge data structure, but switching to a        */
72 /*    triangle-based data structure sped Triangle by a factor of two.)  The  */
73 /*    mesh manipulation primitives and the two aforementioned Delaunay       */
74 /*    triangulation algorithms are described by Leonidas J. Guibas and Jorge */
75 /*    Stolfi, "Primitives for the Manipulation of General Subdivisions and   */
76 /*    the Computation of Voronoi Diagrams," ACM Transactions on Graphics     */
77 /*    4(2):74-123, April 1985.                                               */
78 /*                                                                           */
79 /*  Their O(n log n) divide-and-conquer algorithm is adapted from Der-Tsai   */
80 /*    Lee and Bruce J. Schachter, "Two Algorithms for Constructing the       */
81 /*    Delaunay Triangulation," International Journal of Computer and         */
82 /*    Information Science 9(3):219-242, 1980.  The idea to improve the       */
83 /*    divide-and-conquer algorithm by alternating between vertical and       */
84 /*    horizontal cuts was introduced by Rex A. Dwyer, "A Faster Divide-and-  */
85 /*    Conquer Algorithm for Constructing Delaunay Triangulations,"           */
86 /*    Algorithmica 2(2):137-151, 1987.                                       */
87 /*                                                                           */
88 /*  The incremental insertion algorithm was first proposed by C. L. Lawson,  */
89 /*    "Software for C1 Surface Interpolation," in Mathematical Software III, */
90 /*    John R. Rice, editor, Academic Press, New York, pp. 161-194, 1977.     */
91 /*    For point location, I use the algorithm of Ernst P. Mucke, Isaac       */
92 /*    Saias, and Binhai Zhu, "Fast Randomized Point Location Without         */
93 /*    Preprocessing in Two- and Three-dimensional Delaunay Triangulations,"  */
94 /*    Proceedings of the Twelfth Annual Symposium on Computational Geometry, */
95 /*    ACM, May 1996.  [*]  If I were to randomize the order of point         */
96 /*    insertion (I currently don't bother), their result combined with the   */
97 /*    result of Leonidas J. Guibas, Donald E. Knuth, and Micha Sharir,       */
98 /*    "Randomized Incremental Construction of Delaunay and Voronoi           */
99 /*    Diagrams," Algorithmica 7(4):381-413, 1992, would yield an expected    */
100 /*    O(n^{4/3}) bound on running time.                                      */
101 /*                                                                           */
102 /*  The O(n log n) sweepline Delaunay triangulation algorithm is taken from  */
103 /*    Steven Fortune, "A Sweepline Algorithm for Voronoi Diagrams",          */
104 /*    Algorithmica 2(2):153-174, 1987.  A random sample of edges on the      */
105 /*    boundary of the triangulation are maintained in a splay tree for the   */
106 /*    purpose of point location.  Splay trees are described by Daniel        */
107 /*    Dominic Sleator and Robert Endre Tarjan, "Self-Adjusting Binary Search */
108 /*    Trees," Journal of the ACM 32(3):652-686, July 1985.                   */
109 /*                                                                           */
110 /*  The algorithms for exact computation of the signs of determinants are    */
111 /*    described in Jonathan Richard Shewchuk, "Adaptive Precision Floating-  */
112 /*    Point Arithmetic and Fast Robust Geometric Predicates," Technical      */
113 /*    Report CMU-CS-96-140, School of Computer Science, Carnegie Mellon      */
114 /*    University, Pittsburgh, Pennsylvania, May 1996.  [*]  (Submitted to    */
115 /*    Discrete & Computational Geometry.)  An abbreviated version appears as */
116 /*    Jonathan Richard Shewchuk, "Robust Adaptive Floating-Point Geometric   */
117 /*    Predicates," Proceedings of the Twelfth Annual Symposium on Computa-   */
118 /*    tional Geometry, ACM, May 1996.  [*]  Many of the ideas for my exact   */
119 /*    arithmetic routines originate with Douglas M. Priest, "Algorithms for  */
120 /*    Arbitrary Precision Floating Point Arithmetic," Tenth Symposium on     */
121 /*    Computer Arithmetic, 132-143, IEEE Computer Society Press, 1991.  [*]  */
122 /*    Many of the ideas for the correct evaluation of the signs of           */
123 /*    determinants are taken from Steven Fortune and Christopher J. Van Wyk, */
124 /*    "Efficient Exact Arithmetic for Computational Geometry," Proceedings   */
125 /*    of the Ninth Annual Symposium on Computational Geometry, ACM,          */
126 /*    pp. 163-172, May 1993, and from Steven Fortune, "Numerical Stability   */
127 /*    of Algorithms for 2D Delaunay Triangulations," International Journal   */
128 /*    of Computational Geometry & Applications 5(1-2):193-213, March-June    */
129 /*    1995.                                                                  */
130 /*                                                                           */
131 /*  For definitions of and results involving Delaunay triangulations,        */
132 /*    constrained and conforming versions thereof, and other aspects of      */
133 /*    triangular mesh generation, see the excellent survey by Marshall Bern  */
134 /*    and David Eppstein, "Mesh Generation and Optimal Triangulation," in    */
135 /*    Computing and Euclidean Geometry, Ding-Zhu Du and Frank Hwang,         */
136 /*    editors, World Scientific, Singapore, pp. 23-90, 1992.                 */
137 /*                                                                           */
138 /*  The time for incrementally adding PSLG (planar straight line graph)      */
139 /*    segments to create a constrained Delaunay triangulation is probably    */
140 /*    O(n^2) per segment in the worst case and O(n) per edge in the common   */
141 /*    case, where n is the number of triangles that intersect the segment    */
142 /*    before it is inserted.  This doesn't count point location, which can   */
143 /*    be much more expensive.  (This note does not apply to conforming       */
144 /*    Delaunay triangulations, for which a different method is used to       */
145 /*    insert segments.)                                                      */
146 /*                                                                           */
147 /*  The time for adding segments to a conforming Delaunay triangulation is   */
148 /*    not clear, but does not depend upon n alone.  In some cases, very      */
149 /*    small features (like a point lying next to a segment) can cause a      */
150 /*    single segment to be split an arbitrary number of times.  Of course,   */
151 /*    floating-point precision is a practical barrier to how much this can   */
152 /*    happen.                                                                */
153 /*                                                                           */
154 /*  The time for deleting a point from a Delaunay triangulation is O(n^2) in */
155 /*    the worst case and O(n) in the common case, where n is the degree of   */
156 /*    the point being deleted.  I could improve this to expected O(n) time   */
157 /*    by "inserting" the neighboring vertices in random order, but n is      */
158 /*    usually quite small, so it's not worth the bother.  (The O(n) time     */
159 /*    for random insertion follows from L. Paul Chew, "Building Voronoi      */
160 /*    Diagrams for Convex Polygons in Linear Expected Time," Technical       */
161 /*    Report PCS-TR90-147, Department of Mathematics and Computer Science,   */
162 /*    Dartmouth College, 1990.                                               */
163 /*                                                                           */
164 /*  Ruppert's Delaunay refinement algorithm typically generates triangles    */
165 /*    at a linear rate (constant time per triangle) after the initial        */
166 /*    triangulation is formed.  There may be pathological cases where more   */
167 /*    time is required, but these never arise in practice.                   */
168 /*                                                                           */
169 /*  The segment intersection formulae are straightforward.  If you want to   */
170 /*    see them derived, see Franklin Antonio.  "Faster Line Segment          */
171 /*    Intersection."  In Graphics Gems III (David Kirk, editor), pp. 199-    */
172 /*    202.  Academic Press, Boston, 1992.                                    */
173 /*                                                                           */
174 /*  If you make any improvements to this code, please please please let me   */
175 /*    know, so that I may obtain the improvements.  Even if you don't change */
176 /*    the code, I'd still love to hear what it's being used for.             */
177 /*                                                                           */
178 /*  Disclaimer:  Neither I nor Carnegie Mellon warrant this code in any way  */
179 /*    whatsoever.  This code is provided "as-is".  Use at your own risk.     */
180 /*                                                                           */
181 /*****************************************************************************/
182
183 /* For single precision (which will save some memory and reduce paging),     */
184 /*   define the symbol SINGLE by using the -DSINGLE compiler switch or by    */
185 /*   writing "#define SINGLE" below.                                         */
186 /*                                                                           */
187 /* For double precision (which will allow you to refine meshes to a smaller  */
188 /*   edge length), leave SINGLE undefined.                                   */
189 /*                                                                           */
190 /* Double precision uses more memory, but improves the resolution of the     */
191 /*   meshes you can generate with Triangle.  It also reduces the likelihood  */
192 /*   of a floating exception due to overflow.  Finally, it is much faster    */
193 /*   than single precision on 64-bit architectures like the DEC Alpha.  I    */
194 /*   recommend double precision unless you want to generate a mesh for which */
195 /*   you do not have enough memory.                                          */
196
197 #define
198 SINGLE
199
200 #ifdef
201 SINGLE
202 #define
203 REAL float
204 #else /* not SINGLE */
205 #define
206 REAL double
207 #endif /* not SINGLE */
208
209 /* If yours is not a Unix system, define the NO_TIMER compiler switch to     */
210 /*   remove the Unix-specific timing code.                                   */
211
212 #define
213 NO_TIMER
214
215 /* To insert lots of self-checks for internal errors, define the SELF_CHECK  */
216 /*   symbol.  This will slow down the program significantly.  It is best to  */
217 /*   define the symbol using the -DSELF_CHECK compiler switch, but you could */
218 /*   write "#define SELF_CHECK" below.  If you are modifying this code, I    */
219 /*   recommend you turn self-checks on.                                      */
220
221 /* #define SELF_CHECK */
222
223 /* To compile Triangle as a callable object library (triangle.o), define the */
224 /*   TRILIBRARY symbol.  Read the file triangle.h for details on how to call */
225 /*   the procedure triangulate() that results.                               */
226
227 #define
228 TRILIBRARY
229
230 /* It is possible to generate a smaller version of Triangle using one or     */
231 /*   both of the following symbols.  Define the REDUCED symbol to eliminate  */
232 /*   all features that are primarily of research interest; specifically, the */
233 /*   -i, -F, -s, and -C switches.  Define the CDT_ONLY symbol to eliminate   */
234 /*   all meshing algorithms above and beyond constrained Delaunay            */
235 /*   triangulation; specifically, the -r, -q, -a, -S, and -s switches.       */
236 /*   These reductions are most likely to be useful when generating an object */
237 /*   library (triangle.o) by defining the TRILIBRARY symbol.                 */
238
239 #define
240 REDUCED
241 #define
242 CDT_ONLY
243
244 /* On some machines, the exact arithmetic routines might be defeated by the  */
245 /*   use of internal extended precision floating-point registers.  Sometimes */
246 /*   this problem can be fixed by defining certain values to be volatile,    */
247 /*   thus forcing them to be stored to memory and rounded off.  This isn't   */
248 /*   a great solution, though, as it slows Triangle down.                    */
249 /*                                                                           */
250 /* To try this out, write "#define INEXACT volatile" below.  Normally,       */
251 /*   however, INEXACT should be defined to be nothing.  ("#define INEXACT".) */
252
253 #define
254 INEXACT /* Nothing */
255 /* #define INEXACT volatile */
256
257 /* Maximum number of characters in a file name (including the null).         */
258
259 #define
260 FILENAMESIZE 512
261
262 /* Maximum number of characters in a line read from a file (including the    */
263 /*   null).                                                                  */
264
265 #define
266 INPUTLINESIZE 512
267
268 /* For efficiency, a variety of data structures are allocated in bulk.  The  */
269 /*   following constants determine how many of each structure is allocated   */
270 /*   at once.                                                                */
271
272 #define
273 TRIPERBLOCK 4092           /* Number of triangles allocated at once. */
274 #define
275 SHELLEPERBLOCK 508       /* Number of shell edges allocated at once. */
276 #define
277 POINTPERBLOCK 4092            /* Number of points allocated at once. */
278 #define
279 VIRUSPERBLOCK 1020   /* Number of virus triangles allocated at once. */
280 /* Number of encroached segments allocated at once. */
281 #define
282 BADSEGMENTPERBLOCK 252
283 /* Number of skinny triangles allocated at once. */
284 #define
285 BADTRIPERBLOCK 4092
286 /* Number of splay tree nodes allocated at once. */
287 #define
288 SPLAYNODEPERBLOCK 508
289
290 /* The point marker DEADPOINT is an arbitrary number chosen large enough to  */
291 /*   (hopefully) not conflict with user boundary markers.  Make sure that it */
292 /*   is small enough to fit into your machine's integer size.                */
293
294 #define
295 DEADPOINT -1073741824
296
297 /* The next line is used to outsmart some very stupid compilers.  If your    */
298 /*   compiler is smarter, feel free to replace the "int" with "void".        */
299 /*   Not that it matters.                                                    */
300
301 #define
302 VOID int
303
304 /* Two constants for algorithms based on random sampling.  Both constants    */
305 /*   have been chosen empirically to optimize their respective algorithms.   */
306
307 /* Used for the point location scheme of Mucke, Saias, and Zhu, to decide    */
308 /*   how large a random sample of triangles to inspect.                      */
309 #define
310 SAMPLEFACTOR 11
311 /* Used in Fortune's sweepline Delaunay algorithm to determine what fraction */
312 /*   of boundary edges should be maintained in the splay tree for point      */
313 /*   location on the front.                                                  */
314 #define
315 SAMPLERATE 10
316
317 /* A number that speaks for itself, every kissable digit.                    */
318
319 #define
320 PI 3.141592653589793238462643383279502884197169399375105820974944592308
321
322 /* Another fave.                                                             */
323
324 #define
325 SQUAREROOTTWO 1.4142135623730950488016887242096980785696718753769480732
326
327 /* And here's one for those of you who are intimidated by math.              */
328
329 #define
330 ONETHIRD 0.333333333333333333333333333333333333333333333333333333333333
331
332 #include
333 <stdio.h>
334 #include
335 <string.h>
336 #include
337 <math.h>
338 #ifndef
339 NO_TIMER
340 #include
341 <sys/time.h>
342 #endif /* NO_TIMER */
343 #ifdef
344 TRILIBRARY
345 #include
346 "triangle.h"
347 #endif /* TRILIBRARY */
348
349 /* The following obscenity seems to be necessary to ensure that this program */
350 /* will port to Dec Alphas running OSF/1, because their stdio.h file commits */
351 /* the unpardonable sin of including stdlib.h.  Hence, malloc(), free(), and */
352 /* exit() may or may not already be defined at this point.  I declare these  */
353 /* functions explicitly because some non-ANSI C compilers lack stdlib.h.     */
354
355 #ifndef
356 _STDLIB_H_
357 extern void *malloc();
358 extern void free();
359 extern void exit();
360 extern double strtod();
361 extern long strtol();
362 #endif /* _STDLIB_H_ */
363
364 /* A few forward declarations.                                               */
365
366 void poolrestart();
367 #ifndef
368 TRILIBRARY
369 char *readline();
370 char *findfield();
371 #endif /* not TRILIBRARY */
372
373 /* Labels that signify whether a record consists primarily of pointers or of */
374 /*   floating-point words.  Used to make decisions about data alignment.     */
375
376 enum wordtype {
377 POINTER, FLOATINGPOINT
378 };
379
380 /* Labels that signify the result of point location.  The result of a        */
381 /*   search indicates that the point falls in the interior of a triangle, on */
382 /*   an edge, on a vertex, or outside the mesh.                              */
383
384 enum locateresult { INTRIANGLE, ONEDGE, ONVERTEX, OUTSIDE };
385
386 /* Labels that signify the result of site insertion.  The result indicates   */
387 /*   that the point was inserted with complete success, was inserted but     */
388 /*   encroaches on a segment, was not inserted because it lies on a segment, */
389 /*   or was not inserted because another point occupies the same location.   */
390
391 enum insertsiteresult {
392 SUCCESSFULPOINT, ENCROACHINGPOINT, VIOLATINGPOINT,
393 DUPLICATEPOINT
394 };
395
396 /* Labels that signify the result of direction finding.  The result          */
397 /*   indicates that a segment connecting the two query points falls within   */
398 /*   the direction triangle, along the left edge of the direction triangle,  */
399 /*   or along the right edge of the direction triangle.                      */
400
401 enum finddirectionresult { WITHIN, LEFTCOLLINEAR, RIGHTCOLLINEAR };
402
403 /* Labels that signify the result of the circumcenter computation routine.   */
404 /*   The return value indicates which edge of the triangle is shortest.      */
405
406 enum circumcenterresult { OPPOSITEORG, OPPOSITEDEST, OPPOSITEAPEX };
407
408 /*****************************************************************************/
409 /*                                                                           */
410 /*  The basic mesh data structures                                           */
411 /*                                                                           */
412 /*  There are three:  points, triangles, and shell edges (abbreviated        */
413 /*  `shelle').  These three data structures, linked by pointers, comprise    */
414 /*  the mesh.  A point simply represents a point in space and its properties.*/
415 /*  A triangle is a triangle.  A shell edge is a special data structure used */
416 /*  to represent impenetrable segments in the mesh (including the outer      */
417 /*  boundary, boundaries of holes, and internal boundaries separating two    */
418 /*  triangulated regions).  Shell edges represent boundaries defined by the  */
419 /*  user that triangles may not lie across.                                  */
420 /*                                                                           */
421 /*  A triangle consists of a list of three vertices, a list of three         */
422 /*  adjoining triangles, a list of three adjoining shell edges (when shell   */
423 /*  edges are used), an arbitrary number of optional user-defined floating-  */
424 /*  point attributes, and an optional area constraint.  The latter is an     */
425 /*  upper bound on the permissible area of each triangle in a region, used   */
426 /*  for mesh refinement.                                                     */
427 /*                                                                           */
428 /*  For a triangle on a boundary of the mesh, some or all of the neighboring */
429 /*  triangles may not be present.  For a triangle in the interior of the     */
430 /*  mesh, often no neighboring shell edges are present.  Such absent         */
431 /*  triangles and shell edges are never represented by NULL pointers; they   */
432 /*  are represented by two special records:  `dummytri', the triangle that   */
433 /*  fills "outer space", and `dummysh', the omnipresent shell edge.          */
434 /*  `dummytri' and `dummysh' are used for several reasons; for instance,     */
435 /*  they can be dereferenced and their contents examined without causing the */
436 /*  memory protection exception that would occur if NULL were dereferenced.  */
437 /*                                                                           */
438 /*  However, it is important to understand that a triangle includes other    */
439 /*  information as well.  The pointers to adjoining vertices, triangles, and */
440 /*  shell edges are ordered in a way that indicates their geometric relation */
441 /*  to each other.  Furthermore, each of these pointers contains orientation */
442 /*  information.  Each pointer to an adjoining triangle indicates which face */
443 /*  of that triangle is contacted.  Similarly, each pointer to an adjoining  */
444 /*  shell edge indicates which side of that shell edge is contacted, and how */
445 /*  the shell edge is oriented relative to the triangle.                     */
446 /*                                                                           */
447 /*  Shell edges are found abutting edges of triangles; either sandwiched     */
448 /*  between two triangles, or resting against one triangle on an exterior    */
449 /*  boundary or hole boundary.                                               */
450 /*                                                                           */
451 /*  A shell edge consists of a list of two vertices, a list of two           */
452 /*  adjoining shell edges, and a list of two adjoining triangles.  One of    */
453 /*  the two adjoining triangles may not be present (though there should      */
454 /*  always be one), and neighboring shell edges might not be present.        */
455 /*  Shell edges also store a user-defined integer "boundary marker".         */
456 /*  Typically, this integer is used to indicate what sort of boundary        */
457 /*  conditions are to be applied at that location in a finite element        */
458 /*  simulation.                                                              */
459 /*                                                                           */
460 /*  Like triangles, shell edges maintain information about the relative      */
461 /*  orientation of neighboring objects.                                      */
462 /*                                                                           */
463 /*  Points are relatively simple.  A point is a list of floating point       */
464 /*  numbers, starting with the x, and y coordinates, followed by an          */
465 /*  arbitrary number of optional user-defined floating-point attributes,     */
466 /*  followed by an integer boundary marker.  During the segment insertion    */
467 /*  phase, there is also a pointer from each point to a triangle that may    */
468 /*  contain it.  Each pointer is not always correct, but when one is, it     */
469 /*  speeds up segment insertion.  These pointers are assigned values once    */
470 /*  at the beginning of the segment insertion phase, and are not used or     */
471 /*  updated at any other time.  Edge swapping during segment insertion will  */
472 /*  render some of them incorrect.  Hence, don't rely upon them for          */
473 /*  anything.  For the most part, points do not have any information about   */
474 /*  what triangles or shell edges they are linked to.                        */
475 /*                                                                           */
476 /*****************************************************************************/
477
478 /*****************************************************************************/
479 /*                                                                           */
480 /*  Handles                                                                  */
481 /*                                                                           */
482 /*  The oriented triangle (`triedge') and oriented shell edge (`edge') data  */
483 /*  structures defined below do not themselves store any part of the mesh.   */
484 /*  The mesh itself is made of `triangle's, `shelle's, and `point's.         */
485 /*                                                                           */
486 /*  Oriented triangles and oriented shell edges will usually be referred to  */
487 /*  as "handles".  A handle is essentially a pointer into the mesh; it       */
488 /*  allows you to "hold" one particular part of the mesh.  Handles are used  */
489 /*  to specify the regions in which one is traversing and modifying the mesh.*/
490 /*  A single `triangle' may be held by many handles, or none at all.  (The   */
491 /*  latter case is not a memory leak, because the triangle is still          */
492 /*  connected to other triangles in the mesh.)                               */
493 /*                                                                           */
494 /*  A `triedge' is a handle that holds a triangle.  It holds a specific side */
495 /*  of the triangle.  An `edge' is a handle that holds a shell edge.  It     */
496 /*  holds either the left or right side of the edge.                         */
497 /*                                                                           */
498 /*  Navigation about the mesh is accomplished through a set of mesh          */
499 /*  manipulation primitives, further below.  Many of these primitives take   */
500 /*  a handle and produce a new handle that holds the mesh near the first     */
501 /*  handle.  Other primitives take two handles and glue the corresponding    */
502 /*  parts of the mesh together.  The exact position of the handles is        */
503 /*  important.  For instance, when two triangles are glued together by the   */
504 /*  bond() primitive, they are glued by the sides on which the handles lie.  */
505 /*                                                                           */
506 /*  Because points have no information about which triangles they are        */
507 /*  attached to, I commonly represent a point by use of a handle whose       */
508 /*  origin is the point.  A single handle can simultaneously represent a     */
509 /*  triangle, an edge, and a point.                                          */
510 /*                                                                           */
511 /*****************************************************************************/
512
513 /* The triangle data structure.  Each triangle contains three pointers to    */
514 /*   adjoining triangles, plus three pointers to vertex points, plus three   */
515 /*   pointers to shell edges (defined below; these pointers are usually      */
516 /*   `dummysh').  It may or may not also contain user-defined attributes     */
517 /*   and/or a floating-point "area constraint".  It may also contain extra   */
518 /*   pointers for nodes, when the user asks for high-order elements.         */
519 /*   Because the size and structure of a `triangle' is not decided until     */
520 /*   runtime, I haven't simply defined the type `triangle' to be a struct.   */
521
522 typedef REAL **triangle;            /* Really:  typedef triangle *triangle   */
523
524 /* An oriented triangle:  includes a pointer to a triangle and orientation.  */
525 /*   The orientation denotes an edge of the triangle.  Hence, there are      */
526 /*   three possible orientations.  By convention, each edge is always        */
527 /*   directed to point counterclockwise about the corresponding triangle.    */
528
529 struct triedge {
530 triangle *tri;
531 int orient;                                       /* Ranges from 0 to 2. */
532 };
533
534 /* The shell data structure.  Each shell edge contains two pointers to       */
535 /*   adjoining shell edges, plus two pointers to vertex points, plus two     */
536 /*   pointers to adjoining triangles, plus one shell marker.                 */
537
538 typedef REAL **shelle;                  /* Really:  typedef shelle *shelle   */
539
540 /* An oriented shell edge:  includes a pointer to a shell edge and an        */
541 /*   orientation.  The orientation denotes a side of the edge.  Hence, there */
542 /*   are two possible orientations.  By convention, the edge is always       */
543 /*   directed so that the "side" denoted is the right side of the edge.      */
544
545 struct edge {
546 shelle *sh;
547 int shorient;                                     /* Ranges from 0 to 1. */
548 };
549
550 /* The point data structure.  Each point is actually an array of REALs.      */
551 /*   The number of REALs is unknown until runtime.  An integer boundary      */
552 /*   marker, and sometimes a pointer to a triangle, is appended after the    */
553 /*   REALs.                                                                  */
554
555 typedef REAL *point;
556
557 /* A queue used to store encroached segments.  Each segment's vertices are   */
558 /*   stored so that one can check whether a segment is still the same.       */
559
560 struct badsegment {
561 struct edge encsegment;                        /* An encroached segment. */
562 point segorg, segdest;                              /* The two vertices. */
563 struct badsegment *nextsegment;   /* Pointer to next encroached segment. */
564 };
565
566 /* A queue used to store bad triangles.  The key is the square of the cosine */
567 /*   of the smallest angle of the triangle.  Each triangle's vertices are    */
568 /*   stored so that one can check whether a triangle is still the same.      */
569
570 struct badface {
571 struct triedge badfacetri;                            /* A bad triangle. */
572 REAL key;                           /* cos^2 of smallest (apical) angle. */
573 point faceorg, facedest, faceapex;                /* The three vertices. */
574 struct badface *nextface;               /* Pointer to next bad triangle. */
575 };
576
577 /* A node in a heap used to store events for the sweepline Delaunay          */
578 /*   algorithm.  Nodes do not point directly to their parents or children in */
579 /*   the heap.  Instead, each node knows its position in the heap, and can   */
580 /*   look up its parent and children in a separate array.  The `eventptr'    */
581 /*   points either to a `point' or to a triangle (in encoded format, so that */
582 /*   an orientation is included).  In the latter case, the origin of the     */
583 /*   oriented triangle is the apex of a "circle event" of the sweepline      */
584 /*   algorithm.  To distinguish site events from circle events, all circle   */
585 /*   events are given an invalid (smaller than `xmin') x-coordinate `xkey'.  */
586
587 struct event {
588 REAL xkey, ykey;                            /* Coordinates of the event. */
589 VOID *eventptr;     /* Can be a point or the location of a circle event. */
590 int heapposition;            /* Marks this event's position in the heap. */
591 };
592
593 /* A node in the splay tree.  Each node holds an oriented ghost triangle     */
594 /*   that represents a boundary edge of the growing triangulation.  When a   */
595 /*   circle event covers two boundary edges with a triangle, so that they    */
596 /*   are no longer boundary edges, those edges are not immediately deleted   */
597 /*   from the tree; rather, they are lazily deleted when they are next       */
598 /*   encountered.  (Since only a random sample of boundary edges are kept    */
599 /*   in the tree, lazy deletion is faster.)  `keydest' is used to verify     */
600 /*   that a triangle is still the same as when it entered the splay tree; if */
601 /*   it has been rotated (due to a circle event), it no longer represents a  */
602 /*   boundary edge and should be deleted.                                    */
603
604 struct splaynode {
605 struct triedge keyedge;                /* Lprev of an edge on the front. */
606 point keydest;          /* Used to verify that splay node is still live. */
607 struct splaynode *lchild, *rchild;            /* Children in splay tree. */
608 };
609
610 /* A type used to allocate memory.  firstblock is the first block of items.  */
611 /*   nowblock is the block from which items are currently being allocated.   */
612 /*   nextitem points to the next slab of free memory for an item.            */
613 /*   deaditemstack is the head of a linked list (stack) of deallocated items */
614 /*   that can be recycled.  unallocateditems is the number of items that     */
615 /*   remain to be allocated from nowblock.                                   */
616 /*                                                                           */
617 /* Traversal is the process of walking through the entire list of items, and */
618 /*   is separate from allocation.  Note that a traversal will visit items on */
619 /*   the "deaditemstack" stack as well as live items.  pathblock points to   */
620 /*   the block currently being traversed.  pathitem points to the next item  */
621 /*   to be traversed.  pathitemsleft is the number of items that remain to   */
622 /*   be traversed in pathblock.                                              */
623 /*                                                                           */
624 /* itemwordtype is set to POINTER or FLOATINGPOINT, and is used to suggest   */
625 /*   what sort of word the record is primarily made up of.  alignbytes       */
626 /*   determines how new records should be aligned in memory.  itembytes and  */
627 /*   itemwords are the length of a record in bytes (after rounding up) and   */
628 /*   words.  itemsperblock is the number of items allocated at once in a     */
629 /*   single block.  items is the number of currently allocated items.        */
630 /*   maxitems is the maximum number of items that have been allocated at     */
631 /*   once; it is the current number of items plus the number of records kept */
632 /*   on deaditemstack.                                                       */
633
634 struct memorypool {
635 VOID **firstblock, **nowblock;
636 VOID *nextitem;
637 VOID *deaditemstack;
638 VOID **pathblock;
639 VOID *pathitem;
640 enum wordtype itemwordtype;
641 int alignbytes;
642 int itembytes, itemwords;
643 int itemsperblock;
644 long items, maxitems;
645 int unallocateditems;
646 int pathitemsleft;
647 };
648
649 /* Variables used to allocate memory for triangles, shell edges, points,     */
650 /*   viri (triangles being eaten), bad (encroached) segments, bad (skinny    */
651 /*   or too large) triangles, and splay tree nodes.                          */
652
653 static struct memorypool triangles;
654 static struct memorypool shelles;
655 static struct memorypool points;
656 static struct memorypool viri;
657 static struct memorypool badsegments;
658 static struct memorypool badtriangles;
659 static struct memorypool splaynodes;
660
661 /* Variables that maintain the bad triangle queues.  The tails are pointers  */
662 /*   to the pointers that have to be filled in to enqueue an item.           */
663
664 static struct badface *queuefront[64];
665 static struct badface **queuetail[64];
666
667 static REAL xmin, xmax, ymin, ymax;                              /* x and y bounds. */
668 static REAL xminextreme;        /* Nonexistent x value used as a flag in sweepline. */
669 static int inpoints;                                     /* Number of input points. */
670 static int inelements;                                /* Number of input triangles. */
671 static int insegments;                                 /* Number of input segments. */
672 static int holes;                                         /* Number of input holes. */
673 static int regions;                                     /* Number of input regions. */
674 static long edges;                                       /* Number of output edges. */
675 static int mesh_dim;                                  /* Dimension (ought to be 2). */
676 static int nextras;                              /* Number of attributes per point. */
677 static int eextras;                           /* Number of attributes per triangle. */
678 static long hullsize;                            /* Number of edges of convex hull. */
679 static int triwords;                                   /* Total words per triangle. */
680 static int shwords;                                  /* Total words per shell edge. */
681 static int pointmarkindex;             /* Index to find boundary marker of a point. */
682 static int point2triindex;         /* Index to find a triangle adjacent to a point. */
683 static int highorderindex;    /* Index to find extra nodes for high-order elements. */
684 static int elemattribindex;              /* Index to find attributes of a triangle. */
685 static int areaboundindex;               /* Index to find area bound of a triangle. */
686 static int checksegments;           /* Are there segments in the triangulation yet? */
687 static int readnodefile;                             /* Has a .node file been read? */
688 static long samples;                /* Number of random samples for point location. */
689 static unsigned long randomseed;                     /* Current random number seed. */
690
691 static REAL splitter;       /* Used to split REAL factors for exact multiplication. */
692 static REAL epsilon;                             /* Floating-point machine epsilon. */
693 static REAL resulterrbound;
694 static REAL ccwerrboundA, ccwerrboundB, ccwerrboundC;
695 static REAL iccerrboundA, iccerrboundB, iccerrboundC;
696
697 static long incirclecount;                   /* Number of incircle tests performed. */
698 static long counterclockcount;       /* Number of counterclockwise tests performed. */
699 static long hyperbolacount;        /* Number of right-of-hyperbola tests performed. */
700 static long circumcentercount;    /* Number of circumcenter calculations performed. */
701 static long circletopcount;         /* Number of circle top calculations performed. */
702
703 /* Switches for the triangulator.                                            */
704 /*   poly: -p switch.  refine: -r switch.                                    */
705 /*   quality: -q switch.                                                     */
706 /*     minangle: minimum angle bound, specified after -q switch.             */
707 /*     goodangle: cosine squared of minangle.                                */
708 /*   vararea: -a switch without number.                                      */
709 /*   fixedarea: -a switch with number.                                       */
710 /*     maxarea: maximum area bound, specified after -a switch.               */
711 /*   regionattrib: -A switch.  convex: -c switch.                            */
712 /*   firstnumber: inverse of -z switch.  All items are numbered starting     */
713 /*     from firstnumber.                                                     */
714 /*   edgesout: -e switch.  voronoi: -v switch.                               */
715 /*   neighbors: -n switch.  geomview: -g switch.                             */
716 /*   nobound: -B switch.  nopolywritten: -P switch.                          */
717 /*   nonodewritten: -N switch.  noelewritten: -E switch.                     */
718 /*   noiterationnum: -I switch.  noholes: -O switch.                         */
719 /*   noexact: -X switch.                                                     */
720 /*   order: element order, specified after -o switch.                        */
721 /*   nobisect: count of how often -Y switch is selected.                     */
722 /*   steiner: maximum number of Steiner points, specified after -S switch.   */
723 /*     steinerleft: number of Steiner points not yet used.                   */
724 /*   incremental: -i switch.  sweepline: -F switch.                          */
725 /*   dwyer: inverse of -l switch.                                            */
726 /*   splitseg: -s switch.                                                    */
727 /*   docheck: -C switch.                                                     */
728 /*   quiet: -Q switch.  verbose: count of how often -V switch is selected.   */
729 /*   useshelles: -p, -r, -q, or -c switch; determines whether shell edges    */
730 /*     are used at all.                                                      */
731 /*                                                                           */
732 /* Read the instructions to find out the meaning of these switches.          */
733
734 static int poly, refine, quality, vararea, fixedarea, regionattrib, convex;
735 static int firstnumber;
736 static int edgesout, voronoi, neighbors, geomview;
737 static int nobound, nopolywritten, nonodewritten, noelewritten, noiterationnum;
738 static int noholes, noexact;
739 static int incremental, sweepline, dwyer;
740 static int splitseg;
741 static int docheck;
742 static int quiet, verbose;
743 static int useshelles;
744 static int order;
745 static int nobisect;
746 static int steiner, steinerleft;
747 static REAL minangle, goodangle;
748 static REAL maxarea;
749
750 /* Variables for file names.                                                 */
751
752 #ifndef
753 TRILIBRARY
754 char innodefilename[FILENAMESIZE];
755 char inelefilename[FILENAMESIZE];
756 char inpolyfilename[FILENAMESIZE];
757 char areafilename[FILENAMESIZE];
758 char outnodefilename[FILENAMESIZE];
759 char outelefilename[FILENAMESIZE];
760 char outpolyfilename[FILENAMESIZE];
761 char edgefilename[FILENAMESIZE];
762 char vnodefilename[FILENAMESIZE];
763 char vedgefilename[FILENAMESIZE];
764 char neighborfilename[FILENAMESIZE];
765 char offfilename[FILENAMESIZE];
766 #endif /* not TRILIBRARY */
767
768 /* Triangular bounding box points.                                           */
769
770 static point infpoint1, infpoint2, infpoint3;
771
772 /* Pointer to the `triangle' that occupies all of "outer space".             */
773
774 static triangle *dummytri;
775 static triangle *dummytribase;      /* Keep base address so we can free() it later. */
776
777 /* Pointer to the omnipresent shell edge.  Referenced by any triangle or     */
778 /*   shell edge that isn't really connected to a shell edge at that          */
779 /*   location.                                                               */
780
781 static shelle *dummysh;
782 static shelle *dummyshbase;         /* Keep base address so we can free() it later. */
783
784 /* Pointer to a recently visited triangle.  Improves point location if       */
785 /*   proximate points are inserted sequentially.                             */
786
787 static struct triedge recenttri;
788
789 /*****************************************************************************/
790 /*                                                                           */
791 /*  Mesh manipulation primitives.  Each triangle contains three pointers to  */
792 /*  other triangles, with orientations.  Each pointer points not to the      */
793 /*  first byte of a triangle, but to one of the first three bytes of a       */
794 /*  triangle.  It is necessary to extract both the triangle itself and the   */
795 /*  orientation.  To save memory, I keep both pieces of information in one   */
796 /*  pointer.  To make this possible, I assume that all triangles are aligned */
797 /*  to four-byte boundaries.  The `decode' routine below decodes a pointer,  */
798 /*  extracting an orientation (in the range 0 to 2) and a pointer to the     */
799 /*  beginning of a triangle.  The `encode' routine compresses a pointer to a */
800 /*  triangle and an orientation into a single pointer.  My assumptions that  */
801 /*  triangles are four-byte-aligned and that the `unsigned long' type is     */
802 /*  long enough to hold a pointer are two of the few kludges in this program.*/
803 /*                                                                           */
804 /*  Shell edges are manipulated similarly.  A pointer to a shell edge        */
805 /*  carries both an address and an orientation in the range 0 to 1.          */
806 /*                                                                           */
807 /*  The other primitives take an oriented triangle or oriented shell edge,   */
808 /*  and return an oriented triangle or oriented shell edge or point; or they */
809 /*  change the connections in the data structure.                            */
810 /*                                                                           */
811 /*****************************************************************************/
812
813 /********* Mesh manipulation primitives begin here                   *********/
814 /**                                                                         **/
815 /**                                                                         **/
816
817 /* Fast lookup arrays to speed some of the mesh manipulation primitives.     */
818
819 int plus1mod3[3] = { 1, 2, 0 };
820 int minus1mod3[3] = { 2, 0, 1 };
821
822 /********* Primitives for triangles                                  *********/
823 /*                                                                           */
824 /*                                                                           */
825
826 /* decode() converts a pointer to an oriented triangle.  The orientation is  */
827 /*   extracted from the two least significant bits of the pointer.           */
828
829 #define
830 decode( ptr, triedge )                                                    \
831     ( triedge ).orient = (int) ((unsigned long) ( ptr ) & (unsigned long) 3l );      \
832     ( triedge ).tri = (triangle *)                                                  \
833                       ((unsigned long) ( ptr ) ^ (unsigned long) ( triedge ).orient )
834
835 /* encode() compresses an oriented triangle into a single pointer.  It       */
836 /*   relies on the assumption that all triangles are aligned to four-byte    */
837 /*   boundaries, so the two least significant bits of (triedge).tri are zero.*/
838
839 #define
840 encode( triedge )                                                        \
841     (triangle) ((unsigned long) ( triedge ).tri | (unsigned long) ( triedge ).orient )
842
843 /* The following edge manipulation primitives are all described by Guibas    */
844 /*   and Stolfi.  However, they use an edge-based data structure, whereas I  */
845 /*   am using a triangle-based data structure.                               */
846
847 /* sym() finds the abutting triangle, on the same edge.  Note that the       */
848 /*   edge direction is necessarily reversed, because triangle/edge handles   */
849 /*   are always directed counterclockwise around the triangle.               */
850
851 #define
852 sym( triedge1, triedge2 )                                                \
853     ptr = ( triedge1 ).tri[( triedge1 ).orient];                                    \
854     decode( ptr, triedge2 );
855
856 #define
857 symself( triedge )                                                        \
858     ptr = ( triedge ).tri[( triedge ).orient];                                        \
859     decode( ptr, triedge );
860
861 /* lnext() finds the next edge (counterclockwise) of a triangle.             */
862
863 #define
864 lnext( triedge1, triedge2 )                                                \
865     ( triedge2 ).tri = ( triedge1 ).tri;                                            \
866     ( triedge2 ).orient = plus1mod3[( triedge1 ).orient]
867
868 #define
869 lnextself( triedge )                                                    \
870     ( triedge ).orient = plus1mod3[( triedge ).orient]
871
872 /* lprev() finds the previous edge (clockwise) of a triangle.                */
873
874 #define
875 lprev( triedge1, triedge2 )                                                \
876     ( triedge2 ).tri = ( triedge1 ).tri;                                            \
877     ( triedge2 ).orient = minus1mod3[( triedge1 ).orient]
878
879 #define
880 lprevself( triedge )                                                    \
881     ( triedge ).orient = minus1mod3[( triedge ).orient]
882
883 /* onext() spins counterclockwise around a point; that is, it finds the next */
884 /*   edge with the same origin in the counterclockwise direction.  This edge */
885 /*   will be part of a different triangle.                                   */
886
887 #define
888 onext( triedge1, triedge2 )                                                \
889     lprev( triedge1, triedge2 );                                                  \
890     symself( triedge2 );
891
892 #define
893 onextself( triedge )                                                    \
894     lprevself( triedge );                                                          \
895     symself( triedge );
896
897 /* oprev() spins clockwise around a point; that is, it finds the next edge   */
898 /*   with the same origin in the clockwise direction.  This edge will be     */
899 /*   part of a different triangle.                                           */
900
901 #define
902 oprev( triedge1, triedge2 )                                                \
903     sym( triedge1, triedge2 );                                                      \
904     lnextself( triedge2 );
905
906 #define
907 oprevself( triedge )                                                    \
908     symself( triedge );                                                              \
909     lnextself( triedge );
910
911 /* dnext() spins counterclockwise around a point; that is, it finds the next */
912 /*   edge with the same destination in the counterclockwise direction.  This */
913 /*   edge will be part of a different triangle.                              */
914
915 #define
916 dnext( triedge1, triedge2 )                                                \
917     sym( triedge1, triedge2 );                                                      \
918     lprevself( triedge2 );
919
920 #define
921 dnextself( triedge )                                                    \
922     symself( triedge );                                                              \
923     lprevself( triedge );
924
925 /* dprev() spins clockwise around a point; that is, it finds the next edge   */
926 /*   with the same destination in the clockwise direction.  This edge will   */
927 /*   be part of a different triangle.                                        */
928
929 #define
930 dprev( triedge1, triedge2 )                                                \
931     lnext( triedge1, triedge2 );                                                  \
932     symself( triedge2 );
933
934 #define
935 dprevself( triedge )                                                    \
936     lnextself( triedge );                                                          \
937     symself( triedge );
938
939 /* rnext() moves one edge counterclockwise about the adjacent triangle.      */
940 /*   (It's best understood by reading Guibas and Stolfi.  It involves        */
941 /*   changing triangles twice.)                                              */
942
943 #define
944 rnext( triedge1, triedge2 )                                                \
945     sym( triedge1, triedge2 );                                                      \
946     lnextself( triedge2 );                                                          \
947     symself( triedge2 );
948
949 #define
950 rnextself( triedge )                                                    \
951     symself( triedge );                                                              \
952     lnextself( triedge );                                                          \
953     symself( triedge );
954
955 /* rnext() moves one edge clockwise about the adjacent triangle.             */
956 /*   (It's best understood by reading Guibas and Stolfi.  It involves        */
957 /*   changing triangles twice.)                                              */
958
959 #define
960 rprev( triedge1, triedge2 )                                                \
961     sym( triedge1, triedge2 );                                                      \
962     lprevself( triedge2 );                                                          \
963     symself( triedge2 );
964
965 #define
966 rprevself( triedge )                                                    \
967     symself( triedge );                                                              \
968     lprevself( triedge );                                                          \
969     symself( triedge );
970
971 /* These primitives determine or set the origin, destination, or apex of a   */
972 /* triangle.                                                                 */
973
974 #define
975 org( triedge, pointptr )                                                \
976     pointptr = (point) ( triedge ).tri[plus1mod3[( triedge ).orient] + 3]
977
978 #define
979 dest( triedge, pointptr )                                                \
980     pointptr = (point) ( triedge ).tri[minus1mod3[( triedge ).orient] + 3]
981
982 #define
983 apex( triedge, pointptr )                                                \
984     pointptr = (point) ( triedge ).tri[( triedge ).orient + 3]
985
986 #define
987 setorg( triedge, pointptr )                                                \
988     ( triedge ).tri[plus1mod3[( triedge ).orient] + 3] = (triangle) pointptr
989
990 #define
991 setdest( triedge, pointptr )                                            \
992     ( triedge ).tri[minus1mod3[( triedge ).orient] + 3] = (triangle) pointptr
993
994 #define
995 setapex( triedge, pointptr )                                            \
996     ( triedge ).tri[( triedge ).orient + 3] = (triangle) pointptr
997
998 #define
999 setvertices2null( triedge )                                                \
1000     ( triedge ).tri[3] = (triangle) NULL;                                          \
1001     ( triedge ).tri[4] = (triangle) NULL;                                          \
1002     ( triedge ).tri[5] = (triangle) NULL;
1003
1004 /* Bond two triangles together.                                              */
1005
1006 #define
1007 bond( triedge1, triedge2 )                                                \
1008     ( triedge1 ).tri[( triedge1 ).orient] = encode( triedge2 );                          \
1009     ( triedge2 ).tri[( triedge2 ).orient] = encode( triedge1 )
1010
1011 /* Dissolve a bond (from one side).  Note that the other triangle will still */
1012 /*   think it's connected to this triangle.  Usually, however, the other     */
1013 /*   triangle is being deleted entirely, or bonded to another triangle, so   */
1014 /*   it doesn't matter.                                                      */
1015
1016 #define
1017 dissolve( triedge )                                                        \
1018     ( triedge ).tri[( triedge ).orient] = (triangle) dummytri
1019
1020 /* Copy a triangle/edge handle.                                              */
1021
1022 #define
1023 triedgecopy( triedge1, triedge2 )                                        \
1024     ( triedge2 ).tri = ( triedge1 ).tri;                                            \
1025     ( triedge2 ).orient = ( triedge1 ).orient
1026
1027 /* Test for equality of triangle/edge handles.                               */
1028
1029 #define
1030 triedgeequal( triedge1, triedge2 )                                        \
1031     ((( triedge1 ).tri == ( triedge2 ).tri ) &&                                       \
1032       (( triedge1 ).orient == ( triedge2 ).orient ))
1033
1034 /* Primitives to infect or cure a triangle with the virus.  These rely on    */
1035 /*   the assumption that all shell edges are aligned to four-byte boundaries.*/
1036
1037 #define
1038 infect( triedge )                                                        \
1039     ( triedge ).tri[6] = (triangle)                                                  \
1040                          ((unsigned long) ( triedge ).tri[6] | (unsigned long) 2l )
1041
1042 #define
1043 uninfect( triedge )                                                        \
1044     ( triedge ).tri[6] = (triangle)                                                  \
1045                          ((unsigned long) ( triedge ).tri[6] & ~(unsigned long) 2l )
1046
1047 /* Test a triangle for viral infection.                                      */
1048
1049 #define
1050 infected( triedge )                                                        \
1051     (((unsigned long) ( triedge ).tri[6] & (unsigned long) 2l ) != 0 )
1052
1053 /* Check or set a triangle's attributes.                                     */
1054
1055 #define
1056 elemattribute( triedge, attnum )                                        \
1057     ((REAL *) ( triedge ).tri )[elemattribindex + ( attnum )]
1058
1059 #define
1060 setelemattribute( triedge, attnum, value )                                \
1061     ((REAL *) ( triedge ).tri )[elemattribindex + ( attnum )] = (REAL)value
1062
1063 /* Check or set a triangle's maximum area bound.                             */
1064
1065 #define
1066 areabound( triedge )  ((REAL *) ( triedge ).tri )[areaboundindex]
1067
1068 #define
1069 setareabound( triedge, value )                                            \
1070     ((REAL *) ( triedge ).tri )[areaboundindex] = (REAL)value
1071
1072 /********* Primitives for shell edges                                *********/
1073 /*                                                                           */
1074 /*                                                                           */
1075
1076 /* sdecode() converts a pointer to an oriented shell edge.  The orientation  */
1077 /*   is extracted from the least significant bit of the pointer.  The two    */
1078 /*   least significant bits (one for orientation, one for viral infection)   */
1079 /*   are masked out to produce the real pointer.                             */
1080
1081 #define
1082 sdecode( sptr, edge )                                                    \
1083     ( edge ).shorient = (int) ((unsigned long) ( sptr ) & (unsigned long) 1l );      \
1084     ( edge ).sh = (shelle *)                                                      \
1085                   ((unsigned long) ( sptr ) & ~(unsigned long) 3l )
1086
1087 /* sencode() compresses an oriented shell edge into a single pointer.  It    */
1088 /*   relies on the assumption that all shell edges are aligned to two-byte   */
1089 /*   boundaries, so the least significant bit of (edge).sh is zero.          */
1090
1091 #define
1092 sencode( edge )                                                            \
1093     (shelle) ((unsigned long) ( edge ).sh | (unsigned long) ( edge ).shorient )
1094
1095 /* ssym() toggles the orientation of a shell edge.                           */
1096
1097 #define
1098 ssym( edge1, edge2 )                                                    \
1099     ( edge2 ).sh = ( edge1 ).sh;                                                    \
1100     ( edge2 ).shorient = 1 - ( edge1 ).shorient
1101
1102 #define
1103 ssymself( edge )                                                        \
1104     ( edge ).shorient = 1 - ( edge ).shorient
1105
1106 /* spivot() finds the other shell edge (from the same segment) that shares   */
1107 /*   the same origin.                                                        */
1108
1109 #define
1110 spivot( edge1, edge2 )                                                    \
1111     sptr = ( edge1 ).sh[( edge1 ).shorient];                                        \
1112     sdecode( sptr, edge2 )
1113
1114 #define
1115 spivotself( edge )                                                        \
1116     sptr = ( edge ).sh[( edge ).shorient];                                            \
1117     sdecode( sptr, edge )
1118
1119 /* snext() finds the next shell edge (from the same segment) in sequence;    */
1120 /*   one whose origin is the input shell edge's destination.                 */
1121
1122 #define
1123 snext( edge1, edge2 )                                                    \
1124     sptr = ( edge1 ).sh[1 - ( edge1 ).shorient];                                    \
1125     sdecode( sptr, edge2 )
1126
1127 #define
1128 snextself( edge )                                                        \
1129     sptr = ( edge ).sh[1 - ( edge ).shorient];                                        \
1130     sdecode( sptr, edge )
1131
1132 /* These primitives determine or set the origin or destination of a shell    */
1133 /*   edge.                                                                   */
1134
1135 #define
1136 sorg( edge, pointptr )                                                    \
1137     pointptr = (point) ( edge ).sh[2 + ( edge ).shorient]
1138
1139 #define
1140 sdest( edge, pointptr )                                                    \
1141     pointptr = (point) ( edge ).sh[3 - ( edge ).shorient]
1142
1143 #define
1144 setsorg( edge, pointptr )                                                \
1145     ( edge ).sh[2 + ( edge ).shorient] = (shelle) pointptr
1146
1147 #define
1148 setsdest( edge, pointptr )                                                \
1149     ( edge ).sh[3 - ( edge ).shorient] = (shelle) pointptr
1150
1151 /* These primitives read or set a shell marker.  Shell markers are used to   */
1152 /*   hold user boundary information.                                         */
1153
1154 #define
1155 mark( edge )  ( *(int *) (( edge ).sh + 6 ))
1156
1157 #define
1158 setmark( edge, value )                                                    \
1159     *(int *) (( edge ).sh + 6 ) = value
1160
1161 /* Bond two shell edges together.                                            */
1162
1163 #define
1164 sbond( edge1, edge2 )                                                    \
1165     ( edge1 ).sh[( edge1 ).shorient] = sencode( edge2 );                              \
1166     ( edge2 ).sh[( edge2 ).shorient] = sencode( edge1 )
1167
1168 /* Dissolve a shell edge bond (from one side).  Note that the other shell    */
1169 /*   edge will still think it's connected to this shell edge.                */
1170
1171 #define
1172 sdissolve( edge )                                                        \
1173     ( edge ).sh[( edge ).shorient] = (shelle) dummysh
1174
1175 /* Copy a shell edge.                                                        */
1176
1177 #define
1178 shellecopy( edge1, edge2 )                                                \
1179     ( edge2 ).sh = ( edge1 ).sh;                                                    \
1180     ( edge2 ).shorient = ( edge1 ).shorient
1181
1182 /* Test for equality of shell edges.                                         */
1183
1184 #define
1185 shelleequal( edge1, edge2 )                                                \
1186     ((( edge1 ).sh == ( edge2 ).sh ) &&                                               \
1187       (( edge1 ).shorient == ( edge2 ).shorient ))
1188
1189 /********* Primitives for interacting triangles and shell edges      *********/
1190 /*                                                                           */
1191 /*                                                                           */
1192
1193 /* tspivot() finds a shell edge abutting a triangle.                         */
1194
1195 #define
1196 tspivot( triedge, edge )                                                \
1197     sptr = (shelle) ( triedge ).tri[6 + ( triedge ).orient];                        \
1198     sdecode( sptr, edge )
1199
1200 /* stpivot() finds a triangle abutting a shell edge.  It requires that the   */
1201 /*   variable `ptr' of type `triangle' be defined.                           */
1202
1203 #define
1204 stpivot( edge, triedge )                                                \
1205     ptr = (triangle) ( edge ).sh[4 + ( edge ).shorient];                            \
1206     decode( ptr, triedge )
1207
1208 /* Bond a triangle to a shell edge.                                          */
1209
1210 #define
1211 tsbond( triedge, edge )                                                    \
1212     ( triedge ).tri[6 + ( triedge ).orient] = (triangle) sencode( edge );              \
1213     ( edge ).sh[4 + ( edge ).shorient] = (shelle) encode( triedge )
1214
1215 /* Dissolve a bond (from the triangle side).                                 */
1216
1217 #define
1218 tsdissolve( triedge )                                                    \
1219     ( triedge ).tri[6 + ( triedge ).orient] = (triangle) dummysh
1220
1221 /* Dissolve a bond (from the shell edge side).                               */
1222
1223 #define
1224 stdissolve( edge )                                                        \
1225     ( edge ).sh[4 + ( edge ).shorient] = (shelle) dummytri
1226
1227 /********* Primitives for points                                     *********/
1228 /*                                                                           */
1229 /*                                                                           */
1230
1231 #define
1232 pointmark( pt )  ((int *) ( pt ))[pointmarkindex]
1233
1234 #define
1235 setpointmark( pt, value )                                                \
1236     ((int *) ( pt ))[pointmarkindex] = value
1237
1238 #define
1239 point2tri( pt )  ((triangle *) ( pt ))[point2triindex]
1240
1241 #define
1242 setpoint2tri( pt, value )                                                \
1243     ((triangle *) ( pt ))[point2triindex] = value
1244
1245 /**                                                                         **/
1246 /**                                                                         **/
1247 /********* Mesh manipulation primitives end here                     *********/
1248
1249 /********* User interaction routines begin here                      *********/
1250 /**                                                                         **/
1251 /**                                                                         **/
1252
1253 /*****************************************************************************/
1254 /*                                                                           */
1255 /*  syntax()   Print list of command line switches.                          */
1256 /*                                                                           */
1257 /*****************************************************************************/
1258
1259 #ifndef
1260 TRILIBRARY
1261
1262 void syntax(){
1263 #ifdef
1264 CDT_ONLY
1265 #ifdef
1266 REDUCED
1267 printf( "triangle [-pAcevngBPNEIOXzo_lQVh] input_file\n" );
1268 #else /* not REDUCED */
1269 printf( "triangle [-pAcevngBPNEIOXzo_iFlCQVh] input_file\n" );
1270 #endif /* not REDUCED */
1271 #else /* not CDT_ONLY */
1272 #ifdef
1273 REDUCED
1274 printf( "triangle [-prq__a__AcevngBPNEIOXzo_YS__lQVh] input_file\n" );
1275 #else /* not REDUCED */
1276 printf( "triangle [-prq__a__AcevngBPNEIOXzo_YS__iFlsCQVh] input_file\n" );
1277 #endif /* not REDUCED */
1278 #endif /* not CDT_ONLY */
1279
1280 printf( "    -p  Triangulates a Planar Straight Line Graph (.poly file).\n" );
1281 #ifndef
1282 CDT_ONLY
1283 printf( "    -r  Refines a previously generated mesh.\n" );
1284 printf(
1285 "    -q  Quality mesh generation.  A minimum angle may be specified.\n" );
1286 printf( "    -a  Applies a maximum triangle area constraint.\n" );
1287 #endif /* not CDT_ONLY */
1288 printf(
1289 "    -A  Applies attributes to identify elements in certain regions.\n" );
1290 printf( "    -c  Encloses the convex hull with segments.\n" );
1291 printf( "    -e  Generates an edge list.\n" );
1292 printf( "    -v  Generates a Voronoi diagram.\n" );
1293 printf( "    -n  Generates a list of triangle neighbors.\n" );
1294 printf( "    -g  Generates an .off file for Geomview.\n" );
1295 printf( "    -B  Suppresses output of boundary information.\n" );
1296 printf( "    -P  Suppresses output of .poly file.\n" );
1297 printf( "    -N  Suppresses output of .node file.\n" );
1298 printf( "    -E  Suppresses output of .ele file.\n" );
1299 printf( "    -I  Suppresses mesh iteration numbers.\n" );
1300 printf( "    -O  Ignores holes in .poly file.\n" );
1301 printf( "    -X  Suppresses use of exact arithmetic.\n" );
1302 printf( "    -z  Numbers all items starting from zero (rather than one).\n" );
1303 printf( "    -o2 Generates second-order subparametric elements.\n" );
1304 #ifndef
1305 CDT_ONLY
1306 printf( "    -Y  Suppresses boundary segment splitting.\n" );
1307 printf( "    -S  Specifies maximum number of added Steiner points.\n" );
1308 #endif /* not CDT_ONLY */
1309 #ifndef
1310 REDUCED
1311 printf( "    -i  Uses incremental method, rather than divide-and-conquer.\n" );
1312 printf( "    -F  Uses Fortune's sweepline algorithm, rather than d-and-c.\n" );
1313 #endif /* not REDUCED */
1314 printf( "    -l  Uses vertical cuts only, rather than alternating cuts.\n" );
1315 #ifndef
1316 REDUCED
1317 #ifndef
1318 CDT_ONLY
1319 printf(
1320 "    -s  Force segments into mesh by splitting (instead of using CDT).\n" );
1321 #endif /* not CDT_ONLY */
1322 printf( "    -C  Check consistency of final mesh.\n" );
1323 #endif /* not REDUCED */
1324 printf( "    -Q  Quiet:  No terminal output except errors.\n" );
1325 printf( "    -V  Verbose:  Detailed information on what I'm doing.\n" );
1326 printf( "    -h  Help:  Detailed instructions for Triangle.\n" );
1327 exit( 0 );
1328 }
1329
1330 #endif /* not TRILIBRARY */
1331
1332 /*****************************************************************************/
1333 /*                                                                           */
1334 /*  info()   Print out complete instructions.                                */
1335 /*                                                                           */
1336 /*****************************************************************************/
1337
1338 #ifndef
1339 TRILIBRARY
1340
1341 void info(){
1342 printf( "Triangle\n" );
1343 printf(
1344 "A Two-Dimensional Quality Mesh Generator and Delaunay Triangulator.\n" );
1345 printf( "Version 1.3\n\n" );
1346 printf(
1347 "Copyright 1996 Jonathan Richard Shewchuk  (bugs/comments to jrs@cs.cmu.edu)\n"
1348 );
1349 printf( "School of Computer Science / Carnegie Mellon University\n" );
1350 printf( "5000 Forbes Avenue / Pittsburgh, Pennsylvania  15213-3891\n" );
1351 printf(
1352 "Created as part of the Archimedes project (tools for parallel FEM).\n" );
1353 printf(
1354 "Supported in part by NSF Grant CMS-9318163 and an NSERC 1967 Scholarship.\n" );
1355 printf( "There is no warranty whatsoever.  Use at your own risk.\n" );
1356 #ifdef
1357 SINGLE
1358 printf( "This executable is compiled for single precision arithmetic.\n\n\n" );
1359 #else /* not SINGLE */
1360 printf( "This executable is compiled for double precision arithmetic.\n\n\n" );
1361 #endif /* not SINGLE */
1362 printf(
1363 "Triangle generates exact Delaunay triangulations, constrained Delaunay\n" );
1364 printf(
1365 "triangulations, and quality conforming Delaunay triangulations.  The latter\n"
1366 );
1367 printf(
1368 "can be generated with no small angles, and are thus suitable for finite\n" );
1369 printf(
1370 "element analysis.  If no command line switches are specified, your .node\n" );
1371 printf(
1372 "input file will be read, and the Delaunay triangulation will be returned in\n"
1373 );
1374 printf( ".node and .ele output files.  The command syntax is:\n\n" );
1375 #ifdef
1376 CDT_ONLY
1377 #ifdef
1378 REDUCED
1379 printf( "triangle [-pAcevngBPNEIOXzo_lQVh] input_file\n\n" );
1380 #else /* not REDUCED */
1381 printf( "triangle [-pAcevngBPNEIOXzo_iFlCQVh] input_file\n\n" );
1382 #endif /* not REDUCED */
1383 #else /* not CDT_ONLY */
1384 #ifdef
1385 REDUCED
1386 printf( "triangle [-prq__a__AcevngBPNEIOXzo_YS__lQVh] input_file\n\n" );
1387 #else /* not REDUCED */
1388 printf( "triangle [-prq__a__AcevngBPNEIOXzo_YS__iFlsCQVh] input_file\n\n" );
1389 #endif /* not REDUCED */
1390 #endif /* not CDT_ONLY */
1391 printf(
1392 "Underscores indicate that numbers may optionally follow certain switches;\n" );
1393 printf(
1394 "do not leave any space between a switch and its numeric parameter.\n" );
1395 printf(
1396 "input_file must be a file with extension .node, or extension .poly if the\n" );
1397 printf(
1398 "-p switch is used.  If -r is used, you must supply .node and .ele files,\n" );
1399 printf(
1400 "and possibly a .poly file and .area file as well.  The formats of these\n" );
1401 printf( "files are described below.\n\n" );
1402 printf( "Command Line Switches:\n\n" );
1403 printf(
1404 "    -p  Reads a Planar Straight Line Graph (.poly file), which can specify\n"
1405 );
1406 printf(
1407 "        points, segments, holes, and regional attributes and area\n" );
1408 printf(
1409 "        constraints.  Will generate a constrained Delaunay triangulation\n" );
1410 printf(
1411 "        fitting the input; or, if -s, -q, or -a is used, a conforming\n" );
1412 printf(
1413 "        Delaunay triangulation.  If -p is not used, Triangle reads a .node\n"
1414 );
1415 printf( "        file by default.\n" );
1416 printf(
1417 "    -r  Refines a previously generated mesh.  The mesh is read from a .node\n"
1418 );
1419 printf(
1420 "        file and an .ele file.  If -p is also used, a .poly file is read\n" );
1421 printf(
1422 "        and used to constrain edges in the mesh.  Further details on\n" );
1423 printf( "        refinement are given below.\n" );
1424 printf(
1425 "    -q  Quality mesh generation by Jim Ruppert's Delaunay refinement\n" );
1426 printf(
1427 "        algorithm.  Adds points to the mesh to ensure that no angles\n" );
1428 printf(
1429 "        smaller than 20 degrees occur.  An alternative minimum angle may be\n"
1430 );
1431 printf(
1432 "        specified after the `q'.  If the minimum angle is 20.7 degrees or\n" );
1433 printf(
1434 "        smaller, the triangulation algorithm is theoretically guaranteed to\n"
1435 );
1436 printf(
1437 "        terminate (assuming infinite precision arithmetic - Triangle may\n" );
1438 printf(
1439 "        fail to terminate if you run out of precision).  In practice, the\n" );
1440 printf(
1441 "        algorithm often succeeds for minimum angles up to 33.8 degrees.\n" );
1442 printf(
1443 "        For highly refined meshes, however, it may be necessary to reduce\n" );
1444 printf(
1445 "        the minimum angle to well below 20 to avoid problems associated\n" );
1446 printf(
1447 "        with insufficient floating-point precision.  The specified angle\n" );
1448 printf( "        may include a decimal point.\n" );
1449 printf(
1450 "    -a  Imposes a maximum triangle area.  If a number follows the `a', no\n" );
1451 printf(
1452 "        triangle will be generated whose area is larger than that number.\n" );
1453 printf(
1454 "        If no number is specified, an .area file (if -r is used) or .poly\n" );
1455 printf(
1456 "        file (if -r is not used) specifies a number of maximum area\n" );
1457 printf(
1458 "        constraints.  An .area file contains a separate area constraint for\n"
1459 );
1460 printf(
1461 "        each triangle, and is useful for refining a finite element mesh\n" );
1462 printf(
1463 "        based on a posteriori error estimates.  A .poly file can optionally\n"
1464 );
1465 printf(
1466 "        contain an area constraint for each segment-bounded region, thereby\n"
1467 );
1468 printf(
1469 "        enforcing triangle densities in a first triangulation.  You can\n" );
1470 printf(
1471 "        impose both a fixed area constraint and a varying area constraint\n" );
1472 printf(
1473 "        by invoking the -a switch twice, once with and once without a\n" );
1474 printf(
1475 "        number following.  Each area specified may include a decimal point.\n"
1476 );
1477 printf(
1478 "    -A  Assigns an additional attribute to each triangle that identifies\n" );
1479 printf(
1480 "        what segment-bounded region each triangle belongs to.  Attributes\n" );
1481 printf(
1482 "        are assigned to regions by the .poly file.  If a region is not\n" );
1483 printf(
1484 "        explicitly marked by the .poly file, triangles in that region are\n" );
1485 printf(
1486 "        assigned an attribute of zero.  The -A switch has an effect only\n" );
1487 printf( "        when the -p switch is used and the -r switch is not.\n" );
1488 printf(
1489 "    -c  Creates segments on the convex hull of the triangulation.  If you\n" );
1490 printf(
1491 "        are triangulating a point set, this switch causes a .poly file to\n" );
1492 printf(
1493 "        be written, containing all edges in the convex hull.  (By default,\n"
1494 );
1495 printf(
1496 "        a .poly file is written only if a .poly file is read.)  If you are\n"
1497 );
1498 printf(
1499 "        triangulating a PSLG, this switch specifies that the interior of\n" );
1500 printf(
1501 "        the convex hull of the PSLG should be triangulated.  If you do not\n"
1502 );
1503 printf(
1504 "        use this switch when triangulating a PSLG, it is assumed that you\n" );
1505 printf(
1506 "        have identified the region to be triangulated by surrounding it\n" );
1507 printf(
1508 "        with segments of the input PSLG.  Beware:  if you are not careful,\n"
1509 );
1510 printf(
1511 "        this switch can cause the introduction of an extremely thin angle\n" );
1512 printf(
1513 "        between a PSLG segment and a convex hull segment, which can cause\n" );
1514 printf(
1515 "        overrefinement or failure if Triangle runs out of precision.  If\n" );
1516 printf(
1517 "        you are refining a mesh, the -c switch works differently; it\n" );
1518 printf(
1519 "        generates the set of boundary edges of the mesh, rather than the\n" );
1520 printf( "        convex hull.\n" );
1521 printf(
1522 "    -e  Outputs (to an .edge file) a list of edges of the triangulation.\n" );
1523 printf(
1524 "    -v  Outputs the Voronoi diagram associated with the triangulation.\n" );
1525 printf( "        Does not attempt to detect degeneracies.\n" );
1526 printf(
1527 "    -n  Outputs (to a .neigh file) a list of triangles neighboring each\n" );
1528 printf( "        triangle.\n" );
1529 printf(
1530 "    -g  Outputs the mesh to an Object File Format (.off) file, suitable for\n"
1531 );
1532 printf( "        viewing with the Geometry Center's Geomview package.\n" );
1533 printf(
1534 "    -B  No boundary markers in the output .node, .poly, and .edge output\n" );
1535 printf(
1536 "        files.  See the detailed discussion of boundary markers below.\n" );
1537 printf(
1538 "    -P  No output .poly file.  Saves disk space, but you lose the ability\n" );
1539 printf(
1540 "        to impose segment constraints on later refinements of the mesh.\n" );
1541 printf( "    -N  No output .node file.\n" );
1542 printf( "    -E  No output .ele file.\n" );
1543 printf(
1544 "    -I  No iteration numbers.  Suppresses the output of .node and .poly\n" );
1545 printf(
1546 "        files, so your input files won't be overwritten.  (If your input is\n"
1547 );
1548 printf(
1549 "        a .poly file only, a .node file will be written.)  Cannot be used\n" );
1550 printf(
1551 "        with the -r switch, because that would overwrite your input .ele\n" );
1552 printf(
1553 "        file.  Shouldn't be used with the -s, -q, or -a switch if you are\n" );
1554 printf(
1555 "        using a .node file for input, because no .node file will be\n" );
1556 printf( "        written, so there will be no record of any added points.\n" );
1557 printf( "    -O  No holes.  Ignores the holes in the .poly file.\n" );
1558 printf(
1559 "    -X  No exact arithmetic.  Normally, Triangle uses exact floating-point\n"
1560 );
1561 printf(
1562 "        arithmetic for certain tests if it thinks the inexact tests are not\n"
1563 );
1564 printf(
1565 "        accurate enough.  Exact arithmetic ensures the robustness of the\n" );
1566 printf(
1567 "        triangulation algorithms, despite floating-point roundoff error.\n" );
1568 printf(
1569 "        Disabling exact arithmetic with the -X switch will cause a small\n" );
1570 printf(
1571 "        improvement in speed and create the possibility (albeit small) that\n"
1572 );
1573 printf(
1574 "        Triangle will fail to produce a valid mesh.  Not recommended.\n" );
1575 printf(
1576 "    -z  Numbers all items starting from zero (rather than one).  Note that\n"
1577 );
1578 printf(
1579 "        this switch is normally overrided by the value used to number the\n" );
1580 printf(
1581 "        first point of the input .node or .poly file.  However, this switch\n"
1582 );
1583 printf( "        is useful when calling Triangle from another program.\n" );
1584 printf(
1585 "    -o2 Generates second-order subparametric elements with six nodes each.\n"
1586 );
1587 printf(
1588 "    -Y  No new points on the boundary.  This switch is useful when the mesh\n"
1589 );
1590 printf(
1591 "        boundary must be preserved so that it conforms to some adjacent\n" );
1592 printf(
1593 "        mesh.  Be forewarned that you will probably sacrifice some of the\n" );
1594 printf(
1595 "        quality of the mesh; Triangle will try, but the resulting mesh may\n"
1596 );
1597 printf(
1598 "        contain triangles of poor aspect ratio.  Works well if all the\n" );
1599 printf(
1600 "        boundary points are closely spaced.  Specify this switch twice\n" );
1601 printf(
1602 "        (`-YY') to prevent all segment splitting, including internal\n" );
1603 printf( "        boundaries.\n" );
1604 printf(
1605 "    -S  Specifies the maximum number of Steiner points (points that are not\n"
1606 );
1607 printf(
1608 "        in the input, but are added to meet the constraints of minimum\n" );
1609 printf(
1610 "        angle and maximum area).  The default is to allow an unlimited\n" );
1611 printf(
1612 "        number.  If you specify this switch with no number after it,\n" );
1613 printf(
1614 "        the limit is set to zero.  Triangle always adds points at segment\n" );
1615 printf(
1616 "        intersections, even if it needs to use more points than the limit\n" );
1617 printf(
1618 "        you set.  When Triangle inserts segments by splitting (-s), it\n" );
1619 printf(
1620 "        always adds enough points to ensure that all the segments appear in\n"
1621 );
1622 printf(
1623 "        the triangulation, again ignoring the limit.  Be forewarned that\n" );
1624 printf(
1625 "        the -S switch may result in a conforming triangulation that is not\n"
1626 );
1627 printf(
1628 "        truly Delaunay, because Triangle may be forced to stop adding\n" );
1629 printf(
1630 "        points when the mesh is in a state where a segment is non-Delaunay\n"
1631 );
1632 printf(
1633 "        and needs to be split.  If so, Triangle will print a warning.\n" );
1634 printf(
1635 "    -i  Uses an incremental rather than divide-and-conquer algorithm to\n" );
1636 printf(
1637 "        form a Delaunay triangulation.  Try it if the divide-and-conquer\n" );
1638 printf( "        algorithm fails.\n" );
1639 printf(
1640 "    -F  Uses Steven Fortune's sweepline algorithm to form a Delaunay\n" );
1641 printf(
1642 "        triangulation.  Warning:  does not use exact arithmetic for all\n" );
1643 printf( "        calculations.  An exact result is not guaranteed.\n" );
1644 printf(
1645 "    -l  Uses only vertical cuts in the divide-and-conquer algorithm.  By\n" );
1646 printf(
1647 "        default, Triangle uses alternating vertical and horizontal cuts,\n" );
1648 printf(
1649 "        which usually improve the speed except with point sets that are\n" );
1650 printf(
1651 "        small or short and wide.  This switch is primarily of theoretical\n" );
1652 printf( "        interest.\n" );
1653 printf(
1654 "    -s  Specifies that segments should be forced into the triangulation by\n"
1655 );
1656 printf(
1657 "        recursively splitting them at their midpoints, rather than by\n" );
1658 printf(
1659 "        generating a constrained Delaunay triangulation.  Segment splitting\n"
1660 );
1661 printf(
1662 "        is true to Ruppert's original algorithm, but can create needlessly\n"
1663 );
1664 printf( "        small triangles near external small features.\n" );
1665 printf(
1666 "    -C  Check the consistency of the final mesh.  Uses exact arithmetic for\n"
1667 );
1668 printf(
1669 "        checking, even if the -X switch is used.  Useful if you suspect\n" );
1670 printf( "        Triangle is buggy.\n" );
1671 printf(
1672 "    -Q  Quiet: Suppresses all explanation of what Triangle is doing, unless\n"
1673 );
1674 printf( "        an error occurs.\n" );
1675 printf(
1676 "    -V  Verbose: Gives detailed information about what Triangle is doing.\n" );
1677 printf(
1678 "        Add more `V's for increasing amount of detail.  `-V' gives\n" );
1679 printf(
1680 "        information on algorithmic progress and more detailed statistics.\n" );
1681 printf(
1682 "        `-VV' gives point-by-point details, and will print so much that\n" );
1683 printf(
1684 "        Triangle will run much more slowly.  `-VVV' gives information only\n"
1685 );
1686 printf( "        a debugger could love.\n" );
1687 printf( "    -h  Help:  Displays these instructions.\n" );
1688 printf( "\n" );
1689 printf( "Definitions:\n" );
1690 printf( "\n" );
1691 printf(
1692 "  A Delaunay triangulation of a point set is a triangulation whose vertices\n"
1693 );
1694 printf(
1695 "  are the point set, having the property that no point in the point set\n" );
1696 printf(
1697 "  falls in the interior of the circumcircle (circle that passes through all\n"
1698 );
1699 printf( "  three vertices) of any triangle in the triangulation.\n\n" );
1700 printf(
1701 "  A Voronoi diagram of a point set is a subdivision of the plane into\n" );
1702 printf(
1703 "  polygonal regions (some of which may be infinite), where each region is\n" );
1704 printf(
1705 "  the set of points in the plane that are closer to some input point than\n" );
1706 printf(
1707 "  to any other input point.  (The Voronoi diagram is the geometric dual of\n"
1708 );
1709 printf( "  the Delaunay triangulation.)\n\n" );
1710 printf(
1711 "  A Planar Straight Line Graph (PSLG) is a collection of points and\n" );
1712 printf(
1713 "  segments.  Segments are simply edges, whose endpoints are points in the\n" );
1714 printf(
1715 "  PSLG.  The file format for PSLGs (.poly files) is described below.\n" );
1716 printf( "\n" );
1717 printf(
1718 "  A constrained Delaunay triangulation of a PSLG is similar to a Delaunay\n" );
1719 printf(
1720 "  triangulation, but each PSLG segment is present as a single edge in the\n" );
1721 printf(
1722 "  triangulation.  (A constrained Delaunay triangulation is not truly a\n" );
1723 printf( "  Delaunay triangulation.)\n\n" );
1724 printf(
1725 "  A conforming Delaunay triangulation of a PSLG is a true Delaunay\n" );
1726 printf(
1727 "  triangulation in which each PSLG segment may have been subdivided into\n" );
1728 printf(
1729 "  several edges by the insertion of additional points.  These inserted\n" );
1730 printf(
1731 "  points are necessary to allow the segments to exist in the mesh while\n" );
1732 printf( "  maintaining the Delaunay property.\n\n" );
1733 printf( "File Formats:\n\n" );
1734 printf(
1735 "  All files may contain comments prefixed by the character '#'.  Points,\n" );
1736 printf(
1737 "  triangles, edges, holes, and maximum area constraints must be numbered\n" );
1738 printf(
1739 "  consecutively, starting from either 1 or 0.  Whichever you choose, all\n" );
1740 printf(
1741 "  input files must be consistent; if the nodes are numbered from 1, so must\n"
1742 );
1743 printf(
1744 "  be all other objects.  Triangle automatically detects your choice while\n" );
1745 printf(
1746 "  reading the .node (or .poly) file.  (When calling Triangle from another\n" );
1747 printf(
1748 "  program, use the -z switch if you wish to number objects from zero.)\n" );
1749 printf( "  Examples of these file formats are given below.\n\n" );
1750 printf( "  .node files:\n" );
1751 printf(
1752 "    First line:  <# of points> <dimension (must be 2)> <# of attributes>\n" );
1753 printf(
1754 "                                           <# of boundary markers (0 or 1)>\n"
1755 );
1756 printf(
1757 "    Remaining lines:  <point #> <x> <y> [attributes] [boundary marker]\n" );
1758 printf( "\n" );
1759 printf(
1760 "    The attributes, which are typically floating-point values of physical\n" );
1761 printf(
1762 "    quantities (such as mass or conductivity) associated with the nodes of\n"
1763 );
1764 printf(
1765 "    a finite element mesh, are copied unchanged to the output mesh.  If -s,\n"
1766 );
1767 printf(
1768 "    -q, or -a is selected, each new Steiner point added to the mesh will\n" );
1769 printf( "    have attributes assigned to it by linear interpolation.\n\n" );
1770 printf(
1771 "    If the fourth entry of the first line is `1', the last column of the\n" );
1772 printf(
1773 "    remainder of the file is assumed to contain boundary markers.  Boundary\n"
1774 );
1775 printf(
1776 "    markers are used to identify boundary points and points resting on PSLG\n"
1777 );
1778 printf(
1779 "    segments; a complete description appears in a section below.  The .node\n"
1780 );
1781 printf(
1782 "    file produced by Triangle will contain boundary markers in the last\n" );
1783 printf( "    column unless they are suppressed by the -B switch.\n\n" );
1784 printf( "  .ele files:\n" );
1785 printf(
1786 "    First line:  <# of triangles> <points per triangle> <# of attributes>\n" );
1787 printf(
1788 "    Remaining lines:  <triangle #> <point> <point> <point> ... [attributes]\n"
1789 );
1790 printf( "\n" );
1791 printf(
1792 "    Points are indices into the corresponding .node file.  The first three\n"
1793 );
1794 printf(
1795 "    points are the corners, and are listed in counterclockwise order around\n"
1796 );
1797 printf(
1798 "    each triangle.  (The remaining points, if any, depend on the type of\n" );
1799 printf(
1800 "    finite element used.)  The attributes are just like those of .node\n" );
1801 printf(
1802 "    files.  Because there is no simple mapping from input to output\n" );
1803 printf(
1804 "    triangles, an attempt is made to interpolate attributes, which may\n" );
1805 printf(
1806 "    result in a good deal of diffusion of attributes among nearby triangles\n"
1807 );
1808 printf(
1809 "    as the triangulation is refined.  Diffusion does not occur across\n" );
1810 printf(
1811 "    segments, so attributes used to identify segment-bounded regions remain\n"
1812 );
1813 printf(
1814 "    intact.  In output .ele files, all triangles have three points each\n" );
1815 printf(
1816 "    unless the -o2 switch is used, in which case they have six, and the\n" );
1817 printf(
1818 "    fourth, fifth, and sixth points lie on the midpoints of the edges\n" );
1819 printf( "    opposite the first, second, and third corners.\n\n" );
1820 printf( "  .poly files:\n" );
1821 printf(
1822 "    First line:  <# of points> <dimension (must be 2)> <# of attributes>\n" );
1823 printf(
1824 "                                           <# of boundary markers (0 or 1)>\n"
1825 );
1826 printf(
1827 "    Following lines:  <point #> <x> <y> [attributes] [boundary marker]\n" );
1828 printf( "    One line:  <# of segments> <# of boundary markers (0 or 1)>\n" );
1829 printf(
1830 "    Following lines:  <segment #> <endpoint> <endpoint> [boundary marker]\n" );
1831 printf( "    One line:  <# of holes>\n" );
1832 printf( "    Following lines:  <hole #> <x> <y>\n" );
1833 printf(
1834 "    Optional line:  <# of regional attributes and/or area constraints>\n" );
1835 printf(
1836 "    Optional following lines:  <constraint #> <x> <y> <attrib> <max area>\n" );
1837 printf( "\n" );
1838 printf(
1839 "    A .poly file represents a PSLG, as well as some additional information.\n"
1840 );
1841 printf(
1842 "    The first section lists all the points, and is identical to the format\n"
1843 );
1844 printf(
1845 "    of .node files.  <# of points> may be set to zero to indicate that the\n"
1846 );
1847 printf(
1848 "    points are listed in a separate .node file; .poly files produced by\n" );
1849 printf(
1850 "    Triangle always have this format.  This has the advantage that a point\n"
1851 );
1852 printf(
1853 "    set may easily be triangulated with or without segments.  (The same\n" );
1854 printf(
1855 "    effect can be achieved, albeit using more disk space, by making a copy\n"
1856 );
1857 printf(
1858 "    of the .poly file with the extension .node; all sections of the file\n" );
1859 printf( "    but the first are ignored.)\n\n" );
1860 printf(
1861 "    The second section lists the segments.  Segments are edges whose\n" );
1862 printf(
1863 "    presence in the triangulation is enforced.  Each segment is specified\n" );
1864 printf(
1865 "    by listing the indices of its two endpoints.  This means that you must\n"
1866 );
1867 printf(
1868 "    include its endpoints in the point list.  If -s, -q, and -a are not\n" );
1869 printf(
1870 "    selected, Triangle will produce a constrained Delaunay triangulation,\n" );
1871 printf(
1872 "    in which each segment appears as a single edge in the triangulation.\n" );
1873 printf(
1874 "    If -q or -a is selected, Triangle will produce a conforming Delaunay\n" );
1875 printf(
1876 "    triangulation, in which segments may be subdivided into smaller edges.\n"
1877 );
1878 printf( "    Each segment, like each point, may have a boundary marker.\n\n" );
1879 printf(
1880 "    The third section lists holes (and concavities, if -c is selected) in\n" );
1881 printf(
1882 "    the triangulation.  Holes are specified by identifying a point inside\n" );
1883 printf(
1884 "    each hole.  After the triangulation is formed, Triangle creates holes\n" );
1885 printf(
1886 "    by eating triangles, spreading out from each hole point until its\n" );
1887 printf(
1888 "    progress is blocked by PSLG segments; you must be careful to enclose\n" );
1889 printf(
1890 "    each hole in segments, or your whole triangulation may be eaten away.\n" );
1891 printf(
1892 "    If the two triangles abutting a segment are eaten, the segment itself\n" );
1893 printf(
1894 "    is also eaten.  Do not place a hole directly on a segment; if you do,\n" );
1895 printf( "    Triangle will choose one side of the segment arbitrarily.\n\n" );
1896 printf(
1897 "    The optional fourth section lists regional attributes (to be assigned\n" );
1898 printf(
1899 "    to all triangles in a region) and regional constraints on the maximum\n" );
1900 printf(
1901 "    triangle area.  Triangle will read this section only if the -A switch\n" );
1902 printf(
1903 "    is used or the -a switch is used without a number following it, and the\n"
1904 );
1905 printf(
1906 "    -r switch is not used.  Regional attributes and area constraints are\n" );
1907 printf(
1908 "    propagated in the same manner as holes; you specify a point for each\n" );
1909 printf(
1910 "    attribute and/or constraint, and the attribute and/or constraint will\n" );
1911 printf(
1912 "    affect the whole region (bounded by segments) containing the point.  If\n"
1913 );
1914 printf(
1915 "    two values are written on a line after the x and y coordinate, the\n" );
1916 printf(
1917 "    former is assumed to be a regional attribute (but will only be applied\n"
1918 );
1919 printf(
1920 "    if the -A switch is selected), and the latter is assumed to be a\n" );
1921 printf(
1922 "    regional area constraint (but will only be applied if the -a switch is\n"
1923 );
1924 printf(
1925 "    selected).  You may also specify just one value after the coordinates,\n"
1926 );
1927 printf(
1928 "    which can serve as both an attribute and an area constraint, depending\n"
1929 );
1930 printf(
1931 "    on the choice of switches.  If you are using the -A and -a switches\n" );
1932 printf(
1933 "    simultaneously and wish to assign an attribute to some region without\n" );
1934 printf( "    imposing an area constraint, use a negative maximum area.\n\n" );
1935 printf(
1936 "    When a triangulation is created from a .poly file, you must either\n" );
1937 printf(
1938 "    enclose the entire region to be triangulated in PSLG segments, or\n" );
1939 printf(
1940 "    use the -c switch, which encloses the convex hull of the input point\n" );
1941 printf(
1942 "    set.  If you do not use the -c switch, Triangle will eat all triangles\n"
1943 );
1944 printf(
1945 "    on the outer boundary that are not protected by segments; if you are\n" );
1946 printf(
1947 "    not careful, your whole triangulation may be eaten away.  If you do\n" );
1948 printf(
1949 "    use the -c switch, you can still produce concavities by appropriate\n" );
1950 printf( "    placement of holes just inside the convex hull.\n\n" );
1951 printf(
1952 "    An ideal PSLG has no intersecting segments, nor any points that lie\n" );
1953 printf(
1954 "    upon segments (except, of course, the endpoints of each segment.)  You\n"
1955 );
1956 printf(
1957 "    aren't required to make your .poly files ideal, but you should be aware\n"
1958 );
1959 printf(
1960 "    of what can go wrong.  Segment intersections are relatively safe -\n" );
1961 printf(
1962 "    Triangle will calculate the intersection points for you and add them to\n"
1963 );
1964 printf(
1965 "    the triangulation - as long as your machine's floating-point precision\n"
1966 );
1967 printf(
1968 "    doesn't become a problem.  You are tempting the fates if you have three\n"
1969 );
1970 printf(
1971 "    segments that cross at the same location, and expect Triangle to figure\n"
1972 );
1973 printf(
1974 "    out where the intersection point is.  Thanks to floating-point roundoff\n"
1975 );
1976 printf(
1977 "    error, Triangle will probably decide that the three segments intersect\n"
1978 );
1979 printf(
1980 "    at three different points, and you will find a minuscule triangle in\n" );
1981 printf(
1982 "    your output - unless Triangle tries to refine the tiny triangle, uses\n" );
1983 printf(
1984 "    up the last bit of machine precision, and fails to terminate at all.\n" );
1985 printf(
1986 "    You're better off putting the intersection point in the input files,\n" );
1987 printf(
1988 "    and manually breaking up each segment into two.  Similarly, if you\n" );
1989 printf(
1990 "    place a point at the middle of a segment, and hope that Triangle will\n" );
1991 printf(
1992 "    break up the segment at that point, you might get lucky.  On the other\n"
1993 );
1994 printf(
1995 "    hand, Triangle might decide that the point doesn't lie precisely on the\n"
1996 );
1997 printf(
1998 "    line, and you'll have a needle-sharp triangle in your output - or a lot\n"
1999 );
2000 printf( "    of tiny triangles if you're generating a quality mesh.\n\n" );
2001 printf(
2002 "    When Triangle reads a .poly file, it also writes a .poly file, which\n" );
2003 printf(
2004 "    includes all edges that are part of input segments.  If the -c switch\n" );
2005 printf(
2006 "    is used, the output .poly file will also include all of the edges on\n" );
2007 printf(
2008 "    the convex hull.  Hence, the output .poly file is useful for finding\n" );
2009 printf(
2010 "    edges associated with input segments and setting boundary conditions in\n"
2011 );
2012 printf(
2013 "    finite element simulations.  More importantly, you will need it if you\n"
2014 );
2015 printf(
2016 "    plan to refine the output mesh, and don't want segments to be missing\n" );
2017 printf( "    in later triangulations.\n\n" );
2018 printf( "  .area files:\n" );
2019 printf( "    First line:  <# of triangles>\n" );
2020 printf( "    Following lines:  <triangle #> <maximum area>\n\n" );
2021 printf(
2022 "    An .area file associates with each triangle a maximum area that is used\n"
2023 );
2024 printf(
2025 "    for mesh refinement.  As with other file formats, every triangle must\n" );
2026 printf(
2027 "    be represented, and they must be numbered consecutively.  A triangle\n" );
2028 printf(
2029 "    may be left unconstrained by assigning it a negative maximum area.\n" );
2030 printf( "\n" );
2031 printf( "  .edge files:\n" );
2032 printf( "    First line:  <# of edges> <# of boundary markers (0 or 1)>\n" );
2033 printf(
2034 "    Following lines:  <edge #> <endpoint> <endpoint> [boundary marker]\n" );
2035 printf( "\n" );
2036 printf(
2037 "    Endpoints are indices into the corresponding .node file.  Triangle can\n"
2038 );
2039 printf(
2040 "    produce .edge files (use the -e switch), but cannot read them.  The\n" );
2041 printf(
2042 "    optional column of boundary markers is suppressed by the -B switch.\n" );
2043 printf( "\n" );
2044 printf(
2045 "    In Voronoi diagrams, one also finds a special kind of edge that is an\n" );
2046 printf(
2047 "    infinite ray with only one endpoint.  For these edges, a different\n" );
2048 printf( "    format is used:\n\n" );
2049 printf( "        <edge #> <endpoint> -1 <direction x> <direction y>\n\n" );
2050 printf(
2051 "    The `direction' is a floating-point vector that indicates the direction\n"
2052 );
2053 printf( "    of the infinite ray.\n\n" );
2054 printf( "  .neigh files:\n" );
2055 printf(
2056 "    First line:  <# of triangles> <# of neighbors per triangle (always 3)>\n"
2057 );
2058 printf(
2059 "    Following lines:  <triangle #> <neighbor> <neighbor> <neighbor>\n" );
2060 printf( "\n" );
2061 printf(
2062 "    Neighbors are indices into the corresponding .ele file.  An index of -1\n"
2063 );
2064 printf(
2065 "    indicates a mesh boundary, and therefore no neighbor.  Triangle can\n" );
2066 printf(
2067 "    produce .neigh files (use the -n switch), but cannot read them.\n" );
2068 printf( "\n" );
2069 printf(
2070 "    The first neighbor of triangle i is opposite the first corner of\n" );
2071 printf( "    triangle i, and so on.\n\n" );
2072 printf( "Boundary Markers:\n\n" );
2073 printf(
2074 "  Boundary markers are tags used mainly to identify which output points and\n"
2075 );
2076 printf(
2077 "  edges are associated with which PSLG segment, and to identify which\n" );
2078 printf(
2079 "  points and edges occur on a boundary of the triangulation.  A common use\n"
2080 );
2081 printf(
2082 "  is to determine where boundary conditions should be applied to a finite\n" );
2083 printf(
2084 "  element mesh.  You can prevent boundary markers from being written into\n" );
2085 printf( "  files produced by Triangle by using the -B switch.\n\n" );
2086 printf(
2087 "  The boundary marker associated with each segment in an output .poly file\n"
2088 );
2089 printf( "  or edge in an output .edge file is chosen as follows:\n" );
2090 printf(
2091 "    - If an output edge is part or all of a PSLG segment with a nonzero\n" );
2092 printf(
2093 "      boundary marker, then the edge is assigned the same marker.\n" );
2094 printf(
2095 "    - Otherwise, if the edge occurs on a boundary of the triangulation\n" );
2096 printf(
2097 "      (including boundaries of holes), then the edge is assigned the marker\n"
2098 );
2099 printf( "      one (1).\n" );
2100 printf( "    - Otherwise, the edge is assigned the marker zero (0).\n" );
2101 printf(
2102 "  The boundary marker associated with each point in an output .node file is\n"
2103 );
2104 printf( "  chosen as follows:\n" );
2105 printf(
2106 "    - If a point is assigned a nonzero boundary marker in the input file,\n" );
2107 printf(
2108 "      then it is assigned the same marker in the output .node file.\n" );
2109 printf(
2110 "    - Otherwise, if the point lies on a PSLG segment (including the\n" );
2111 printf(
2112 "      segment's endpoints) with a nonzero boundary marker, then the point\n" );
2113 printf(
2114 "      is assigned the same marker.  If the point lies on several such\n" );
2115 printf( "      segments, one of the markers is chosen arbitrarily.\n" );
2116 printf(
2117 "    - Otherwise, if the point occurs on a boundary of the triangulation,\n" );
2118 printf( "      then the point is assigned the marker one (1).\n" );
2119 printf( "    - Otherwise, the point is assigned the marker zero (0).\n" );
2120 printf( "\n" );
2121 printf(
2122 "  If you want Triangle to determine for you which points and edges are on\n" );
2123 printf(
2124 "  the boundary, assign them the boundary marker zero (or use no markers at\n"
2125 );
2126 printf(
2127 "  all) in your input files.  Alternatively, you can mark some of them and\n" );
2128 printf( "  leave others marked zero, allowing Triangle to label them.\n\n" );
2129 printf( "Triangulation Iteration Numbers:\n\n" );
2130 printf(
2131 "  Because Triangle can read and refine its own triangulations, input\n" );
2132 printf(
2133 "  and output files have iteration numbers.  For instance, Triangle might\n" );
2134 printf(
2135 "  read the files mesh.3.node, mesh.3.ele, and mesh.3.poly, refine the\n" );
2136 printf(
2137 "  triangulation, and output the files mesh.4.node, mesh.4.ele, and\n" );
2138 printf( "  mesh.4.poly.  Files with no iteration number are treated as if\n" );
2139 printf(
2140 "  their iteration number is zero; hence, Triangle might read the file\n" );
2141 printf(
2142 "  points.node, triangulate it, and produce the files points.1.node and\n" );
2143 printf( "  points.1.ele.\n\n" );
2144 printf(
2145 "  Iteration numbers allow you to create a sequence of successively finer\n" );
2146 printf(
2147 "  meshes suitable for multigrid methods.  They also allow you to produce a\n"
2148 );
2149 printf(
2150 "  sequence of meshes using error estimate-driven mesh refinement.\n" );
2151 printf( "\n" );
2152 printf(
2153 "  If you're not using refinement or quality meshing, and you don't like\n" );
2154 printf(
2155 "  iteration numbers, use the -I switch to disable them.  This switch will\n" );
2156 printf(
2157 "  also disable output of .node and .poly files to prevent your input files\n"
2158 );
2159 printf(
2160 "  from being overwritten.  (If the input is a .poly file that contains its\n"
2161 );
2162 printf( "  own points, a .node file will be written.)\n\n" );
2163 printf( "Examples of How to Use Triangle:\n\n" );
2164 printf(
2165 "  `triangle dots' will read points from dots.node, and write their Delaunay\n"
2166 );
2167 printf(
2168 "  triangulation to dots.1.node and dots.1.ele.  (dots.1.node will be\n" );
2169 printf(
2170 "  identical to dots.node.)  `triangle -I dots' writes the triangulation to\n"
2171 );
2172 printf(
2173 "  dots.ele instead.  (No additional .node file is needed, so none is\n" );
2174 printf( "  written.)\n\n" );
2175 printf(
2176 "  `triangle -pe object.1' will read a PSLG from object.1.poly (and possibly\n"
2177 );
2178 printf(
2179 "  object.1.node, if the points are omitted from object.1.poly) and write\n" );
2180 printf( "  their constrained Delaunay triangulation to object.2.node and\n" );
2181 printf(
2182 "  object.2.ele.  The segments will be copied to object.2.poly, and all\n" );
2183 printf( "  edges will be written to object.2.edge.\n\n" );
2184 printf(
2185 "  `triangle -pq31.5a.1 object' will read a PSLG from object.poly (and\n" );
2186 printf(
2187 "  possibly object.node), generate a mesh whose angles are all greater than\n"
2188 );
2189 printf(
2190 "  31.5 degrees and whose triangles all have area smaller than 0.1, and\n" );
2191 printf(
2192 "  write the mesh to object.1.node and object.1.ele.  Each segment may have\n"
2193 );
2194 printf(
2195 "  been broken up into multiple edges; the resulting constrained edges are\n" );
2196 printf( "  written to object.1.poly.\n\n" );
2197 printf(
2198 "  Here is a sample file `box.poly' describing a square with a square hole:\n"
2199 );
2200 printf( "\n" );
2201 printf(
2202 "    # A box with eight points in 2D, no attributes, one boundary marker.\n" );
2203 printf( "    8 2 0 1\n" );
2204 printf( "    # Outer box has these vertices:\n" );
2205 printf( "     1   0 0   0\n" );
2206 printf( "     2   0 3   0\n" );
2207 printf( "     3   3 0   0\n" );
2208 printf( "     4   3 3   33     # A special marker for this point.\n" );
2209 printf( "    # Inner square has these vertices:\n" );
2210 printf( "     5   1 1   0\n" );
2211 printf( "     6   1 2   0\n" );
2212 printf( "     7   2 1   0\n" );
2213 printf( "     8   2 2   0\n" );
2214 printf( "    # Five segments with boundary markers.\n" );
2215 printf( "    5 1\n" );
2216 printf( "     1   1 2   5      # Left side of outer box.\n" );
2217 printf( "     2   5 7   0      # Segments 2 through 5 enclose the hole.\n" );
2218 printf( "     3   7 8   0\n" );
2219 printf( "     4   8 6   10\n" );
2220 printf( "     5   6 5   0\n" );
2221 printf( "    # One hole in the middle of the inner square.\n" );
2222 printf( "    1\n" );
2223 printf( "     1   1.5 1.5\n\n" );
2224 printf(
2225 "  Note that some segments are missing from the outer square, so one must\n" );
2226 printf(
2227 "  use the `-c' switch.  After `triangle -pqc box.poly', here is the output\n"
2228 );
2229 printf(
2230 "  file `box.1.node', with twelve points.  The last four points were added\n" );
2231 printf(
2232 "  to meet the angle constraint.  Points 1, 2, and 9 have markers from\n" );
2233 printf(
2234 "  segment 1.  Points 6 and 8 have markers from segment 4.  All the other\n" );
2235 printf(
2236 "  points but 4 have been marked to indicate that they lie on a boundary.\n" );
2237 printf( "\n" );
2238 printf( "    12  2  0  1\n" );
2239 printf( "       1    0   0      5\n" );
2240 printf( "       2    0   3      5\n" );
2241 printf( "       3    3   0      1\n" );
2242 printf( "       4    3   3     33\n" );
2243 printf( "       5    1   1      1\n" );
2244 printf( "       6    1   2     10\n" );
2245 printf( "       7    2   1      1\n" );
2246 printf( "       8    2   2     10\n" );
2247 printf( "       9    0   1.5    5\n" );
2248 printf( "      10    1.5   0    1\n" );
2249 printf( "      11    3   1.5    1\n" );
2250 printf( "      12    1.5   3    1\n" );
2251 printf( "    # Generated by triangle -pqc box.poly\n\n" );
2252 printf( "  Here is the output file `box.1.ele', with twelve triangles.\n\n" );
2253 printf( "    12  3  0\n" );
2254 printf( "       1     5   6   9\n" );
2255 printf( "       2    10   3   7\n" );
2256 printf( "       3     6   8  12\n" );
2257 printf( "       4     9   1   5\n" );
2258 printf( "       5     6   2   9\n" );
2259 printf( "       6     7   3  11\n" );
2260 printf( "       7    11   4   8\n" );
2261 printf( "       8     7   5  10\n" );
2262 printf( "       9    12   2   6\n" );
2263 printf( "      10     8   7  11\n" );
2264 printf( "      11     5   1  10\n" );
2265 printf( "      12     8   4  12\n" );
2266 printf( "    # Generated by triangle -pqc box.poly\n\n" );
2267 printf(
2268 "  Here is the output file `box.1.poly'.  Note that segments have been added\n"
2269 );
2270 printf(
2271 "  to represent the convex hull, and some segments have been split by newly\n"
2272 );
2273 printf(
2274 "  added points.  Note also that <# of points> is set to zero to indicate\n" );
2275 printf( "  that the points should be read from the .node file.\n\n" );
2276 printf( "    0  2  0  1\n" );
2277 printf( "    12  1\n" );
2278 printf( "       1     1   9     5\n" );
2279 printf( "       2     5   7     1\n" );
2280 printf( "       3     8   7     1\n" );
2281 printf( "       4     6   8    10\n" );
2282 printf( "       5     5   6     1\n" );
2283 printf( "       6     3  10     1\n" );
2284 printf( "       7     4  11     1\n" );
2285 printf( "       8     2  12     1\n" );
2286 printf( "       9     9   2     5\n" );
2287 printf( "      10    10   1     1\n" );
2288 printf( "      11    11   3     1\n" );
2289 printf( "      12    12   4     1\n" );
2290 printf( "    1\n" );
2291 printf( "       1   1.5 1.5\n" );
2292 printf( "    # Generated by triangle -pqc box.poly\n\n" );
2293 printf( "Refinement and Area Constraints:\n\n" );
2294 printf(
2295 "  The -r switch causes a mesh (.node and .ele files) to be read and\n" );
2296 printf(
2297 "  refined.  If the -p switch is also used, a .poly file is read and used to\n"
2298 );
2299 printf(
2300 "  specify edges that are constrained and cannot be eliminated (although\n" );
2301 printf(
2302 "  they can be divided into smaller edges) by the refinement process.\n" );
2303 printf( "\n" );
2304 printf(
2305 "  When you refine a mesh, you generally want to impose tighter quality\n" );
2306 printf(
2307 "  constraints.  One way to accomplish this is to use -q with a larger\n" );
2308 printf(
2309 "  angle, or -a followed by a smaller area than you used to generate the\n" );
2310 printf(
2311 "  mesh you are refining.  Another way to do this is to create an .area\n" );
2312 printf(
2313 "  file, which specifies a maximum area for each triangle, and use the -a\n" );
2314 printf(
2315 "  switch (without a number following).  Each triangle's area constraint is\n"
2316 );
2317 printf(
2318 "  applied to that triangle.  Area constraints tend to diffuse as the mesh\n" );
2319 printf(
2320 "  is refined, so if there are large variations in area constraint between\n" );
2321 printf( "  adjacent triangles, you may not get the results you want.\n\n" );
2322 printf(
2323 "  If you are refining a mesh composed of linear (three-node) elements, the\n"
2324 );
2325 printf(
2326 "  output mesh will contain all the nodes present in the input mesh, in the\n"
2327 );
2328 printf(
2329 "  same order, with new nodes added at the end of the .node file.  However,\n"
2330 );
2331 printf(
2332 "  there is no guarantee that each output element is contained in a single\n" );
2333 printf(
2334 "  input element.  Often, output elements will overlap two input elements,\n" );
2335 printf(
2336 "  and input edges are not present in the output mesh.  Hence, a sequence of\n"
2337 );
2338 printf(
2339 "  refined meshes will form a hierarchy of nodes, but not a hierarchy of\n" );
2340 printf(
2341 "  elements.  If you a refining a mesh of higher-order elements, the\n" );
2342 printf(
2343 "  hierarchical property applies only to the nodes at the corners of an\n" );
2344 printf( "  element; other nodes may not be present in the refined mesh.\n\n" );
2345 printf(
2346 "  It is important to understand that maximum area constraints in .poly\n" );
2347 printf(
2348 "  files are handled differently from those in .area files.  A maximum area\n"
2349 );
2350 printf(
2351 "  in a .poly file applies to the whole (segment-bounded) region in which a\n"
2352 );
2353 printf(
2354 "  point falls, whereas a maximum area in an .area file applies to only one\n"
2355 );
2356 printf(
2357 "  triangle.  Area constraints in .poly files are used only when a mesh is\n" );
2358 printf(
2359 "  first generated, whereas area constraints in .area files are used only to\n"
2360 );
2361 printf(
2362 "  refine an existing mesh, and are typically based on a posteriori error\n" );
2363 printf(
2364 "  estimates resulting from a finite element simulation on that mesh.\n" );
2365 printf( "\n" );
2366 printf(
2367 "  `triangle -rq25 object.1' will read object.1.node and object.1.ele, then\n"
2368 );
2369 printf(
2370 "  refine the triangulation to enforce a 25 degree minimum angle, and then\n" );
2371 printf(
2372 "  write the refined triangulation to object.2.node and object.2.ele.\n" );
2373 printf( "\n" );
2374 printf(
2375 "  `triangle -rpaa6.2 z.3' will read z.3.node, z.3.ele, z.3.poly, and\n" );
2376 printf(
2377 "  z.3.area.  After reconstructing the mesh and its segments, Triangle will\n"
2378 );
2379 printf(
2380 "  refine the mesh so that no triangle has area greater than 6.2, and\n" );
2381 printf(
2382 "  furthermore the triangles satisfy the maximum area constraints in\n" );
2383 printf(
2384 "  z.3.area.  The output is written to z.4.node, z.4.ele, and z.4.poly.\n" );
2385 printf( "\n" );
2386 printf(
2387 "  The sequence `triangle -qa1 x', `triangle -rqa.3 x.1', `triangle -rqa.1\n" );
2388 printf(
2389 "  x.2' creates a sequence of successively finer meshes x.1, x.2, and x.3,\n" );
2390 printf( "  suitable for multigrid.\n\n" );
2391 printf( "Convex Hulls and Mesh Boundaries:\n\n" );
2392 printf(
2393 "  If the input is a point set (rather than a PSLG), Triangle produces its\n" );
2394 printf(
2395 "  convex hull as a by-product in the output .poly file if you use the -c\n" );
2396 printf(
2397 "  switch.  There are faster algorithms for finding a two-dimensional convex\n"
2398 );
2399 printf(
2400 "  hull than triangulation, of course, but this one comes for free.  If the\n"
2401 );
2402 printf(
2403 "  input is an unconstrained mesh (you are using the -r switch but not the\n" );
2404 printf(
2405 "  -p switch), Triangle produces a list of its boundary edges (including\n" );
2406 printf( "  hole boundaries) as a by-product if you use the -c switch.\n\n" );
2407 printf( "Voronoi Diagrams:\n\n" );
2408 printf(
2409 "  The -v switch produces a Voronoi diagram, in files suffixed .v.node and\n" );
2410 printf(
2411 "  .v.edge.  For example, `triangle -v points' will read points.node,\n" );
2412 printf(
2413 "  produce its Delaunay triangulation in points.1.node and points.1.ele,\n" );
2414 printf(
2415 "  and produce its Voronoi diagram in points.1.v.node and points.1.v.edge.\n" );
2416 printf(
2417 "  The .v.node file contains a list of all Voronoi vertices, and the .v.edge\n"
2418 );
2419 printf(
2420 "  file contains a list of all Voronoi edges, some of which may be infinite\n"
2421 );
2422 printf(
2423 "  rays.  (The choice of filenames makes it easy to run the set of Voronoi\n" );
2424 printf( "  vertices through Triangle, if so desired.)\n\n" );
2425 printf(
2426 "  This implementation does not use exact arithmetic to compute the Voronoi\n"
2427 );
2428 printf(
2429 "  vertices, and does not check whether neighboring vertices are identical.\n"
2430 );
2431 printf(
2432 "  Be forewarned that if the Delaunay triangulation is degenerate or\n" );
2433 printf(
2434 "  near-degenerate, the Voronoi diagram may have duplicate points, crossing\n"
2435 );
2436 printf(
2437 "  edges, or infinite rays whose direction vector is zero.  Also, if you\n" );
2438 printf(
2439 "  generate a constrained (as opposed to conforming) Delaunay triangulation,\n"
2440 );
2441 printf(
2442 "  or if the triangulation has holes, the corresponding Voronoi diagram is\n" );
2443 printf( "  likely to have crossing edges and unlikely to make sense.\n\n" );
2444 printf( "Mesh Topology:\n\n" );
2445 printf(
2446 "  You may wish to know which triangles are adjacent to a certain Delaunay\n" );
2447 printf(
2448 "  edge in an .edge file, which Voronoi regions are adjacent to a certain\n" );
2449 printf(
2450 "  Voronoi edge in a .v.edge file, or which Voronoi regions are adjacent to\n"
2451 );
2452 printf(
2453 "  each other.  All of this information can be found by cross-referencing\n" );
2454 printf(
2455 "  output files with the recollection that the Delaunay triangulation and\n" );
2456 printf( "  the Voronoi diagrams are planar duals.\n\n" );
2457 printf(
2458 "  Specifically, edge i of an .edge file is the dual of Voronoi edge i of\n" );
2459 printf(
2460 "  the corresponding .v.edge file, and is rotated 90 degrees counterclock-\n" );
2461 printf(
2462 "  wise from the Voronoi edge.  Triangle j of an .ele file is the dual of\n" );
2463 printf(
2464 "  vertex j of the corresponding .v.node file; and Voronoi region k is the\n" );
2465 printf( "  dual of point k of the corresponding .node file.\n\n" );
2466 printf(
2467 "  Hence, to find the triangles adjacent to a Delaunay edge, look at the\n" );
2468 printf(
2469 "  vertices of the corresponding Voronoi edge; their dual triangles are on\n" );
2470 printf(
2471 "  the left and right of the Delaunay edge, respectively.  To find the\n" );
2472 printf(
2473 "  Voronoi regions adjacent to a Voronoi edge, look at the endpoints of the\n"
2474 );
2475 printf(
2476 "  corresponding Delaunay edge; their dual regions are on the right and left\n"
2477 );
2478 printf(
2479 "  of the Voronoi edge, respectively.  To find which Voronoi regions are\n" );
2480 printf( "  adjacent to each other, just read the list of Delaunay edges.\n" );
2481 printf( "\n" );
2482 printf( "Statistics:\n" );
2483 printf( "\n" );
2484 printf(
2485 "  After generating a mesh, Triangle prints a count of the number of points,\n"
2486 );
2487 printf(
2488 "  triangles, edges, boundary edges, and segments in the output mesh.  If\n" );
2489 printf(
2490 "  you've forgotten the statistics for an existing mesh, the -rNEP switches\n"
2491 );
2492 printf(
2493 "  (or -rpNEP if you've got a .poly file for the existing mesh) will\n" );
2494 printf( "  regenerate these statistics without writing any output.\n\n" );
2495 printf(
2496 "  The -V switch produces extended statistics, including a rough estimate\n" );
2497 printf(
2498 "  of memory use and a histogram of triangle aspect ratios and angles in the\n"
2499 );
2500 printf( "  mesh.\n\n" );
2501 printf( "Exact Arithmetic:\n\n" );
2502 printf(
2503 "  Triangle uses adaptive exact arithmetic to perform what computational\n" );
2504 printf(
2505 "  geometers call the `orientation' and `incircle' tests.  If the floating-\n"
2506 );
2507 printf(
2508 "  point arithmetic of your machine conforms to the IEEE 754 standard (as\n" );
2509 printf(
2510 "  most workstations do), and does not use extended precision internal\n" );
2511 printf(
2512 "  registers, then your output is guaranteed to be an absolutely true\n" );
2513 printf( "  Delaunay or conforming Delaunay triangulation, roundoff error\n" );
2514 printf(
2515 "  notwithstanding.  The word `adaptive' implies that these arithmetic\n" );
2516 printf(
2517 "  routines compute the result only to the precision necessary to guarantee\n"
2518 );
2519 printf(
2520 "  correctness, so they are usually nearly as fast as their approximate\n" );
2521 printf(
2522 "  counterparts.  The exact tests can be disabled with the -X switch.  On\n" );
2523 printf(
2524 "  most inputs, this switch will reduce the computation time by about eight\n"
2525 );
2526 printf(
2527 "  percent - it's not worth the risk.  There are rare difficult inputs\n" );
2528 printf(
2529 "  (having many collinear and cocircular points), however, for which the\n" );
2530 printf(
2531 "  difference could be a factor of two.  These are precisely the inputs most\n"
2532 );
2533 printf( "  likely to cause errors if you use the -X switch.\n\n" );
2534 printf(
2535 "  Unfortunately, these routines don't solve every numerical problem.  Exact\n"
2536 );
2537 printf(
2538 "  arithmetic is not used to compute the positions of points, because the\n" );
2539 printf(
2540 "  bit complexity of point coordinates would grow without bound.  Hence,\n" );
2541 printf(
2542 "  segment intersections aren't computed exactly; in very unusual cases,\n" );
2543 printf(
2544 "  roundoff error in computing an intersection point might actually lead to\n"
2545 );
2546 printf(
2547 "  an inverted triangle and an invalid triangulation.  (This is one reason\n" );
2548 printf(
2549 "  to compute your own intersection points in your .poly files.)  Similarly,\n"
2550 );
2551 printf(
2552 "  exact arithmetic is not used to compute the vertices of the Voronoi\n" );
2553 printf( "  diagram.\n\n" );
2554 printf(
2555 "  Underflow and overflow can also cause difficulties; the exact arithmetic\n"
2556 );
2557 printf(
2558 "  routines do not ameliorate out-of-bounds exponents, which can arise\n" );
2559 printf(
2560 "  during the orientation and incircle tests.  As a rule of thumb, you\n" );
2561 printf(
2562 "  should ensure that your input values are within a range such that their\n" );
2563 printf(
2564 "  third powers can be taken without underflow or overflow.  Underflow can\n" );
2565 printf(
2566 "  silently prevent the tests from being performed exactly, while overflow\n" );
2567 printf( "  will typically cause a floating exception.\n\n" );
2568 printf( "Calling Triangle from Another Program:\n\n" );
2569 printf( "  Read the file triangle.h for details.\n\n" );
2570 printf( "Troubleshooting:\n\n" );
2571 printf( "  Please read this section before mailing me bugs.\n\n" );
2572 printf( "  `My output mesh has no triangles!'\n\n" );
2573 printf(
2574 "    If you're using a PSLG, you've probably failed to specify a proper set\n"
2575 );
2576 printf(
2577 "    of bounding segments, or forgotten to use the -c switch.  Or you may\n" );
2578 printf(
2579 "    have placed a hole badly.  To test these possibilities, try again with\n"
2580 );
2581 printf(
2582 "    the -c and -O switches.  Alternatively, all your input points may be\n" );
2583 printf(
2584 "    collinear, in which case you can hardly expect to triangulate them.\n" );
2585 printf( "\n" );
2586 printf( "  `Triangle doesn't terminate, or just crashes.'\n" );
2587 printf( "\n" );
2588 printf(
2589 "    Bad things can happen when triangles get so small that the distance\n" );
2590 printf(
2591 "    between their vertices isn't much larger than the precision of your\n" );
2592 printf(
2593 "    machine's arithmetic.  If you've compiled Triangle for single-precision\n"
2594 );
2595 printf(
2596 "    arithmetic, you might do better by recompiling it for double-precision.\n"
2597 );
2598 printf(
2599 "    Then again, you might just have to settle for more lenient constraints\n"
2600 );
2601 printf(
2602 "    on the minimum angle and the maximum area than you had planned.\n" );
2603 printf( "\n" );
2604 printf(
2605 "    You can minimize precision problems by ensuring that the origin lies\n" );
2606 printf(
2607 "    inside your point set, or even inside the densest part of your\n" );
2608 printf(
2609 "    mesh.  On the other hand, if you're triangulating an object whose x\n" );
2610 printf(
2611 "    coordinates all fall between 6247133 and 6247134, you're not leaving\n" );
2612 printf( "    much floating-point precision for Triangle to work with.\n\n" );
2613 printf(
2614 "    Precision problems can occur covertly if the input PSLG contains two\n" );
2615 printf(
2616 "    segments that meet (or intersect) at a very small angle, or if such an\n"
2617 );
2618 printf(
2619 "    angle is introduced by the -c switch, which may occur if a point lies\n" );
2620 printf(
2621 "    ever-so-slightly inside the convex hull, and is connected by a PSLG\n" );
2622 printf(
2623 "    segment to a point on the convex hull.  If you don't realize that a\n" );
2624 printf(
2625 "    small angle is being formed, you might never discover why Triangle is\n" );
2626 printf(
2627 "    crashing.  To check for this possibility, use the -S switch (with an\n" );
2628 printf(
2629 "    appropriate limit on the number of Steiner points, found by trial-and-\n"
2630 );
2631 printf(
2632 "    error) to stop Triangle early, and view the output .poly file with\n" );
2633 printf(
2634 "    Show Me (described below).  Look carefully for small angles between\n" );
2635 printf(
2636 "    segments; zoom in closely, as such segments might look like a single\n" );
2637 printf( "    segment from a distance.\n\n" );
2638 printf(
2639 "    If some of the input values are too large, Triangle may suffer a\n" );
2640 printf(
2641 "    floating exception due to overflow when attempting to perform an\n" );
2642 printf(
2643 "    orientation or incircle test.  (Read the section on exact arithmetic\n" );
2644 printf(
2645 "    above.)  Again, I recommend compiling Triangle for double (rather\n" );
2646 printf( "    than single) precision arithmetic.\n\n" );
2647 printf(
2648 "  `The numbering of the output points doesn't match the input points.'\n" );
2649 printf( "\n" );
2650 printf(
2651 "    You may have eaten some of your input points with a hole, or by placing\n"
2652 );
2653 printf( "    them outside the area enclosed by segments.\n\n" );
2654 printf(
2655 "  `Triangle executes without incident, but when I look at the resulting\n" );
2656 printf(
2657 "  mesh, it has overlapping triangles or other geometric inconsistencies.'\n" );
2658 printf( "\n" );
2659 printf(
2660 "    If you select the -X switch, Triangle's divide-and-conquer Delaunay\n" );
2661 printf(
2662 "    triangulation algorithm occasionally makes mistakes due to floating-\n" );
2663 printf(
2664 "    point roundoff error.  Although these errors are rare, don't use the -X\n"
2665 );
2666 printf( "    switch.  If you still have problems, please report the bug.\n" );
2667 printf( "\n" );
2668 printf(
2669 "  Strange things can happen if you've taken liberties with your PSLG.  Do\n" );
2670 printf(
2671 "  you have a point lying in the middle of a segment?  Triangle sometimes\n" );
2672 printf(
2673 "  copes poorly with that sort of thing.  Do you want to lay out a collinear\n"
2674 );
2675 printf(
2676 "  row of evenly spaced, segment-connected points?  Have you simply defined\n"
2677 );
2678 printf(
2679 "  one long segment connecting the leftmost point to the rightmost point,\n" );
2680 printf(
2681 "  and a bunch of points lying along it?  This method occasionally works,\n" );
2682 printf(
2683 "  especially with horizontal and vertical lines, but often it doesn't, and\n"
2684 );
2685 printf(
2686 "  you'll have to connect each adjacent pair of points with a separate\n" );
2687 printf( "  segment.  If you don't like it, tough.\n\n" );
2688 printf(
2689 "  Furthermore, if you have segments that intersect other than at their\n" );
2690 printf(
2691 "  endpoints, try not to let the intersections fall extremely close to PSLG\n"
2692 );
2693 printf( "  points or each other.\n\n" );
2694 printf(
2695 "  If you have problems refining a triangulation not produced by Triangle:\n" );
2696 printf(
2697 "  Are you sure the triangulation is geometrically valid?  Is it formatted\n" );
2698 printf(
2699 "  correctly for Triangle?  Are the triangles all listed so the first three\n"
2700 );
2701 printf( "  points are their corners in counterclockwise order?\n\n" );
2702 printf( "Show Me:\n\n" );
2703 printf(
2704 "  Triangle comes with a separate program named `Show Me', whose primary\n" );
2705 printf(
2706 "  purpose is to draw meshes on your screen or in PostScript.  Its secondary\n"
2707 );
2708 printf(
2709 "  purpose is to check the validity of your input files, and do so more\n" );
2710 printf(
2711 "  thoroughly than Triangle does.  Show Me requires that you have the X\n" );
2712 printf(
2713 "  Windows system.  If you didn't receive Show Me with Triangle, complain to\n"
2714 );
2715 printf( "  whomever you obtained Triangle from, then send me mail.\n\n" );
2716 printf( "Triangle on the Web:\n\n" );
2717 printf(
2718 "  To see an illustrated, updated version of these instructions, check out\n" );
2719 printf( "\n" );
2720 printf( "    http://www.cs.cmu.edu/~quake/triangle.html\n" );
2721 printf( "\n" );
2722 printf( "A Brief Plea:\n" );
2723 printf( "\n" );
2724 printf(
2725 "  If you use Triangle, and especially if you use it to accomplish real\n" );
2726 printf(
2727 "  work, I would like very much to hear from you.  A short letter or email\n" );
2728 printf(
2729 "  (to jrs@cs.cmu.edu) describing how you use Triangle will mean a lot to\n" );
2730 printf(
2731 "  me.  The more people I know are using this program, the more easily I can\n"
2732 );
2733 printf(
2734 "  justify spending time on improvements and on the three-dimensional\n" );
2735 printf(
2736 "  successor to Triangle, which in turn will benefit you.  Also, I can put\n" );
2737 printf(
2738 "  you on a list to receive email whenever a new version of Triangle is\n" );
2739 printf( "  available.\n\n" );
2740 printf(
2741 "  If you use a mesh generated by Triangle in a publication, please include\n"
2742 );
2743 printf( "  an acknowledgment as well.\n\n" );
2744 printf( "Research credit:\n\n" );
2745 printf(
2746 "  Of course, I can take credit for only a fraction of the ideas that made\n" );
2747 printf(
2748 "  this mesh generator possible.  Triangle owes its existence to the efforts\n"
2749 );
2750 printf(
2751 "  of many fine computational geometers and other researchers, including\n" );
2752 printf(
2753 "  Marshall Bern, L. Paul Chew, Boris Delaunay, Rex A. Dwyer, David\n" );
2754 printf(
2755 "  Eppstein, Steven Fortune, Leonidas J. Guibas, Donald E. Knuth, C. L.\n" );
2756 printf(
2757 "  Lawson, Der-Tsai Lee, Ernst P. Mucke, Douglas M. Priest, Jim Ruppert,\n" );
2758 printf(
2759 "  Isaac Saias, Bruce J. Schachter, Micha Sharir, Jorge Stolfi, Christopher\n"
2760 );
2761 printf(
2762 "  J. Van Wyk, David F. Watson, and Binhai Zhu.  See the comments at the\n" );
2763 printf( "  beginning of the source code for references.\n\n" );
2764 exit( 0 );
2765 }
2766
2767 #endif /* not TRILIBRARY */
2768
2769 /*****************************************************************************/
2770 /*                                                                           */
2771 /*  internalerror()   Ask the user to send me the defective product.  Exit.  */
2772 /*                                                                           */
2773 /*****************************************************************************/
2774
2775 void internalerror(){
2776 printf( "  Please report this bug to jrs@cs.cmu.edu\n" );
2777 printf( "  Include the message above, your input data set, and the exact\n" );
2778 printf( "    command line you used to run Triangle.\n" );
2779 exit( 1 );
2780 }
2781
2782 /*****************************************************************************/
2783 /*                                                                           */
2784 /*  parsecommandline()   Read the command line, identify switches, and set   */
2785 /*                       up options and file names.                          */
2786 /*                                                                           */
2787 /*  The effects of this routine are felt entirely through global variables.  */
2788 /*                                                                           */
2789 /*****************************************************************************/
2790
2791 void parsecommandline( argc, argv )
2792 int argc;
2793 char **argv;
2794 {
2795 #ifdef
2796 TRILIBRARY
2797 #define
2798 STARTINDEX 0
2799 #else /* not TRILIBRARY */
2800 #define
2801 STARTINDEX 1
2802 int increment;
2803 int meshnumber;
2804 #endif /* not TRILIBRARY */
2805 int i, j;
2806 #ifndef
2807 CDT_ONLY
2808 int k;
2809 char workstring[FILENAMESIZE];
2810 #endif
2811
2812 poly = refine = quality = vararea = fixedarea = regionattrib = convex = 0;
2813 firstnumber = 1;
2814 edgesout = voronoi = neighbors = geomview = 0;
2815 nobound = nopolywritten = nonodewritten = noelewritten = noiterationnum = 0;
2816 noholes = noexact = 0;
2817 incremental = sweepline = 0;
2818 dwyer = 1;
2819 splitseg = 0;
2820 docheck = 0;
2821 nobisect = 0;
2822 steiner = -1;
2823 order = 1;
2824 minangle = 0.0;
2825 maxarea = -1.0;
2826 quiet = verbose = 0;
2827 #ifndef
2828 TRILIBRARY
2829 innodefilename[0] = '\0';
2830 #endif /* not TRILIBRARY */
2831
2832 for ( i = STARTINDEX; i < argc; i++ ) {
2833 #ifndef
2834 TRILIBRARY
2835 if ( argv[i][0] == '-' ) {
2836 #endif /* not TRILIBRARY */
2837 for ( j = STARTINDEX; argv[i][j] != '\0'; j++ ) {
2838 if ( argv[i][j] == 'p' ) {
2839 poly = 1;
2840 }
2841 #ifndef
2842 CDT_ONLY
2843 if ( argv[i][j] == 'r' ) {
2844 refine = 1;
2845 }
2846 if ( argv[i][j] == 'q' ) {
2847 quality = 1;
2848 if ((( argv[i][j + 1] >= '0' ) && ( argv[i][j + 1] <= '9' )) ||
2849 ( argv[i][j + 1] == '.' )) {
2850 k = 0;
2851 while ((( argv[i][j + 1] >= '0' ) && ( argv[i][j + 1] <= '9' )) ||
2852 ( argv[i][j + 1] == '.' )) {
2853 j++;
2854 workstring[k] = argv[i][j];
2855 k++;
2856 }
2857 workstring[k] = '\0';
2858 minangle = (REAL) strtod( workstring, (char **) NULL );
2859 }
2860 else {
2861 minangle = 20.0;
2862 }
2863 }
2864 if ( argv[i][j] == 'a' ) {
2865 quality = 1;
2866 if ((( argv[i][j + 1] >= '0' ) && ( argv[i][j + 1] <= '9' )) ||
2867 ( argv[i][j + 1] == '.' )) {
2868 fixedarea = 1;
2869 k = 0;
2870 while ((( argv[i][j + 1] >= '0' ) && ( argv[i][j + 1] <= '9' )) ||
2871 ( argv[i][j + 1] == '.' )) {
2872 j++;
2873 workstring[k] = argv[i][j];
2874 k++;
2875 }
2876 workstring[k] = '\0';
2877 maxarea = (REAL) strtod( workstring, (char **) NULL );
2878 if ( maxarea <= 0.0 ) {
2879 printf( "Error:  Maximum area must be greater than zero.\n" );
2880 exit( 1 );
2881 }
2882 }
2883 else {
2884 vararea = 1;
2885 }
2886 }
2887 #endif /* not CDT_ONLY */
2888 if ( argv[i][j] == 'A' ) {
2889 regionattrib = 1;
2890 }
2891 if ( argv[i][j] == 'c' ) {
2892 convex = 1;
2893 }
2894 if ( argv[i][j] == 'z' ) {
2895 firstnumber = 0;
2896 }
2897 if ( argv[i][j] == 'e' ) {
2898 edgesout = 1;
2899 }
2900 if ( argv[i][j] == 'v' ) {
2901 voronoi = 1;
2902 }
2903 if ( argv[i][j] == 'n' ) {
2904 neighbors = 1;
2905 }
2906 if ( argv[i][j] == 'g' ) {
2907 geomview = 1;
2908 }
2909 if ( argv[i][j] == 'B' ) {
2910 nobound = 1;
2911 }
2912 if ( argv[i][j] == 'P' ) {
2913 nopolywritten = 1;
2914 }
2915 if ( argv[i][j] == 'N' ) {
2916 nonodewritten = 1;
2917 }
2918 if ( argv[i][j] == 'E' ) {
2919 noelewritten = 1;
2920 }
2921 #ifndef
2922 TRILIBRARY
2923 if ( argv[i][j] == 'I' ) {
2924 noiterationnum = 1;
2925 }
2926 #endif /* not TRILIBRARY */
2927 if ( argv[i][j] == 'O' ) {
2928 noholes = 1;
2929 }
2930 if ( argv[i][j] == 'X' ) {
2931 noexact = 1;
2932 }
2933 if ( argv[i][j] == 'o' ) {
2934 if ( argv[i][j + 1] == '2' ) {
2935 j++;
2936 order = 2;
2937 }
2938 }
2939 #ifndef
2940 CDT_ONLY
2941 if ( argv[i][j] == 'Y' ) {
2942 nobisect++;
2943 }
2944 if ( argv[i][j] == 'S' ) {
2945 steiner = 0;
2946 while (( argv[i][j + 1] >= '0' ) && ( argv[i][j + 1] <= '9' )) {
2947 j++;
2948 steiner = steiner * 10 + (int) ( argv[i][j] - '0' );
2949 }
2950 }
2951 #endif /* not CDT_ONLY */
2952 #ifndef
2953 REDUCED
2954 if ( argv[i][j] == 'i' ) {
2955 incremental = 1;
2956 }
2957 if ( argv[i][j] == 'F' ) {
2958 sweepline = 1;
2959 }
2960 #endif /* not REDUCED */
2961 if ( argv[i][j] == 'l' ) {
2962 dwyer = 0;
2963 }
2964 #ifndef
2965 REDUCED
2966 #ifndef
2967 CDT_ONLY
2968 if ( argv[i][j] == 's' ) {
2969 splitseg = 1;
2970 }
2971 #endif /* not CDT_ONLY */
2972 if ( argv[i][j] == 'C' ) {
2973 docheck = 1;
2974 }
2975 #endif /* not REDUCED */
2976 if ( argv[i][j] == 'Q' ) {
2977 quiet = 1;
2978 }
2979 if ( argv[i][j] == 'V' ) {
2980 verbose++;
2981 }
2982 #ifndef
2983 TRILIBRARY
2984 if (( argv[i][j] == 'h' ) || ( argv[i][j] == 'H' ) ||
2985 ( argv[i][j] == '?' )) {
2986 info();
2987 }
2988 #endif /* not TRILIBRARY */
2989 }
2990 #ifndef
2991 TRILIBRARY
2992 } else {
2993 strncpy( innodefilename, argv[i], FILENAMESIZE - 1 );
2994 innodefilename[FILENAMESIZE - 1] = '\0';
2995 }
2996 #endif /* not TRILIBRARY */
2997 }
2998 #ifndef
2999 TRILIBRARY
3000 if ( innodefilename[0] == '\0' ) {
3001 syntax();
3002 }
3003 if ( !strcmp( &innodefilename[strlen( innodefilename ) - 5], ".node" )) {
3004 innodefilename[strlen( innodefilename ) - 5] = '\0';
3005 }
3006 if ( !strcmp( &innodefilename[strlen( innodefilename ) - 5], ".poly" )) {
3007 innodefilename[strlen( innodefilename ) - 5] = '\0';
3008 poly = 1;
3009 }
3010 #ifndef
3011 CDT_ONLY
3012 if ( !strcmp( &innodefilename[strlen( innodefilename ) - 4], ".ele" )) {
3013 innodefilename[strlen( innodefilename ) - 4] = '\0';
3014 refine = 1;
3015 }
3016 if ( !strcmp( &innodefilename[strlen( innodefilename ) - 5], ".area" )) {
3017 innodefilename[strlen( innodefilename ) - 5] = '\0';
3018 refine = 1;
3019 quality = 1;
3020 vararea = 1;
3021 }
3022 #endif /* not CDT_ONLY */
3023 #endif /* not TRILIBRARY */
3024 steinerleft = steiner;
3025 useshelles = poly || refine || quality || convex;
3026 goodangle = (REAL)cos( minangle * PI / 180.0 );
3027 goodangle *= goodangle;
3028 if ( refine && noiterationnum ) {
3029 printf(
3030 "Error:  You cannot use the -I switch when refining a triangulation.\n" );
3031 exit( 1 );
3032 }
3033 /* Be careful not to allocate space for element area constraints that */
3034 /*   will never be assigned any value (other than the default -1.0).  */
3035 if ( !refine && !poly ) {
3036 vararea = 0;
3037 }
3038 /* Be careful not to add an extra attribute to each element unless the */
3039 /*   input supports it (PSLG in, but not refining a preexisting mesh). */
3040 if ( refine || !poly ) {
3041 regionattrib = 0;
3042 }
3043
3044 #ifndef
3045 TRILIBRARY
3046 strcpy( inpolyfilename, innodefilename );
3047 strcpy( inelefilename, innodefilename );
3048 strcpy( areafilename, innodefilename );
3049 increment = 0;
3050 strcpy( workstring, innodefilename );
3051 j = 1;
3052 while ( workstring[j] != '\0' ) {
3053 if (( workstring[j] == '.' ) && ( workstring[j + 1] != '\0' )) {
3054 increment = j + 1;
3055 }
3056 j++;
3057 }
3058 meshnumber = 0;
3059 if ( increment > 0 ) {
3060 j = increment;
3061 do {
3062 if (( workstring[j] >= '0' ) && ( workstring[j] <= '9' )) {
3063 meshnumber = meshnumber * 10 + (int) ( workstring[j] - '0' );
3064 }
3065 else {
3066 increment = 0;
3067 }
3068 j++;
3069 } while ( workstring[j] != '\0' );
3070 }
3071 if ( noiterationnum ) {
3072 strcpy( outnodefilename, innodefilename );
3073 strcpy( outelefilename, innodefilename );
3074 strcpy( edgefilename, innodefilename );
3075 strcpy( vnodefilename, innodefilename );
3076 strcpy( vedgefilename, innodefilename );
3077 strcpy( neighborfilename, innodefilename );
3078 strcpy( offfilename, innodefilename );
3079 strcat( outnodefilename, ".node" );
3080 strcat( outelefilename, ".ele" );
3081 strcat( edgefilename, ".edge" );
3082 strcat( vnodefilename, ".v.node" );
3083 strcat( vedgefilename, ".v.edge" );
3084 strcat( neighborfilename, ".neigh" );
3085 strcat( offfilename, ".off" );
3086 }
3087 else if ( increment == 0 ) {
3088 strcpy( outnodefilename, innodefilename );
3089 strcpy( outpolyfilename, innodefilename );
3090 strcpy( outelefilename, innodefilename );
3091 strcpy( edgefilename, innodefilename );
3092 strcpy( vnodefilename, innodefilename );
3093 strcpy( vedgefilename, innodefilename );
3094 strcpy( neighborfilename, innodefilename );
3095 strcpy( offfilename, innodefilename );
3096 strcat( outnodefilename, ".1.node" );
3097 strcat( outpolyfilename, ".1.poly" );
3098 strcat( outelefilename, ".1.ele" );
3099 strcat( edgefilename, ".1.edge" );
3100 strcat( vnodefilename, ".1.v.node" );
3101 strcat( vedgefilename, ".1.v.edge" );
3102 strcat( neighborfilename, ".1.neigh" );
3103 strcat( offfilename, ".1.off" );
3104 }
3105 else {
3106 workstring[increment] = '%';
3107 workstring[increment + 1] = 'd';
3108 workstring[increment + 2] = '\0';
3109 sprintf( outnodefilename, workstring, meshnumber + 1 );
3110 strcpy( outpolyfilename, outnodefilename );
3111 strcpy( outelefilename, outnodefilename );
3112 strcpy( edgefilename, outnodefilename );
3113 strcpy( vnodefilename, outnodefilename );
3114 strcpy( vedgefilename, outnodefilename );
3115 strcpy( neighborfilename, outnodefilename );
3116 strcpy( offfilename, outnodefilename );
3117 strcat( outnodefilename, ".node" );
3118 strcat( outpolyfilename, ".poly" );
3119 strcat( outelefilename, ".ele" );
3120 strcat( edgefilename, ".edge" );
3121 strcat( vnodefilename, ".v.node" );
3122 strcat( vedgefilename, ".v.edge" );
3123 strcat( neighborfilename, ".neigh" );
3124 strcat( offfilename, ".off" );
3125 }
3126 strcat( innodefilename, ".node" );
3127 strcat( inpolyfilename, ".poly" );
3128 strcat( inelefilename, ".ele" );
3129 strcat( areafilename, ".area" );
3130 #endif /* not TRILIBRARY */
3131 }
3132
3133 /**                                                                         **/
3134 /**                                                                         **/
3135 /********* User interaction routines begin here                      *********/
3136
3137 /********* Debugging routines begin here                             *********/
3138 /**                                                                         **/
3139 /**                                                                         **/
3140
3141 /*****************************************************************************/
3142 /*                                                                           */
3143 /*  printtriangle()   Print out the details of a triangle/edge handle.       */
3144 /*                                                                           */
3145 /*  I originally wrote this procedure to simplify debugging; it can be       */
3146 /*  called directly from the debugger, and presents information about a      */
3147 /*  triangle/edge handle in digestible form.  It's also used when the        */
3148 /*  highest level of verbosity (`-VVV') is specified.                        */
3149 /*                                                                           */
3150 /*****************************************************************************/
3151
3152 void printtriangle( t )
3153 struct triedge *t;
3154 {
3155 struct triedge printtri;
3156 struct edge printsh;
3157 point printpoint;
3158
3159 printf( "triangle x%lx with orientation %d:\n", (unsigned long) t->tri,
3160 t->orient );
3161 decode( t->tri[0], printtri );
3162 if ( printtri.tri == dummytri ) {
3163 printf( "    [0] = Outer space\n" );
3164 }
3165 else {
3166 printf( "    [0] = x%lx  %d\n", (unsigned long) printtri.tri,
3167 printtri.orient );
3168 }
3169 decode( t->tri[1], printtri );
3170 if ( printtri.tri == dummytri ) {
3171 printf( "    [1] = Outer space\n" );
3172 }
3173 else {
3174 printf( "    [1] = x%lx  %d\n", (unsigned long) printtri.tri,
3175 printtri.orient );
3176 }
3177 decode( t->tri[2], printtri );
3178 if ( printtri.tri == dummytri ) {
3179 printf( "    [2] = Outer space\n" );
3180 }
3181 else {
3182 printf( "    [2] = x%lx  %d\n", (unsigned long) printtri.tri,
3183 printtri.orient );
3184 }
3185 org( *t, printpoint );
3186 if ( printpoint == (point) NULL ) {
3187 printf( "    Origin[%d] = NULL\n", ( t->orient + 1 ) % 3 + 3 );
3188 }
3189 else{
3190 printf( "    Origin[%d] = x%lx  (%.12g, %.12g)\n",
3191 ( t->orient + 1 ) % 3 + 3, (unsigned long) printpoint,
3192 printpoint[0], printpoint[1] );
3193 }
3194 dest( *t, printpoint );
3195 if ( printpoint == (point) NULL ) {
3196 printf( "    Dest  [%d] = NULL\n", ( t->orient + 2 ) % 3 + 3 );
3197 }
3198 else{
3199 printf( "    Dest  [%d] = x%lx  (%.12g, %.12g)\n",
3200 ( t->orient + 2 ) % 3 + 3, (unsigned long) printpoint,
3201 printpoint[0], printpoint[1] );
3202 }
3203 apex( *t, printpoint );
3204 if ( printpoint == (point) NULL ) {
3205 printf( "    Apex  [%d] = NULL\n", t->orient + 3 );
3206 }
3207 else{
3208 printf( "    Apex  [%d] = x%lx  (%.12g, %.12g)\n",
3209 t->orient + 3, (unsigned long) printpoint,
3210 printpoint[0], printpoint[1] );
3211 }
3212 if ( useshelles ) {
3213 sdecode( t->tri[6], printsh );
3214 if ( printsh.sh != dummysh ) {
3215 printf( "    [6] = x%lx  %d\n", (unsigned long) printsh.sh,
3216 printsh.shorient );
3217 }
3218 sdecode( t->tri[7], printsh );
3219 if ( printsh.sh != dummysh ) {
3220 printf( "    [7] = x%lx  %d\n", (unsigned long) printsh.sh,
3221 printsh.shorient );
3222 }
3223 sdecode( t->tri[8], printsh );
3224 if ( printsh.sh != dummysh ) {
3225 printf( "    [8] = x%lx  %d\n", (unsigned long) printsh.sh,
3226 printsh.shorient );
3227 }
3228 }
3229 if ( vararea ) {
3230 printf( "    Area constraint:  %.4g\n", areabound( *t ));
3231 }
3232 }
3233
3234 /*****************************************************************************/
3235 /*                                                                           */
3236 /*  printshelle()   Print out the details of a shell edge handle.            */
3237 /*                                                                           */
3238 /*  I originally wrote this procedure to simplify debugging; it can be       */
3239 /*  called directly from the debugger, and presents information about a      */
3240 /*  shell edge handle in digestible form.  It's also used when the highest   */
3241 /*  level of verbosity (`-VVV') is specified.                                */
3242 /*                                                                           */
3243 /*****************************************************************************/
3244
3245 void printshelle( s )
3246 struct edge *s;
3247 {
3248 struct edge printsh;
3249 struct triedge printtri;
3250 point printpoint;
3251
3252 printf( "shell edge x%lx with orientation %d and mark %d:\n",
3253 (unsigned long) s->sh, s->shorient, mark( *s ));
3254 sdecode( s->sh[0], printsh );
3255 if ( printsh.sh == dummysh ) {
3256 printf( "    [0] = No shell\n" );
3257 }
3258 else {
3259 printf( "    [0] = x%lx  %d\n", (unsigned long) printsh.sh,
3260 printsh.shorient );
3261 }
3262 sdecode( s->sh[1], printsh );
3263 if ( printsh.sh == dummysh ) {
3264 printf( "    [1] = No shell\n" );
3265 }
3266 else {
3267 printf( "    [1] = x%lx  %d\n", (unsigned long) printsh.sh,
3268 printsh.shorient );
3269 }
3270 sorg( *s, printpoint );
3271 if ( printpoint == (point) NULL ) {
3272 printf( "    Origin[%d] = NULL\n", 2 + s->shorient );
3273 }
3274 else{
3275 printf( "    Origin[%d] = x%lx  (%.12g, %.12g)\n",
3276 2 + s->shorient, (unsigned long) printpoint,
3277 printpoint[0], printpoint[1] );
3278 }
3279 sdest( *s, printpoint );
3280 if ( printpoint == (point) NULL ) {
3281 printf( "    Dest  [%d] = NULL\n", 3 - s->shorient );
3282 }
3283 else{
3284 printf( "    Dest  [%d] = x%lx  (%.12g, %.12g)\n",
3285 3 - s->shorient, (unsigned long) printpoint,
3286 printpoint[0], printpoint[1] );
3287 }
3288 decode( s->sh[4], printtri );
3289 if ( printtri.tri == dummytri ) {
3290 printf( "    [4] = Outer space\n" );
3291 }
3292 else {
3293 printf( "    [4] = x%lx  %d\n", (unsigned long) printtri.tri,
3294 printtri.orient );
3295 }
3296 decode( s->sh[5], printtri );
3297 if ( printtri.tri == dummytri ) {
3298 printf( "    [5] = Outer space\n" );
3299 }
3300 else {
3301 printf( "    [5] = x%lx  %d\n", (unsigned long) printtri.tri,
3302 printtri.orient );
3303 }
3304 }
3305
3306 /**                                                                         **/
3307 /**                                                                         **/
3308 /********* Debugging routines end here                               *********/
3309
3310 /********* Memory management routines begin here                     *********/
3311 /**                                                                         **/
3312 /**                                                                         **/
3313
3314 /*****************************************************************************/
3315 /*                                                                           */
3316 /*  poolinit()   Initialize a pool of memory for allocation of items.        */
3317 /*                                                                           */
3318 /*  This routine initializes the machinery for allocating items.  A `pool'   */
3319 /*  is created whose records have size at least `bytecount'.  Items will be  */
3320 /*  allocated in `itemcount'-item blocks.  Each item is assumed to be a      */
3321 /*  collection of words, and either pointers or floating-point values are    */
3322 /*  assumed to be the "primary" word type.  (The "primary" word type is used */
3323 /*  to determine alignment of items.)  If `alignment' isn't zero, all items  */
3324 /*  will be `alignment'-byte aligned in memory.  `alignment' must be either  */
3325 /*  a multiple or a factor of the primary word size; powers of two are safe. */
3326 /*  `alignment' is normally used to create a few unused bits at the bottom   */
3327 /*  of each item's pointer, in which information may be stored.              */
3328 /*                                                                           */
3329 /*  Don't change this routine unless you understand it.                      */
3330 /*                                                                           */
3331 /*****************************************************************************/
3332
3333 void poolinit( pool, bytecount, itemcount, wtype, alignment )
3334 struct memorypool *pool;
3335 int bytecount;
3336 int itemcount;
3337 enum wordtype wtype;
3338 int alignment;
3339 {
3340 int wordsize;
3341
3342 /* Initialize values in the pool. */
3343 pool->itemwordtype = wtype;
3344 wordsize = ( pool->itemwordtype == POINTER ) ? sizeof( VOID * ) : sizeof( REAL );
3345 /* Find the proper alignment, which must be at least as large as:   */
3346 /*   - The parameter `alignment'.                                   */
3347 /*   - The primary word type, to avoid unaligned accesses.          */
3348 /*   - sizeof(VOID *), so the stack of dead items can be maintained */
3349 /*       without unaligned accesses.                                */
3350 if ( alignment > wordsize ) {
3351 pool->alignbytes = alignment;
3352 }
3353 else {
3354 pool->alignbytes = wordsize;
3355 }
3356 if ( sizeof( VOID * ) > pool->alignbytes ) {
3357 pool->alignbytes = sizeof( VOID * );
3358 }
3359 pool->itemwords = (( bytecount + pool->alignbytes - 1 ) / pool->alignbytes )
3360 * ( pool->alignbytes / wordsize );
3361 pool->itembytes = pool->itemwords * wordsize;
3362 pool->itemsperblock = itemcount;
3363
3364 /* Allocate a block of items.  Space for `itemsperblock' items and one    */
3365 /*   pointer (to point to the next block) are allocated, as well as space */
3366 /*   to ensure alignment of the items.                                    */
3367 pool->firstblock = (VOID **) malloc( pool->itemsperblock * pool->itembytes
3368 + sizeof( VOID * ) + pool->alignbytes );
3369 if ( pool->firstblock == (VOID **) NULL ) {
3370 printf( "Error:  Out of memory.\n" );
3371 exit( 1 );
3372 }
3373 /* Set the next block pointer to NULL. */
3374 *( pool->firstblock ) = (VOID *) NULL;
3375 poolrestart( pool );
3376 }
3377
3378 /*****************************************************************************/
3379 /*                                                                           */
3380 /*  poolrestart()   Deallocate all items in a pool.                          */
3381 /*                                                                           */
3382 /*  The pool is returned to its starting state, except that no memory is     */
3383 /*  freed to the operating system.  Rather, the previously allocated blocks  */
3384 /*  are ready to be reused.                                                  */
3385 /*                                                                           */
3386 /*****************************************************************************/
3387
3388 void poolrestart( pool )
3389 struct memorypool *pool;
3390 {
3391 unsigned long alignptr;
3392
3393 pool->items = 0;
3394 pool->maxitems = 0;
3395
3396 /* Set the currently active block. */
3397 pool->nowblock = pool->firstblock;
3398 /* Find the first item in the pool.  Increment by the size of (VOID *). */
3399 alignptr = (unsigned long) ( pool->nowblock + 1 );
3400 /* Align the item on an `alignbytes'-byte boundary. */
3401 pool->nextitem = (VOID *)
3402 ( alignptr + (unsigned long) pool->alignbytes
3403 - ( alignptr % (unsigned long) pool->alignbytes ));
3404 /* There are lots of unallocated items left in this block. */
3405 pool->unallocateditems = pool->itemsperblock;
3406 /* The stack of deallocated items is empty. */
3407 pool->deaditemstack = (VOID *) NULL;
3408 }
3409
3410 /*****************************************************************************/
3411 /*                                                                           */
3412 /*  pooldeinit()   Free to the operating system all memory taken by a pool.  */
3413 /*                                                                           */
3414 /*****************************************************************************/
3415
3416 void pooldeinit( pool )
3417 struct memorypool *pool;
3418 {
3419 while ( pool->firstblock != (VOID **) NULL ) {
3420 pool->nowblock = (VOID **) *( pool->firstblock );
3421 free( pool->firstblock );
3422 pool->firstblock = pool->nowblock;
3423 }
3424 }
3425
3426 /*****************************************************************************/
3427 /*                                                                           */
3428 /*  poolalloc()   Allocate space for an item.                                */
3429 /*                                                                           */
3430 /*****************************************************************************/
3431
3432 VOID *poolalloc( pool )
3433 struct memorypool *pool;
3434 {
3435 VOID *newitem;
3436 VOID **newblock;
3437 unsigned long alignptr;
3438
3439 /* First check the linked list of dead items.  If the list is not   */
3440 /*   empty, allocate an item from the list rather than a fresh one. */
3441 if ( pool->deaditemstack != (VOID *) NULL ) {
3442 newitem = pool->deaditemstack;           /* Take first item in list. */
3443 pool->deaditemstack = *(VOID **) pool->deaditemstack;
3444 }
3445 else {
3446 /* Check if there are any free items left in the current block. */
3447 if ( pool->unallocateditems == 0 ) {
3448 /* Check if another block must be allocated. */
3449 if ( *( pool->nowblock ) == (VOID *) NULL ) {
3450 /* Allocate a new block of items, pointed to by the previous block. */
3451 newblock = (VOID **) malloc( pool->itemsperblock * pool->itembytes
3452 + sizeof( VOID * ) + pool->alignbytes );
3453 if ( newblock == (VOID **) NULL ) {
3454 printf( "Error:  Out of memory.\n" );
3455 exit( 1 );
3456 }
3457 *( pool->nowblock ) = (VOID *) newblock;
3458 /* The next block pointer is NULL. */
3459 *newblock = (VOID *) NULL;
3460 }
3461 /* Move to the new block. */
3462 pool->nowblock = (VOID **) *( pool->nowblock );
3463 /* Find the first item in the block.    */
3464 /*   Increment by the size of (VOID *). */
3465 alignptr = (unsigned long) ( pool->nowblock + 1 );
3466 /* Align the item on an `alignbytes'-byte boundary. */
3467 pool->nextitem = (VOID *)
3468 ( alignptr + (unsigned long) pool->alignbytes
3469 - ( alignptr % (unsigned long) pool->alignbytes ));
3470 /* There are lots of unallocated items left in this block. */
3471 pool->unallocateditems = pool->itemsperblock;
3472 }
3473 /* Allocate a new item. */
3474 newitem = pool->nextitem;
3475 /* Advance `nextitem' pointer to next free item in block. */
3476 if ( pool->itemwordtype == POINTER ) {
3477 pool->nextitem = (VOID *) ((VOID **) pool->nextitem + pool->itemwords );
3478 }
3479 else {
3480 pool->nextitem = (VOID *) ((REAL *) pool->nextitem + pool->itemwords );
3481 }
3482 pool->unallocateditems--;
3483 pool->maxitems++;
3484 }
3485 pool->items++;
3486 return newitem;
3487 }
3488
3489 /*****************************************************************************/
3490 /*                                                                           */
3491 /*  pooldealloc()   Deallocate space for an item.                            */
3492 /*                                                                           */
3493 /*  The deallocated space is stored in a queue for later reuse.              */
3494 /*                                                                           */
3495 /*****************************************************************************/
3496
3497 void pooldealloc( pool, dyingitem )
3498 struct memorypool *pool;
3499 VOID *dyingitem;
3500 {
3501 /* Push freshly killed item onto stack. */
3502 *((VOID **) dyingitem ) = pool->deaditemstack;
3503 pool->deaditemstack = dyingitem;
3504 pool->items--;
3505 }
3506
3507 /*****************************************************************************/
3508 /*                                                                           */
3509 /*  traversalinit()   Prepare to traverse the entire list of items.          */
3510 /*                                                                           */
3511 /*  This routine is used in conjunction with traverse().                     */
3512 /*                                                                           */
3513 /*****************************************************************************/
3514
3515 void traversalinit( pool )
3516 struct memorypool *pool;
3517 {
3518 unsigned long alignptr;
3519
3520 /* Begin the traversal in the first block. */
3521 pool->pathblock = pool->firstblock;
3522 /* Find the first item in the block.  Increment by the size of (VOID *). */
3523 alignptr = (unsigned long) ( pool->pathblock + 1 );
3524 /* Align with item on an `alignbytes'-byte boundary. */
3525 pool->pathitem = (VOID *)
3526 ( alignptr + (unsigned long) pool->alignbytes
3527 - ( alignptr % (unsigned long) pool->alignbytes ));
3528 /* Set the number of items left in the current block. */
3529 pool->pathitemsleft = pool->itemsperblock;
3530 }
3531
3532 /*****************************************************************************/
3533 /*                                                                           */
3534 /*  traverse()   Find the next item in the list.                             */
3535 /*                                                                           */
3536 /*  This routine is used in conjunction with traversalinit().  Be forewarned */
3537 /*  that this routine successively returns all items in the list, including  */
3538 /*  deallocated ones on the deaditemqueue.  It's up to you to figure out     */
3539 /*  which ones are actually dead.  Why?  I don't want to allocate extra      */
3540 /*  space just to demarcate dead items.  It can usually be done more         */
3541 /*  space-efficiently by a routine that knows something about the structure  */
3542 /*  of the item.                                                             */
3543 /*                                                                           */
3544 /*****************************************************************************/
3545
3546 VOID *traverse( pool )
3547 struct memorypool *pool;
3548 {
3549 VOID *newitem;
3550 unsigned long alignptr;
3551
3552 /* Stop upon exhausting the list of items. */
3553 if ( pool->pathitem == pool->nextitem ) {
3554 return (VOID *) NULL;
3555 }
3556 /* Check whether any untraversed items remain in the current block. */
3557 if ( pool->pathitemsleft == 0 ) {
3558 /* Find the next block. */
3559 pool->pathblock = (VOID **) *( pool->pathblock );
3560 /* Find the first item in the block.  Increment by the size of (VOID *). */
3561 alignptr = (unsigned long) ( pool->pathblock + 1 );
3562 /* Align with item on an `alignbytes'-byte boundary. */
3563 pool->pathitem = (VOID *)
3564 ( alignptr + (unsigned long) pool->alignbytes
3565 - ( alignptr % (unsigned long) pool->alignbytes ));
3566 /* Set the number of items left in the current block. */
3567 pool->pathitemsleft = pool->itemsperblock;
3568 }
3569 newitem = pool->pathitem;
3570 /* Find the next item in the block. */
3571 if ( pool->itemwordtype == POINTER ) {
3572 pool->pathitem = (VOID *) ((VOID **) pool->pathitem + pool->itemwords );
3573 }
3574 else {
3575 pool->pathitem = (VOID *) ((REAL *) pool->pathitem + pool->itemwords );
3576 }
3577 pool->pathitemsleft--;
3578 return newitem;
3579 }
3580
3581 /*****************************************************************************/
3582 /*                                                                           */
3583 /*  dummyinit()   Initialize the triangle that fills "outer space" and the   */
3584 /*                omnipresent shell edge.                                    */
3585 /*                                                                           */
3586 /*  The triangle that fills "outer space", called `dummytri', is pointed to  */
3587 /*  by every triangle and shell edge on a boundary (be it outer or inner) of */
3588 /*  the triangulation.  Also, `dummytri' points to one of the triangles on   */
3589 /*  the convex hull (until the holes and concavities are carved), making it  */
3590 /*  possible to find a starting triangle for point location.                 */
3591 /*                                                                           */
3592 /*  The omnipresent shell edge, `dummysh', is pointed to by every triangle   */
3593 /*  or shell edge that doesn't have a full complement of real shell edges    */
3594 /*  to point to.                                                             */
3595 /*                                                                           */
3596 /*****************************************************************************/
3597
3598 void dummyinit( trianglewords, shellewords )
3599 int trianglewords;
3600 int shellewords;
3601 {
3602 unsigned long alignptr;
3603
3604 /* `triwords' and `shwords' are used by the mesh manipulation primitives */
3605 /*   to extract orientations of triangles and shell edges from pointers. */
3606 triwords = trianglewords;     /* Initialize `triwords' once and for all. */
3607 shwords = shellewords;         /* Initialize `shwords' once and for all. */
3608
3609 /* Set up `dummytri', the `triangle' that occupies "outer space". */
3610 dummytribase = (triangle *) malloc( triwords * sizeof( triangle )
3611 + triangles.alignbytes );
3612 if ( dummytribase == (triangle *) NULL ) {
3613 printf( "Error:  Out of memory.\n" );
3614 exit( 1 );
3615 }
3616 /* Align `dummytri' on a `triangles.alignbytes'-byte boundary. */
3617 alignptr = (unsigned long) dummytribase;
3618 dummytri = (triangle *)
3619 ( alignptr + (unsigned long) triangles.alignbytes
3620 - ( alignptr % (unsigned long) triangles.alignbytes ));
3621 /* Initialize the three adjoining triangles to be "outer space".  These  */
3622 /*   will eventually be changed by various bonding operations, but their */
3623 /*   values don't really matter, as long as they can legally be          */
3624 /*   dereferenced.                                                       */
3625 dummytri[0] = (triangle) dummytri;
3626 dummytri[1] = (triangle) dummytri;
3627 dummytri[2] = (triangle) dummytri;
3628 /* Three NULL vertex points. */
3629 dummytri[3] = (triangle) NULL;
3630 dummytri[4] = (triangle) NULL;
3631 dummytri[5] = (triangle) NULL;
3632
3633 if ( useshelles ) {
3634 /* Set up `dummysh', the omnipresent "shell edge" pointed to by any      */
3635 /*   triangle side or shell edge end that isn't attached to a real shell */
3636 /*   edge.                                                               */
3637 dummyshbase = (shelle *) malloc( shwords * sizeof( shelle )
3638 + shelles.alignbytes );
3639 if ( dummyshbase == (shelle *) NULL ) {
3640 printf( "Error:  Out of memory.\n" );
3641 exit( 1 );
3642 }
3643 /* Align `dummysh' on a `shelles.alignbytes'-byte boundary. */
3644 alignptr = (unsigned long) dummyshbase;
3645 dummysh = (shelle *)
3646 ( alignptr + (unsigned long) shelles.alignbytes
3647 - ( alignptr % (unsigned long) shelles.alignbytes ));
3648 /* Initialize the two adjoining shell edges to be the omnipresent shell */
3649 /*   edge.  These will eventually be changed by various bonding         */
3650 /*   operations, but their values don't really matter, as long as they  */
3651 /*   can legally be dereferenced.                                       */
3652 dummysh[0] = (shelle) dummysh;
3653 dummysh[1] = (shelle) dummysh;
3654 /* Two NULL vertex points. */
3655 dummysh[2] = (shelle) NULL;
3656 dummysh[3] = (shelle) NULL;
3657 /* Initialize the two adjoining triangles to be "outer space". */
3658 dummysh[4] = (shelle) dummytri;
3659 dummysh[5] = (shelle) dummytri;
3660 /* Set the boundary marker to zero. */
3661 *(int *) ( dummysh + 6 ) = 0;
3662
3663 /* Initialize the three adjoining shell edges of `dummytri' to be */
3664 /*   the omnipresent shell edge.                                  */
3665 dummytri[6] = (triangle) dummysh;
3666 dummytri[7] = (triangle) dummysh;
3667 dummytri[8] = (triangle) dummysh;
3668 }
3669 }
3670
3671 /*****************************************************************************/
3672 /*                                                                           */
3673 /*  initializepointpool()   Calculate the size of the point data structure   */
3674 /*                          and initialize its memory pool.                  */
3675 /*                                                                           */
3676 /*  This routine also computes the `pointmarkindex' and `point2triindex'     */
3677 /*  indices used to find values within each point.                           */
3678 /*                                                                           */
3679 /*****************************************************************************/
3680
3681 void initializepointpool(){
3682 int pointsize;
3683
3684 /* The index within each point at which the boundary marker is found.  */
3685 /*   Ensure the point marker is aligned to a sizeof(int)-byte address. */
3686 pointmarkindex = (( mesh_dim + nextras ) * sizeof( REAL ) + sizeof( int ) - 1 )
3687 / sizeof( int );
3688 pointsize = ( pointmarkindex + 1 ) * sizeof( int );
3689 if ( poly ) {
3690 /* The index within each point at which a triangle pointer is found.   */
3691 /*   Ensure the pointer is aligned to a sizeof(triangle)-byte address. */
3692 point2triindex = ( pointsize + sizeof( triangle ) - 1 ) / sizeof( triangle );
3693 pointsize = ( point2triindex + 1 ) * sizeof( triangle );
3694 }
3695 /* Initialize the pool of points. */
3696 poolinit( &points, pointsize, POINTPERBLOCK,
3697 ( sizeof( REAL ) >= sizeof( triangle )) ? FLOATINGPOINT : POINTER, 0 );
3698 }
3699
3700 /*****************************************************************************/
3701 /*                                                                           */
3702 /*  initializetrisegpools()   Calculate the sizes of the triangle and shell  */
3703 /*                            edge data structures and initialize their      */
3704 /*                            memory pools.                                  */
3705 /*                                                                           */
3706 /*  This routine also computes the `highorderindex', `elemattribindex', and  */
3707 /*  `areaboundindex' indices used to find values within each triangle.       */
3708 /*                                                                           */
3709 /*****************************************************************************/
3710
3711 void initializetrisegpools(){
3712 int trisize;
3713
3714 /* The index within each triangle at which the extra nodes (above three)  */
3715 /*   associated with high order elements are found.  There are three      */
3716 /*   pointers to other triangles, three pointers to corners, and possibly */
3717 /*   three pointers to shell edges before the extra nodes.                */
3718 highorderindex = 6 + ( useshelles * 3 );
3719 /* The number of bytes occupied by a triangle. */
3720 trisize = (( order + 1 ) * ( order + 2 ) / 2 + ( highorderindex - 3 )) *
3721 sizeof( triangle );
3722 /* The index within each triangle at which its attributes are found, */
3723 /*   where the index is measured in REALs.                           */
3724 elemattribindex = ( trisize + sizeof( REAL ) - 1 ) / sizeof( REAL );
3725 /* The index within each triangle at which the maximum area constraint  */
3726 /*   is found, where the index is measured in REALs.  Note that if the  */
3727 /*   `regionattrib' flag is set, an additional attribute will be added. */
3728 areaboundindex = elemattribindex + eextras + regionattrib;
3729 /* If triangle attributes or an area bound are needed, increase the number */
3730 /*   of bytes occupied by a triangle.                                      */
3731 if ( vararea ) {
3732 trisize = ( areaboundindex + 1 ) * sizeof( REAL );
3733 }
3734 else if ( eextras + regionattrib > 0 ) {
3735 trisize = areaboundindex * sizeof( REAL );
3736 }
3737 /* If a Voronoi diagram or triangle neighbor graph is requested, make    */
3738 /*   sure there's room to store an integer index in each triangle.  This */
3739 /*   integer index can occupy the same space as the shell edges or       */
3740 /*   attributes or area constraint or extra nodes.                       */
3741 if (( voronoi || neighbors ) &&
3742 ( trisize < 6 * sizeof( triangle ) + sizeof( int ))) {
3743 trisize = 6 * sizeof( triangle ) + sizeof( int );
3744 }
3745 /* Having determined the memory size of a triangle, initialize the pool. */
3746 poolinit( &triangles, trisize, TRIPERBLOCK, POINTER, 4 );
3747
3748 if ( useshelles ) {
3749 /* Initialize the pool of shell edges. */
3750 poolinit( &shelles, 6 * sizeof( triangle ) + sizeof( int ), SHELLEPERBLOCK,
3751 POINTER, 4 );
3752
3753 /* Initialize the "outer space" triangle and omnipresent shell edge. */
3754 dummyinit( triangles.itemwords, shelles.itemwords );
3755 }
3756 else {
3757 /* Initialize the "outer space" triangle. */
3758 dummyinit( triangles.itemwords, 0 );
3759 }
3760 }
3761
3762 /*****************************************************************************/
3763 /*                                                                           */
3764 /*  triangledealloc()   Deallocate space for a triangle, marking it dead.    */
3765 /*                                                                           */
3766 /*****************************************************************************/
3767
3768 void triangledealloc( dyingtriangle )
3769 triangle * dyingtriangle;
3770 {
3771 /* Set triangle's vertices to NULL.  This makes it possible to        */
3772 /*   detect dead triangles when traversing the list of all triangles. */
3773 dyingtriangle[3] = (triangle) NULL;
3774 dyingtriangle[4] = (triangle) NULL;
3775 dyingtriangle[5] = (triangle) NULL;
3776 pooldealloc( &triangles, (VOID *) dyingtriangle );
3777 }
3778
3779 /*****************************************************************************/
3780 /*                                                                           */
3781 /*  triangletraverse()   Traverse the triangles, skipping dead ones.         */
3782 /*                                                                           */
3783 /*****************************************************************************/
3784
3785 triangle *triangletraverse(){
3786 triangle *newtriangle;
3787
3788 do {
3789 newtriangle = (triangle *) traverse( &triangles );
3790 if ( newtriangle == (triangle *) NULL ) {
3791 return (triangle *) NULL;
3792 }
3793 } while ( newtriangle[3] == (triangle) NULL );        /* Skip dead ones. */
3794 return newtriangle;
3795 }
3796
3797 /*****************************************************************************/
3798 /*                                                                           */
3799 /*  shelledealloc()   Deallocate space for a shell edge, marking it dead.    */
3800 /*                                                                           */
3801 /*****************************************************************************/
3802
3803 void shelledealloc( dyingshelle )
3804 shelle * dyingshelle;
3805 {
3806 /* Set shell edge's vertices to NULL.  This makes it possible to */
3807 /*   detect dead shells when traversing the list of all shells.  */
3808 dyingshelle[2] = (shelle) NULL;
3809 dyingshelle[3] = (shelle) NULL;
3810 pooldealloc( &shelles, (VOID *) dyingshelle );
3811 }
3812
3813 /*****************************************************************************/
3814 /*                                                                           */
3815 /*  shelletraverse()   Traverse the shell edges, skipping dead ones.         */
3816 /*                                                                           */
3817 /*****************************************************************************/
3818
3819 shelle *shelletraverse(){
3820 shelle *newshelle;
3821
3822 do {
3823 newshelle = (shelle *) traverse( &shelles );
3824 if ( newshelle == (shelle *) NULL ) {
3825 return (shelle *) NULL;
3826 }
3827 } while ( newshelle[2] == (shelle) NULL );            /* Skip dead ones. */
3828 return newshelle;
3829 }
3830
3831 /*****************************************************************************/
3832 /*                                                                           */
3833 /*  pointdealloc()   Deallocate space for a point, marking it dead.          */
3834 /*                                                                           */
3835 /*****************************************************************************/
3836
3837 void pointdealloc( dyingpoint )
3838 point dyingpoint;
3839 {
3840 /* Mark the point as dead.  This makes it possible to detect dead points */
3841 /*   when traversing the list of all points.                             */
3842 setpointmark( dyingpoint, DEADPOINT );
3843 pooldealloc( &points, (VOID *) dyingpoint );
3844 }
3845
3846 /*****************************************************************************/
3847 /*                                                                           */
3848 /*  pointtraverse()   Traverse the points, skipping dead ones.               */
3849 /*                                                                           */
3850 /*****************************************************************************/
3851
3852 point pointtraverse(){
3853 point newpoint;
3854
3855 do {
3856 newpoint = (point) traverse( &points );
3857 if ( newpoint == (point) NULL ) {
3858 return (point) NULL;
3859 }
3860 } while ( pointmark( newpoint ) == DEADPOINT );       /* Skip dead ones. */
3861 return newpoint;
3862 }
3863
3864 /*****************************************************************************/
3865 /*                                                                           */
3866 /*  badsegmentdealloc()   Deallocate space for a bad segment, marking it     */
3867 /*                        dead.                                              */
3868 /*                                                                           */
3869 /*****************************************************************************/
3870
3871 #ifndef
3872 CDT_ONLY
3873
3874 void badsegmentdealloc( dyingseg )
3875 struct edge *dyingseg;
3876 {
3877 /* Set segment's orientation to -1.  This makes it possible to      */
3878 /*   detect dead segments when traversing the list of all segments. */
3879 dyingseg->shorient = -1;
3880 pooldealloc( &badsegments, (VOID *) dyingseg );
3881 }
3882
3883 #endif /* not CDT_ONLY */
3884
3885 /*****************************************************************************/
3886 /*                                                                           */
3887 /*  badsegmenttraverse()   Traverse the bad segments, skipping dead ones.    */
3888 /*                                                                           */
3889 /*****************************************************************************/
3890
3891 #ifndef
3892 CDT_ONLY
3893
3894 struct edge *badsegmenttraverse(){
3895 struct edge *newseg;
3896
3897 do {
3898 newseg = (struct edge *) traverse( &badsegments );
3899 if ( newseg == (struct edge *) NULL ) {
3900 return (struct edge *) NULL;
3901 }
3902 } while ( newseg->shorient == -1 );                   /* Skip dead ones. */
3903 return newseg;
3904 }
3905
3906 #endif /* not CDT_ONLY */
3907
3908 /*****************************************************************************/
3909 /*                                                                           */
3910 /*  getpoint()   Get a specific point, by number, from the list.             */
3911 /*                                                                           */
3912 /*  The first point is number 'firstnumber'.                                 */
3913 /*                                                                           */
3914 /*  Note that this takes O(n) time (with a small constant, if POINTPERBLOCK  */
3915 /*  is large).  I don't care to take the trouble to make it work in constant */
3916 /*  time.                                                                    */
3917 /*                                                                           */
3918 /*****************************************************************************/
3919
3920 point getpoint( number )
3921 int number;
3922 {
3923 VOID **getblock;
3924 point foundpoint;
3925 unsigned long alignptr;
3926 int current;
3927
3928 getblock = points.firstblock;
3929 current = firstnumber;
3930 /* Find the right block. */
3931 while ( current + points.itemsperblock <= number ) {
3932 getblock = (VOID **) *getblock;
3933 current += points.itemsperblock;
3934 }
3935 /* Now find the right point. */
3936 alignptr = (unsigned long) ( getblock + 1 );
3937 foundpoint = (point) ( alignptr + (unsigned long) points.alignbytes
3938 - ( alignptr % (unsigned long) points.alignbytes ));
3939 while ( current < number ) {
3940 foundpoint += points.itemwords;
3941 current++;
3942 }
3943 return foundpoint;
3944 }
3945
3946 /*****************************************************************************/
3947 /*                                                                           */
3948 /*  triangledeinit()   Free all remaining allocated memory.                  */
3949 /*                                                                           */
3950 /*****************************************************************************/
3951
3952 void triangledeinit(){
3953 pooldeinit( &triangles );
3954 free( dummytribase );
3955 if ( useshelles ) {
3956 pooldeinit( &shelles );
3957 free( dummyshbase );
3958 }
3959 pooldeinit( &points );
3960 #ifndef
3961 CDT_ONLY
3962 if ( quality ) {
3963 pooldeinit( &badsegments );
3964 if (( minangle > 0.0 ) || vararea || fixedarea ) {
3965 pooldeinit( &badtriangles );
3966 }
3967 }
3968 #endif /* not CDT_ONLY */
3969 }
3970
3971 /**                                                                         **/
3972 /**                                                                         **/
3973 /********* Memory management routines end here                       *********/
3974
3975 /********* Constructors begin here                                   *********/
3976 /**                                                                         **/
3977 /**                                                                         **/
3978
3979 /*****************************************************************************/
3980 /*                                                                           */
3981 /*  maketriangle()   Create a new triangle with orientation zero.            */
3982 /*                                                                           */
3983 /*****************************************************************************/
3984
3985 void maketriangle( newtriedge )
3986 struct triedge *newtriedge;
3987 {
3988 int i;
3989
3990 newtriedge->tri = (triangle *) poolalloc( &triangles );
3991 /* Initialize the three adjoining triangles to be "outer space". */
3992 newtriedge->tri[0] = (triangle) dummytri;
3993 newtriedge->tri[1] = (triangle) dummytri;
3994 newtriedge->tri[2] = (triangle) dummytri;
3995 /* Three NULL vertex points. */
3996 newtriedge->tri[3] = (triangle) NULL;
3997 newtriedge->tri[4] = (triangle) NULL;
3998 newtriedge->tri[5] = (triangle) NULL;
3999 /* Initialize the three adjoining shell edges to be the omnipresent */
4000 /*   shell edge.                                                    */
4001 if ( useshelles ) {
4002 newtriedge->tri[6] = (triangle) dummysh;
4003 newtriedge->tri[7] = (triangle) dummysh;
4004 newtriedge->tri[8] = (triangle) dummysh;
4005 }
4006 for ( i = 0; i < eextras; i++ ) {
4007 setelemattribute( *newtriedge, i, 0.0 );
4008 }
4009 if ( vararea ) {
4010 setareabound( *newtriedge, -1.0 );
4011 }
4012
4013 newtriedge->orient = 0;
4014 }
4015
4016 /*****************************************************************************/
4017 /*                                                                           */
4018 /*  makeshelle()   Create a new shell edge with orientation zero.            */
4019 /*                                                                           */
4020 /*****************************************************************************/
4021
4022 void makeshelle( newedge )
4023 struct edge *newedge;
4024 {
4025 newedge->sh = (shelle *) poolalloc( &shelles );
4026 /* Initialize the two adjoining shell edges to be the omnipresent */
4027 /*   shell edge.                                                  */
4028 newedge->sh[0] = (shelle) dummysh;
4029 newedge->sh[1] = (shelle) dummysh;
4030 /* Two NULL vertex points. */
4031 newedge->sh[2] = (shelle) NULL;
4032 newedge->sh[3] = (shelle) NULL;
4033 /* Initialize the two adjoining triangles to be "outer space". */
4034 newedge->sh[4] = (shelle) dummytri;
4035 newedge->sh[5] = (shelle) dummytri;
4036 /* Set the boundary marker to zero. */
4037 setmark( *newedge, 0 );
4038
4039 newedge->shorient = 0;
4040 }
4041
4042 /**                                                                         **/
4043 /**                                                                         **/
4044 /********* Constructors end here                                     *********/
4045
4046 /********* Determinant evaluation routines begin here                *********/
4047 /**                                                                         **/
4048 /**                                                                         **/
4049
4050 /* The adaptive exact arithmetic geometric predicates implemented herein are */
4051 /*   described in detail in my Technical Report CMU-CS-96-140.  The complete */
4052 /*   reference is given in the header.                                       */
4053
4054 /* Which of the following two methods of finding the absolute values is      */
4055 /*   fastest is compiler-dependent.  A few compilers can inline and optimize */
4056 /*   the fabs() call; but most will incur the overhead of a function call,   */
4057 /*   which is disastrously slow.  A faster way on IEEE machines might be to  */
4058 /*   mask the appropriate bit, but that's difficult to do in C.              */
4059
4060 #define
4061 Absolute( a )  (( a ) >= 0.0 ? ( a ) : -( a ))
4062 /* #define Absolute(a)  fabs(a) */
4063
4064 /* Many of the operations are broken up into two pieces, a main part that    */
4065 /*   performs an approximate operation, and a "tail" that computes the       */
4066 /*   roundoff error of that operation.                                       */
4067 /*                                                                           */
4068 /* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(),    */
4069 /*   Split(), and Two_Product() are all implemented as described in the      */
4070 /*   reference.  Each of these macros requires certain variables to be       */
4071 /*   defined in the calling routine.  The variables `bvirt', `c', `abig',    */
4072 /*   `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because   */
4073 /*   they store the result of an operation that may incur roundoff error.    */
4074 /*   The input parameter `x' (or the highest numbered `x_' parameter) must   */
4075 /*   also be declared `INEXACT'.                                             */
4076
4077 #define
4078 Fast_Two_Sum_Tail( a, b, x, y )    \
4079     bvirt = x - a; \
4080     y = b - bvirt
4081
4082 #define
4083 Fast_Two_Sum( a, b, x, y ) \
4084     x = (REAL) ( a + b ); \
4085     Fast_Two_Sum_Tail( a, b, x, y )
4086
4087 #define
4088 Two_Sum_Tail( a, b, x, y ) \
4089     bvirt = (REAL) ( x - a ); \
4090     avirt = x - bvirt; \
4091     bround = b - bvirt;    \
4092     around = a - avirt;    \
4093     y = around + bround
4094
4095 #define
4096 Two_Sum( a, b, x, y ) \
4097     x = (REAL) ( a + b ); \
4098     Two_Sum_Tail( a, b, x, y )
4099
4100 #define
4101 Two_Diff_Tail( a, b, x, y )    \
4102     bvirt = (REAL) ( a - x ); \
4103     avirt = x + bvirt; \
4104     bround = bvirt - b;    \
4105     around = a - avirt;    \
4106     y = around + bround
4107
4108 #define
4109 Two_Diff( a, b, x, y ) \
4110     x = (REAL) ( a - b ); \
4111     Two_Diff_Tail( a, b, x, y )
4112
4113 #define
4114 Split( a, ahi, alo ) \
4115     c = (REAL) ( splitter * a ); \
4116     abig = (REAL) ( c - a ); \
4117     ahi = (REAL)( c - abig ); \
4118     alo = (REAL)( a - ahi )
4119
4120 #define
4121 Two_Product_Tail( a, b, x, y ) \
4122     Split( a, ahi, alo ); \
4123     Split( b, bhi, blo ); \
4124     err1 = x - ( ahi * bhi ); \
4125     err2 = err1 - ( alo * bhi ); \
4126     err3 = err2 - ( ahi * blo ); \
4127     y = ( alo * blo ) - err3
4128
4129 #define
4130 Two_Product( a, b, x, y ) \
4131     x = (REAL) ( a * b ); \
4132     Two_Product_Tail( a, b, x, y )
4133
4134 /* Two_Product_Presplit() is Two_Product() where one of the inputs has       */
4135 /*   already been split.  Avoids redundant splitting.                        */
4136
4137 #define
4138 Two_Product_Presplit( a, b, bhi, blo, x, y ) \
4139     x = (REAL) ( a * b ); \
4140     Split( a, ahi, alo ); \
4141     err1 = x - ( ahi * bhi ); \
4142     err2 = err1 - ( alo * bhi ); \
4143     err3 = err2 - ( ahi * blo ); \
4144     y = ( alo * blo ) - err3
4145
4146 /* Square() can be done more quickly than Two_Product().                     */
4147
4148 #define
4149 Square_Tail( a, x, y ) \
4150     Split( a, ahi, alo ); \
4151     err1 = x - ( ahi * ahi ); \
4152     err3 = err1 - (( ahi + ahi ) * alo ); \
4153     y = ( alo * alo ) - err3
4154
4155 #define
4156 Square( a, x, y ) \
4157     x = (REAL) ( a * a ); \
4158     Square_Tail( a, x, y )
4159
4160 /* Macros for summing expansions of various fixed lengths.  These are all    */
4161 /*   unrolled versions of Expansion_Sum().                                   */
4162
4163 #define
4164 Two_One_Sum( a1, a0, b, x2, x1, x0 ) \
4165     Two_Sum( a0, b, _i, x0 ); \
4166     Two_Sum( a1, _i, x2, x1 )
4167
4168 #define
4169 Two_One_Diff( a1, a0, b, x2, x1, x0 ) \
4170     Two_Diff( a0, b, _i, x0 ); \
4171     Two_Sum( a1, _i, x2, x1 )
4172
4173 #define
4174 Two_Two_Sum( a1, a0, b1, b0, x3, x2, x1, x0 ) \
4175     Two_One_Sum( a1, a0, b0, _j, _0, x0 ); \
4176     Two_One_Sum( _j, _0, b1, x3, x2, x1 )
4177
4178 #define
4179 Two_Two_Diff( a1, a0, b1, b0, x3, x2, x1, x0 ) \
4180     Two_One_Diff( a1, a0, b0, _j, _0, x0 );    \
4181     Two_One_Diff( _j, _0, b1, x3, x2, x1 )
4182
4183 /*****************************************************************************/
4184 /*                                                                           */
4185 /*  exactinit()   Initialize the variables used for exact arithmetic.        */
4186 /*                                                                           */
4187 /*  `epsilon' is the largest power of two such that 1.0 + epsilon = 1.0 in   */
4188 /*  floating-point arithmetic.  `epsilon' bounds the relative roundoff       */
4189 /*  error.  It is used for floating-point error analysis.                    */
4190 /*                                                                           */
4191 /*  `splitter' is used to split floating-point numbers into two half-        */
4192 /*  length significands for exact multiplication.                            */
4193 /*                                                                           */
4194 /*  I imagine that a highly optimizing compiler might be too smart for its   */
4195 /*  own good, and somehow cause this routine to fail, if it pretends that    */
4196 /*  floating-point arithmetic is too much like real arithmetic.              */
4197 /*                                                                           */
4198 /*  Don't change this routine unless you fully understand it.                */
4199 /*                                                                           */
4200 /*****************************************************************************/
4201
4202 void exactinit(){
4203 REAL half;
4204 REAL check, lastcheck;
4205 int every_other;
4206
4207 every_other = 1;
4208 half = 0.5;
4209 epsilon = 1.0;
4210 splitter = 1.0;
4211 check = 1.0;
4212 /* Repeatedly divide `epsilon' by two until it is too small to add to      */
4213 /*   one without causing roundoff.  (Also check if the sum is equal to     */
4214 /*   the previous sum, for machines that round up instead of using exact   */
4215 /*   rounding.  Not that these routines will work on such machines anyway. */
4216 do {
4217 lastcheck = check;
4218 epsilon *= half;
4219 if ( every_other ) {
4220 splitter *= 2.0;
4221 }
4222 every_other = !every_other;
4223 check = (REAL)( 1.0 + epsilon );
4224 } while (( check != 1.0 ) && ( check != lastcheck ));
4225 splitter += 1.0;
4226 if ( verbose > 1 ) {
4227 printf( "Floating point roundoff is of magnitude %.17g\n", epsilon );
4228 printf( "Floating point splitter is %.17g\n", splitter );
4229 }
4230 /* Error bounds for orientation and incircle tests. */
4231 resulterrbound = (REAL)(( 3.0 + 8.0 * epsilon ) * epsilon );
4232 ccwerrboundA = (REAL)(( 3.0 + 16.0 * epsilon ) * epsilon );
4233 ccwerrboundB = (REAL)(( 2.0 + 12.0 * epsilon ) * epsilon );
4234 ccwerrboundC = (REAL)(( 9.0 + 64.0 * epsilon ) * epsilon * epsilon );
4235 iccerrboundA = (REAL)(( 10.0 + 96.0 * epsilon ) * epsilon );
4236 iccerrboundB = (REAL)(( 4.0 + 48.0 * epsilon ) * epsilon );
4237 iccerrboundC = (REAL)(( 44.0 + 576.0 * epsilon ) * epsilon * epsilon );
4238 }
4239
4240 /*****************************************************************************/
4241 /*                                                                           */
4242 /*  fast_expansion_sum_zeroelim()   Sum two expansions, eliminating zero     */
4243 /*                                  components from the output expansion.    */
4244 /*                                                                           */
4245 /*  Sets h = e + f.  See my Robust Predicates paper for details.             */
4246 /*                                                                           */
4247 /*  If round-to-even is used (as with IEEE 754), maintains the strongly      */
4248 /*  nonoverlapping property.  (That is, if e is strongly nonoverlapping, h   */
4249 /*  will be also.)  Does NOT maintain the nonoverlapping or nonadjacent      */
4250 /*  properties.                                                              */
4251 /*                                                                           */
4252 /*****************************************************************************/
4253
4254 int fast_expansion_sum_zeroelim( elen, e, flen, f, h )  /* h cannot be e or f. */
4255 int elen;
4256 REAL *e;
4257 int flen;
4258 REAL *f;
4259 REAL *h;
4260 {
4261 REAL Q;
4262 INEXACT REAL Qnew;
4263 INEXACT REAL hh;
4264 INEXACT REAL bvirt;
4265 REAL avirt, bround, around;
4266 int eindex, findex, hindex;
4267 REAL enow, fnow;
4268
4269 enow = e[0];
4270 fnow = f[0];
4271 eindex = findex = 0;
4272 if (( fnow > enow ) == ( fnow > -enow )) {
4273 Q = enow;
4274 enow = e[++eindex];
4275 }
4276 else {
4277 Q = fnow;
4278 fnow = f[++findex];
4279 }
4280 hindex = 0;
4281 if (( eindex < elen ) && ( findex < flen )) {
4282 if (( fnow > enow ) == ( fnow > -enow )) {
4283 Fast_Two_Sum( enow, Q, Qnew, hh );
4284 enow = e[++eindex];
4285 }
4286 else {
4287 Fast_Two_Sum( fnow, Q, Qnew, hh );
4288 fnow = f[++findex];
4289 }
4290 Q = Qnew;
4291 if ( hh != 0.0 ) {
4292 h[hindex++] = hh;
4293 }
4294 while (( eindex < elen ) && ( findex < flen )) {
4295 if (( fnow > enow ) == ( fnow > -enow )) {
4296 Two_Sum( Q, enow, Qnew, hh );
4297 enow = e[++eindex];
4298 }
4299 else {
4300 Two_Sum( Q, fnow, Qnew, hh );
4301 fnow = f[++findex];
4302 }
4303 Q = Qnew;
4304 if ( hh != 0.0 ) {
4305 h[hindex++] = hh;
4306 }
4307 }
4308 }
4309 while ( eindex < elen ) {
4310 Two_Sum( Q, enow, Qnew, hh );
4311 enow = e[++eindex];
4312 Q = Qnew;
4313 if ( hh != 0.0 ) {
4314 h[hindex++] = hh;
4315 }
4316 }
4317 while ( findex < flen ) {
4318 Two_Sum( Q, fnow, Qnew, hh );
4319 fnow = f[++findex];
4320 Q = Qnew;
4321 if ( hh != 0.0 ) {
4322 h[hindex++] = hh;
4323 }
4324 }
4325 if (( Q != 0.0 ) || ( hindex == 0 )) {
4326 h[hindex++] = Q;
4327 }
4328 return hindex;
4329 }
4330
4331 /*****************************************************************************/
4332 /*                                                                           */
4333 /*  scale_expansion_zeroelim()   Multiply an expansion by a scalar,          */
4334 /*                               eliminating zero components from the        */
4335 /*                               output expansion.                           */
4336 /*                                                                           */
4337 /*  Sets h = be.  See my Robust Predicates paper for details.                */
4338 /*                                                                           */
4339 /*  Maintains the nonoverlapping property.  If round-to-even is used (as     */
4340 /*  with IEEE 754), maintains the strongly nonoverlapping and nonadjacent    */
4341 /*  properties as well.  (That is, if e has one of these properties, so      */
4342 /*  will h.)                                                                 */
4343 /*                                                                           */
4344 /*****************************************************************************/
4345
4346 int scale_expansion_zeroelim( elen, e, b, h )   /* e and h cannot be the same. */
4347 int elen;
4348 REAL *e;
4349 REAL b;
4350 REAL *h;
4351 {
4352 INEXACT REAL Q, sum;
4353 REAL hh;
4354 INEXACT REAL product1;
4355 REAL product0;
4356 int eindex, hindex;
4357 REAL enow;
4358 INEXACT REAL bvirt;
4359 REAL avirt, bround, around;
4360 INEXACT REAL c;
4361 INEXACT REAL abig;
4362 REAL ahi, alo, bhi, blo;
4363 REAL err1, err2, err3;
4364
4365 Split( b, bhi, blo );
4366 Two_Product_Presplit( e[0], b, bhi, blo, Q, hh );
4367 hindex = 0;
4368 if ( hh != 0 ) {
4369 h[hindex++] = hh;
4370 }
4371 for ( eindex = 1; eindex < elen; eindex++ ) {
4372 enow = e[eindex];
4373 Two_Product_Presplit( enow, b, bhi, blo, product1, product0 );
4374 Two_Sum( Q, product0, sum, hh );
4375 if ( hh != 0 ) {
4376 h[hindex++] = hh;
4377 }
4378 Fast_Two_Sum( product1, sum, Q, hh );
4379 if ( hh != 0 ) {
4380 h[hindex++] = hh;
4381 }
4382 }
4383 if (( Q != 0.0 ) || ( hindex == 0 )) {
4384 h[hindex++] = Q;
4385 }
4386 return hindex;
4387 }
4388
4389 /*****************************************************************************/
4390 /*                                                                           */
4391 /*  estimate()   Produce a one-word estimate of an expansion's value.        */
4392 /*                                                                           */
4393 /*  See my Robust Predicates paper for details.                              */
4394 /*                                                                           */
4395 /*****************************************************************************/
4396
4397 REAL estimate( elen, e )
4398 int elen;
4399 REAL *e;
4400 {
4401 REAL Q;
4402 int eindex;
4403
4404 Q = e[0];
4405 for ( eindex = 1; eindex < elen; eindex++ ) {
4406 Q += e[eindex];
4407 }
4408 return Q;
4409 }
4410
4411 /*****************************************************************************/
4412 /*                                                                           */
4413 /*  counterclockwise()   Return a positive value if the points pa, pb, and   */
4414 /*                       pc occur in counterclockwise order; a negative      */
4415 /*                       value if they occur in clockwise order; and zero    */
4416 /*                       if they are collinear.  The result is also a rough  */
4417 /*                       approximation of twice the signed area of the       */
4418 /*                       triangle defined by the three points.               */
4419 /*                                                                           */
4420 /*  Uses exact arithmetic if necessary to ensure a correct answer.  The      */
4421 /*  result returned is the determinant of a matrix.  This determinant is     */
4422 /*  computed adaptively, in the sense that exact arithmetic is used only to  */
4423 /*  the degree it is needed to ensure that the returned value has the        */
4424 /*  correct sign.  Hence, this function is usually quite fast, but will run  */
4425 /*  more slowly when the input points are collinear or nearly so.            */
4426 /*                                                                           */
4427 /*  See my Robust Predicates paper for details.                              */
4428 /*                                                                           */
4429 /*****************************************************************************/
4430
4431 REAL counterclockwiseadapt( pa, pb, pc, detsum )
4432 point pa;
4433 point pb;
4434 point pc;
4435 REAL detsum;
4436 {
4437 INEXACT REAL acx, acy, bcx, bcy;
4438 REAL acxtail, acytail, bcxtail, bcytail;
4439 INEXACT REAL detleft, detright;
4440 REAL detlefttail, detrighttail;
4441 REAL det, errbound;
4442 REAL B[4], C1[8], C2[12], D[16];
4443 INEXACT REAL B3;
4444 int C1length, C2length, Dlength;
4445 REAL u[4];
4446 INEXACT REAL u3;
4447 INEXACT REAL s1, t1;
4448 REAL s0, t0;
4449
4450 INEXACT REAL bvirt;
4451 REAL avirt, bround, around;
4452 INEXACT REAL c;
4453 INEXACT REAL abig;
4454 REAL ahi, alo, bhi, blo;
4455 REAL err1, err2, err3;
4456 INEXACT REAL _i, _j;
4457 REAL _0;
4458
4459 acx = (REAL) ( pa[0] - pc[0] );
4460 bcx = (REAL) ( pb[0] - pc[0] );
4461 acy = (REAL) ( pa[1] - pc[1] );
4462 bcy = (REAL) ( pb[1] - pc[1] );
4463
4464 Two_Product( acx, bcy, detleft, detlefttail );
4465 Two_Product( acy, bcx, detright, detrighttail );
4466
4467 Two_Two_Diff( detleft, detlefttail, detright, detrighttail,
4468 B3, B[2], B[1], B[0] );
4469 B[3] = B3;
4470
4471 det = estimate( 4, B );
4472 errbound = (REAL)( ccwerrboundB * detsum );
4473 if (( det >= errbound ) || ( -det >= errbound )) {
4474 return det;
4475 }
4476
4477 Two_Diff_Tail( pa[0], pc[0], acx, acxtail );
4478 Two_Diff_Tail( pb[0], pc[0], bcx, bcxtail );
4479 Two_Diff_Tail( pa[1], pc[1], acy, acytail );
4480 Two_Diff_Tail( pb[1], pc[1], bcy, bcytail );
4481
4482 if (( acxtail == 0.0 ) && ( acytail == 0.0 )
4483 && ( bcxtail == 0.0 ) && ( bcytail == 0.0 )) {
4484 return det;
4485 }
4486
4487 errbound = (REAL)( ccwerrboundC * detsum + resulterrbound * Absolute( det ));
4488 det += ( acx * bcytail + bcy * acxtail )
4489 - ( acy * bcxtail + bcx * acytail );
4490 if (( det >= errbound ) || ( -det >= errbound )) {
4491 return det;
4492 }
4493
4494 Two_Product( acxtail, bcy, s1, s0 );
4495 Two_Product( acytail, bcx, t1, t0 );
4496 Two_Two_Diff( s1, s0, t1, t0, u3, u[2], u[1], u[0] );
4497 u[3] = u3;
4498 C1length = fast_expansion_sum_zeroelim( 4, B, 4, u, C1 );
4499
4500 Two_Product( acx, bcytail, s1, s0 );
4501 Two_Product( acy, bcxtail, t1, t0 );
4502 Two_Two_Diff( s1, s0, t1, t0, u3, u[2], u[1], u[0] );
4503 u[3] = u3;
4504 C2length = fast_expansion_sum_zeroelim( C1length, C1, 4, u, C2 );
4505
4506 Two_Product( acxtail, bcytail, s1, s0 );
4507 Two_Product( acytail, bcxtail, t1, t0 );
4508 Two_Two_Diff( s1, s0, t1, t0, u3, u[2], u[1], u[0] );
4509 u[3] = u3;
4510 Dlength = fast_expansion_sum_zeroelim( C2length, C2, 4, u, D );
4511
4512 return( D[Dlength - 1] );
4513 }
4514
4515 REAL counterclockwise( pa, pb, pc )
4516 point pa;
4517 point pb;
4518 point pc;
4519 {
4520 REAL detleft, detright, det;
4521 REAL detsum, errbound;
4522
4523 counterclockcount++;
4524
4525 detleft = ( pa[0] - pc[0] ) * ( pb[1] - pc[1] );
4526 detright = ( pa[1] - pc[1] ) * ( pb[0] - pc[0] );
4527 det = detleft - detright;
4528
4529 if ( noexact ) {
4530 return det;
4531 }
4532
4533 if ( detleft > 0.0 ) {
4534 if ( detright <= 0.0 ) {
4535 return det;
4536 }
4537 else {
4538 detsum = detleft + detright;
4539 }
4540 }
4541 else if ( detleft < 0.0 ) {
4542 if ( detright >= 0.0 ) {
4543 return det;
4544 }
4545 else {
4546 detsum = -detleft - detright;
4547 }
4548 }
4549 else {
4550 return det;
4551 }
4552
4553 errbound = ccwerrboundA * detsum;
4554 if (( det >= errbound ) || ( -det >= errbound )) {
4555 return det;
4556 }
4557
4558 return counterclockwiseadapt( pa, pb, pc, detsum );
4559 }
4560
4561 /*****************************************************************************/
4562 /*                                                                           */
4563 /*  incircle()   Return a positive value if the point pd lies inside the     */
4564 /*               circle passing through pa, pb, and pc; a negative value if  */
4565 /*               it lies outside; and zero if the four points are cocircular.*/
4566 /*               The points pa, pb, and pc must be in counterclockwise       */
4567 /*               order, or the sign of the result will be reversed.          */
4568 /*                                                                           */
4569 /*  Uses exact arithmetic if necessary to ensure a correct answer.  The      */
4570 /*  result returned is the determinant of a matrix.  This determinant is     */
4571 /*  computed adaptively, in the sense that exact arithmetic is used only to  */
4572 /*  the degree it is needed to ensure that the returned value has the        */
4573 /*  correct sign.  Hence, this function is usually quite fast, but will run  */
4574 /*  more slowly when the input points are cocircular or nearly so.           */
4575 /*                                                                           */
4576 /*  See my Robust Predicates paper for details.                              */
4577 /*                                                                           */
4578 /*****************************************************************************/
4579
4580 REAL incircleadapt( pa, pb, pc, pd, permanent )
4581 point pa;
4582 point pb;
4583 point pc;
4584 point pd;
4585 REAL permanent;
4586 {
4587 INEXACT REAL adx, bdx, cdx, ady, bdy, cdy;
4588 REAL det, errbound;
4589
4590 INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1;
4591 REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0;
4592 REAL bc[4], ca[4], ab[4];
4593 INEXACT REAL bc3, ca3, ab3;
4594 REAL axbc[8], axxbc[16], aybc[8], ayybc[16], adet[32];
4595 int axbclen, axxbclen, aybclen, ayybclen, alen;
4596 REAL bxca[8], bxxca[16], byca[8], byyca[16], bdet[32];
4597 int bxcalen, bxxcalen, bycalen, byycalen, blen;
4598 REAL cxab[8], cxxab[16], cyab[8], cyyab[16], cdet[32];
4599 int cxablen, cxxablen, cyablen, cyyablen, clen;
4600 REAL abdet[64];
4601 int ablen;
4602 REAL fin1[1152], fin2[1152];
4603 REAL *finnow, *finother, *finswap;
4604 int finlength;
4605
4606 REAL adxtail, bdxtail, cdxtail, adytail, bdytail, cdytail;
4607 INEXACT REAL adxadx1, adyady1, bdxbdx1, bdybdy1, cdxcdx1, cdycdy1;
4608 REAL adxadx0, adyady0, bdxbdx0, bdybdy0, cdxcdx0, cdycdy0;
4609 REAL aa[4], bb[4], cc[4];
4610 INEXACT REAL aa3, bb3, cc3;
4611 INEXACT REAL ti1, tj1;
4612 REAL ti0, tj0;
4613 REAL u[4], v[4];
4614 INEXACT REAL u3, v3;
4615 REAL temp8[8], temp16a[16], temp16b[16], temp16c[16];
4616 REAL temp32a[32], temp32b[32], temp48[48], temp64[64];
4617 int temp8len, temp16alen, temp16blen, temp16clen;
4618 int temp32alen, temp32blen, temp48len, temp64len;
4619 REAL axtbb[8], axtcc[8], aytbb[8], aytcc[8];
4620 int axtbblen, axtcclen, aytbblen, aytcclen;
4621 REAL bxtaa[8], bxtcc[8], bytaa[8], bytcc[8];
4622 int bxtaalen, bxtcclen, bytaalen, bytcclen;
4623 REAL cxtaa[8], cxtbb[8], cytaa[8], cytbb[8];
4624 int cxtaalen, cxtbblen, cytaalen, cytbblen;
4625 REAL axtbc[8], aytbc[8], bxtca[8], bytca[8], cxtab[8], cytab[8];
4626 int axtbclen, aytbclen, bxtcalen, bytcalen, cxtablen, cytablen;
4627 REAL axtbct[16], aytbct[16], bxtcat[16], bytcat[16], cxtabt[16], cytabt[16];
4628 int axtbctlen, aytbctlen, bxtcatlen, bytcatlen, cxtabtlen, cytabtlen;
4629 REAL axtbctt[8], aytbctt[8], bxtcatt[8];
4630 REAL bytcatt[8], cxtabtt[8], cytabtt[8];
4631 int axtbcttlen, aytbcttlen, bxtcattlen, bytcattlen, cxtabttlen, cytabttlen;
4632 REAL abt[8], bct[8], cat[8];
4633 int abtlen, bctlen, catlen;
4634 REAL abtt[4], bctt[4], catt[4];
4635 int abttlen, bcttlen, cattlen;
4636 INEXACT REAL abtt3, bctt3, catt3;
4637 REAL negate;
4638
4639 INEXACT REAL bvirt;
4640 REAL avirt, bround, around;
4641 INEXACT REAL c;
4642 INEXACT REAL abig;
4643 REAL ahi, alo, bhi, blo;
4644 REAL err1, err2, err3;
4645 INEXACT REAL _i, _j;
4646 REAL _0;
4647
4648 adx = (REAL) ( pa[0] - pd[0] );
4649 bdx = (REAL) ( pb[0] - pd[0] );
4650 cdx = (REAL) ( pc[0] - pd[0] );
4651 ady = (REAL) ( pa[1] - pd[1] );
4652 bdy = (REAL) ( pb[1] - pd[1] );
4653 cdy = (REAL) ( pc[1] - pd[1] );
4654
4655 Two_Product( bdx, cdy, bdxcdy1, bdxcdy0 );
4656 Two_Product( cdx, bdy, cdxbdy1, cdxbdy0 );
4657 Two_Two_Diff( bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0] );
4658 bc[3] = bc3;
4659 axbclen = scale_expansion_zeroelim( 4, bc, adx, axbc );
4660 axxbclen = scale_expansion_zeroelim( axbclen, axbc, adx, axxbc );
4661 aybclen = scale_expansion_zeroelim( 4, bc, ady, aybc );
4662 ayybclen = scale_expansion_zeroelim( aybclen, aybc, ady, ayybc );
4663 alen = fast_expansion_sum_zeroelim( axxbclen, axxbc, ayybclen, ayybc, adet );
4664
4665 Two_Product( cdx, ady, cdxady1, cdxady0 );
4666 Two_Product( adx, cdy, adxcdy1, adxcdy0 );
4667 Two_Two_Diff( cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0] );
4668 ca[3] = ca3;
4669 bxcalen = scale_expansion_zeroelim( 4, ca, bdx, bxca );
4670 bxxcalen = scale_expansion_zeroelim( bxcalen, bxca, bdx, bxxca );
4671 bycalen = scale_expansion_zeroelim( 4, ca, bdy, byca );
4672 byycalen = scale_expansion_zeroelim( bycalen, byca, bdy, byyca );
4673 blen = fast_expansion_sum_zeroelim( bxxcalen, bxxca, byycalen, byyca, bdet );
4674
4675 Two_Product( adx, bdy, adxbdy1, adxbdy0 );
4676 Two_Product( bdx, ady, bdxady1, bdxady0 );
4677 Two_Two_Diff( adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0] );
4678 ab[3] = ab3;
4679 cxablen = scale_expansion_zeroelim( 4, ab, cdx, cxab );
4680 cxxablen = scale_expansion_zeroelim( cxablen, cxab, cdx, cxxab );
4681 cyablen = scale_expansion_zeroelim( 4, ab, cdy, cyab );
4682 cyyablen = scale_expansion_zeroelim( cyablen, cyab, cdy, cyyab );
4683 clen = fast_expansion_sum_zeroelim( cxxablen, cxxab, cyyablen, cyyab, cdet );
4684
4685 ablen = fast_expansion_sum_zeroelim( alen, adet, blen, bdet, abdet );
4686 finlength = fast_expansion_sum_zeroelim( ablen, abdet, clen, cdet, fin1 );
4687
4688 det = estimate( finlength, fin1 );
4689 errbound = (REAL)( iccerrboundB * permanent );
4690 if (( det >= errbound ) || ( -det >= errbound )) {
4691 return det;
4692 }
4693
4694 Two_Diff_Tail( pa[0], pd[0], adx, adxtail );
4695 Two_Diff_Tail( pa[1], pd[1], ady, adytail );
4696 Two_Diff_Tail( pb[0], pd[0], bdx, bdxtail );
4697 Two_Diff_Tail( pb[1], pd[1], bdy, bdytail );
4698 Two_Diff_Tail( pc[0], pd[0], cdx, cdxtail );
4699 Two_Diff_Tail( pc[1], pd[1], cdy, cdytail );
4700 if (( adxtail == 0.0 ) && ( bdxtail == 0.0 ) && ( cdxtail == 0.0 )
4701 && ( adytail == 0.0 ) && ( bdytail == 0.0 ) && ( cdytail == 0.0 )) {
4702 return det;
4703 }
4704
4705 errbound = (REAL)( iccerrboundC * permanent + resulterrbound * Absolute( det ));
4706 det += (REAL)((( adx * adx + ady * ady ) * (( bdx * cdytail + cdy * bdxtail )
4707 - ( bdy * cdxtail + cdx * bdytail ))
4708 + 2.0 * ( adx * adxtail + ady * adytail ) * ( bdx * cdy - bdy * cdx ))
4709 + (( bdx * bdx + bdy * bdy ) * (( cdx * adytail + ady * cdxtail )
4710 - ( cdy * adxtail + adx * cdytail ))
4711 + 2.0 * ( bdx * bdxtail + bdy * bdytail ) * ( cdx * ady - cdy * adx ))
4712 + (( cdx * cdx + cdy * cdy ) * (( adx * bdytail + bdy * adxtail )
4713 - ( ady * bdxtail + bdx * adytail ))
4714 + 2.0 * ( cdx * cdxtail + cdy * cdytail ) * ( adx * bdy - ady * bdx )));
4715 if (( det >= errbound ) || ( -det >= errbound )) {
4716 return det;
4717 }
4718
4719 finnow = fin1;
4720 finother = fin2;
4721
4722 if (( bdxtail != 0.0 ) || ( bdytail != 0.0 )
4723 || ( cdxtail != 0.0 ) || ( cdytail != 0.0 )) {
4724 Square( adx, adxadx1, adxadx0 );
4725 Square( ady, adyady1, adyady0 );
4726 Two_Two_Sum( adxadx1, adxadx0, adyady1, adyady0, aa3, aa[2], aa[1], aa[0] );
4727 aa[3] = aa3;
4728 }
4729 if (( cdxtail != 0.0 ) || ( cdytail != 0.0 )
4730 || ( adxtail != 0.0 ) || ( adytail != 0.0 )) {
4731 Square( bdx, bdxbdx1, bdxbdx0 );
4732 Square( bdy, bdybdy1, bdybdy0 );
4733 Two_Two_Sum( bdxbdx1, bdxbdx0, bdybdy1, bdybdy0, bb3, bb[2], bb[1], bb[0] );
4734 bb[3] = bb3;
4735 }
4736 if (( adxtail != 0.0 ) || ( adytail != 0.0 )
4737 || ( bdxtail != 0.0 ) || ( bdytail != 0.0 )) {
4738 Square( cdx, cdxcdx1, cdxcdx0 );
4739 Square( cdy, cdycdy1, cdycdy0 );
4740 Two_Two_Sum( cdxcdx1, cdxcdx0, cdycdy1, cdycdy0, cc3, cc[2], cc[1], cc[0] );
4741 cc[3] = cc3;
4742 }
4743
4744 if ( adxtail != 0.0 ) {
4745 axtbclen = scale_expansion_zeroelim( 4, bc, adxtail, axtbc );
4746 temp16alen = scale_expansion_zeroelim( axtbclen, axtbc, 2.0 * adx,
4747 temp16a );
4748
4749 axtcclen = scale_expansion_zeroelim( 4, cc, adxtail, axtcc );
4750 temp16blen = scale_expansion_zeroelim( axtcclen, axtcc, bdy, temp16b );
4751
4752 axtbblen = scale_expansion_zeroelim( 4, bb, adxtail, axtbb );
4753 temp16clen = scale_expansion_zeroelim( axtbblen, axtbb, -cdy, temp16c );
4754
4755 temp32alen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4756 temp16blen, temp16b, temp32a );
4757 temp48len = fast_expansion_sum_zeroelim( temp16clen, temp16c,
4758 temp32alen, temp32a, temp48 );
4759 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
4760 temp48, finother );
4761 finswap = finnow; finnow = finother; finother = finswap;
4762 }
4763 if ( adytail != 0.0 ) {
4764 aytbclen = scale_expansion_zeroelim( 4, bc, adytail, aytbc );
4765 temp16alen = scale_expansion_zeroelim( aytbclen, aytbc, 2.0 * ady,
4766 temp16a );
4767
4768 aytbblen = scale_expansion_zeroelim( 4, bb, adytail, aytbb );
4769 temp16blen = scale_expansion_zeroelim( aytbblen, aytbb, cdx, temp16b );
4770
4771 aytcclen = scale_expansion_zeroelim( 4, cc, adytail, aytcc );
4772 temp16clen = scale_expansion_zeroelim( aytcclen, aytcc, -bdx, temp16c );
4773
4774 temp32alen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4775 temp16blen, temp16b, temp32a );
4776 temp48len = fast_expansion_sum_zeroelim( temp16clen, temp16c,
4777 temp32alen, temp32a, temp48 );
4778 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
4779 temp48, finother );
4780 finswap = finnow; finnow = finother; finother = finswap;
4781 }
4782 if ( bdxtail != 0.0 ) {
4783 bxtcalen = scale_expansion_zeroelim( 4, ca, bdxtail, bxtca );
4784 temp16alen = scale_expansion_zeroelim( bxtcalen, bxtca, 2.0 * bdx,
4785 temp16a );
4786
4787 bxtaalen = scale_expansion_zeroelim( 4, aa, bdxtail, bxtaa );
4788 temp16blen = scale_expansion_zeroelim( bxtaalen, bxtaa, cdy, temp16b );
4789
4790 bxtcclen = scale_expansion_zeroelim( 4, cc, bdxtail, bxtcc );
4791 temp16clen = scale_expansion_zeroelim( bxtcclen, bxtcc, -ady, temp16c );
4792
4793 temp32alen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4794 temp16blen, temp16b, temp32a );
4795 temp48len = fast_expansion_sum_zeroelim( temp16clen, temp16c,
4796 temp32alen, temp32a, temp48 );
4797 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
4798 temp48, finother );
4799 finswap = finnow; finnow = finother; finother = finswap;
4800 }
4801 if ( bdytail != 0.0 ) {
4802 bytcalen = scale_expansion_zeroelim( 4, ca, bdytail, bytca );
4803 temp16alen = scale_expansion_zeroelim( bytcalen, bytca, 2.0 * bdy,
4804 temp16a );
4805
4806 bytcclen = scale_expansion_zeroelim( 4, cc, bdytail, bytcc );
4807 temp16blen = scale_expansion_zeroelim( bytcclen, bytcc, adx, temp16b );
4808
4809 bytaalen = scale_expansion_zeroelim( 4, aa, bdytail, bytaa );
4810 temp16clen = scale_expansion_zeroelim( bytaalen, bytaa, -cdx, temp16c );
4811
4812 temp32alen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4813 temp16blen, temp16b, temp32a );
4814 temp48len = fast_expansion_sum_zeroelim( temp16clen, temp16c,
4815 temp32alen, temp32a, temp48 );
4816 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
4817 temp48, finother );
4818 finswap = finnow; finnow = finother; finother = finswap;
4819 }
4820 if ( cdxtail != 0.0 ) {
4821 cxtablen = scale_expansion_zeroelim( 4, ab, cdxtail, cxtab );
4822 temp16alen = scale_expansion_zeroelim( cxtablen, cxtab, 2.0 * cdx,
4823 temp16a );
4824
4825 cxtbblen = scale_expansion_zeroelim( 4, bb, cdxtail, cxtbb );
4826 temp16blen = scale_expansion_zeroelim( cxtbblen, cxtbb, ady, temp16b );
4827
4828 cxtaalen = scale_expansion_zeroelim( 4, aa, cdxtail, cxtaa );
4829 temp16clen = scale_expansion_zeroelim( cxtaalen, cxtaa, -bdy, temp16c );
4830
4831 temp32alen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4832 temp16blen, temp16b, temp32a );
4833 temp48len = fast_expansion_sum_zeroelim( temp16clen, temp16c,
4834 temp32alen, temp32a, temp48 );
4835 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
4836 temp48, finother );
4837 finswap = finnow; finnow = finother; finother = finswap;
4838 }
4839 if ( cdytail != 0.0 ) {
4840 cytablen = scale_expansion_zeroelim( 4, ab, cdytail, cytab );
4841 temp16alen = scale_expansion_zeroelim( cytablen, cytab, 2.0 * cdy,
4842 temp16a );
4843
4844 cytaalen = scale_expansion_zeroelim( 4, aa, cdytail, cytaa );
4845 temp16blen = scale_expansion_zeroelim( cytaalen, cytaa, bdx, temp16b );
4846
4847 cytbblen = scale_expansion_zeroelim( 4, bb, cdytail, cytbb );
4848 temp16clen = scale_expansion_zeroelim( cytbblen, cytbb, -adx, temp16c );
4849
4850 temp32alen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4851 temp16blen, temp16b, temp32a );
4852 temp48len = fast_expansion_sum_zeroelim( temp16clen, temp16c,
4853 temp32alen, temp32a, temp48 );
4854 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
4855 temp48, finother );
4856 finswap = finnow; finnow = finother; finother = finswap;
4857 }
4858
4859 if (( adxtail != 0.0 ) || ( adytail != 0.0 )) {
4860 if (( bdxtail != 0.0 ) || ( bdytail != 0.0 )
4861 || ( cdxtail != 0.0 ) || ( cdytail != 0.0 )) {
4862 Two_Product( bdxtail, cdy, ti1, ti0 );
4863 Two_Product( bdx, cdytail, tj1, tj0 );
4864 Two_Two_Sum( ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0] );
4865 u[3] = u3;
4866 negate = -bdy;
4867 Two_Product( cdxtail, negate, ti1, ti0 );
4868 negate = -bdytail;
4869 Two_Product( cdx, negate, tj1, tj0 );
4870 Two_Two_Sum( ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0] );
4871 v[3] = v3;
4872 bctlen = fast_expansion_sum_zeroelim( 4, u, 4, v, bct );
4873
4874 Two_Product( bdxtail, cdytail, ti1, ti0 );
4875 Two_Product( cdxtail, bdytail, tj1, tj0 );
4876 Two_Two_Diff( ti1, ti0, tj1, tj0, bctt3, bctt[2], bctt[1], bctt[0] );
4877 bctt[3] = bctt3;
4878 bcttlen = 4;
4879 }
4880 else {
4881 bct[0] = 0.0;
4882 bctlen = 1;
4883 bctt[0] = 0.0;
4884 bcttlen = 1;
4885 }
4886
4887 if ( adxtail != 0.0 ) {
4888 temp16alen = scale_expansion_zeroelim( axtbclen, axtbc, adxtail, temp16a );
4889 axtbctlen = scale_expansion_zeroelim( bctlen, bct, adxtail, axtbct );
4890 temp32alen = scale_expansion_zeroelim( axtbctlen, axtbct, 2.0 * adx,
4891 temp32a );
4892 temp48len = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4893 temp32alen, temp32a, temp48 );
4894 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
4895 temp48, finother );
4896 finswap = finnow; finnow = finother; finother = finswap;
4897 if ( bdytail != 0.0 ) {
4898 temp8len = scale_expansion_zeroelim( 4, cc, adxtail, temp8 );
4899 temp16alen = scale_expansion_zeroelim( temp8len, temp8, bdytail,
4900 temp16a );
4901 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp16alen,
4902 temp16a, finother );
4903 finswap = finnow; finnow = finother; finother = finswap;
4904 }
4905 if ( cdytail != 0.0 ) {
4906 temp8len = scale_expansion_zeroelim( 4, bb, -adxtail, temp8 );
4907 temp16alen = scale_expansion_zeroelim( temp8len, temp8, cdytail,
4908 temp16a );
4909 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp16alen,
4910 temp16a, finother );
4911 finswap = finnow; finnow = finother; finother = finswap;
4912 }
4913
4914 temp32alen = scale_expansion_zeroelim( axtbctlen, axtbct, adxtail,
4915 temp32a );
4916 axtbcttlen = scale_expansion_zeroelim( bcttlen, bctt, adxtail, axtbctt );
4917 temp16alen = scale_expansion_zeroelim( axtbcttlen, axtbctt, 2.0 * adx,
4918 temp16a );
4919 temp16blen = scale_expansion_zeroelim( axtbcttlen, axtbctt, adxtail,
4920 temp16b );
4921 temp32blen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4922 temp16blen, temp16b, temp32b );
4923 temp64len = fast_expansion_sum_zeroelim( temp32alen, temp32a,
4924 temp32blen, temp32b, temp64 );
4925 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp64len,
4926 temp64, finother );
4927 finswap = finnow; finnow = finother; finother = finswap;
4928 }
4929 if ( adytail != 0.0 ) {
4930 temp16alen = scale_expansion_zeroelim( aytbclen, aytbc, adytail, temp16a );
4931 aytbctlen = scale_expansion_zeroelim( bctlen, bct, adytail, aytbct );
4932 temp32alen = scale_expansion_zeroelim( aytbctlen, aytbct, 2.0 * ady,
4933 temp32a );
4934 temp48len = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4935 temp32alen, temp32a, temp48 );
4936 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
4937 temp48, finother );
4938 finswap = finnow; finnow = finother; finother = finswap;
4939
4940
4941 temp32alen = scale_expansion_zeroelim( aytbctlen, aytbct, adytail,
4942 temp32a );
4943 aytbcttlen = scale_expansion_zeroelim( bcttlen, bctt, adytail, aytbctt );
4944 temp16alen = scale_expansion_zeroelim( aytbcttlen, aytbctt, 2.0 * ady,
4945 temp16a );
4946 temp16blen = scale_expansion_zeroelim( aytbcttlen, aytbctt, adytail,
4947 temp16b );
4948 temp32blen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4949 temp16blen, temp16b, temp32b );
4950 temp64len = fast_expansion_sum_zeroelim( temp32alen, temp32a,
4951 temp32blen, temp32b, temp64 );
4952 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp64len,
4953 temp64, finother );
4954 finswap = finnow; finnow = finother; finother = finswap;
4955 }
4956 }
4957 if (( bdxtail != 0.0 ) || ( bdytail != 0.0 )) {
4958 if (( cdxtail != 0.0 ) || ( cdytail != 0.0 )
4959 || ( adxtail != 0.0 ) || ( adytail != 0.0 )) {
4960 Two_Product( cdxtail, ady, ti1, ti0 );
4961 Two_Product( cdx, adytail, tj1, tj0 );
4962 Two_Two_Sum( ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0] );
4963 u[3] = u3;
4964 negate = -cdy;
4965 Two_Product( adxtail, negate, ti1, ti0 );
4966 negate = -cdytail;
4967 Two_Product( adx, negate, tj1, tj0 );
4968 Two_Two_Sum( ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0] );
4969 v[3] = v3;
4970 catlen = fast_expansion_sum_zeroelim( 4, u, 4, v, cat );
4971
4972 Two_Product( cdxtail, adytail, ti1, ti0 );
4973 Two_Product( adxtail, cdytail, tj1, tj0 );
4974 Two_Two_Diff( ti1, ti0, tj1, tj0, catt3, catt[2], catt[1], catt[0] );
4975 catt[3] = catt3;
4976 cattlen = 4;
4977 }
4978 else {
4979 cat[0] = 0.0;
4980 catlen = 1;
4981 catt[0] = 0.0;
4982 cattlen = 1;
4983 }
4984
4985 if ( bdxtail != 0.0 ) {
4986 temp16alen = scale_expansion_zeroelim( bxtcalen, bxtca, bdxtail, temp16a );
4987 bxtcatlen = scale_expansion_zeroelim( catlen, cat, bdxtail, bxtcat );
4988 temp32alen = scale_expansion_zeroelim( bxtcatlen, bxtcat, 2.0 * bdx,
4989 temp32a );
4990 temp48len = fast_expansion_sum_zeroelim( temp16alen, temp16a,
4991 temp32alen, temp32a, temp48 );
4992 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
4993 temp48, finother );
4994 finswap = finnow; finnow = finother; finother = finswap;
4995 if ( cdytail != 0.0 ) {
4996 temp8len = scale_expansion_zeroelim( 4, aa, bdxtail, temp8 );
4997 temp16alen = scale_expansion_zeroelim( temp8len, temp8, cdytail,
4998 temp16a );
4999 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp16alen,
5000 temp16a, finother );
5001 finswap = finnow; finnow = finother; finother = finswap;
5002 }
5003 if ( adytail != 0.0 ) {
5004 temp8len = scale_expansion_zeroelim( 4, cc, -bdxtail, temp8 );
5005 temp16alen = scale_expansion_zeroelim( temp8len, temp8, adytail,
5006 temp16a );
5007 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp16alen,
5008 temp16a, finother );
5009 finswap = finnow; finnow = finother; finother = finswap;
5010 }
5011
5012 temp32alen = scale_expansion_zeroelim( bxtcatlen, bxtcat, bdxtail,
5013 temp32a );
5014 bxtcattlen = scale_expansion_zeroelim( cattlen, catt, bdxtail, bxtcatt );
5015 temp16alen = scale_expansion_zeroelim( bxtcattlen, bxtcatt, 2.0 * bdx,
5016 temp16a );
5017 temp16blen = scale_expansion_zeroelim( bxtcattlen, bxtcatt, bdxtail,
5018 temp16b );
5019 temp32blen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
5020 temp16blen, temp16b, temp32b );
5021 temp64len = fast_expansion_sum_zeroelim( temp32alen, temp32a,
5022 temp32blen, temp32b, temp64 );
5023 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp64len,
5024 temp64, finother );
5025 finswap = finnow; finnow = finother; finother = finswap;
5026 }
5027 if ( bdytail != 0.0 ) {
5028 temp16alen = scale_expansion_zeroelim( bytcalen, bytca, bdytail, temp16a );
5029 bytcatlen = scale_expansion_zeroelim( catlen, cat, bdytail, bytcat );
5030 temp32alen = scale_expansion_zeroelim( bytcatlen, bytcat, 2.0 * bdy,
5031 temp32a );
5032 temp48len = fast_expansion_sum_zeroelim( temp16alen, temp16a,
5033 temp32alen, temp32a, temp48 );
5034 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
5035 temp48, finother );
5036 finswap = finnow; finnow = finother; finother = finswap;
5037
5038
5039 temp32alen = scale_expansion_zeroelim( bytcatlen, bytcat, bdytail,
5040 temp32a );
5041 bytcattlen = scale_expansion_zeroelim( cattlen, catt, bdytail, bytcatt );
5042 temp16alen = scale_expansion_zeroelim( bytcattlen, bytcatt, 2.0 * bdy,
5043 temp16a );
5044 temp16blen = scale_expansion_zeroelim( bytcattlen, bytcatt, bdytail,
5045 temp16b );
5046 temp32blen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
5047 temp16blen, temp16b, temp32b );
5048 temp64len = fast_expansion_sum_zeroelim( temp32alen, temp32a,
5049 temp32blen, temp32b, temp64 );
5050 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp64len,
5051 temp64, finother );
5052 finswap = finnow; finnow = finother; finother = finswap;
5053 }
5054 }
5055 if (( cdxtail != 0.0 ) || ( cdytail != 0.0 )) {
5056 if (( adxtail != 0.0 ) || ( adytail != 0.0 )
5057 || ( bdxtail != 0.0 ) || ( bdytail != 0.0 )) {
5058 Two_Product( adxtail, bdy, ti1, ti0 );
5059 Two_Product( adx, bdytail, tj1, tj0 );
5060 Two_Two_Sum( ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0] );
5061 u[3] = u3;
5062 negate = -ady;
5063 Two_Product( bdxtail, negate, ti1, ti0 );
5064 negate = -adytail;
5065 Two_Product( bdx, negate, tj1, tj0 );
5066 Two_Two_Sum( ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0] );
5067 v[3] = v3;
5068 abtlen = fast_expansion_sum_zeroelim( 4, u, 4, v, abt );
5069
5070 Two_Product( adxtail, bdytail, ti1, ti0 );
5071 Two_Product( bdxtail, adytail, tj1, tj0 );
5072 Two_Two_Diff( ti1, ti0, tj1, tj0, abtt3, abtt[2], abtt[1], abtt[0] );
5073 abtt[3] = abtt3;
5074 abttlen = 4;
5075 }
5076 else {
5077 abt[0] = 0.0;
5078 abtlen = 1;
5079 abtt[0] = 0.0;
5080 abttlen = 1;
5081 }
5082
5083 if ( cdxtail != 0.0 ) {
5084 temp16alen = scale_expansion_zeroelim( cxtablen, cxtab, cdxtail, temp16a );
5085 cxtabtlen = scale_expansion_zeroelim( abtlen, abt, cdxtail, cxtabt );
5086 temp32alen = scale_expansion_zeroelim( cxtabtlen, cxtabt, 2.0 * cdx,
5087 temp32a );
5088 temp48len = fast_expansion_sum_zeroelim( temp16alen, temp16a,
5089 temp32alen, temp32a, temp48 );
5090 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
5091 temp48, finother );
5092 finswap = finnow; finnow = finother; finother = finswap;
5093 if ( adytail != 0.0 ) {
5094 temp8len = scale_expansion_zeroelim( 4, bb, cdxtail, temp8 );
5095 temp16alen = scale_expansion_zeroelim( temp8len, temp8, adytail,
5096 temp16a );
5097 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp16alen,
5098 temp16a, finother );
5099 finswap = finnow; finnow = finother; finother = finswap;
5100 }
5101 if ( bdytail != 0.0 ) {
5102 temp8len = scale_expansion_zeroelim( 4, aa, -cdxtail, temp8 );
5103 temp16alen = scale_expansion_zeroelim( temp8len, temp8, bdytail,
5104 temp16a );
5105 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp16alen,
5106 temp16a, finother );
5107 finswap = finnow; finnow = finother; finother = finswap;
5108 }
5109
5110 temp32alen = scale_expansion_zeroelim( cxtabtlen, cxtabt, cdxtail,
5111 temp32a );
5112 cxtabttlen = scale_expansion_zeroelim( abttlen, abtt, cdxtail, cxtabtt );
5113 temp16alen = scale_expansion_zeroelim( cxtabttlen, cxtabtt, 2.0 * cdx,
5114 temp16a );
5115 temp16blen = scale_expansion_zeroelim( cxtabttlen, cxtabtt, cdxtail,
5116 temp16b );
5117 temp32blen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
5118 temp16blen, temp16b, temp32b );
5119 temp64len = fast_expansion_sum_zeroelim( temp32alen, temp32a,
5120 temp32blen, temp32b, temp64 );
5121 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp64len,
5122 temp64, finother );
5123 finswap = finnow; finnow = finother; finother = finswap;
5124 }
5125 if ( cdytail != 0.0 ) {
5126 temp16alen = scale_expansion_zeroelim( cytablen, cytab, cdytail, temp16a );
5127 cytabtlen = scale_expansion_zeroelim( abtlen, abt, cdytail, cytabt );
5128 temp32alen = scale_expansion_zeroelim( cytabtlen, cytabt, 2.0 * cdy,
5129 temp32a );
5130 temp48len = fast_expansion_sum_zeroelim( temp16alen, temp16a,
5131 temp32alen, temp32a, temp48 );
5132 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp48len,
5133 temp48, finother );
5134 finswap = finnow; finnow = finother; finother = finswap;
5135
5136
5137 temp32alen = scale_expansion_zeroelim( cytabtlen, cytabt, cdytail,
5138 temp32a );
5139 cytabttlen = scale_expansion_zeroelim( abttlen, abtt, cdytail, cytabtt );
5140 temp16alen = scale_expansion_zeroelim( cytabttlen, cytabtt, 2.0 * cdy,
5141 temp16a );
5142 temp16blen = scale_expansion_zeroelim( cytabttlen, cytabtt, cdytail,
5143 temp16b );
5144 temp32blen = fast_expansion_sum_zeroelim( temp16alen, temp16a,
5145 temp16blen, temp16b, temp32b );
5146 temp64len = fast_expansion_sum_zeroelim( temp32alen, temp32a,
5147 temp32blen, temp32b, temp64 );
5148 finlength = fast_expansion_sum_zeroelim( finlength, finnow, temp64len,
5149 temp64, finother );
5150 finswap = finnow; finnow = finother; finother = finswap;
5151 }
5152 }
5153
5154 return finnow[finlength - 1];
5155 }
5156
5157 REAL incircle( pa, pb, pc, pd )
5158 point pa;
5159 point pb;
5160 point pc;
5161 point pd;
5162 {
5163 REAL adx, bdx, cdx, ady, bdy, cdy;
5164 REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
5165 REAL alift, blift, clift;
5166 REAL det;
5167 REAL permanent, errbound;
5168
5169 incirclecount++;
5170
5171 adx = pa[0] - pd[0];
5172 bdx = pb[0] - pd[0];
5173 cdx = pc[0] - pd[0];
5174 ady = pa[1] - pd[1];
5175 bdy = pb[1] - pd[1];
5176 cdy = pc[1] - pd[1];
5177
5178 bdxcdy = bdx * cdy;
5179 cdxbdy = cdx * bdy;
5180 alift = adx * adx + ady * ady;
5181
5182 cdxady = cdx * ady;
5183 adxcdy = adx * cdy;
5184 blift = bdx * bdx + bdy * bdy;
5185
5186 adxbdy = adx * bdy;
5187 bdxady = bdx * ady;
5188 clift = cdx * cdx + cdy * cdy;
5189
5190 det = alift * ( bdxcdy - cdxbdy )
5191 + blift * ( cdxady - adxcdy )
5192 + clift * ( adxbdy - bdxady );
5193
5194 if ( noexact ) {
5195 return det;
5196 }
5197
5198 permanent = ( Absolute( bdxcdy ) + Absolute( cdxbdy )) * alift
5199 + ( Absolute( cdxady ) + Absolute( adxcdy )) * blift
5200 + ( Absolute( adxbdy ) + Absolute( bdxady )) * clift;
5201 errbound = iccerrboundA * permanent;
5202 if (( det > errbound ) || ( -det > errbound )) {
5203 return det;
5204 }
5205
5206 return incircleadapt( pa, pb, pc, pd, permanent );
5207 }
5208
5209 /**                                                                         **/
5210 /**                                                                         **/
5211 /********* Determinant evaluation routines end here                  *********/
5212
5213 /*****************************************************************************/
5214 /*                                                                           */
5215 /*  triangleinit()   Initialize some variables.                              */
5216 /*                                                                           */
5217 /*****************************************************************************/
5218
5219 void triangleinit(){
5220 points.maxitems = triangles.maxitems = shelles.maxitems = viri.maxitems =
5221 badsegments.maxitems = badtriangles.maxitems = splaynodes.maxitems = 0l;
5222 points.itembytes = triangles.itembytes = shelles.itembytes = viri.itembytes =
5223 badsegments.itembytes = badtriangles.itembytes = splaynodes.itembytes = 0;
5224 recenttri.tri = (triangle *) NULL;  /* No triangle has been visited yet. */
5225 samples = 1;          /* Point location should take at least one sample. */
5226 checksegments = 0;    /* There are no segments in the triangulation yet. */
5227 incirclecount = counterclockcount = hyperbolacount = 0;
5228 circumcentercount = circletopcount = 0;
5229 randomseed = 1;
5230
5231 exactinit();                   /* Initialize exact arithmetic constants. */
5232 }
5233
5234 /*****************************************************************************/
5235 /*                                                                           */
5236 /*  randomnation()   Generate a random number between 0 and `choices' - 1.   */
5237 /*                                                                           */
5238 /*  This is a simple linear congruential random number generator.  Hence, it */
5239 /*  is a bad random number generator, but good enough for most randomized    */
5240 /*  geometric algorithms.                                                    */
5241 /*                                                                           */
5242 /*****************************************************************************/
5243
5244 unsigned long randomnation( choices )
5245 unsigned int choices;
5246 {
5247 randomseed = ( randomseed * 1366l + 150889l ) % 714025l;
5248 return randomseed / ( 714025l / choices + 1 );
5249 }
5250
5251 /********* Mesh quality testing routines begin here                  *********/
5252 /**                                                                         **/
5253 /**                                                                         **/
5254
5255 /*****************************************************************************/
5256 /*                                                                           */
5257 /*  checkmesh()   Test the mesh for topological consistency.                 */
5258 /*                                                                           */
5259 /*****************************************************************************/
5260
5261 #ifndef
5262 REDUCED
5263
5264 void checkmesh(){
5265 struct triedge triangleloop;
5266 struct triedge oppotri, oppooppotri;
5267 point triorg, tridest, triapex;
5268 point oppoorg, oppodest;
5269 int horrors;
5270 int saveexact;
5271 triangle ptr;                       /* Temporary variable used by sym(). */
5272
5273 /* Temporarily turn on exact arithmetic if it's off. */
5274 saveexact = noexact;
5275 noexact = 0;
5276 if ( !quiet ) {
5277 printf( "  Checking consistency of mesh...\n" );
5278 }
5279 horrors = 0;
5280 /* Run through the list of triangles, checking each one. */
5281 traversalinit( &triangles );
5282 triangleloop.tri = triangletraverse();
5283 while ( triangleloop.tri != (triangle *) NULL ) {
5284 /* Check all three edges of the triangle. */
5285 for ( triangleloop.orient = 0; triangleloop.orient < 3;
5286 triangleloop.orient++ ) {
5287 org( triangleloop, triorg );
5288 dest( triangleloop, tridest );
5289 if ( triangleloop.orient == 0 ) { /* Only test for inversion once. */
5290 /* Test if the triangle is flat or inverted. */
5291 apex( triangleloop, triapex );
5292 if ( counterclockwise( triorg, tridest, triapex ) <= 0.0 ) {
5293 printf( "  !! !! Inverted " );
5294 printtriangle( &triangleloop );
5295 horrors++;
5296 }
5297 }
5298 /* Find the neighboring triangle on this edge. */
5299 sym( triangleloop, oppotri );
5300 if ( oppotri.tri != dummytri ) {
5301 /* Check that the triangle's neighbor knows it's a neighbor. */
5302 sym( oppotri, oppooppotri );
5303 if (( triangleloop.tri != oppooppotri.tri )
5304 || ( triangleloop.orient != oppooppotri.orient )) {
5305 printf( "  !! !! Asymmetric triangle-triangle bond:\n" );
5306 if ( triangleloop.tri == oppooppotri.tri ) {
5307 printf( "   (Right triangle, wrong orientation)\n" );
5308 }
5309 printf( "    First " );
5310 printtriangle( &triangleloop );
5311 printf( "    Second (nonreciprocating) " );
5312 printtriangle( &oppotri );
5313 horrors++;
5314 }
5315 /* Check that both triangles agree on the identities */
5316 /*   of their shared vertices.                       */
5317 org( oppotri, oppoorg );
5318 dest( oppotri, oppodest );
5319 if (( triorg != oppodest ) || ( tridest != oppoorg )) {
5320 printf( "  !! !! Mismatched edge coordinates between two triangles:\n"
5321 );
5322 printf( "    First mismatched " );
5323 printtriangle( &triangleloop );
5324 printf( "    Second mismatched " );
5325 printtriangle( &oppotri );
5326 horrors++;
5327 }
5328 }
5329 }
5330 triangleloop.tri = triangletraverse();
5331 }
5332 if ( horrors == 0 ) {
5333 if ( !quiet ) {
5334 printf( "  In my studied opinion, the mesh appears to be consistent.\n" );
5335 }
5336 }
5337 else if ( horrors == 1 ) {
5338 printf( "  !! !! !! !! Precisely one festering wound discovered.\n" );
5339 }
5340 else {
5341 printf( "  !! !! !! !! %d abominations witnessed.\n", horrors );
5342 }
5343 /* Restore the status of exact arithmetic. */
5344 noexact = saveexact;
5345 }
5346
5347 #endif /* not REDUCED */
5348
5349 /*****************************************************************************/
5350 /*                                                                           */
5351 /*  checkdelaunay()   Ensure that the mesh is (constrained) Delaunay.        */
5352 /*                                                                           */
5353 /*****************************************************************************/
5354
5355 #ifndef
5356 REDUCED
5357
5358 void checkdelaunay(){
5359 struct triedge triangleloop;
5360 struct triedge oppotri;
5361 struct edge opposhelle;
5362 point triorg, tridest, triapex;
5363 point oppoapex;
5364 int shouldbedelaunay;
5365 int horrors;
5366 int saveexact;
5367 triangle ptr;                       /* Temporary variable used by sym(). */
5368 shelle sptr;                    /* Temporary variable used by tspivot(). */
5369
5370 /* Temporarily turn on exact arithmetic if it's off. */
5371 saveexact = noexact;
5372 noexact = 0;
5373 if ( !quiet ) {
5374 printf( "  Checking Delaunay property of mesh...\n" );
5375 }
5376 horrors = 0;
5377 /* Run through the list of triangles, checking each one. */
5378 traversalinit( &triangles );
5379 triangleloop.tri = triangletraverse();
5380 while ( triangleloop.tri != (triangle *) NULL ) {
5381 /* Check all three edges of the triangle. */
5382 for ( triangleloop.orient = 0; triangleloop.orient < 3;
5383 triangleloop.orient++ ) {
5384 org( triangleloop, triorg );
5385 dest( triangleloop, tridest );
5386 apex( triangleloop, triapex );
5387 sym( triangleloop, oppotri );
5388 apex( oppotri, oppoapex );
5389 /* Only test that the edge is locally Delaunay if there is an   */
5390 /*   adjoining triangle whose pointer is larger (to ensure that */
5391 /*   each pair isn't tested twice).                             */
5392 shouldbedelaunay = ( oppotri.tri != dummytri )
5393 && ( triapex != (point) NULL ) && ( oppoapex != (point) NULL )
5394 && ( triangleloop.tri < oppotri.tri );
5395 if ( checksegments && shouldbedelaunay ) {
5396 /* If a shell edge separates the triangles, then the edge is */
5397 /*   constrained, so no local Delaunay test should be done.  */
5398 tspivot( triangleloop, opposhelle );
5399 if ( opposhelle.sh != dummysh ) {
5400 shouldbedelaunay = 0;
5401 }
5402 }
5403 if ( shouldbedelaunay ) {
5404 if ( incircle( triorg, tridest, triapex, oppoapex ) > 0.0 ) {
5405 printf( "  !! !! Non-Delaunay pair of triangles:\n" );
5406 printf( "    First non-Delaunay " );
5407 printtriangle( &triangleloop );
5408 printf( "    Second non-Delaunay " );
5409 printtriangle( &oppotri );
5410 horrors++;
5411 }
5412 }
5413 }
5414 triangleloop.tri = triangletraverse();
5415 }
5416 if ( horrors == 0 ) {
5417 if ( !quiet ) {
5418 printf(
5419 "  By virtue of my perceptive intelligence, I declare the mesh Delaunay.\n" );
5420 }
5421 }
5422 else if ( horrors == 1 ) {
5423 printf(
5424 "  !! !! !! !! Precisely one terrifying transgression identified.\n" );
5425 }
5426 else {
5427 printf( "  !! !! !! !! %d obscenities viewed with horror.\n", horrors );
5428 }
5429 /* Restore the status of exact arithmetic. */
5430 noexact = saveexact;
5431 }
5432
5433 #endif /* not REDUCED */
5434
5435 /*****************************************************************************/
5436 /*                                                                           */
5437 /*  enqueuebadtri()   Add a bad triangle to the end of a queue.              */
5438 /*                                                                           */
5439 /*  The queue is actually a set of 64 queues.  I use multiple queues to give */
5440 /*  priority to smaller angles.  I originally implemented a heap, but the    */
5441 /*  queues are (to my surprise) much faster.                                 */
5442 /*                                                                           */
5443 /*****************************************************************************/
5444
5445 #ifndef
5446 CDT_ONLY
5447
5448 void enqueuebadtri( instri, angle, insapex, insorg, insdest )
5449 struct triedge *instri;
5450 REAL angle;
5451 point insapex;
5452 point insorg;
5453 point insdest;
5454 {
5455 struct badface *newface;
5456 int queuenumber;
5457
5458 if ( verbose > 2 ) {
5459 printf( "  Queueing bad triangle:\n" );
5460 printf( "    (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n", insorg[0],
5461 insorg[1], insdest[0], insdest[1], insapex[0], insapex[1] );
5462 }
5463 /* Allocate space for the bad triangle. */
5464 newface = (struct badface *) poolalloc( &badtriangles );
5465 triedgecopy( *instri, newface->badfacetri );
5466 newface->key = angle;
5467 newface->faceapex = insapex;
5468 newface->faceorg = insorg;
5469 newface->facedest = insdest;
5470 newface->nextface = (struct badface *) NULL;
5471 /* Determine the appropriate queue to put the bad triangle into. */
5472 if ( angle > 0.6 ) {
5473 queuenumber = (int) ( 160.0 * ( angle - 0.6 ));
5474 if ( queuenumber > 63 ) {
5475 queuenumber = 63;
5476 }
5477 }
5478 else {
5479 /* It's not a bad angle; put the triangle in the lowest-priority queue. */
5480 queuenumber = 0;
5481 }
5482 /* Add the triangle to the end of a queue. */
5483 *queuetail[queuenumber] = newface;
5484 /* Maintain a pointer to the NULL pointer at the end of the queue. */
5485 queuetail[queuenumber] = &newface->nextface;
5486 }
5487
5488 #endif /* not CDT_ONLY */
5489
5490 /*****************************************************************************/
5491 /*                                                                           */
5492 /*  dequeuebadtri()   Remove a triangle from the front of the queue.         */
5493 /*                                                                           */
5494 /*****************************************************************************/
5495
5496 #ifndef
5497 CDT_ONLY
5498
5499 struct badface *dequeuebadtri(){
5500 struct badface *result;
5501 int queuenumber;
5502
5503 /* Look for a nonempty queue. */
5504 for ( queuenumber = 63; queuenumber >= 0; queuenumber-- ) {
5505 result = queuefront[queuenumber];
5506 if ( result != (struct badface *) NULL ) {
5507 /* Remove the triangle from the queue. */
5508 queuefront[queuenumber] = result->nextface;
5509 /* Maintain a pointer to the NULL pointer at the end of the queue. */
5510 if ( queuefront[queuenumber] == (struct badface *) NULL ) {
5511 queuetail[queuenumber] = &queuefront[queuenumber];
5512 }
5513 return result;
5514 }
5515 }
5516 return (struct badface *) NULL;
5517 }
5518
5519 #endif /* not CDT_ONLY */
5520
5521 /*****************************************************************************/
5522 /*                                                                           */
5523 /*  checkedge4encroach()   Check a segment to see if it is encroached; add   */
5524 /*                         it to the list if it is.                          */
5525 /*                                                                           */
5526 /*  An encroached segment is an unflippable edge that has a point in its     */
5527 /*  diametral circle (that is, it faces an angle greater than 90 degrees).   */
5528 /*  This definition is due to Ruppert.                                       */
5529 /*                                                                           */
5530 /*  Returns a nonzero value if the edge is encroached.                       */
5531 /*                                                                           */
5532 /*****************************************************************************/
5533
5534 #ifndef
5535 CDT_ONLY
5536
5537 int checkedge4encroach( testedge )
5538 struct edge *testedge;
5539 {
5540 struct triedge neighbortri;
5541 struct edge testsym;
5542 struct edge *badedge;
5543 int addtolist;
5544 int sides;
5545 point eorg, edest, eapex;
5546 triangle ptr;                   /* Temporary variable used by stpivot(). */
5547
5548 addtolist = 0;
5549 sides = 0;
5550
5551 sorg( *testedge, eorg );
5552 sdest( *testedge, edest );
5553 /* Check one neighbor of the shell edge. */
5554 stpivot( *testedge, neighbortri );
5555 /* Does the neighbor exist, or is this a boundary edge? */
5556 if ( neighbortri.tri != dummytri ) {
5557 sides++;
5558 /* Find a vertex opposite this edge. */
5559 apex( neighbortri, eapex );
5560 /* Check whether the vertex is inside the diametral circle of the  */
5561 /*   shell edge.  Pythagoras' Theorem is used to check whether the */
5562 /*   angle at the vertex is greater than 90 degrees.               */
5563 if ( eapex[0] * ( eorg[0] + edest[0] ) + eapex[1] * ( eorg[1] + edest[1] ) >
5564 eapex[0] * eapex[0] + eorg[0] * edest[0] +
5565 eapex[1] * eapex[1] + eorg[1] * edest[1] ) {
5566 addtolist = 1;
5567 }
5568 }
5569 /* Check the other neighbor of the shell edge. */
5570 ssym( *testedge, testsym );
5571 stpivot( testsym, neighbortri );
5572 /* Does the neighbor exist, or is this a boundary edge? */
5573 if ( neighbortri.tri != dummytri ) {
5574 sides++;
5575 /* Find the other vertex opposite this edge. */
5576 apex( neighbortri, eapex );
5577 /* Check whether the vertex is inside the diametral circle of the  */
5578 /*   shell edge.  Pythagoras' Theorem is used to check whether the */
5579 /*   angle at the vertex is greater than 90 degrees.               */
5580 if ( eapex[0] * ( eorg[0] + edest[0] ) +
5581 eapex[1] * ( eorg[1] + edest[1] ) >
5582 eapex[0] * eapex[0] + eorg[0] * edest[0] +
5583 eapex[1] * eapex[1] + eorg[1] * edest[1] ) {
5584 addtolist += 2;
5585 }
5586 }
5587
5588 if ( addtolist && ( !nobisect || (( nobisect == 1 ) && ( sides == 2 )))) {
5589 if ( verbose > 2 ) {
5590 printf( "  Queueing encroached segment (%.12g, %.12g) (%.12g, %.12g).\n",
5591 eorg[0], eorg[1], edest[0], edest[1] );
5592 }
5593 /* Add the shell edge to the list of encroached segments. */
5594 /*   Be sure to get the orientation right.                */
5595 badedge = (struct edge *) poolalloc( &badsegments );
5596 if ( addtolist == 1 ) {
5597 shellecopy( *testedge, *badedge );
5598 }
5599 else {
5600 shellecopy( testsym, *badedge );
5601 }
5602 }
5603 return addtolist;
5604 }
5605
5606 #endif /* not CDT_ONLY */
5607
5608 /*****************************************************************************/
5609 /*                                                                           */
5610 /*  testtriangle()   Test a face for quality measures.                       */
5611 /*                                                                           */
5612 /*  Tests a triangle to see if it satisfies the minimum angle condition and  */
5613 /*  the maximum area condition.  Triangles that aren't up to spec are added  */
5614 /*  to the bad triangle queue.                                               */
5615 /*                                                                           */
5616 /*****************************************************************************/
5617
5618 #ifndef
5619 CDT_ONLY
5620
5621 void testtriangle( testtri )
5622 struct triedge *testtri;
5623 {
5624 struct triedge sametesttri;
5625 struct edge edge1, edge2;
5626 point torg, tdest, tapex;
5627 point anglevertex;
5628 REAL dxod, dyod, dxda, dyda, dxao, dyao;
5629 REAL dxod2, dyod2, dxda2, dyda2, dxao2, dyao2;
5630 REAL apexlen, orglen, destlen;
5631 REAL angle;
5632 REAL area;
5633 shelle sptr;                    /* Temporary variable used by tspivot(). */
5634
5635 org( *testtri, torg );
5636 dest( *testtri, tdest );
5637 apex( *testtri, tapex );
5638 dxod = torg[0] - tdest[0];
5639 dyod = torg[1] - tdest[1];
5640 dxda = tdest[0] - tapex[0];
5641 dyda = tdest[1] - tapex[1];
5642 dxao = tapex[0] - torg[0];
5643 dyao = tapex[1] - torg[1];
5644 dxod2 = dxod * dxod;
5645 dyod2 = dyod * dyod;
5646 dxda2 = dxda * dxda;
5647 dyda2 = dyda * dyda;
5648 dxao2 = dxao * dxao;
5649 dyao2 = dyao * dyao;
5650 /* Find the lengths of the triangle's three edges. */
5651 apexlen = dxod2 + dyod2;
5652 orglen = dxda2 + dyda2;
5653 destlen = dxao2 + dyao2;
5654 if (( apexlen < orglen ) && ( apexlen < destlen )) {
5655 /* The edge opposite the apex is shortest. */
5656 /* Find the square of the cosine of the angle at the apex. */
5657 angle = dxda * dxao + dyda * dyao;
5658 angle = angle * angle / ( orglen * destlen );
5659 anglevertex = tapex;
5660 lnext( *testtri, sametesttri );
5661 tspivot( sametesttri, edge1 );
5662 lnextself( sametesttri );
5663 tspivot( sametesttri, edge2 );
5664 }
5665 else if ( orglen < destlen ) {
5666 /* The edge opposite the origin is shortest. */
5667 /* Find the square of the cosine of the angle at the origin. */
5668 angle = dxod * dxao + dyod * dyao;
5669 angle = angle * angle / ( apexlen * destlen );
5670 anglevertex = torg;
5671 tspivot( *testtri, edge1 );
5672 lprev( *testtri, sametesttri );
5673 tspivot( sametesttri, edge2 );
5674 }
5675 else {
5676 /* The edge opposite the destination is shortest. */
5677 /* Find the square of the cosine of the angle at the destination. */
5678 angle = dxod * dxda + dyod * dyda;
5679 angle = angle * angle / ( apexlen * orglen );
5680 anglevertex = tdest;
5681 tspivot( *testtri, edge1 );
5682 lnext( *testtri, sametesttri );
5683 tspivot( sametesttri, edge2 );
5684 }
5685 /* Check if both edges that form the angle are segments. */
5686 if (( edge1.sh != dummysh ) && ( edge2.sh != dummysh )) {
5687 /* The angle is a segment intersection. */
5688 if (( angle > 0.9924 ) && !quiet ) {          /* Roughly 5 degrees. */
5689 if ( angle > 1.0 ) {
5690 /* Beware of a floating exception in acos(). */
5691 angle = 1.0;
5692 }
5693 /* Find the actual angle in degrees, for printing. */
5694 angle = acos( sqrt( angle )) * ( 180.0 / PI );
5695 printf(
5696 "Warning:  Small angle (%.4g degrees) between segments at point\n",
5697 angle );
5698 printf( "  (%.12g, %.12g)\n", anglevertex[0], anglevertex[1] );
5699 }
5700 /* Don't add this bad triangle to the list; there's nothing that */
5701 /*   can be done about a small angle between two segments.       */
5702 angle = 0.0;
5703 }
5704 /* Check whether the angle is smaller than permitted. */
5705 if ( angle > goodangle ) {
5706 /* Add this triangle to the list of bad triangles. */
5707 enqueuebadtri( testtri, angle, tapex, torg, tdest );
5708 return;
5709 }
5710 if ( vararea || fixedarea ) {
5711 /* Check whether the area is larger than permitted. */
5712 area = 0.5 * ( dxod * dyda - dyod * dxda );
5713 if ( fixedarea && ( area > maxarea )) {
5714 /* Add this triangle to the list of bad triangles. */
5715 enqueuebadtri( testtri, angle, tapex, torg, tdest );
5716 }
5717 else if ( vararea ) {
5718 /* Nonpositive area constraints are treated as unconstrained. */
5719 if (( area > areabound( *testtri )) && ( areabound( *testtri ) > 0.0 )) {
5720 /* Add this triangle to the list of bad triangles. */
5721 enqueuebadtri( testtri, angle, tapex, torg, tdest );
5722 }
5723 }
5724 }
5725 }
5726
5727 #endif /* not CDT_ONLY */
5728
5729 /**                                                                         **/
5730 /**                                                                         **/
5731 /********* Mesh quality testing routines end here                    *********/
5732
5733 /********* Point location routines begin here                        *********/
5734 /**                                                                         **/
5735 /**                                                                         **/
5736
5737 /*****************************************************************************/
5738 /*                                                                           */
5739 /*  makepointmap()   Construct a mapping from points to triangles to improve  */
5740 /*                  the speed of point location for segment insertion.       */
5741 /*                                                                           */
5742 /*  Traverses all the triangles, and provides each corner of each triangle   */
5743 /*  with a pointer to that triangle.  Of course, pointers will be            */
5744 /*  overwritten by other pointers because (almost) each point is a corner    */
5745 /*  of several triangles, but in the end every point will point to some      */
5746 /*  triangle that contains it.                                               */
5747 /*                                                                           */
5748 /*****************************************************************************/
5749
5750 void makepointmap(){
5751 struct triedge triangleloop;
5752 point triorg;
5753
5754 if ( verbose ) {
5755 printf( "    Constructing mapping from points to triangles.\n" );
5756 }
5757 traversalinit( &triangles );
5758 triangleloop.tri = triangletraverse();
5759 while ( triangleloop.tri != (triangle *) NULL ) {
5760 /* Check all three points of the triangle. */
5761 for ( triangleloop.orient = 0; triangleloop.orient < 3;
5762 triangleloop.orient++ ) {
5763 org( triangleloop, triorg );
5764 setpoint2tri( triorg, encode( triangleloop ));
5765 }
5766 triangleloop.tri = triangletraverse();
5767 }
5768 }
5769
5770 /*****************************************************************************/
5771 /*                                                                           */
5772 /*  preciselocate()   Find a triangle or edge containing a given point.      */
5773 /*                                                                           */
5774 /*  Begins its search from `searchtri'.  It is important that `searchtri'    */
5775 /*  be a handle with the property that `searchpoint' is strictly to the left */
5776 /*  of the edge denoted by `searchtri', or is collinear with that edge and   */
5777 /*  does not intersect that edge.  (In particular, `searchpoint' should not  */
5778 /*  be the origin or destination of that edge.)                              */
5779 /*                                                                           */
5780 /*  These conditions are imposed because preciselocate() is normally used in */
5781 /*  one of two situations:                                                   */
5782 /*                                                                           */
5783 /*  (1)  To try to find the location to insert a new point.  Normally, we    */
5784 /*       know an edge that the point is strictly to the left of.  In the     */
5785 /*       incremental Delaunay algorithm, that edge is a bounding box edge.   */
5786 /*       In Ruppert's Delaunay refinement algorithm for quality meshing,     */
5787 /*       that edge is the shortest edge of the triangle whose circumcenter   */
5788 /*       is being inserted.                                                  */
5789 /*                                                                           */
5790 /*  (2)  To try to find an existing point.  In this case, any edge on the    */
5791 /*       convex hull is a good starting edge.  The possibility that the      */
5792 /*       vertex one seeks is an endpoint of the starting edge must be        */
5793 /*       screened out before preciselocate() is called.                      */
5794 /*                                                                           */
5795 /*  On completion, `searchtri' is a triangle that contains `searchpoint'.    */
5796 /*                                                                           */
5797 /*  This implementation differs from that given by Guibas and Stolfi.  It    */
5798 /*  walks from triangle to triangle, crossing an edge only if `searchpoint'  */
5799 /*  is on the other side of the line containing that edge.  After entering   */
5800 /*  a triangle, there are two edges by which one can leave that triangle.    */
5801 /*  If both edges are valid (`searchpoint' is on the other side of both      */
5802 /*  edges), one of the two is chosen by drawing a line perpendicular to      */
5803 /*  the entry edge (whose endpoints are `forg' and `fdest') passing through  */
5804 /*  `fapex'.  Depending on which side of this perpendicular `searchpoint'    */
5805 /*  falls on, an exit edge is chosen.                                        */
5806 /*                                                                           */
5807 /*  This implementation is empirically faster than the Guibas and Stolfi     */
5808 /*  point location routine (which I originally used), which tends to spiral  */
5809 /*  in toward its target.                                                    */
5810 /*                                                                           */
5811 /*  Returns ONVERTEX if the point lies on an existing vertex.  `searchtri'   */
5812 /*  is a handle whose origin is the existing vertex.                         */
5813 /*                                                                           */
5814 /*  Returns ONEDGE if the point lies on a mesh edge.  `searchtri' is a       */
5815 /*  handle whose primary edge is the edge on which the point lies.           */
5816 /*                                                                           */
5817 /*  Returns INTRIANGLE if the point lies strictly within a triangle.         */
5818 /*  `searchtri' is a handle on the triangle that contains the point.         */
5819 /*                                                                           */
5820 /*  Returns OUTSIDE if the point lies outside the mesh.  `searchtri' is a    */
5821 /*  handle whose primary edge the point is to the right of.  This might      */
5822 /*  occur when the circumcenter of a triangle falls just slightly outside    */
5823 /*  the mesh due to floating-point roundoff error.  It also occurs when      */
5824 /*  seeking a hole or region point that a foolish user has placed outside    */
5825 /*  the mesh.                                                                */
5826 /*                                                                           */
5827 /*  WARNING:  This routine is designed for convex triangulations, and will   */
5828 /*  not generally work after the holes and concavities have been carved.     */
5829 /*  However, it can still be used to find the circumcenter of a triangle, as */
5830 /*  long as the search is begun from the triangle in question.               */
5831 /*                                                                           */
5832 /*****************************************************************************/
5833
5834 enum locateresult preciselocate( searchpoint, searchtri )
5835 point searchpoint;
5836 struct triedge *searchtri;
5837 {
5838 struct triedge backtracktri;
5839 point forg, fdest, fapex;
5840 point swappoint;
5841 REAL orgorient, destorient;
5842 int moveleft;
5843 triangle ptr;                       /* Temporary variable used by sym(). */
5844
5845 if ( verbose > 2 ) {
5846 printf( "  Searching for point (%.12g, %.12g).\n",
5847 searchpoint[0], searchpoint[1] );
5848 }
5849 /* Where are we? */
5850 org( *searchtri, forg );
5851 dest( *searchtri, fdest );
5852 apex( *searchtri, fapex );
5853 while ( 1 ) {
5854 if ( verbose > 2 ) {
5855 printf( "    At (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
5856 forg[0], forg[1], fdest[0], fdest[1], fapex[0], fapex[1] );
5857 }
5858 /* Check whether the apex is the point we seek. */
5859 if (( fapex[0] == searchpoint[0] ) && ( fapex[1] == searchpoint[1] )) {
5860 lprevself( *searchtri );
5861 return ONVERTEX;
5862 }
5863 /* Does the point lie on the other side of the line defined by the */
5864 /*   triangle edge opposite the triangle's destination?            */
5865 destorient = counterclockwise( forg, fapex, searchpoint );
5866 /* Does the point lie on the other side of the line defined by the */
5867 /*   triangle edge opposite the triangle's origin?                 */
5868 orgorient = counterclockwise( fapex, fdest, searchpoint );
5869 if ( destorient > 0.0 ) {
5870 if ( orgorient > 0.0 ) {
5871 /* Move left if the inner product of (fapex - searchpoint) and  */
5872 /*   (fdest - forg) is positive.  This is equivalent to drawing */
5873 /*   a line perpendicular to the line (forg, fdest) passing     */
5874 /*   through `fapex', and determining which side of this line   */
5875 /*   `searchpoint' falls on.                                    */
5876 moveleft = ( fapex[0] - searchpoint[0] ) * ( fdest[0] - forg[0] ) +
5877 ( fapex[1] - searchpoint[1] ) * ( fdest[1] - forg[1] ) > 0.0;
5878 }
5879 else {
5880 moveleft = 1;
5881 }
5882 }
5883 else {
5884 if ( orgorient > 0.0 ) {
5885 moveleft = 0;
5886 }
5887 else {
5888 /* The point we seek must be on the boundary of or inside this */
5889 /*   triangle.                                                 */
5890 if ( destorient == 0.0 ) {
5891 lprevself( *searchtri );
5892 return ONEDGE;
5893 }
5894 if ( orgorient == 0.0 ) {
5895 lnextself( *searchtri );
5896 return ONEDGE;
5897 }
5898 return INTRIANGLE;
5899 }
5900 }
5901
5902 /* Move to another triangle.  Leave a trace `backtracktri' in case */
5903 /*   floating-point roundoff or some such bogey causes us to walk  */
5904 /*   off a boundary of the triangulation.  We can just bounce off  */
5905 /*   the boundary as if it were an elastic band.                   */
5906 if ( moveleft ) {
5907 lprev( *searchtri, backtracktri );
5908 fdest = fapex;
5909 }
5910 else {
5911 lnext( *searchtri, backtracktri );
5912 forg = fapex;
5913 }
5914 sym( backtracktri, *searchtri );
5915
5916 /* Check for walking off the edge. */
5917 if ( searchtri->tri == dummytri ) {
5918 /* Turn around. */
5919 triedgecopy( backtracktri, *searchtri );
5920 swappoint = forg;
5921 forg = fdest;
5922 fdest = swappoint;
5923 apex( *searchtri, fapex );
5924 /* Check if the point really is beyond the triangulation boundary. */
5925 destorient = counterclockwise( forg, fapex, searchpoint );
5926 orgorient = counterclockwise( fapex, fdest, searchpoint );
5927 if (( orgorient < 0.0 ) && ( destorient < 0.0 )) {
5928 return OUTSIDE;
5929 }
5930 }
5931 else {
5932 apex( *searchtri, fapex );
5933 }
5934 }
5935 }
5936
5937 /*****************************************************************************/
5938 /*                                                                           */
5939 /*  locate()   Find a triangle or edge containing a given point.             */
5940 /*                                                                           */
5941 /*  Searching begins from one of:  the input `searchtri', a recently         */
5942 /*  encountered triangle `recenttri', or from a triangle chosen from a       */
5943 /*  random sample.  The choice is made by determining which triangle's       */
5944 /*  origin is closest to the point we are searcing for.  Normally,           */
5945 /*  `searchtri' should be a handle on the convex hull of the triangulation.  */
5946 /*                                                                           */
5947 /*  Details on the random sampling method can be found in the Mucke, Saias,  */
5948 /*  and Zhu paper cited in the header of this code.                          */
5949 /*                                                                           */
5950 /*  On completion, `searchtri' is a triangle that contains `searchpoint'.    */
5951 /*                                                                           */
5952 /*  Returns ONVERTEX if the point lies on an existing vertex.  `searchtri'   */
5953 /*  is a handle whose origin is the existing vertex.                         */
5954 /*                                                                           */
5955 /*  Returns ONEDGE if the point lies on a mesh edge.  `searchtri' is a       */
5956 /*  handle whose primary edge is the edge on which the point lies.           */
5957 /*                                                                           */
5958 /*  Returns INTRIANGLE if the point lies strictly within a triangle.         */
5959 /*  `searchtri' is a handle on the triangle that contains the point.         */
5960 /*                                                                           */
5961 /*  Returns OUTSIDE if the point lies outside the mesh.  `searchtri' is a    */
5962 /*  handle whose primary edge the point is to the right of.  This might      */
5963 /*  occur when the circumcenter of a triangle falls just slightly outside    */
5964 /*  the mesh due to floating-point roundoff error.  It also occurs when      */
5965 /*  seeking a hole or region point that a foolish user has placed outside    */
5966 /*  the mesh.                                                                */
5967 /*                                                                           */
5968 /*  WARNING:  This routine is designed for convex triangulations, and will   */
5969 /*  not generally work after the holes and concavities have been carved.     */
5970 /*                                                                           */
5971 /*****************************************************************************/
5972
5973 enum locateresult locate( searchpoint, searchtri )
5974 point searchpoint;
5975 struct triedge *searchtri;
5976 {
5977 VOID **sampleblock;
5978 triangle *firsttri;
5979 struct triedge sampletri;
5980 point torg, tdest;
5981 unsigned long alignptr;
5982 REAL searchdist, dist;
5983 REAL ahead;
5984 long sampleblocks, samplesperblock, samplenum;
5985 long triblocks;
5986 long i, j;
5987 triangle ptr;                       /* Temporary variable used by sym(). */
5988
5989 if ( verbose > 2 ) {
5990 printf( "  Randomly sampling for a triangle near point (%.12g, %.12g).\n",
5991 searchpoint[0], searchpoint[1] );
5992 }
5993 /* Record the distance from the suggested starting triangle to the */
5994 /*   point we seek.                                                */
5995 org( *searchtri, torg );
5996 searchdist = ( searchpoint[0] - torg[0] ) * ( searchpoint[0] - torg[0] )
5997 + ( searchpoint[1] - torg[1] ) * ( searchpoint[1] - torg[1] );
5998 if ( verbose > 2 ) {
5999 printf( "    Boundary triangle has origin (%.12g, %.12g).\n",
6000 torg[0], torg[1] );
6001 }
6002
6003 /* If a recently encountered triangle has been recorded and has not been */
6004 /*   deallocated, test it as a good starting point.                      */
6005 if ( recenttri.tri != (triangle *) NULL ) {
6006 if ( recenttri.tri[3] != (triangle) NULL ) {
6007 org( recenttri, torg );
6008 if (( torg[0] == searchpoint[0] ) && ( torg[1] == searchpoint[1] )) {
6009 triedgecopy( recenttri, *searchtri );
6010 return ONVERTEX;
6011 }
6012 dist = ( searchpoint[0] - torg[0] ) * ( searchpoint[0] - torg[0] )
6013 + ( searchpoint[1] - torg[1] ) * ( searchpoint[1] - torg[1] );
6014 if ( dist < searchdist ) {
6015 triedgecopy( recenttri, *searchtri );
6016 searchdist = dist;
6017 if ( verbose > 2 ) {
6018 printf( "    Choosing recent triangle with origin (%.12g, %.12g).\n",
6019 torg[0], torg[1] );
6020 }
6021 }
6022 }
6023 }
6024
6025 /* The number of random samples taken is proportional to the cube root of */
6026 /*   the number of triangles in the mesh.  The next bit of code assumes   */
6027 /*   that the number of triangles increases monotonically.                */
6028 while ( SAMPLEFACTOR * samples * samples * samples < triangles.items ) {
6029 samples++;
6030 }
6031 triblocks = ( triangles.maxitems + TRIPERBLOCK - 1 ) / TRIPERBLOCK;
6032 samplesperblock = 1 + ( samples / triblocks );
6033 sampleblocks = samples / samplesperblock;
6034 sampleblock = triangles.firstblock;
6035 sampletri.orient = 0;
6036 for ( i = 0; i < sampleblocks; i++ ) {
6037 alignptr = (unsigned long) ( sampleblock + 1 );
6038 firsttri = (triangle *) ( alignptr + (unsigned long) triangles.alignbytes
6039 - ( alignptr % (unsigned long) triangles.alignbytes ));
6040 for ( j = 0; j < samplesperblock; j++ ) {
6041 if ( i == triblocks - 1 ) {
6042 samplenum = randomnation((int)
6043 ( triangles.maxitems - ( i * TRIPERBLOCK )));
6044 }
6045 else {
6046 samplenum = randomnation( TRIPERBLOCK );
6047 }
6048 sampletri.tri = (triangle *)
6049 ( firsttri + ( samplenum * triangles.itemwords ));
6050 if ( sampletri.tri[3] != (triangle) NULL ) {
6051 org( sampletri, torg );
6052 dist = ( searchpoint[0] - torg[0] ) * ( searchpoint[0] - torg[0] )
6053 + ( searchpoint[1] - torg[1] ) * ( searchpoint[1] - torg[1] );
6054 if ( dist < searchdist ) {
6055 triedgecopy( sampletri, *searchtri );
6056 searchdist = dist;
6057 if ( verbose > 2 ) {
6058 printf( "    Choosing triangle with origin (%.12g, %.12g).\n",
6059 torg[0], torg[1] );
6060 }
6061 }
6062 }
6063 }
6064 sampleblock = (VOID **) *sampleblock;
6065 }
6066 /* Where are we? */
6067 org( *searchtri, torg );
6068 dest( *searchtri, tdest );
6069 /* Check the starting triangle's vertices. */
6070 if (( torg[0] == searchpoint[0] ) && ( torg[1] == searchpoint[1] )) {
6071 return ONVERTEX;
6072 }
6073 if (( tdest[0] == searchpoint[0] ) && ( tdest[1] == searchpoint[1] )) {
6074 lnextself( *searchtri );
6075 return ONVERTEX;
6076 }
6077 /* Orient `searchtri' to fit the preconditions of calling preciselocate(). */
6078 ahead = counterclockwise( torg, tdest, searchpoint );
6079 if ( ahead < 0.0 ) {
6080 /* Turn around so that `searchpoint' is to the left of the */
6081 /*   edge specified by `searchtri'.                        */
6082 symself( *searchtri );
6083 }
6084 else if ( ahead == 0.0 ) {
6085 /* Check if `searchpoint' is between `torg' and `tdest'. */
6086 if ((( torg[0] < searchpoint[0] ) == ( searchpoint[0] < tdest[0] ))
6087 && (( torg[1] < searchpoint[1] ) == ( searchpoint[1] < tdest[1] ))) {
6088 return ONEDGE;
6089 }
6090 }
6091 return preciselocate( searchpoint, searchtri );
6092 }
6093
6094 /**                                                                         **/
6095 /**                                                                         **/
6096 /********* Point location routines end here                          *********/
6097
6098 /********* Mesh transformation routines begin here                   *********/
6099 /**                                                                         **/
6100 /**                                                                         **/
6101
6102 /*****************************************************************************/
6103 /*                                                                           */
6104 /*  insertshelle()   Create a new shell edge and insert it between two       */
6105 /*                   triangles.                                              */
6106 /*                                                                           */
6107 /*  The new shell edge is inserted at the edge described by the handle       */
6108 /*  `tri'.  Its vertices are properly initialized.  The marker `shellemark'  */
6109 /*  is applied to the shell edge and, if appropriate, its vertices.          */
6110 /*                                                                           */
6111 /*****************************************************************************/
6112
6113 void insertshelle( tri, shellemark )
6114 struct triedge *tri;          /* Edge at which to insert the new shell edge. */
6115 int shellemark;                            /* Marker for the new shell edge. */
6116 {
6117 struct triedge oppotri;
6118 struct edge newshelle;
6119 point triorg, tridest;
6120 triangle ptr;                       /* Temporary variable used by sym(). */
6121 shelle sptr;                    /* Temporary variable used by tspivot(). */
6122
6123 /* Mark points if possible. */
6124 org( *tri, triorg );
6125 dest( *tri, tridest );
6126 if ( pointmark( triorg ) == 0 ) {
6127 setpointmark( triorg, shellemark );
6128 }
6129 if ( pointmark( tridest ) == 0 ) {
6130 setpointmark( tridest, shellemark );
6131 }
6132 /* Check if there's already a shell edge here. */
6133 tspivot( *tri, newshelle );
6134 if ( newshelle.sh == dummysh ) {
6135 /* Make new shell edge and initialize its vertices. */
6136 makeshelle( &newshelle );
6137 setsorg( newshelle, tridest );
6138 setsdest( newshelle, triorg );
6139 /* Bond new shell edge to the two triangles it is sandwiched between. */
6140 /*   Note that the facing triangle `oppotri' might be equal to        */
6141 /*   `dummytri' (outer space), but the new shell edge is bonded to it */
6142 /*   all the same.                                                    */
6143 tsbond( *tri, newshelle );
6144 sym( *tri, oppotri );
6145 ssymself( newshelle );
6146 tsbond( oppotri, newshelle );
6147 setmark( newshelle, shellemark );
6148 if ( verbose > 2 ) {
6149 printf( "  Inserting new " );
6150 printshelle( &newshelle );
6151 }
6152 }
6153 else {
6154 if ( mark( newshelle ) == 0 ) {
6155 setmark( newshelle, shellemark );
6156 }
6157 }
6158 }
6159
6160 /*****************************************************************************/
6161 /*                                                                           */
6162 /*  Terminology                                                              */
6163 /*                                                                           */
6164 /*  A "local transformation" replaces a small set of triangles with another  */
6165 /*  set of triangles.  This may or may not involve inserting or deleting a   */
6166 /*  point.                                                                   */
6167 /*                                                                           */
6168 /*  The term "casing" is used to describe the set of triangles that are      */
6169 /*  attached to the triangles being transformed, but are not transformed     */
6170 /*  themselves.  Think of the casing as a fixed hollow structure inside      */
6171 /*  which all the action happens.  A "casing" is only defined relative to    */
6172 /*  a single transformation; each occurrence of a transformation will        */
6173 /*  involve a different casing.                                              */
6174 /*                                                                           */
6175 /*  A "shell" is similar to a "casing".  The term "shell" describes the set  */
6176 /*  of shell edges (if any) that are attached to the triangles being         */
6177 /*  transformed.  However, I sometimes use "shell" to refer to a single      */
6178 /*  shell edge, so don't get confused.                                       */
6179 /*                                                                           */
6180 /*****************************************************************************/
6181
6182 /*****************************************************************************/
6183 /*                                                                           */
6184 /*  flip()   Transform two triangles to two different triangles by flipping  */
6185 /*           an edge within a quadrilateral.                                 */
6186 /*                                                                           */
6187 /*  Imagine the original triangles, abc and bad, oriented so that the        */
6188 /*  shared edge ab lies in a horizontal plane, with the point b on the left  */
6189 /*  and the point a on the right.  The point c lies below the edge, and the  */
6190 /*  point d lies above the edge.  The `flipedge' handle holds the edge ab    */
6191 /*  of triangle abc, and is directed left, from vertex a to vertex b.        */
6192 /*                                                                           */
6193 /*  The triangles abc and bad are deleted and replaced by the triangles cdb  */
6194 /*  and dca.  The triangles that represent abc and bad are NOT deallocated;  */
6195 /*  they are reused for dca and cdb, respectively.  Hence, any handles that  */
6196 /*  may have held the original triangles are still valid, although not       */
6197 /*  directed as they were before.                                            */
6198 /*                                                                           */
6199 /*  Upon completion of this routine, the `flipedge' handle holds the edge    */
6200 /*  dc of triangle dca, and is directed down, from vertex d to vertex c.     */
6201 /*  (Hence, the two triangles have rotated counterclockwise.)                */
6202 /*                                                                           */
6203 /*  WARNING:  This transformation is geometrically valid only if the         */
6204 /*  quadrilateral adbc is convex.  Furthermore, this transformation is       */
6205 /*  valid only if there is not a shell edge between the triangles abc and    */
6206 /*  bad.  This routine does not check either of these preconditions, and     */
6207 /*  it is the responsibility of the calling routine to ensure that they are  */
6208 /*  met.  If they are not, the streets shall be filled with wailing and      */
6209 /*  gnashing of teeth.                                                       */
6210 /*                                                                           */
6211 /*****************************************************************************/
6212
6213 void flip( flipedge )
6214 struct triedge *flipedge;                    /* Handle for the triangle abc. */
6215 {
6216 struct triedge botleft, botright;
6217 struct triedge topleft, topright;
6218 struct triedge top;
6219 struct triedge botlcasing, botrcasing;
6220 struct triedge toplcasing, toprcasing;
6221 struct edge botlshelle, botrshelle;
6222 struct edge toplshelle, toprshelle;
6223 point leftpoint, rightpoint, botpoint;
6224 point farpoint;
6225 triangle ptr;                       /* Temporary variable used by sym(). */
6226 shelle sptr;                    /* Temporary variable used by tspivot(). */
6227
6228 /* Identify the vertices of the quadrilateral. */
6229 org( *flipedge, rightpoint );
6230 dest( *flipedge, leftpoint );
6231 apex( *flipedge, botpoint );
6232 sym( *flipedge, top );
6233 #ifdef
6234 SELF_CHECK
6235 if ( top.tri == dummytri ) {
6236 printf( "Internal error in flip():  Attempt to flip on boundary.\n" );
6237 lnextself( *flipedge );
6238 return;
6239 }
6240 if ( checksegments ) {
6241 tspivot( *flipedge, toplshelle );
6242 if ( toplshelle.sh != dummysh ) {
6243 printf( "Internal error in flip():  Attempt to flip a segment.\n" );
6244 lnextself( *flipedge );
6245 return;
6246 }
6247 }
6248 #endif /* SELF_CHECK */
6249 apex( top, farpoint );
6250
6251 /* Identify the casing of the quadrilateral. */
6252 lprev( top, topleft );
6253 sym( topleft, toplcasing );
6254 lnext( top, topright );
6255 sym( topright, toprcasing );
6256 lnext( *flipedge, botleft );
6257 sym( botleft, botlcasing );
6258 lprev( *flipedge, botright );
6259 sym( botright, botrcasing );
6260 /* Rotate the quadrilateral one-quarter turn counterclockwise. */
6261 bond( topleft, botlcasing );
6262 bond( botleft, botrcasing );
6263 bond( botright, toprcasing );
6264 bond( topright, toplcasing );
6265
6266 if ( checksegments ) {
6267 /* Check for shell edges and rebond them to the quadrilateral. */
6268 tspivot( topleft, toplshelle );
6269 tspivot( botleft, botlshelle );
6270 tspivot( botright, botrshelle );
6271 tspivot( topright, toprshelle );
6272 if ( toplshelle.sh == dummysh ) {
6273 tsdissolve( topright );
6274 }
6275 else {
6276 tsbond( topright, toplshelle );
6277 }
6278 if ( botlshelle.sh == dummysh ) {
6279 tsdissolve( topleft );
6280 }
6281 else {
6282 tsbond( topleft, botlshelle );
6283 }
6284 if ( botrshelle.sh == dummysh ) {
6285 tsdissolve( botleft );
6286 }
6287 else {
6288 tsbond( botleft, botrshelle );
6289 }
6290 if ( toprshelle.sh == dummysh ) {
6291 tsdissolve( botright );
6292 }
6293 else {
6294 tsbond( botright, toprshelle );
6295 }
6296 }
6297
6298 /* New point assignments for the rotated quadrilateral. */
6299 setorg( *flipedge, farpoint );
6300 setdest( *flipedge, botpoint );
6301 setapex( *flipedge, rightpoint );
6302 setorg( top, botpoint );
6303 setdest( top, farpoint );
6304 setapex( top, leftpoint );
6305 if ( verbose > 2 ) {
6306 printf( "  Edge flip results in left " );
6307 lnextself( topleft );
6308 printtriangle( &topleft );
6309 printf( "  and right " );
6310 printtriangle( flipedge );
6311 }
6312 }
6313
6314 /*****************************************************************************/
6315 /*                                                                           */
6316 /*  insertsite()   Insert a vertex into a Delaunay triangulation,            */
6317 /*                 performing flips as necessary to maintain the Delaunay    */
6318 /*                 property.                                                 */
6319 /*                                                                           */
6320 /*  The point `insertpoint' is located.  If `searchtri.tri' is not NULL,     */
6321 /*  the search for the containing triangle begins from `searchtri'.  If      */
6322 /*  `searchtri.tri' is NULL, a full point location procedure is called.      */
6323 /*  If `insertpoint' is found inside a triangle, the triangle is split into  */
6324 /*  three; if `insertpoint' lies on an edge, the edge is split in two,       */
6325 /*  thereby splitting the two adjacent triangles into four.  Edge flips are  */
6326 /*  used to restore the Delaunay property.  If `insertpoint' lies on an      */
6327 /*  existing vertex, no action is taken, and the value DUPLICATEPOINT is     */
6328 /*  returned.  On return, `searchtri' is set to a handle whose origin is the */
6329 /*  existing vertex.                                                         */
6330 /*                                                                           */
6331 /*  Normally, the parameter `splitedge' is set to NULL, implying that no     */
6332 /*  segment should be split.  In this case, if `insertpoint' is found to     */
6333 /*  lie on a segment, no action is taken, and the value VIOLATINGPOINT is    */
6334 /*  returned.  On return, `searchtri' is set to a handle whose primary edge  */
6335 /*  is the violated segment.                                                 */
6336 /*                                                                           */
6337 /*  If the calling routine wishes to split a segment by inserting a point in */
6338 /*  it, the parameter `splitedge' should be that segment.  In this case,     */
6339 /*  `searchtri' MUST be the triangle handle reached by pivoting from that    */
6340 /*  segment; no point location is done.                                      */
6341 /*                                                                           */
6342 /*  `segmentflaws' and `triflaws' are flags that indicate whether or not     */
6343 /*  there should be checks for the creation of encroached segments or bad    */
6344 /*  quality faces.  If a newly inserted point encroaches upon segments,      */
6345 /*  these segments are added to the list of segments to be split if          */
6346 /*  `segmentflaws' is set.  If bad triangles are created, these are added    */
6347 /*  to the queue if `triflaws' is set.                                       */
6348 /*                                                                           */
6349 /*  If a duplicate point or violated segment does not prevent the point      */
6350 /*  from being inserted, the return value will be ENCROACHINGPOINT if the    */
6351 /*  point encroaches upon a segment (and checking is enabled), or            */
6352 /*  SUCCESSFULPOINT otherwise.  In either case, `searchtri' is set to a      */
6353 /*  handle whose origin is the newly inserted vertex.                        */
6354 /*                                                                           */
6355 /*  insertsite() does not use flip() for reasons of speed; some              */
6356 /*  information can be reused from edge flip to edge flip, like the          */
6357 /*  locations of shell edges.                                                */
6358 /*                                                                           */
6359 /*****************************************************************************/
6360
6361 enum insertsiteresult insertsite( insertpoint, searchtri, splitedge,
6362 segmentflaws, triflaws )
6363 point insertpoint;
6364 struct triedge *searchtri;
6365 struct edge *splitedge;
6366 int segmentflaws;
6367 int triflaws;
6368 {
6369 struct triedge horiz;
6370 struct triedge top;
6371 struct triedge botleft, botright;
6372 struct triedge topleft, topright;
6373 struct triedge newbotleft, newbotright;
6374 struct triedge newtopright;
6375 struct triedge botlcasing, botrcasing;
6376 struct triedge toplcasing, toprcasing;
6377 struct triedge testtri;
6378 struct edge botlshelle, botrshelle;
6379 struct edge toplshelle, toprshelle;
6380 struct edge brokenshelle;
6381 struct edge checkshelle;
6382 struct edge rightedge;
6383 struct edge newedge;
6384 struct edge *encroached;
6385 point first;
6386 point leftpoint, rightpoint, botpoint, toppoint, farpoint;
6387 REAL attrib;
6388 REAL area;
6389 enum insertsiteresult success;
6390 enum locateresult intersect;
6391 int doflip;
6392 int mirrorflag;
6393 int i;
6394 triangle ptr;                       /* Temporary variable used by sym(). */
6395 shelle sptr;       /* Temporary variable used by spivot() and tspivot(). */
6396
6397 if ( verbose > 1 ) {
6398 printf( "  Inserting (%.12g, %.12g).\n", insertpoint[0], insertpoint[1] );
6399 }
6400 if ( splitedge == (struct edge *) NULL ) {
6401 /* Find the location of the point to be inserted.  Check if a good */
6402 /*   starting triangle has already been provided by the caller.    */
6403 if ( searchtri->tri == (triangle *) NULL ) {
6404 /* Find a boundary triangle. */
6405 horiz.tri = dummytri;
6406 horiz.orient = 0;
6407 symself( horiz );
6408 /* Search for a triangle containing `insertpoint'. */
6409 intersect = locate( insertpoint, &horiz );
6410 }
6411 else {
6412 /* Start searching from the triangle provided by the caller. */
6413 triedgecopy( *searchtri, horiz );
6414 intersect = preciselocate( insertpoint, &horiz );
6415 }
6416 }
6417 else {
6418 /* The calling routine provides the edge in which the point is inserted. */
6419 triedgecopy( *searchtri, horiz );
6420 intersect = ONEDGE;
6421 }
6422 if ( intersect == ONVERTEX ) {
6423 /* There's already a vertex there.  Return in `searchtri' a triangle */
6424 /*   whose origin is the existing vertex.                            */
6425 triedgecopy( horiz, *searchtri );
6426 triedgecopy( horiz, recenttri );
6427 return DUPLICATEPOINT;
6428 }
6429 if (( intersect == ONEDGE ) || ( intersect == OUTSIDE )) {
6430 /* The vertex falls on an edge or boundary. */
6431 if ( checksegments && ( splitedge == (struct edge *) NULL )) {
6432 /* Check whether the vertex falls on a shell edge. */
6433 tspivot( horiz, brokenshelle );
6434 if ( brokenshelle.sh != dummysh ) {
6435 /* The vertex falls on a shell edge. */
6436 if ( segmentflaws ) {
6437 if ( nobisect == 0 ) {
6438 /* Add the shell edge to the list of encroached segments. */
6439 encroached = (struct edge *) poolalloc( &badsegments );
6440 shellecopy( brokenshelle, *encroached );
6441 }
6442 else if (( nobisect == 1 ) && ( intersect == ONEDGE )) {
6443 /* This segment may be split only if it is an internal boundary. */
6444 sym( horiz, testtri );
6445 if ( testtri.tri != dummytri ) {
6446 /* Add the shell edge to the list of encroached segments. */
6447 encroached = (struct edge *) poolalloc( &badsegments );
6448 shellecopy( brokenshelle, *encroached );
6449 }
6450 }
6451 }
6452 /* Return a handle whose primary edge contains the point, */
6453 /*   which has not been inserted.                         */
6454 triedgecopy( horiz, *searchtri );
6455 triedgecopy( horiz, recenttri );
6456 return VIOLATINGPOINT;
6457 }
6458 }
6459 /* Insert the point on an edge, dividing one triangle into two (if */
6460 /*   the edge lies on a boundary) or two triangles into four.      */
6461 lprev( horiz, botright );
6462 sym( botright, botrcasing );
6463 sym( horiz, topright );
6464 /* Is there a second triangle?  (Or does this edge lie on a boundary?) */
6465 mirrorflag = topright.tri != dummytri;
6466 if ( mirrorflag ) {
6467 lnextself( topright );
6468 sym( topright, toprcasing );
6469 maketriangle( &newtopright );
6470 }
6471 else {
6472 /* Splitting the boundary edge increases the number of boundary edges. */
6473 hullsize++;
6474 }
6475 maketriangle( &newbotright );
6476
6477 /* Set the vertices of changed and new triangles. */
6478 org( horiz, rightpoint );
6479 dest( horiz, leftpoint );
6480 apex( horiz, botpoint );
6481 setorg( newbotright, botpoint );
6482 setdest( newbotright, rightpoint );
6483 setapex( newbotright, insertpoint );
6484 setorg( horiz, insertpoint );
6485 for ( i = 0; i < eextras; i++ ) {
6486 /* Set the element attributes of a new triangle. */
6487 setelemattribute( newbotright, i, elemattribute( botright, i ));
6488 }
6489 if ( vararea ) {
6490 /* Set the area constraint of a new triangle. */
6491 setareabound( newbotright, areabound( botright ));
6492 }
6493 if ( mirrorflag ) {
6494 dest( topright, toppoint );
6495 setorg( newtopright, rightpoint );
6496 setdest( newtopright, toppoint );
6497 setapex( newtopright, insertpoint );
6498 setorg( topright, insertpoint );
6499 for ( i = 0; i < eextras; i++ ) {
6500 /* Set the element attributes of another new triangle. */
6501 setelemattribute( newtopright, i, elemattribute( topright, i ));
6502 }
6503 if ( vararea ) {
6504 /* Set the area constraint of another new triangle. */
6505 setareabound( newtopright, areabound( topright ));
6506 }
6507 }
6508
6509 /* There may be shell edges that need to be bonded */
6510 /*   to the new triangle(s).                       */
6511 if ( checksegments ) {
6512 tspivot( botright, botrshelle );
6513 if ( botrshelle.sh != dummysh ) {
6514 tsdissolve( botright );
6515 tsbond( newbotright, botrshelle );
6516 }
6517 if ( mirrorflag ) {
6518 tspivot( topright, toprshelle );
6519 if ( toprshelle.sh != dummysh ) {
6520 tsdissolve( topright );
6521 tsbond( newtopright, toprshelle );
6522 }
6523 }
6524 }
6525
6526 /* Bond the new triangle(s) to the surrounding triangles. */
6527 bond( newbotright, botrcasing );
6528 lprevself( newbotright );
6529 bond( newbotright, botright );
6530 lprevself( newbotright );
6531 if ( mirrorflag ) {
6532 bond( newtopright, toprcasing );
6533 lnextself( newtopright );
6534 bond( newtopright, topright );
6535 lnextself( newtopright );
6536 bond( newtopright, newbotright );
6537 }
6538
6539 if ( splitedge != (struct edge *) NULL ) {
6540 /* Split the shell edge into two. */
6541 setsdest( *splitedge, insertpoint );
6542 ssymself( *splitedge );
6543 spivot( *splitedge, rightedge );
6544 insertshelle( &newbotright, mark( *splitedge ));
6545 tspivot( newbotright, newedge );
6546 sbond( *splitedge, newedge );
6547 ssymself( newedge );
6548 sbond( newedge, rightedge );
6549 ssymself( *splitedge );
6550 }
6551
6552 #ifdef
6553 SELF_CHECK
6554 if ( counterclockwise( rightpoint, leftpoint, botpoint ) < 0.0 ) {
6555 printf( "Internal error in insertsite():\n" );
6556 printf( "  Clockwise triangle prior to edge point insertion (bottom).\n" );
6557 }
6558 if ( mirrorflag ) {
6559 if ( counterclockwise( leftpoint, rightpoint, toppoint ) < 0.0 ) {
6560 printf( "Internal error in insertsite():\n" );
6561 printf( "  Clockwise triangle prior to edge point insertion (top).\n" );
6562 }
6563 if ( counterclockwise( rightpoint, toppoint, insertpoint ) < 0.0 ) {
6564 printf( "Internal error in insertsite():\n" );
6565 printf( "  Clockwise triangle after edge point insertion (top right).\n"
6566 );
6567 }
6568 if ( counterclockwise( toppoint, leftpoint, insertpoint ) < 0.0 ) {
6569 printf( "Internal error in insertsite():\n" );
6570 printf( "  Clockwise triangle after edge point insertion (top left).\n"
6571 );
6572 }
6573 }
6574 if ( counterclockwise( leftpoint, botpoint, insertpoint ) < 0.0 ) {
6575 printf( "Internal error in insertsite():\n" );
6576 printf( "  Clockwise triangle after edge point insertion (bottom left).\n"
6577 );
6578 }
6579 if ( counterclockwise( botpoint, rightpoint, insertpoint ) < 0.0 ) {
6580 printf( "Internal error in insertsite():\n" );
6581 printf(
6582 "  Clockwise triangle after edge point insertion (bottom right).\n" );
6583 }
6584 #endif /* SELF_CHECK */
6585 if ( verbose > 2 ) {
6586 printf( "  Updating bottom left " );
6587 printtriangle( &botright );
6588 if ( mirrorflag ) {
6589 printf( "  Updating top left " );
6590 printtriangle( &topright );
6591 printf( "  Creating top right " );
6592 printtriangle( &newtopright );
6593 }
6594 printf( "  Creating bottom right " );
6595 printtriangle( &newbotright );
6596 }
6597
6598 /* Position `horiz' on the first edge to check for */
6599 /*   the Delaunay property.                        */
6600 lnextself( horiz );
6601 }
6602 else {
6603 /* Insert the point in a triangle, splitting it into three. */
6604 lnext( horiz, botleft );
6605 lprev( horiz, botright );
6606 sym( botleft, botlcasing );
6607 sym( botright, botrcasing );
6608 maketriangle( &newbotleft );
6609 maketriangle( &newbotright );
6610
6611 /* Set the vertices of changed and new triangles. */
6612 org( horiz, rightpoint );
6613 dest( horiz, leftpoint );
6614 apex( horiz, botpoint );
6615 setorg( newbotleft, leftpoint );
6616 setdest( newbotleft, botpoint );
6617 setapex( newbotleft, insertpoint );
6618 setorg( newbotright, botpoint );
6619 setdest( newbotright, rightpoint );
6620 setapex( newbotright, insertpoint );
6621 setapex( horiz, insertpoint );
6622 for ( i = 0; i < eextras; i++ ) {
6623 /* Set the element attributes of the new triangles. */
6624 attrib = elemattribute( horiz, i );
6625 setelemattribute( newbotleft, i, attrib );
6626 setelemattribute( newbotright, i, attrib );
6627 }
6628 if ( vararea ) {
6629 /* Set the area constraint of the new triangles. */
6630 area = areabound( horiz );
6631 setareabound( newbotleft, area );
6632 setareabound( newbotright, area );
6633 }
6634
6635 /* There may be shell edges that need to be bonded */
6636 /*   to the new triangles.                         */
6637 if ( checksegments ) {
6638 tspivot( botleft, botlshelle );
6639 if ( botlshelle.sh != dummysh ) {
6640 tsdissolve( botleft );
6641 tsbond( newbotleft, botlshelle );
6642 }
6643 tspivot( botright, botrshelle );
6644 if ( botrshelle.sh != dummysh ) {
6645 tsdissolve( botright );
6646 tsbond( newbotright, botrshelle );
6647 }
6648 }
6649
6650 /* Bond the new triangles to the surrounding triangles. */
6651 bond( newbotleft, botlcasing );
6652 bond( newbotright, botrcasing );
6653 lnextself( newbotleft );
6654 lprevself( newbotright );
6655 bond( newbotleft, newbotright );
6656 lnextself( newbotleft );
6657 bond( botleft, newbotleft );
6658 lprevself( newbotright );
6659 bond( botright, newbotright );
6660
6661 #ifdef
6662 SELF_CHECK
6663 if ( counterclockwise( rightpoint, leftpoint, botpoint ) < 0.0 ) {
6664 printf( "Internal error in insertsite():\n" );
6665 printf( "  Clockwise triangle prior to point insertion.\n" );
6666 }
6667 if ( counterclockwise( rightpoint, leftpoint, insertpoint ) < 0.0 ) {
6668 printf( "Internal error in insertsite():\n" );
6669 printf( "  Clockwise triangle after point insertion (top).\n" );
6670 }
6671 if ( counterclockwise( leftpoint, botpoint, insertpoint ) < 0.0 ) {
6672 printf( "Internal error in insertsite():\n" );
6673 printf( "  Clockwise triangle after point insertion (left).\n" );
6674 }
6675 if ( counterclockwise( botpoint, rightpoint, insertpoint ) < 0.0 ) {
6676 printf( "Internal error in insertsite():\n" );
6677 printf( "  Clockwise triangle after point insertion (right).\n" );
6678 }
6679 #endif /* SELF_CHECK */
6680 if ( verbose > 2 ) {
6681 printf( "  Updating top " );
6682 printtriangle( &horiz );
6683 printf( "  Creating left " );
6684 printtriangle( &newbotleft );
6685 printf( "  Creating right " );
6686 printtriangle( &newbotright );
6687 }
6688 }
6689
6690 /* The insertion is successful by default, unless an encroached */
6691 /*   edge is found.                                             */
6692 success = SUCCESSFULPOINT;
6693 /* Circle around the newly inserted vertex, checking each edge opposite */
6694 /*   it for the Delaunay property.  Non-Delaunay edges are flipped.     */
6695 /*   `horiz' is always the edge being checked.  `first' marks where to  */
6696 /*   stop circling.                                                     */
6697 org( horiz, first );
6698 rightpoint = first;
6699 dest( horiz, leftpoint );
6700 /* Circle until finished. */
6701 while ( 1 ) {
6702 /* By default, the edge will be flipped. */
6703 doflip = 1;
6704 if ( checksegments ) {
6705 /* Check for a segment, which cannot be flipped. */
6706 tspivot( horiz, checkshelle );
6707 if ( checkshelle.sh != dummysh ) {
6708 /* The edge is a segment and cannot be flipped. */
6709 doflip = 0;
6710 #ifndef
6711 CDT_ONLY
6712 if ( segmentflaws ) {
6713 /* Does the new point encroach upon this segment? */
6714 if ( checkedge4encroach( &checkshelle )) {
6715 success = ENCROACHINGPOINT;
6716 }
6717 }
6718 #endif /* not CDT_ONLY */
6719 }
6720 }
6721 if ( doflip ) {
6722 /* Check if the edge is a boundary edge. */
6723 sym( horiz, top );
6724 if ( top.tri == dummytri ) {
6725 /* The edge is a boundary edge and cannot be flipped. */
6726 doflip = 0;
6727 }
6728 else {
6729 /* Find the point on the other side of the edge. */
6730 apex( top, farpoint );
6731 /* In the incremental Delaunay triangulation algorithm, any of    */
6732 /*   `leftpoint', `rightpoint', and `farpoint' could be vertices  */
6733 /*   of the triangular bounding box.  These vertices must be      */
6734 /*   treated as if they are infinitely distant, even though their */
6735 /*   "coordinates" are not.                                       */
6736 if (( leftpoint == infpoint1 ) || ( leftpoint == infpoint2 )
6737 || ( leftpoint == infpoint3 )) {
6738 /* `leftpoint' is infinitely distant.  Check the convexity of */
6739 /*   the boundary of the triangulation.  'farpoint' might be  */
6740 /*   infinite as well, but trust me, this same condition      */
6741 /*   should be applied.                                       */
6742 doflip = counterclockwise( insertpoint, rightpoint, farpoint ) > 0.0;
6743 }
6744 else if (( rightpoint == infpoint1 ) || ( rightpoint == infpoint2 )
6745 || ( rightpoint == infpoint3 )) {
6746 /* `rightpoint' is infinitely distant.  Check the convexity of */
6747 /*   the boundary of the triangulation.  'farpoint' might be  */
6748 /*   infinite as well, but trust me, this same condition      */
6749 /*   should be applied.                                       */
6750 doflip = counterclockwise( farpoint, leftpoint, insertpoint ) > 0.0;
6751 }
6752 else if (( farpoint == infpoint1 ) || ( farpoint == infpoint2 )
6753 || ( farpoint == infpoint3 )) {
6754 /* `farpoint' is infinitely distant and cannot be inside */
6755 /*   the circumcircle of the triangle `horiz'.           */
6756 doflip = 0;
6757 }
6758 else {
6759 /* Test whether the edge is locally Delaunay. */
6760 doflip = incircle( leftpoint, insertpoint, rightpoint, farpoint )
6761 > 0.0;
6762 }
6763 if ( doflip ) {
6764 /* We made it!  Flip the edge `horiz' by rotating its containing */
6765 /*   quadrilateral (the two triangles adjacent to `horiz').      */
6766 /* Identify the casing of the quadrilateral. */
6767 lprev( top, topleft );
6768 sym( topleft, toplcasing );
6769 lnext( top, topright );
6770 sym( topright, toprcasing );
6771 lnext( horiz, botleft );
6772 sym( botleft, botlcasing );
6773 lprev( horiz, botright );
6774 sym( botright, botrcasing );
6775 /* Rotate the quadrilateral one-quarter turn counterclockwise. */
6776 bond( topleft, botlcasing );
6777 bond( botleft, botrcasing );
6778 bond( botright, toprcasing );
6779 bond( topright, toplcasing );
6780 if ( checksegments ) {
6781 /* Check for shell edges and rebond them to the quadrilateral. */
6782 tspivot( topleft, toplshelle );
6783 tspivot( botleft, botlshelle );
6784 tspivot( botright, botrshelle );
6785 tspivot( topright, toprshelle );
6786 if ( toplshelle.sh == dummysh ) {
6787 tsdissolve( topright );
6788 }
6789 else {
6790 tsbond( topright, toplshelle );
6791 }
6792 if ( botlshelle.sh == dummysh ) {
6793 tsdissolve( topleft );
6794 }
6795 else {
6796 tsbond( topleft, botlshelle );
6797 }
6798 if ( botrshelle.sh == dummysh ) {
6799 tsdissolve( botleft );
6800 }
6801 else {
6802 tsbond( botleft, botrshelle );
6803 }
6804 if ( toprshelle.sh == dummysh ) {
6805 tsdissolve( botright );
6806 }
6807 else {
6808 tsbond( botright, toprshelle );
6809 }
6810 }
6811 /* New point assignments for the rotated quadrilateral. */
6812 setorg( horiz, farpoint );
6813 setdest( horiz, insertpoint );
6814 setapex( horiz, rightpoint );
6815 setorg( top, insertpoint );
6816 setdest( top, farpoint );
6817 setapex( top, leftpoint );
6818 for ( i = 0; i < eextras; i++ ) {
6819 /* Take the average of the two triangles' attributes. */
6820 attrib = (REAL)( 0.5 * ( elemattribute( top, i ) + elemattribute( horiz, i )));
6821 setelemattribute( top, i, attrib );
6822 setelemattribute( horiz, i, attrib );
6823 }
6824 if ( vararea ) {
6825 if (( areabound( top ) <= 0.0 ) || ( areabound( horiz ) <= 0.0 )) {
6826 area = -1.0;
6827 }
6828 else {
6829 /* Take the average of the two triangles' area constraints.    */
6830 /*   This prevents small area constraints from migrating a     */
6831 /*   long, long way from their original location due to flips. */
6832 area = (REAL)( 0.5 * ( areabound( top ) + areabound( horiz )));
6833 }
6834 setareabound( top, area );
6835 setareabound( horiz, area );
6836 }
6837 #ifdef
6838 SELF_CHECK
6839 if ( insertpoint != (point) NULL ) {
6840 if ( counterclockwise( leftpoint, insertpoint, rightpoint ) < 0.0 ) {
6841 printf( "Internal error in insertsite():\n" );
6842 printf( "  Clockwise triangle prior to edge flip (bottom).\n" );
6843 }
6844 /* The following test has been removed because constrainededge() */
6845 /*   sometimes generates inverted triangles that insertsite()    */
6846 /*   removes.                                                    */
6847 /*
6848             if (counterclockwise(rightpoint, farpoint, leftpoint) < 0.0) {
6849               printf("Internal error in insertsite():\n");
6850               printf("  Clockwise triangle prior to edge flip (top).\n");
6851             }
6852  */
6853 if ( counterclockwise( farpoint, leftpoint, insertpoint ) < 0.0 ) {
6854 printf( "Internal error in insertsite():\n" );
6855 printf( "  Clockwise triangle after edge flip (left).\n" );
6856 }
6857 if ( counterclockwise( insertpoint, rightpoint, farpoint ) < 0.0 ) {
6858 printf( "Internal error in insertsite():\n" );
6859 printf( "  Clockwise triangle after edge flip (right).\n" );
6860 }
6861 }
6862 #endif /* SELF_CHECK */
6863 if ( verbose > 2 ) {
6864 printf( "  Edge flip results in left " );
6865 lnextself( topleft );
6866 printtriangle( &topleft );
6867 printf( "  and right " );
6868 printtriangle( &horiz );
6869 }
6870 /* On the next iterations, consider the two edges that were  */
6871 /*   exposed (this is, are now visible to the newly inserted */
6872 /*   point) by the edge flip.                                */
6873 lprevself( horiz );
6874 leftpoint = farpoint;
6875 }
6876 }
6877 }
6878 if ( !doflip ) {
6879 /* The handle `horiz' is accepted as locally Delaunay. */
6880 #ifndef
6881 CDT_ONLY
6882 if ( triflaws ) {
6883 /* Check the triangle `horiz' for quality. */
6884 testtriangle( &horiz );
6885 }
6886 #endif /* not CDT_ONLY */
6887 /* Look for the next edge around the newly inserted point. */
6888 lnextself( horiz );
6889 sym( horiz, testtri );
6890 /* Check for finishing a complete revolution about the new point, or */
6891 /*   falling off the edge of the triangulation.  The latter will     */
6892 /*   happen when a point is inserted at a boundary.                  */
6893 if (( leftpoint == first ) || ( testtri.tri == dummytri )) {
6894 /* We're done.  Return a triangle whose origin is the new point. */
6895 lnext( horiz, *searchtri );
6896 lnext( horiz, recenttri );
6897 return success;
6898 }
6899 /* Finish finding the next edge around the newly inserted point. */
6900 lnext( testtri, horiz );
6901 rightpoint = leftpoint;
6902 dest( horiz, leftpoint );
6903 }
6904 }
6905 }
6906
6907 /*****************************************************************************/
6908 /*                                                                           */
6909 /*  triangulatepolygon()   Find the Delaunay triangulation of a polygon that */
6910 /*                         has a certain "nice" shape.  This includes the    */
6911 /*                         polygons that result from deletion of a point or  */
6912 /*                         insertion of a segment.                           */
6913 /*                                                                           */
6914 /*  This is a conceptually difficult routine.  The starting assumption is    */
6915 /*  that we have a polygon with n sides.  n - 1 of these sides are currently */
6916 /*  represented as edges in the mesh.  One side, called the "base", need not */
6917 /*  be.                                                                      */
6918 /*                                                                           */
6919 /*  Inside the polygon is a structure I call a "fan", consisting of n - 1    */
6920 /*  triangles that share a common origin.  For each of these triangles, the  */
6921 /*  edge opposite the origin is one of the sides of the polygon.  The        */
6922 /*  primary edge of each triangle is the edge directed from the origin to    */
6923 /*  the destination; note that this is not the same edge that is a side of   */
6924 /*  the polygon.  `firstedge' is the primary edge of the first triangle.     */
6925 /*  From there, the triangles follow in counterclockwise order about the     */
6926 /*  polygon, until `lastedge', the primary edge of the last triangle.        */
6927 /*  `firstedge' and `lastedge' are probably connected to other triangles     */
6928 /*  beyond the extremes of the fan, but their identity is not important, as  */
6929 /*  long as the fan remains connected to them.                               */
6930 /*                                                                           */
6931 /*  Imagine the polygon oriented so that its base is at the bottom.  This    */
6932 /*  puts `firstedge' on the far right, and `lastedge' on the far left.       */
6933 /*  The right vertex of the base is the destination of `firstedge', and the  */
6934 /*  left vertex of the base is the apex of `lastedge'.                       */
6935 /*                                                                           */
6936 /*  The challenge now is to find the right sequence of edge flips to         */
6937 /*  transform the fan into a Delaunay triangulation of the polygon.  Each    */
6938 /*  edge flip effectively removes one triangle from the fan, committing it   */
6939 /*  to the polygon.  The resulting polygon has one fewer edge.  If `doflip'  */
6940 /*  is set, the final flip will be performed, resulting in a fan of one      */
6941 /*  (useless?) triangle.  If `doflip' is not set, the final flip is not      */
6942 /*  performed, resulting in a fan of two triangles, and an unfinished        */
6943 /*  triangular polygon that is not yet filled out with a single triangle.    */
6944 /*  On completion of the routine, `lastedge' is the last remaining triangle, */
6945 /*  or the leftmost of the last two.                                         */
6946 /*                                                                           */
6947 /*  Although the flips are performed in the order described above, the       */
6948 /*  decisions about what flips to perform are made in precisely the reverse  */
6949 /*  order.  The recursive triangulatepolygon() procedure makes a decision,   */
6950 /*  uses up to two recursive calls to triangulate the "subproblems"          */
6951 /*  (polygons with fewer edges), and then performs an edge flip.             */
6952 /*                                                                           */
6953 /*  The "decision" it makes is which vertex of the polygon should be         */
6954 /*  connected to the base.  This decision is made by testing every possible  */
6955 /*  vertex.  Once the best vertex is found, the two edges that connect this  */
6956 /*  vertex to the base become the bases for two smaller polygons.  These     */
6957 /*  are triangulated recursively.  Unfortunately, this approach can take     */
6958 /*  O(n^2) time not only in the worst case, but in many common cases.  It's  */
6959 /*  rarely a big deal for point deletion, where n is rarely larger than ten, */
6960 /*  but it could be a big deal for segment insertion, especially if there's  */
6961 /*  a lot of long segments that each cut many triangles.  I ought to code    */
6962 /*  a faster algorithm some time.                                            */
6963 /*                                                                           */
6964 /*  The `edgecount' parameter is the number of sides of the polygon,         */
6965 /*  including its base.  `triflaws' is a flag that determines whether the    */
6966 /*  new triangles should be tested for quality, and enqueued if they are     */
6967 /*  bad.                                                                     */
6968 /*                                                                           */
6969 /*****************************************************************************/
6970
6971 void triangulatepolygon( firstedge, lastedge, edgecount, doflip, triflaws )
6972 struct triedge *firstedge;
6973 struct triedge *lastedge;
6974 int edgecount;
6975 int doflip;
6976 int triflaws;
6977 {
6978 struct triedge testtri;
6979 struct triedge besttri;
6980 struct triedge tempedge;
6981 point leftbasepoint, rightbasepoint;
6982 point testpoint;
6983 point bestpoint;
6984 int bestnumber;
6985 int i;
6986 triangle ptr; /* Temporary variable used by sym(), onext(), and oprev(). */
6987
6988 /* Identify the base vertices. */
6989 apex( *lastedge, leftbasepoint );
6990 dest( *firstedge, rightbasepoint );
6991 if ( verbose > 2 ) {
6992 printf( "  Triangulating interior polygon at edge\n" );
6993 printf( "    (%.12g, %.12g) (%.12g, %.12g)\n", leftbasepoint[0],
6994 leftbasepoint[1], rightbasepoint[0], rightbasepoint[1] );
6995 }
6996 /* Find the best vertex to connect the base to. */
6997 onext( *firstedge, besttri );
6998 dest( besttri, bestpoint );
6999 triedgecopy( besttri, testtri );
7000 bestnumber = 1;
7001 for ( i = 2; i <= edgecount - 2; i++ ) {
7002 onextself( testtri );
7003 dest( testtri, testpoint );
7004 /* Is this a better vertex? */
7005 if ( incircle( leftbasepoint, rightbasepoint, bestpoint, testpoint ) > 0.0 ) {
7006 triedgecopy( testtri, besttri );
7007 bestpoint = testpoint;
7008 bestnumber = i;
7009 }
7010 }
7011 if ( verbose > 2 ) {
7012 printf( "    Connecting edge to (%.12g, %.12g)\n", bestpoint[0],
7013 bestpoint[1] );
7014 }
7015 if ( bestnumber > 1 ) {
7016 /* Recursively triangulate the smaller polygon on the right. */
7017 oprev( besttri, tempedge );
7018 triangulatepolygon( firstedge, &tempedge, bestnumber + 1, 1, triflaws );
7019 }
7020 if ( bestnumber < edgecount - 2 ) {
7021 /* Recursively triangulate the smaller polygon on the left. */
7022 sym( besttri, tempedge );
7023 triangulatepolygon( &besttri, lastedge, edgecount - bestnumber, 1,
7024 triflaws );
7025 /* Find `besttri' again; it may have been lost to edge flips. */
7026 sym( tempedge, besttri );
7027 }
7028 if ( doflip ) {
7029 /* Do one final edge flip. */
7030 flip( &besttri );
7031 #ifndef
7032 CDT_ONLY
7033 if ( triflaws ) {
7034 /* Check the quality of the newly committed triangle. */
7035 sym( besttri, testtri );
7036 testtriangle( &testtri );
7037 }
7038 #endif /* not CDT_ONLY */
7039 }
7040 /* Return the base triangle. */
7041 triedgecopy( besttri, *lastedge );
7042 }
7043
7044 /*****************************************************************************/
7045 /*                                                                           */
7046 /*  deletesite()   Delete a vertex from a Delaunay triangulation, ensuring   */
7047 /*                 that the triangulation remains Delaunay.                  */
7048 /*                                                                           */
7049 /*  The origin of `deltri' is deleted.  The union of the triangles adjacent  */
7050 /*  to this point is a polygon, for which the Delaunay triangulation is      */
7051 /*  found.  Two triangles are removed from the mesh.                         */
7052 /*                                                                           */
7053 /*  Only interior points that do not lie on segments (shell edges) or        */
7054 /*  boundaries may be deleted.                                               */
7055 /*                                                                           */
7056 /*****************************************************************************/
7057
7058 #ifndef
7059 CDT_ONLY
7060
7061 void deletesite( deltri )
7062 struct triedge *deltri;
7063 {
7064 struct triedge countingtri;
7065 struct triedge firstedge, lastedge;
7066 struct triedge deltriright;
7067 struct triedge lefttri, righttri;
7068 struct triedge leftcasing, rightcasing;
7069 struct edge leftshelle, rightshelle;
7070 point delpoint;
7071 point neworg;
7072 int edgecount;
7073 triangle ptr; /* Temporary variable used by sym(), onext(), and oprev(). */
7074 shelle sptr;                    /* Temporary variable used by tspivot(). */
7075
7076 org( *deltri, delpoint );
7077 if ( verbose > 1 ) {
7078 printf( "  Deleting (%.12g, %.12g).\n", delpoint[0], delpoint[1] );
7079 }
7080 pointdealloc( delpoint );
7081
7082 /* Count the degree of the point being deleted. */
7083 onext( *deltri, countingtri );
7084 edgecount = 1;
7085 while ( !triedgeequal( *deltri, countingtri )) {
7086 #ifdef
7087 SELF_CHECK
7088 if ( countingtri.tri == dummytri ) {
7089 printf( "Internal error in deletesite():\n" );
7090 printf( "  Attempt to delete boundary point.\n" );
7091 internalerror();
7092 }
7093 #endif /* SELF_CHECK */
7094 edgecount++;
7095 onextself( countingtri );
7096 }
7097
7098 #ifdef
7099 SELF_CHECK
7100 if ( edgecount < 3 ) {
7101 printf( "Internal error in deletesite():\n  Point has degree %d.\n",
7102 edgecount );
7103 internalerror();
7104 }
7105 #endif /* SELF_CHECK */
7106 if ( edgecount > 3 ) {
7107 /* Triangulate the polygon defined by the union of all triangles */
7108 /*   adjacent to the point being deleted.  Check the quality of  */
7109 /*   the resulting triangles.                                    */
7110 onext( *deltri, firstedge );
7111 oprev( *deltri, lastedge );
7112 triangulatepolygon( &firstedge, &lastedge, edgecount, 0, !nobisect );
7113 }
7114 /* Splice out two triangles. */
7115 lprev( *deltri, deltriright );
7116 dnext( *deltri, lefttri );
7117 sym( lefttri, leftcasing );
7118 oprev( deltriright, righttri );
7119 sym( righttri, rightcasing );
7120 bond( *deltri, leftcasing );
7121 bond( deltriright, rightcasing );
7122 tspivot( lefttri, leftshelle );
7123 if ( leftshelle.sh != dummysh ) {
7124 tsbond( *deltri, leftshelle );
7125 }
7126 tspivot( righttri, rightshelle );
7127 if ( rightshelle.sh != dummysh ) {
7128 tsbond( deltriright, rightshelle );
7129 }
7130
7131 /* Set the new origin of `deltri' and check its quality. */
7132 org( lefttri, neworg );
7133 setorg( *deltri, neworg );
7134 if ( !nobisect ) {
7135 testtriangle( deltri );
7136 }
7137
7138 /* Delete the two spliced-out triangles. */
7139 triangledealloc( lefttri.tri );
7140 triangledealloc( righttri.tri );
7141 }
7142
7143 #endif /* not CDT_ONLY */
7144
7145 /**                                                                         **/
7146 /**                                                                         **/
7147 /********* Mesh transformation routines end here                     *********/
7148
7149 /********* Divide-and-conquer Delaunay triangulation begins here     *********/
7150 /**                                                                         **/
7151 /**                                                                         **/
7152
7153 /*****************************************************************************/
7154 /*                                                                           */
7155 /*  The divide-and-conquer bounding box                                      */
7156 /*                                                                           */
7157 /*  I originally implemented the divide-and-conquer and incremental Delaunay */
7158 /*  triangulations using the edge-based data structure presented by Guibas   */
7159 /*  and Stolfi.  Switching to a triangle-based data structure doubled the    */
7160 /*  speed.  However, I had to think of a few extra tricks to maintain the    */
7161 /*  elegance of the original algorithms.                                     */
7162 /*                                                                           */
7163 /*  The "bounding box" used by my variant of the divide-and-conquer          */
7164 /*  algorithm uses one triangle for each edge of the convex hull of the      */
7165 /*  triangulation.  These bounding triangles all share a common apical       */
7166 /*  vertex, which is represented by NULL and which represents nothing.       */
7167 /*  The bounding triangles are linked in a circular fan about this NULL      */
7168 /*  vertex, and the edges on the convex hull of the triangulation appear     */
7169 /*  opposite the NULL vertex.  You might find it easiest to imagine that     */
7170 /*  the NULL vertex is a point in 3D space behind the center of the          */
7171 /*  triangulation, and that the bounding triangles form a sort of cone.      */
7172 /*                                                                           */
7173 /*  This bounding box makes it easy to represent degenerate cases.  For      */
7174 /*  instance, the triangulation of two vertices is a single edge.  This edge */
7175 /*  is represented by two bounding box triangles, one on each "side" of the  */
7176 /*  edge.  These triangles are also linked together in a fan about the NULL  */
7177 /*  vertex.                                                                  */
7178 /*                                                                           */
7179 /*  The bounding box also makes it easy to traverse the convex hull, as the  */
7180 /*  divide-and-conquer algorithm needs to do.                                */
7181 /*                                                                           */
7182 /*****************************************************************************/
7183
7184 /*****************************************************************************/
7185 /*                                                                           */
7186 /*  pointsort()   Sort an array of points by x-coordinate, using the         */
7187 /*                y-coordinate as a secondary key.                           */
7188 /*                                                                           */
7189 /*  Uses quicksort.  Randomized O(n log n) time.  No, I did not make any of  */
7190 /*  the usual quicksort mistakes.                                            */
7191 /*                                                                           */
7192 /*****************************************************************************/
7193
7194 void pointsort( sortarray, arraysize )
7195 point * sortarray;
7196 int arraysize;
7197 {
7198 int left, right;
7199 int pivot;
7200 REAL pivotx, pivoty;
7201 point temp;
7202
7203 if ( arraysize == 2 ) {
7204 /* Recursive base case. */
7205 if (( sortarray[0][0] > sortarray[1][0] ) ||
7206 (( sortarray[0][0] == sortarray[1][0] ) &&
7207 ( sortarray[0][1] > sortarray[1][1] ))) {
7208 temp = sortarray[1];
7209 sortarray[1] = sortarray[0];
7210 sortarray[0] = temp;
7211 }
7212 return;
7213 }
7214 /* Choose a random pivot to split the array. */
7215 pivot = (int) randomnation( arraysize );
7216 pivotx = sortarray[pivot][0];
7217 pivoty = sortarray[pivot][1];
7218 /* Split the array. */
7219 left = -1;
7220 right = arraysize;
7221 while ( left < right ) {
7222 /* Search for a point whose x-coordinate is too large for the left. */
7223 do {
7224 left++;
7225 } while (( left <= right ) && (( sortarray[left][0] < pivotx ) ||
7226 (( sortarray[left][0] == pivotx ) &&
7227 ( sortarray[left][1] < pivoty ))));
7228 /* Search for a point whose x-coordinate is too small for the right. */
7229 do {
7230 right--;
7231 } while (( left <= right ) && (( sortarray[right][0] > pivotx ) ||
7232 (( sortarray[right][0] == pivotx ) &&
7233 ( sortarray[right][1] > pivoty ))));
7234 if ( left < right ) {
7235 /* Swap the left and right points. */
7236 temp = sortarray[left];
7237 sortarray[left] = sortarray[right];
7238 sortarray[right] = temp;
7239 }
7240 }
7241 if ( left > 1 ) {
7242 /* Recursively sort the left subset. */
7243 pointsort( sortarray, left );
7244 }
7245 if ( right < arraysize - 2 ) {
7246 /* Recursively sort the right subset. */
7247 pointsort( &sortarray[right + 1], arraysize - right - 1 );
7248 }
7249 }
7250
7251 /*****************************************************************************/
7252 /*                                                                           */
7253 /*  pointmedian()   An order statistic algorithm, almost.  Shuffles an array */
7254 /*                  of points so that the first `median' points occur        */
7255 /*                  lexicographically before the remaining points.           */
7256 /*                                                                           */
7257 /*  Uses the x-coordinate as the primary key if axis == 0; the y-coordinate  */
7258 /*  if axis == 1.  Very similar to the pointsort() procedure, but runs in    */
7259 /*  randomized linear time.                                                  */
7260 /*                                                                           */
7261 /*****************************************************************************/
7262
7263 void pointmedian( sortarray, arraysize, median, axis )
7264 point * sortarray;
7265 int arraysize;
7266 int median;
7267 int axis;
7268 {
7269 int left, right;
7270 int pivot;
7271 REAL pivot1, pivot2;
7272 point temp;
7273
7274 if ( arraysize == 2 ) {
7275 /* Recursive base case. */
7276 if (( sortarray[0][axis] > sortarray[1][axis] ) ||
7277 (( sortarray[0][axis] == sortarray[1][axis] ) &&
7278 ( sortarray[0][1 - axis] > sortarray[1][1 - axis] ))) {
7279 temp = sortarray[1];
7280 sortarray[1] = sortarray[0];
7281 sortarray[0] = temp;
7282 }
7283 return;
7284 }
7285 /* Choose a random pivot to split the array. */
7286 pivot = (int) randomnation( arraysize );
7287 pivot1 = sortarray[pivot][axis];
7288 pivot2 = sortarray[pivot][1 - axis];
7289 /* Split the array. */
7290 left = -1;
7291 right = arraysize;
7292 while ( left < right ) {
7293 /* Search for a point whose x-coordinate is too large for the left. */
7294 do {
7295 left++;
7296 } while (( left <= right ) && (( sortarray[left][axis] < pivot1 ) ||
7297 (( sortarray[left][axis] == pivot1 ) &&
7298 ( sortarray[left][1 - axis] < pivot2 ))));
7299 /* Search for a point whose x-coordinate is too small for the right. */
7300 do {
7301 right--;
7302 } while (( left <= right ) && (( sortarray[right][axis] > pivot1 ) ||
7303 (( sortarray[right][axis] == pivot1 ) &&
7304 ( sortarray[right][1 - axis] > pivot2 ))));
7305 if ( left < right ) {
7306 /* Swap the left and right points. */
7307 temp = sortarray[left];
7308 sortarray[left] = sortarray[right];
7309 sortarray[right] = temp;
7310 }
7311 }
7312 /* Unlike in pointsort(), at most one of the following */
7313 /*   conditionals is true.                             */
7314 if ( left > median ) {
7315 /* Recursively shuffle the left subset. */
7316 pointmedian( sortarray, left, median, axis );
7317 }
7318 if ( right < median - 1 ) {
7319 /* Recursively shuffle the right subset. */
7320 pointmedian( &sortarray[right + 1], arraysize - right - 1,
7321 median - right - 1, axis );
7322 }
7323 }
7324
7325 /*****************************************************************************/
7326 /*                                                                           */
7327 /*  alternateaxes()   Sorts the points as appropriate for the divide-and-    */
7328 /*                    conquer algorithm with alternating cuts.               */
7329 /*                                                                           */
7330 /*  Partitions by x-coordinate if axis == 0; by y-coordinate if axis == 1.   */
7331 /*  For the base case, subsets containing only two or three points are       */
7332 /*  always sorted by x-coordinate.                                           */
7333 /*                                                                           */
7334 /*****************************************************************************/
7335
7336 void alternateaxes( sortarray, arraysize, axis )
7337 point * sortarray;
7338 int arraysize;
7339 int axis;
7340 {
7341 int divider;
7342
7343 divider = arraysize >> 1;
7344 if ( arraysize <= 3 ) {
7345 /* Recursive base case:  subsets of two or three points will be      */
7346 /*   handled specially, and should always be sorted by x-coordinate. */
7347 axis = 0;
7348 }
7349 /* Partition with a horizontal or vertical cut. */
7350 pointmedian( sortarray, arraysize, divider, axis );
7351 /* Recursively partition the subsets with a cross cut. */
7352 if ( arraysize - divider >= 2 ) {
7353 if ( divider >= 2 ) {
7354 alternateaxes( sortarray, divider, 1 - axis );
7355 }
7356 alternateaxes( &sortarray[divider], arraysize - divider, 1 - axis );
7357 }
7358 }
7359
7360 /*****************************************************************************/
7361 /*                                                                           */
7362 /*  mergehulls()   Merge two adjacent Delaunay triangulations into a         */
7363 /*                 single Delaunay triangulation.                            */
7364 /*                                                                           */
7365 /*  This is similar to the algorithm given by Guibas and Stolfi, but uses    */
7366 /*  a triangle-based, rather than edge-based, data structure.                */
7367 /*                                                                           */
7368 /*  The algorithm walks up the gap between the two triangulations, knitting  */
7369 /*  them together.  As they are merged, some of their bounding triangles     */
7370 /*  are converted into real triangles of the triangulation.  The procedure   */
7371 /*  pulls each hull's bounding triangles apart, then knits them together     */
7372 /*  like the teeth of two gears.  The Delaunay property determines, at each  */
7373 /*  step, whether the next "tooth" is a bounding triangle of the left hull   */
7374 /*  or the right.  When a bounding triangle becomes real, its apex is        */
7375 /*  changed from NULL to a real point.                                       */
7376 /*                                                                           */
7377 /*  Only two new triangles need to be allocated.  These become new bounding  */
7378 /*  triangles at the top and bottom of the seam.  They are used to connect   */
7379 /*  the remaining bounding triangles (those that have not been converted     */
7380 /*  into real triangles) into a single fan.                                  */
7381 /*                                                                           */
7382 /*  On entry, `farleft' and `innerleft' are bounding triangles of the left   */
7383 /*  triangulation.  The origin of `farleft' is the leftmost vertex, and      */
7384 /*  the destination of `innerleft' is the rightmost vertex of the            */
7385 /*  triangulation.  Similarly, `innerright' and `farright' are bounding      */
7386 /*  triangles of the right triangulation.  The origin of `innerright' and    */
7387 /*  destination of `farright' are the leftmost and rightmost vertices.       */
7388 /*                                                                           */
7389 /*  On completion, the origin of `farleft' is the leftmost vertex of the     */
7390 /*  merged triangulation, and the destination of `farright' is the rightmost */
7391 /*  vertex.                                                                  */
7392 /*                                                                           */
7393 /*****************************************************************************/
7394
7395 void mergehulls( farleft, innerleft, innerright, farright, axis )
7396 struct triedge *farleft;
7397 struct triedge *innerleft;
7398 struct triedge *innerright;
7399 struct triedge *farright;
7400 int axis;
7401 {
7402 struct triedge leftcand, rightcand;
7403 struct triedge baseedge;
7404 struct triedge nextedge;
7405 struct triedge sidecasing, topcasing, outercasing;
7406 struct triedge checkedge;
7407 point innerleftdest;
7408 point innerrightorg;
7409 point innerleftapex, innerrightapex;
7410 point farleftpt, farrightpt;
7411 point farleftapex, farrightapex;
7412 point lowerleft, lowerright;
7413 point upperleft, upperright;
7414 point nextapex;
7415 point checkvertex;
7416 int changemade;
7417 int badedge;
7418 int leftfinished, rightfinished;
7419 triangle ptr;                       /* Temporary variable used by sym(). */
7420
7421 dest( *innerleft, innerleftdest );
7422 apex( *innerleft, innerleftapex );
7423 org( *innerright, innerrightorg );
7424 apex( *innerright, innerrightapex );
7425 /* Special treatment for horizontal cuts. */
7426 if ( dwyer && ( axis == 1 )) {
7427 org( *farleft, farleftpt );
7428 apex( *farleft, farleftapex );
7429 dest( *farright, farrightpt );
7430 apex( *farright, farrightapex );
7431 /* The pointers to the extremal points are shifted to point to the */
7432 /*   topmost and bottommost point of each hull, rather than the    */
7433 /*   leftmost and rightmost points.                                */
7434 while ( farleftapex[1] < farleftpt[1] ) {
7435 lnextself( *farleft );
7436 symself( *farleft );
7437 farleftpt = farleftapex;
7438 apex( *farleft, farleftapex );
7439 }
7440 sym( *innerleft, checkedge );
7441 apex( checkedge, checkvertex );
7442 while ( checkvertex[1] > innerleftdest[1] ) {
7443 lnext( checkedge, *innerleft );
7444 innerleftapex = innerleftdest;
7445 innerleftdest = checkvertex;
7446 sym( *innerleft, checkedge );
7447 apex( checkedge, checkvertex );
7448 }
7449 while ( innerrightapex[1] < innerrightorg[1] ) {
7450 lnextself( *innerright );
7451 symself( *innerright );
7452 innerrightorg = innerrightapex;
7453 apex( *innerright, innerrightapex );
7454 }
7455 sym( *farright, checkedge );
7456 apex( checkedge, checkvertex );
7457 while ( checkvertex[1] > farrightpt[1] ) {
7458 lnext( checkedge, *farright );
7459 farrightapex = farrightpt;
7460 farrightpt = checkvertex;
7461 sym( *farright, checkedge );
7462 apex( checkedge, checkvertex );
7463 }
7464 }
7465 /* Find a line tangent to and below both hulls. */
7466 do {
7467 changemade = 0;
7468 /* Make innerleftdest the "bottommost" point of the left hull. */
7469 if ( counterclockwise( innerleftdest, innerleftapex, innerrightorg ) > 0.0 ) {
7470 lprevself( *innerleft );
7471 symself( *innerleft );
7472 innerleftdest = innerleftapex;
7473 apex( *innerleft, innerleftapex );
7474 changemade = 1;
7475 }
7476 /* Make innerrightorg the "bottommost" point of the right hull. */
7477 if ( counterclockwise( innerrightapex, innerrightorg, innerleftdest ) > 0.0 ) {
7478 lnextself( *innerright );
7479 symself( *innerright );
7480 innerrightorg = innerrightapex;
7481 apex( *innerright, innerrightapex );
7482 changemade = 1;
7483 }
7484 } while ( changemade );
7485 /* Find the two candidates to be the next "gear tooth". */
7486 sym( *innerleft, leftcand );
7487 sym( *innerright, rightcand );
7488 /* Create the bottom new bounding triangle. */
7489 maketriangle( &baseedge );
7490 /* Connect it to the bounding boxes of the left and right triangulations. */
7491 bond( baseedge, *innerleft );
7492 lnextself( baseedge );
7493 bond( baseedge, *innerright );
7494 lnextself( baseedge );
7495 setorg( baseedge, innerrightorg );
7496 setdest( baseedge, innerleftdest );
7497 /* Apex is intentionally left NULL. */
7498 if ( verbose > 2 ) {
7499 printf( "  Creating base bounding " );
7500 printtriangle( &baseedge );
7501 }
7502 /* Fix the extreme triangles if necessary. */
7503 org( *farleft, farleftpt );
7504 if ( innerleftdest == farleftpt ) {
7505 lnext( baseedge, *farleft );
7506 }
7507 dest( *farright, farrightpt );
7508 if ( innerrightorg == farrightpt ) {
7509 lprev( baseedge, *farright );
7510 }
7511 /* The vertices of the current knitting edge. */
7512 lowerleft = innerleftdest;
7513 lowerright = innerrightorg;
7514 /* The candidate vertices for knitting. */
7515 apex( leftcand, upperleft );
7516 apex( rightcand, upperright );
7517 /* Walk up the gap between the two triangulations, knitting them together. */
7518 while ( 1 ) {
7519 /* Have we reached the top?  (This isn't quite the right question,       */
7520 /*   because even though the left triangulation might seem finished now, */
7521 /*   moving up on the right triangulation might reveal a new point of    */
7522 /*   the left triangulation.  And vice-versa.)                           */
7523 leftfinished = counterclockwise( upperleft, lowerleft, lowerright ) <= 0.0;
7524 rightfinished = counterclockwise( upperright, lowerleft, lowerright ) <= 0.0;
7525 if ( leftfinished && rightfinished ) {
7526 /* Create the top new bounding triangle. */
7527 maketriangle( &nextedge );
7528 setorg( nextedge, lowerleft );
7529 setdest( nextedge, lowerright );
7530 /* Apex is intentionally left NULL. */
7531 /* Connect it to the bounding boxes of the two triangulations. */
7532 bond( nextedge, baseedge );
7533 lnextself( nextedge );
7534 bond( nextedge, rightcand );
7535 lnextself( nextedge );
7536 bond( nextedge, leftcand );
7537 if ( verbose > 2 ) {
7538 printf( "  Creating top bounding " );
7539 printtriangle( &baseedge );
7540 }
7541 /* Special treatment for horizontal cuts. */
7542 if ( dwyer && ( axis == 1 )) {
7543 org( *farleft, farleftpt );
7544 apex( *farleft, farleftapex );
7545 dest( *farright, farrightpt );
7546 apex( *farright, farrightapex );
7547 sym( *farleft, checkedge );
7548 apex( checkedge, checkvertex );
7549 /* The pointers to the extremal points are restored to the leftmost */
7550 /*   and rightmost points (rather than topmost and bottommost).     */
7551 while ( checkvertex[0] < farleftpt[0] ) {
7552 lprev( checkedge, *farleft );
7553 farleftapex = farleftpt;
7554 farleftpt = checkvertex;
7555 sym( *farleft, checkedge );
7556 apex( checkedge, checkvertex );
7557 }
7558 while ( farrightapex[0] > farrightpt[0] ) {
7559 lprevself( *farright );
7560 symself( *farright );
7561 farrightpt = farrightapex;
7562 apex( *farright, farrightapex );
7563 }
7564 }
7565 return;
7566 }
7567 /* Consider eliminating edges from the left triangulation. */
7568 if ( !leftfinished ) {
7569 /* What vertex would be exposed if an edge were deleted? */
7570 lprev( leftcand, nextedge );
7571 symself( nextedge );
7572 apex( nextedge, nextapex );
7573 /* If nextapex is NULL, then no vertex would be exposed; the */
7574 /*   triangulation would have been eaten right through.      */
7575 if ( nextapex != (point) NULL ) {
7576 /* Check whether the edge is Delaunay. */
7577 badedge = incircle( lowerleft, lowerright, upperleft, nextapex ) > 0.0;
7578 while ( badedge ) {
7579 /* Eliminate the edge with an edge flip.  As a result, the    */
7580 /*   left triangulation will have one more boundary triangle. */
7581 lnextself( nextedge );
7582 sym( nextedge, topcasing );
7583 lnextself( nextedge );
7584 sym( nextedge, sidecasing );
7585 bond( nextedge, topcasing );
7586 bond( leftcand, sidecasing );
7587 lnextself( leftcand );
7588 sym( leftcand, outercasing );
7589 lprevself( nextedge );
7590 bond( nextedge, outercasing );
7591 /* Correct the vertices to reflect the edge flip. */
7592 setorg( leftcand, lowerleft );
7593 setdest( leftcand, NULL );
7594 setapex( leftcand, nextapex );
7595 setorg( nextedge, NULL );
7596 setdest( nextedge, upperleft );
7597 setapex( nextedge, nextapex );
7598 /* Consider the newly exposed vertex. */
7599 upperleft = nextapex;
7600 /* What vertex would be exposed if another edge were deleted? */
7601 triedgecopy( sidecasing, nextedge );
7602 apex( nextedge, nextapex );
7603 if ( nextapex != (point) NULL ) {
7604 /* Check whether the edge is Delaunay. */
7605 badedge = incircle( lowerleft, lowerright, upperleft, nextapex )
7606 > 0.0;
7607 }
7608 else {
7609 /* Avoid eating right through the triangulation. */
7610 badedge = 0;
7611 }
7612 }
7613 }
7614 }
7615 /* Consider eliminating edges from the right triangulation. */
7616 if ( !rightfinished ) {
7617 /* What vertex would be exposed if an edge were deleted? */
7618 lnext( rightcand, nextedge );
7619 symself( nextedge );
7620 apex( nextedge, nextapex );
7621 /* If nextapex is NULL, then no vertex would be exposed; the */
7622 /*   triangulation would have been eaten right through.      */
7623 if ( nextapex != (point) NULL ) {
7624 /* Check whether the edge is Delaunay. */
7625 badedge = incircle( lowerleft, lowerright, upperright, nextapex ) > 0.0;
7626 while ( badedge ) {
7627 /* Eliminate the edge with an edge flip.  As a result, the     */
7628 /*   right triangulation will have one more boundary triangle. */
7629 lprevself( nextedge );
7630 sym( nextedge, topcasing );
7631 lprevself( nextedge );
7632 sym( nextedge, sidecasing );
7633 bond( nextedge, topcasing );
7634 bond( rightcand, sidecasing );
7635 lprevself( rightcand );
7636 sym( rightcand, outercasing );
7637 lnextself( nextedge );
7638 bond( nextedge, outercasing );
7639 /* Correct the vertices to reflect the edge flip. */
7640 setorg( rightcand, NULL );
7641 setdest( rightcand, lowerright );
7642 setapex( rightcand, nextapex );
7643 setorg( nextedge, upperright );
7644 setdest( nextedge, NULL );
7645 setapex( nextedge, nextapex );
7646 /* Consider the newly exposed vertex. */
7647 upperright = nextapex;
7648 /* What vertex would be exposed if another edge were deleted? */
7649 triedgecopy( sidecasing, nextedge );
7650 apex( nextedge, nextapex );
7651 if ( nextapex != (point) NULL ) {
7652 /* Check whether the edge is Delaunay. */
7653 badedge = incircle( lowerleft, lowerright, upperright, nextapex )
7654 > 0.0;
7655 }
7656 else {
7657 /* Avoid eating right through the triangulation. */
7658 badedge = 0;
7659 }
7660 }
7661 }
7662 }
7663 if ( leftfinished || ( !rightfinished &&
7664 ( incircle( upperleft, lowerleft, lowerright, upperright ) > 0.0 ))) {
7665 /* Knit the triangulations, adding an edge from `lowerleft' */
7666 /*   to `upperright'.                                       */
7667 bond( baseedge, rightcand );
7668 lprev( rightcand, baseedge );
7669 setdest( baseedge, lowerleft );
7670 lowerright = upperright;
7671 sym( baseedge, rightcand );
7672 apex( rightcand, upperright );
7673 }
7674 else {
7675 /* Knit the triangulations, adding an edge from `upperleft' */
7676 /*   to `lowerright'.                                       */
7677 bond( baseedge, leftcand );
7678 lnext( leftcand, baseedge );
7679 setorg( baseedge, lowerright );
7680 lowerleft = upperleft;
7681 sym( baseedge, leftcand );
7682 apex( leftcand, upperleft );
7683 }
7684 if ( verbose > 2 ) {
7685 printf( "  Connecting " );
7686 printtriangle( &baseedge );
7687 }
7688 }
7689 }
7690
7691 /*****************************************************************************/
7692 /*                                                                           */
7693 /*  divconqrecurse()   Recursively form a Delaunay triangulation by the      */
7694 /*                     divide-and-conquer method.                            */
7695 /*                                                                           */
7696 /*  Recursively breaks down the problem into smaller pieces, which are       */
7697 /*  knitted together by mergehulls().  The base cases (problems of two or    */
7698 /*  three points) are handled specially here.                                */
7699 /*                                                                           */
7700 /*  On completion, `farleft' and `farright' are bounding triangles such that */
7701 /*  the origin of `farleft' is the leftmost vertex (breaking ties by         */
7702 /*  choosing the highest leftmost vertex), and the destination of            */
7703 /*  `farright' is the rightmost vertex (breaking ties by choosing the        */
7704 /*  lowest rightmost vertex).                                                */
7705 /*                                                                           */
7706 /*****************************************************************************/
7707
7708 void divconqrecurse( sortarray, vertices, axis, farleft, farright )
7709 point * sortarray;
7710 int vertices;
7711 int axis;
7712 struct triedge *farleft;
7713 struct triedge *farright;
7714 {
7715 struct triedge midtri, tri1, tri2, tri3;
7716 struct triedge innerleft, innerright;
7717 REAL area;
7718 int divider;
7719
7720 if ( verbose > 2 ) {
7721 printf( "  Triangulating %d points.\n", vertices );
7722 }
7723 if ( vertices == 2 ) {
7724 /* The triangulation of two vertices is an edge.  An edge is */
7725 /*   represented by two bounding triangles.                  */
7726 maketriangle( farleft );
7727 setorg( *farleft, sortarray[0] );
7728 setdest( *farleft, sortarray[1] );
7729 /* The apex is intentionally left NULL. */
7730 maketriangle( farright );
7731 setorg( *farright, sortarray[1] );
7732 setdest( *farright, sortarray[0] );
7733 /* The apex is intentionally left NULL. */
7734 bond( *farleft, *farright );
7735 lprevself( *farleft );
7736 lnextself( *farright );
7737 bond( *farleft, *farright );
7738 lprevself( *farleft );
7739 lnextself( *farright );
7740 bond( *farleft, *farright );
7741 if ( verbose > 2 ) {
7742 printf( "  Creating " );
7743 printtriangle( farleft );
7744 printf( "  Creating " );
7745 printtriangle( farright );
7746 }
7747 /* Ensure that the origin of `farleft' is sortarray[0]. */
7748 lprev( *farright, *farleft );
7749 return;
7750 }
7751 else if ( vertices == 3 ) {
7752 /* The triangulation of three vertices is either a triangle (with */
7753 /*   three bounding triangles) or two edges (with four bounding   */
7754 /*   triangles).  In either case, four triangles are created.     */
7755 maketriangle( &midtri );
7756 maketriangle( &tri1 );
7757 maketriangle( &tri2 );
7758 maketriangle( &tri3 );
7759 area = counterclockwise( sortarray[0], sortarray[1], sortarray[2] );
7760 if ( area == 0.0 ) {
7761 /* Three collinear points; the triangulation is two edges. */
7762 setorg( midtri, sortarray[0] );
7763 setdest( midtri, sortarray[1] );
7764 setorg( tri1, sortarray[1] );
7765 setdest( tri1, sortarray[0] );
7766 setorg( tri2, sortarray[2] );
7767 setdest( tri2, sortarray[1] );
7768 setorg( tri3, sortarray[1] );
7769 setdest( tri3, sortarray[2] );
7770 /* All apices are intentionally left NULL. */
7771 bond( midtri, tri1 );
7772 bond( tri2, tri3 );
7773 lnextself( midtri );
7774 lprevself( tri1 );
7775 lnextself( tri2 );
7776 lprevself( tri3 );
7777 bond( midtri, tri3 );
7778 bond( tri1, tri2 );
7779 lnextself( midtri );
7780 lprevself( tri1 );
7781 lnextself( tri2 );
7782 lprevself( tri3 );
7783 bond( midtri, tri1 );
7784 bond( tri2, tri3 );
7785 /* Ensure that the origin of `farleft' is sortarray[0]. */
7786 triedgecopy( tri1, *farleft );
7787 /* Ensure that the destination of `farright' is sortarray[2]. */
7788 triedgecopy( tri2, *farright );
7789 }
7790 else {
7791 /* The three points are not collinear; the triangulation is one */
7792 /*   triangle, namely `midtri'.                                 */
7793 setorg( midtri, sortarray[0] );
7794 setdest( tri1, sortarray[0] );
7795 setorg( tri3, sortarray[0] );
7796 /* Apices of tri1, tri2, and tri3 are left NULL. */
7797 if ( area > 0.0 ) {
7798 /* The vertices are in counterclockwise order. */
7799 setdest( midtri, sortarray[1] );
7800 setorg( tri1, sortarray[1] );
7801 setdest( tri2, sortarray[1] );
7802 setapex( midtri, sortarray[2] );
7803 setorg( tri2, sortarray[2] );
7804 setdest( tri3, sortarray[2] );
7805 }
7806 else {
7807 /* The vertices are in clockwise order. */
7808 setdest( midtri, sortarray[2] );
7809 setorg( tri1, sortarray[2] );
7810 setdest( tri2, sortarray[2] );
7811 setapex( midtri, sortarray[1] );
7812 setorg( tri2, sortarray[1] );
7813 setdest( tri3, sortarray[1] );
7814 }
7815 /* The topology does not depend on how the vertices are ordered. */
7816 bond( midtri, tri1 );
7817 lnextself( midtri );
7818 bond( midtri, tri2 );
7819 lnextself( midtri );
7820 bond( midtri, tri3 );
7821 lprevself( tri1 );
7822 lnextself( tri2 );
7823 bond( tri1, tri2 );
7824 lprevself( tri1 );
7825 lprevself( tri3 );
7826 bond( tri1, tri3 );
7827 lnextself( tri2 );
7828 lprevself( tri3 );
7829 bond( tri2, tri3 );
7830 /* Ensure that the origin of `farleft' is sortarray[0]. */
7831 triedgecopy( tri1, *farleft );
7832 /* Ensure that the destination of `farright' is sortarray[2]. */
7833 if ( area > 0.0 ) {
7834 triedgecopy( tri2, *farright );
7835 }
7836 else {
7837 lnext( *farleft, *farright );
7838 }
7839 }
7840 if ( verbose > 2 ) {
7841 printf( "  Creating " );
7842 printtriangle( &midtri );
7843 printf( "  Creating " );
7844 printtriangle( &tri1 );
7845 printf( "  Creating " );
7846 printtriangle( &tri2 );
7847 printf( "  Creating " );
7848 printtriangle( &tri3 );
7849 }
7850 return;
7851 }
7852 else {
7853 /* Split the vertices in half. */
7854 divider = vertices >> 1;
7855 /* Recursively triangulate each half. */
7856 divconqrecurse( sortarray, divider, 1 - axis, farleft, &innerleft );
7857 divconqrecurse( &sortarray[divider], vertices - divider, 1 - axis,
7858 &innerright, farright );
7859 if ( verbose > 1 ) {
7860 printf( "  Joining triangulations with %d and %d vertices.\n", divider,
7861 vertices - divider );
7862 }
7863 /* Merge the two triangulations into one. */
7864 mergehulls( farleft, &innerleft, &innerright, farright, axis );
7865 }
7866 }
7867
7868 long removeghosts( startghost )
7869 struct triedge *startghost;
7870 {
7871 struct triedge searchedge;
7872 struct triedge dissolveedge;
7873 struct triedge deadtri;
7874 point markorg;
7875 long hullsize;
7876 triangle ptr;                       /* Temporary variable used by sym(). */
7877
7878 if ( verbose ) {
7879 printf( "  Removing ghost triangles.\n" );
7880 }
7881 /* Find an edge on the convex hull to start point location from. */
7882 lprev( *startghost, searchedge );
7883 symself( searchedge );
7884 dummytri[0] = encode( searchedge );
7885 /* Remove the bounding box and count the convex hull edges. */
7886 triedgecopy( *startghost, dissolveedge );
7887 hullsize = 0;
7888 do {
7889 hullsize++;
7890 lnext( dissolveedge, deadtri );
7891 lprevself( dissolveedge );
7892 symself( dissolveedge );
7893 /* If no PSLG is involved, set the boundary markers of all the points */
7894 /*   on the convex hull.  If a PSLG is used, this step is done later. */
7895 if ( !poly ) {
7896 /* Watch out for the case where all the input points are collinear. */
7897 if ( dissolveedge.tri != dummytri ) {
7898 org( dissolveedge, markorg );
7899 if ( pointmark( markorg ) == 0 ) {
7900 setpointmark( markorg, 1 );
7901 }
7902 }
7903 }
7904 /* Remove a bounding triangle from a convex hull triangle. */
7905 dissolve( dissolveedge );
7906 /* Find the next bounding triangle. */
7907 sym( deadtri, dissolveedge );
7908 /* Delete the bounding triangle. */
7909 triangledealloc( deadtri.tri );
7910 } while ( !triedgeequal( dissolveedge, *startghost ));
7911 return hullsize;
7912 }
7913
7914 /*****************************************************************************/
7915 /*                                                                           */
7916 /*  divconqdelaunay()   Form a Delaunay triangulation by the divide-and-     */
7917 /*                      conquer method.                                      */
7918 /*                                                                           */
7919 /*  Sorts the points, calls a recursive procedure to triangulate them, and   */
7920 /*  removes the bounding box, setting boundary markers as appropriate.       */
7921 /*                                                                           */
7922 /*****************************************************************************/
7923
7924 long divconqdelaunay(){
7925 point *sortarray;
7926 struct triedge hullleft, hullright;
7927 int divider;
7928 int i, j;
7929
7930 /* Allocate an array of pointers to points for sorting. */
7931 sortarray = (point *) malloc( inpoints * sizeof( point ));
7932 if ( sortarray == (point *) NULL ) {
7933 printf( "Error:  Out of memory.\n" );
7934 exit( 1 );
7935 }
7936 traversalinit( &points );
7937 for ( i = 0; i < inpoints; i++ ) {
7938 sortarray[i] = pointtraverse();
7939 }
7940 if ( verbose ) {
7941 printf( "  Sorting points.\n" );
7942 }
7943 /* Sort the points. */
7944 pointsort( sortarray, inpoints );
7945 /* Discard duplicate points, which can really mess up the algorithm. */
7946 i = 0;
7947 for ( j = 1; j < inpoints; j++ ) {
7948 if (( sortarray[i][0] == sortarray[j][0] )
7949 && ( sortarray[i][1] == sortarray[j][1] )) {
7950 if ( !quiet ) {
7951 printf(
7952 "Warning:  A duplicate point at (%.12g, %.12g) appeared and was ignored.\n",
7953 sortarray[j][0], sortarray[j][1] );
7954 }
7955 /*  Commented out - would eliminate point from output .node file, but causes
7956     a failure if some segment has this point as an endpoint.
7957       setpointmark(sortarray[j], DEADPOINT);
7958  */
7959 }
7960 else {
7961 i++;
7962 sortarray[i] = sortarray[j];
7963 }
7964 }
7965 i++;
7966 if ( dwyer ) {
7967 /* Re-sort the array of points to accommodate alternating cuts. */
7968 divider = i >> 1;
7969 if ( i - divider >= 2 ) {
7970 if ( divider >= 2 ) {
7971 alternateaxes( sortarray, divider, 1 );
7972 }
7973 alternateaxes( &sortarray[divider], i - divider, 1 );
7974 }
7975 }
7976 if ( verbose ) {
7977 printf( "  Forming triangulation.\n" );
7978 }
7979 /* Form the Delaunay triangulation. */
7980 divconqrecurse( sortarray, i, 0, &hullleft, &hullright );
7981 free( sortarray );
7982
7983 return removeghosts( &hullleft );
7984 }
7985
7986 /**                                                                         **/
7987 /**                                                                         **/
7988 /********* Divide-and-conquer Delaunay triangulation ends here       *********/
7989
7990 /********* Incremental Delaunay triangulation begins here            *********/
7991 /**                                                                         **/
7992 /**                                                                         **/
7993
7994 /*****************************************************************************/
7995 /*                                                                           */
7996 /*  boundingbox()   Form an "infinite" bounding triangle to insert points    */
7997 /*                  into.                                                    */
7998 /*                                                                           */
7999 /*  The points at "infinity" are assigned finite coordinates, which are used */
8000 /*  by the point location routines, but (mostly) ignored by the Delaunay     */
8001 /*  edge flip routines.                                                      */
8002 /*                                                                           */
8003 /*****************************************************************************/
8004
8005 #ifndef
8006 REDUCED
8007
8008 void boundingbox(){
8009 struct triedge inftri;        /* Handle for the triangular bounding box. */
8010 REAL width;
8011
8012 if ( verbose ) {
8013 printf( "  Creating triangular bounding box.\n" );
8014 }
8015 /* Find the width (or height, whichever is larger) of the triangulation. */
8016 width = xmax - xmin;
8017 if ( ymax - ymin > width ) {
8018 width = ymax - ymin;
8019 }
8020 if ( width == 0.0 ) {
8021 width = 1.0;
8022 }
8023 /* Create the vertices of the bounding box. */
8024 infpoint1 = (point) malloc( points.itembytes );
8025 infpoint2 = (point) malloc( points.itembytes );
8026 infpoint3 = (point) malloc( points.itembytes );
8027 if (( infpoint1 == (point) NULL ) || ( infpoint2 == (point) NULL )
8028 || ( infpoint3 == (point) NULL )) {
8029 printf( "Error:  Out of memory.\n" );
8030 exit( 1 );
8031 }
8032 infpoint1[0] = xmin - 50.0 * width;
8033 infpoint1[1] = ymin - 40.0 * width;
8034 infpoint2[0] = xmax + 50.0 * width;
8035 infpoint2[1] = ymin - 40.0 * width;
8036 infpoint3[0] = 0.5 * ( xmin + xmax );
8037 infpoint3[1] = ymax + 60.0 * width;
8038
8039 /* Create the bounding box. */
8040 maketriangle( &inftri );
8041 setorg( inftri, infpoint1 );
8042 setdest( inftri, infpoint2 );
8043 setapex( inftri, infpoint3 );
8044 /* Link dummytri to the bounding box so we can always find an */
8045 /*   edge to begin searching (point location) from.           */
8046 dummytri[0] = (triangle) inftri.tri;
8047 if ( verbose > 2 ) {
8048 printf( "  Creating " );
8049 printtriangle( &inftri );
8050 }
8051 }
8052
8053 #endif /* not REDUCED */
8054
8055 /*****************************************************************************/
8056 /*                                                                           */
8057 /*  removebox()   Remove the "infinite" bounding triangle, setting boundary  */
8058 /*                markers as appropriate.                                    */
8059 /*                                                                           */
8060 /*  The triangular bounding box has three boundary triangles (one for each   */
8061 /*  side of the bounding box), and a bunch of triangles fanning out from     */
8062 /*  the three bounding box vertices (one triangle for each edge of the       */
8063 /*  convex hull of the inner mesh).  This routine removes these triangles.   */
8064 /*                                                                           */
8065 /*****************************************************************************/
8066
8067 #ifndef
8068 REDUCED
8069
8070 long removebox(){
8071 struct triedge deadtri;
8072 struct triedge searchedge;
8073 struct triedge checkedge;
8074 struct triedge nextedge, finaledge, dissolveedge;
8075 point markorg;
8076 long hullsize;
8077 triangle ptr;                       /* Temporary variable used by sym(). */
8078
8079 if ( verbose ) {
8080 printf( "  Removing triangular bounding box.\n" );
8081 }
8082 /* Find a boundary triangle. */
8083 nextedge.tri = dummytri;
8084 nextedge.orient = 0;
8085 symself( nextedge );
8086 /* Mark a place to stop. */
8087 lprev( nextedge, finaledge );
8088 lnextself( nextedge );
8089 symself( nextedge );
8090 /* Find a triangle (on the boundary of the point set) that isn't */
8091 /*   a bounding box triangle.                                    */
8092 lprev( nextedge, searchedge );
8093 symself( searchedge );
8094 /* Check whether nextedge is another boundary triangle */
8095 /*   adjacent to the first one.                        */
8096 lnext( nextedge, checkedge );
8097 symself( checkedge );
8098 if ( checkedge.tri == dummytri ) {
8099 /* Go on to the next triangle.  There are only three boundary   */
8100 /*   triangles, and this next triangle cannot be the third one, */
8101 /*   so it's safe to stop here.                                 */
8102 lprevself( searchedge );
8103 symself( searchedge );
8104 }
8105 /* Find a new boundary edge to search from, as the current search */
8106 /*   edge lies on a bounding box triangle and will be deleted.    */
8107 dummytri[0] = encode( searchedge );
8108 hullsize = -2l;
8109 while ( !triedgeequal( nextedge, finaledge )) {
8110 hullsize++;
8111 lprev( nextedge, dissolveedge );
8112 symself( dissolveedge );
8113 /* If not using a PSLG, the vertices should be marked now. */
8114 /*   (If using a PSLG, markhull() will do the job.)        */
8115 if ( !poly ) {
8116 /* Be careful!  One must check for the case where all the input   */
8117 /*   points are collinear, and thus all the triangles are part of */
8118 /*   the bounding box.  Otherwise, the setpointmark() call below  */
8119 /*   will cause a bad pointer reference.                          */
8120 if ( dissolveedge.tri != dummytri ) {
8121 org( dissolveedge, markorg );
8122 if ( pointmark( markorg ) == 0 ) {
8123 setpointmark( markorg, 1 );
8124 }
8125 }
8126 }
8127 /* Disconnect the bounding box triangle from the mesh triangle. */
8128 dissolve( dissolveedge );
8129 lnext( nextedge, deadtri );
8130 sym( deadtri, nextedge );
8131 /* Get rid of the bounding box triangle. */
8132 triangledealloc( deadtri.tri );
8133 /* Do we need to turn the corner? */
8134 if ( nextedge.tri == dummytri ) {
8135 /* Turn the corner. */
8136 triedgecopy( dissolveedge, nextedge );
8137 }
8138 }
8139 triangledealloc( finaledge.tri );
8140
8141 free( infpoint1 );              /* Deallocate the bounding box vertices. */
8142 free( infpoint2 );
8143 free( infpoint3 );
8144
8145 return hullsize;
8146 }
8147
8148 #endif /* not REDUCED */
8149
8150 /*****************************************************************************/
8151 /*                                                                           */
8152 /*  incrementaldelaunay()   Form a Delaunay triangulation by incrementally   */
8153 /*                          adding vertices.                                 */
8154 /*                                                                           */
8155 /*****************************************************************************/
8156
8157 #ifndef
8158 REDUCED
8159
8160 long incrementaldelaunay(){
8161 struct triedge starttri;
8162 point pointloop;
8163 int i;
8164
8165 /* Create a triangular bounding box. */
8166 boundingbox();
8167 if ( verbose ) {
8168 printf( "  Incrementally inserting points.\n" );
8169 }
8170 traversalinit( &points );
8171 pointloop = pointtraverse();
8172 i = 1;
8173 while ( pointloop != (point) NULL ) {
8174 /* Find a boundary triangle to search from. */
8175 starttri.tri = (triangle *) NULL;
8176 if ( insertsite( pointloop, &starttri, (struct edge *) NULL, 0, 0 ) ==
8177 DUPLICATEPOINT ) {
8178 if ( !quiet ) {
8179 printf(
8180 "Warning:  A duplicate point at (%.12g, %.12g) appeared and was ignored.\n",
8181 pointloop[0], pointloop[1] );
8182 }
8183 /*  Commented out - would eliminate point from output .node file.
8184       setpointmark(pointloop, DEADPOINT);
8185  */
8186 }
8187 pointloop = pointtraverse();
8188 i++;
8189 }
8190 /* Remove the bounding box. */
8191 return removebox();
8192 }
8193
8194 #endif /* not REDUCED */
8195
8196 /**                                                                         **/
8197 /**                                                                         **/
8198 /********* Incremental Delaunay triangulation ends here              *********/
8199
8200 /********* Sweepline Delaunay triangulation begins here              *********/
8201 /**                                                                         **/
8202 /**                                                                         **/
8203
8204 #ifndef
8205 REDUCED
8206
8207 void eventheapinsert( heap, heapsize, newevent )
8208 struct event **heap;
8209 int heapsize;
8210 struct event *newevent;
8211 {
8212 REAL eventx, eventy;
8213 int eventnum;
8214 int parent;
8215 int notdone;
8216
8217 eventx = newevent->xkey;
8218 eventy = newevent->ykey;
8219 eventnum = heapsize;
8220 notdone = eventnum > 0;
8221 while ( notdone ) {
8222 parent = ( eventnum - 1 ) >> 1;
8223 if (( heap[parent]->ykey < eventy ) ||
8224 (( heap[parent]->ykey == eventy )
8225 && ( heap[parent]->xkey <= eventx ))) {
8226 notdone = 0;
8227 }
8228 else {
8229 heap[eventnum] = heap[parent];
8230 heap[eventnum]->heapposition = eventnum;
8231
8232 eventnum = parent;
8233 notdone = eventnum > 0;
8234 }
8235 }
8236 heap[eventnum] = newevent;
8237 newevent->heapposition = eventnum;
8238 }
8239
8240 #endif /* not REDUCED */
8241
8242 #ifndef
8243 REDUCED
8244
8245 void eventheapify( heap, heapsize, eventnum )
8246 struct event **heap;
8247 int heapsize;
8248 int eventnum;
8249 {
8250 struct event *thisevent;
8251 REAL eventx, eventy;
8252 int leftchild, rightchild;
8253 int smallest;
8254 int notdone;
8255
8256 thisevent = heap[eventnum];
8257 eventx = thisevent->xkey;
8258 eventy = thisevent->ykey;
8259 leftchild = 2 * eventnum + 1;
8260 notdone = leftchild < heapsize;
8261 while ( notdone ) {
8262 if (( heap[leftchild]->ykey < eventy ) ||
8263 (( heap[leftchild]->ykey == eventy )
8264 && ( heap[leftchild]->xkey < eventx ))) {
8265 smallest = leftchild;
8266 }
8267 else {
8268 smallest = eventnum;
8269 }
8270 rightchild = leftchild + 1;
8271 if ( rightchild < heapsize ) {
8272 if (( heap[rightchild]->ykey < heap[smallest]->ykey ) ||
8273 (( heap[rightchild]->ykey == heap[smallest]->ykey )
8274 && ( heap[rightchild]->xkey < heap[smallest]->xkey ))) {
8275 smallest = rightchild;
8276 }
8277 }
8278 if ( smallest == eventnum ) {
8279 notdone = 0;
8280 }
8281 else {
8282 heap[eventnum] = heap[smallest];
8283 heap[eventnum]->heapposition = eventnum;
8284 heap[smallest] = thisevent;
8285 thisevent->heapposition = smallest;
8286
8287 eventnum = smallest;
8288 leftchild = 2 * eventnum + 1;
8289 notdone = leftchild < heapsize;
8290 }
8291 }
8292 }
8293
8294 #endif /* not REDUCED */
8295
8296 #ifndef
8297 REDUCED
8298
8299 void eventheapdelete( heap, heapsize, eventnum )
8300 struct event **heap;
8301 int heapsize;
8302 int eventnum;
8303 {
8304 struct event *moveevent;
8305 REAL eventx, eventy;
8306 int parent;
8307 int notdone;
8308
8309 moveevent = heap[heapsize - 1];
8310 if ( eventnum > 0 ) {
8311 eventx = moveevent->xkey;
8312 eventy = moveevent->ykey;
8313 do {
8314 parent = ( eventnum - 1 ) >> 1;
8315 if (( heap[parent]->ykey < eventy ) ||
8316 (( heap[parent]->ykey == eventy )
8317 && ( heap[parent]->xkey <= eventx ))) {
8318 notdone = 0;
8319 }
8320 else {
8321 heap[eventnum] = heap[parent];
8322 heap[eventnum]->heapposition = eventnum;
8323
8324 eventnum = parent;
8325 notdone = eventnum > 0;
8326 }
8327 } while ( notdone );
8328 }
8329 heap[eventnum] = moveevent;
8330 moveevent->heapposition = eventnum;
8331 eventheapify( heap, heapsize - 1, eventnum );
8332 }
8333
8334 #endif /* not REDUCED */
8335
8336 #ifndef
8337 REDUCED
8338
8339 void createeventheap( eventheap, events, freeevents )
8340 struct event ***eventheap;
8341 struct event **events;
8342 struct event **freeevents;
8343 {
8344 point thispoint;
8345 int maxevents;
8346 int i;
8347
8348 maxevents = ( 3 * inpoints ) / 2;
8349 *eventheap = (struct event **) malloc( maxevents * sizeof( struct event * ));
8350 if ( *eventheap == (struct event **) NULL ) {
8351 printf( "Error:  Out of memory.\n" );
8352 exit( 1 );
8353 }
8354 *events = (struct event *) malloc( maxevents * sizeof( struct event ));
8355 if ( *events == (struct event *) NULL ) {
8356 printf( "Error:  Out of memory.\n" );
8357 exit( 1 );
8358 }
8359 traversalinit( &points );
8360 for ( i = 0; i < inpoints; i++ ) {
8361 thispoint = pointtraverse();
8362 ( *events )[i].eventptr = (VOID *) thispoint;
8363 ( *events )[i].xkey = thispoint[0];
8364 ( *events )[i].ykey = thispoint[1];
8365 eventheapinsert( *eventheap, i, *events + i );
8366 }
8367 *freeevents = (struct event *) NULL;
8368 for ( i = maxevents - 1; i >= inpoints; i-- ) {
8369 ( *events )[i].eventptr = (VOID *) *freeevents;
8370 *freeevents = *events + i;
8371 }
8372 }
8373
8374 #endif /* not REDUCED */
8375
8376 #ifndef
8377 REDUCED
8378
8379 int rightofhyperbola( fronttri, newsite )
8380 struct triedge *fronttri;
8381 point newsite;
8382 {
8383 point leftpoint, rightpoint;
8384 REAL dxa, dya, dxb, dyb;
8385
8386 hyperbolacount++;
8387
8388 dest( *fronttri, leftpoint );
8389 apex( *fronttri, rightpoint );
8390 if (( leftpoint[1] < rightpoint[1] )
8391 || (( leftpoint[1] == rightpoint[1] ) && ( leftpoint[0] < rightpoint[0] ))) {
8392 if ( newsite[0] >= rightpoint[0] ) {
8393 return 1;
8394 }
8395 }
8396 else {
8397 if ( newsite[0] <= leftpoint[0] ) {
8398 return 0;
8399 }
8400 }
8401 dxa = leftpoint[0] - newsite[0];
8402 dya = leftpoint[1] - newsite[1];
8403 dxb = rightpoint[0] - newsite[0];
8404 dyb = rightpoint[1] - newsite[1];
8405 return dya * ( dxb * dxb + dyb * dyb ) > dyb * ( dxa * dxa + dya * dya );
8406 }
8407
8408 #endif /* not REDUCED */
8409
8410 #ifndef
8411 REDUCED
8412
8413 REAL circletop( pa, pb, pc, ccwabc )
8414 point pa;
8415 point pb;
8416 point pc;
8417 REAL ccwabc;
8418 {
8419 REAL xac, yac, xbc, ybc, xab, yab;
8420 REAL aclen2, bclen2, ablen2;
8421
8422 circletopcount++;
8423
8424 xac = pa[0] - pc[0];
8425 yac = pa[1] - pc[1];
8426 xbc = pb[0] - pc[0];
8427 ybc = pb[1] - pc[1];
8428 xab = pa[0] - pb[0];
8429 yab = pa[1] - pb[1];
8430 aclen2 = xac * xac + yac * yac;
8431 bclen2 = xbc * xbc + ybc * ybc;
8432 ablen2 = xab * xab + yab * yab;
8433 return pc[1] + ( xac * bclen2 - xbc * aclen2 + sqrt( aclen2 * bclen2 * ablen2 ))
8434 / ( 2.0 * ccwabc );
8435 }
8436
8437 #endif /* not REDUCED */
8438
8439 #ifndef
8440 REDUCED
8441
8442 void check4deadevent( checktri, freeevents, eventheap, heapsize )
8443 struct triedge *checktri;
8444 struct event **freeevents;
8445 struct event **eventheap;
8446 int *heapsize;
8447 {
8448 struct event *deadevent;
8449 point eventpoint;
8450 int eventnum;
8451
8452 org( *checktri, eventpoint );
8453 if ( eventpoint != (point) NULL ) {
8454 deadevent = (struct event *) eventpoint;
8455 eventnum = deadevent->heapposition;
8456 deadevent->eventptr = (VOID *) *freeevents;
8457 *freeevents = deadevent;
8458 eventheapdelete( eventheap, *heapsize, eventnum );
8459 ( *heapsize )--;
8460 setorg( *checktri, NULL );
8461 }
8462 }
8463
8464 #endif /* not REDUCED */
8465
8466 #ifndef
8467 REDUCED
8468
8469 struct splaynode *splay( splaytree, searchpoint, searchtri )
8470 struct splaynode *splaytree;
8471 point searchpoint;
8472 struct triedge *searchtri;
8473 {
8474 struct splaynode *child, *grandchild;
8475 struct splaynode *lefttree, *righttree;
8476 struct splaynode *leftright;
8477 point checkpoint;
8478 int rightofroot, rightofchild;
8479
8480 if ( splaytree == (struct splaynode *) NULL ) {
8481 return (struct splaynode *) NULL;
8482 }
8483 dest( splaytree->keyedge, checkpoint );
8484 if ( checkpoint == splaytree->keydest ) {
8485 rightofroot = rightofhyperbola( &splaytree->keyedge, searchpoint );
8486 if ( rightofroot ) {
8487 triedgecopy( splaytree->keyedge, *searchtri );
8488 child = splaytree->rchild;
8489 }
8490 else {
8491 child = splaytree->lchild;
8492 }
8493 if ( child == (struct splaynode *) NULL ) {
8494 return splaytree;
8495 }
8496 dest( child->keyedge, checkpoint );
8497 if ( checkpoint != child->keydest ) {
8498 child = splay( child, searchpoint, searchtri );
8499 if ( child == (struct splaynode *) NULL ) {
8500 if ( rightofroot ) {
8501 splaytree->rchild = (struct splaynode *) NULL;
8502 }
8503 else {
8504 splaytree->lchild = (struct splaynode *) NULL;
8505 }
8506 return splaytree;
8507 }
8508 }
8509 rightofchild = rightofhyperbola( &child->keyedge, searchpoint );
8510 if ( rightofchild ) {
8511 triedgecopy( child->keyedge, *searchtri );
8512 grandchild = splay( child->rchild, searchpoint, searchtri );
8513 child->rchild = grandchild;
8514 }
8515 else {
8516 grandchild = splay( child->lchild, searchpoint, searchtri );
8517 child->lchild = grandchild;
8518 }
8519 if ( grandchild == (struct splaynode *) NULL ) {
8520 if ( rightofroot ) {
8521 splaytree->rchild = child->lchild;
8522 child->lchild = splaytree;
8523 }
8524 else {
8525 splaytree->lchild = child->rchild;
8526 child->rchild = splaytree;
8527 }
8528 return child;
8529 }
8530 if ( rightofchild ) {
8531 if ( rightofroot ) {
8532 splaytree->rchild = child->lchild;
8533 child->lchild = splaytree;
8534 }
8535 else {
8536 splaytree->lchild = grandchild->rchild;
8537 grandchild->rchild = splaytree;
8538 }
8539 child->rchild = grandchild->lchild;
8540 grandchild->lchild = child;
8541 }
8542 else {
8543 if ( rightofroot ) {
8544 splaytree->rchild = grandchild->lchild;
8545 grandchild->lchild = splaytree;
8546 }
8547 else {
8548 splaytree->lchild = child->rchild;
8549 child->rchild = splaytree;
8550 }
8551 child->lchild = grandchild->rchild;
8552 grandchild->rchild = child;
8553 }
8554 return grandchild;
8555 }
8556 else {
8557 lefttree = splay( splaytree->lchild, searchpoint, searchtri );
8558 righttree = splay( splaytree->rchild, searchpoint, searchtri );
8559
8560 pooldealloc( &splaynodes, (VOID *) splaytree );
8561 if ( lefttree == (struct splaynode *) NULL ) {
8562 return righttree;
8563 }
8564 else if ( righttree == (struct splaynode *) NULL ) {
8565 return lefttree;
8566 }
8567 else if ( lefttree->rchild == (struct splaynode *) NULL ) {
8568 lefttree->rchild = righttree->lchild;
8569 righttree->lchild = lefttree;
8570 return righttree;
8571 }
8572 else if ( righttree->lchild == (struct splaynode *) NULL ) {
8573 righttree->lchild = lefttree->rchild;
8574 lefttree->rchild = righttree;
8575 return lefttree;
8576 }
8577 else {
8578 /*      printf("Holy Toledo!!!\n"); */
8579 leftright = lefttree->rchild;
8580 while ( leftright->rchild != (struct splaynode *) NULL ) {
8581 leftright = leftright->rchild;
8582 }
8583 leftright->rchild = righttree;
8584 return lefttree;
8585 }
8586 }
8587 }
8588
8589 #endif /* not REDUCED */
8590
8591 #ifndef
8592 REDUCED
8593
8594 struct splaynode *splayinsert( splayroot, newkey, searchpoint )
8595 struct splaynode *splayroot;
8596 struct triedge *newkey;
8597 point searchpoint;
8598 {
8599 struct splaynode *newsplaynode;
8600
8601 newsplaynode = (struct splaynode *) poolalloc( &splaynodes );
8602 triedgecopy( *newkey, newsplaynode->keyedge );
8603 dest( *newkey, newsplaynode->keydest );
8604 if ( splayroot == (struct splaynode *) NULL ) {
8605 newsplaynode->lchild = (struct splaynode *) NULL;
8606 newsplaynode->rchild = (struct splaynode *) NULL;
8607 }
8608 else if ( rightofhyperbola( &splayroot->keyedge, searchpoint )) {
8609 newsplaynode->lchild = splayroot;
8610 newsplaynode->rchild = splayroot->rchild;
8611 splayroot->rchild = (struct splaynode *) NULL;
8612 }
8613 else {
8614 newsplaynode->lchild = splayroot->lchild;
8615 newsplaynode->rchild = splayroot;
8616 splayroot->lchild = (struct splaynode *) NULL;
8617 }
8618 return newsplaynode;
8619 }
8620
8621 #endif /* not REDUCED */
8622
8623 #ifndef
8624 REDUCED
8625
8626 struct splaynode *circletopinsert( splayroot, newkey, pa, pb, pc, topy )
8627 struct splaynode *splayroot;
8628 struct triedge *newkey;
8629 point pa;
8630 point pb;
8631 point pc;
8632 REAL topy;
8633 {
8634 REAL ccwabc;
8635 REAL xac, yac, xbc, ybc;
8636 REAL aclen2, bclen2;
8637 REAL searchpoint[2];
8638 struct triedge dummytri;
8639
8640 ccwabc = counterclockwise( pa, pb, pc );
8641 xac = pa[0] - pc[0];
8642 yac = pa[1] - pc[1];
8643 xbc = pb[0] - pc[0];
8644 ybc = pb[1] - pc[1];
8645 aclen2 = xac * xac + yac * yac;
8646 bclen2 = xbc * xbc + ybc * ybc;
8647 searchpoint[0] = pc[0] - ( yac * bclen2 - ybc * aclen2 ) / ( 2.0 * ccwabc );
8648 searchpoint[1] = topy;
8649 return splayinsert( splay( splayroot, (point) searchpoint, &dummytri ), newkey,
8650 (point) searchpoint );
8651 }
8652
8653 #endif /* not REDUCED */
8654
8655 #ifndef
8656 REDUCED
8657
8658 struct splaynode *frontlocate( splayroot, bottommost, searchpoint, searchtri,
8659 farright )
8660 struct splaynode *splayroot;
8661 struct triedge *bottommost;
8662 point searchpoint;
8663 struct triedge *searchtri;
8664 int *farright;
8665 {
8666 int farrightflag;
8667 triangle ptr;                     /* Temporary variable used by onext(). */
8668
8669 triedgecopy( *bottommost, *searchtri );
8670 splayroot = splay( splayroot, searchpoint, searchtri );
8671
8672 farrightflag = 0;
8673 while ( !farrightflag && rightofhyperbola( searchtri, searchpoint )) {
8674 onextself( *searchtri );
8675 farrightflag = triedgeequal( *searchtri, *bottommost );
8676 }
8677 *farright = farrightflag;
8678 return splayroot;
8679 }
8680
8681 #endif /* not REDUCED */
8682
8683 #ifndef
8684 REDUCED
8685
8686 long sweeplinedelaunay(){
8687 struct event **eventheap;
8688 struct event *events;
8689 struct event *freeevents;
8690 struct event *nextevent;
8691 struct event *newevent;
8692 struct splaynode *splayroot;
8693 struct triedge bottommost;
8694 struct triedge searchtri;
8695 struct triedge fliptri;
8696 struct triedge lefttri, righttri, farlefttri, farrighttri;
8697 struct triedge inserttri;
8698 point firstpoint, secondpoint;
8699 point nextpoint, lastpoint;
8700 point connectpoint;
8701 point leftpoint, midpoint, rightpoint;
8702 REAL lefttest, righttest;
8703 int heapsize;
8704 int check4events, farrightflag;
8705 triangle ptr; /* Temporary variable used by sym(), onext(), and oprev(). */
8706
8707 poolinit( &splaynodes, sizeof( struct splaynode ), SPLAYNODEPERBLOCK, POINTER,
8708 0 );
8709 splayroot = (struct splaynode *) NULL;
8710
8711 if ( verbose ) {
8712 printf( "  Placing points in event heap.\n" );
8713 }
8714 createeventheap( &eventheap, &events, &freeevents );
8715 heapsize = inpoints;
8716
8717 if ( verbose ) {
8718 printf( "  Forming triangulation.\n" );
8719 }
8720 maketriangle( &lefttri );
8721 maketriangle( &righttri );
8722 bond( lefttri, righttri );
8723 lnextself( lefttri );
8724 lprevself( righttri );
8725 bond( lefttri, righttri );
8726 lnextself( lefttri );
8727 lprevself( righttri );
8728 bond( lefttri, righttri );
8729 firstpoint = (point) eventheap[0]->eventptr;
8730 eventheap[0]->eventptr = (VOID *) freeevents;
8731 freeevents = eventheap[0];
8732 eventheapdelete( eventheap, heapsize, 0 );
8733 heapsize--;
8734 do {
8735 if ( heapsize == 0 ) {
8736 printf( "Error:  Input points are all identical.\n" );
8737 exit( 1 );
8738 }
8739 secondpoint = (point) eventheap[0]->eventptr;
8740 eventheap[0]->eventptr = (VOID *) freeevents;
8741 freeevents = eventheap[0];
8742 eventheapdelete( eventheap, heapsize, 0 );
8743 heapsize--;
8744 if (( firstpoint[0] == secondpoint[0] )
8745 && ( firstpoint[1] == secondpoint[1] )) {
8746 printf(
8747 "Warning:  A duplicate point at (%.12g, %.12g) appeared and was ignored.\n",
8748 secondpoint[0], secondpoint[1] );
8749 /*  Commented out - would eliminate point from output .node file.
8750       setpointmark(secondpoint, DEADPOINT);
8751  */
8752 }
8753 } while (( firstpoint[0] == secondpoint[0] )
8754 && ( firstpoint[1] == secondpoint[1] ));
8755 setorg( lefttri, firstpoint );
8756 setdest( lefttri, secondpoint );
8757 setorg( righttri, secondpoint );
8758 setdest( righttri, firstpoint );
8759 lprev( lefttri, bottommost );
8760 lastpoint = secondpoint;
8761 while ( heapsize > 0 ) {
8762 nextevent = eventheap[0];
8763 eventheapdelete( eventheap, heapsize, 0 );
8764 heapsize--;
8765 check4events = 1;
8766 if ( nextevent->xkey < xmin ) {
8767 decode( nextevent->eventptr, fliptri );
8768 oprev( fliptri, farlefttri );
8769 check4deadevent( &farlefttri, &freeevents, eventheap, &heapsize );
8770 onext( fliptri, farrighttri );
8771 check4deadevent( &farrighttri, &freeevents, eventheap, &heapsize );
8772
8773 if ( triedgeequal( farlefttri, bottommost )) {
8774 lprev( fliptri, bottommost );
8775 }
8776 flip( &fliptri );
8777 setapex( fliptri, NULL );
8778 lprev( fliptri, lefttri );
8779 lnext( fliptri, righttri );
8780 sym( lefttri, farlefttri );
8781
8782 if ( randomnation( SAMPLERATE ) == 0 ) {
8783 symself( fliptri );
8784 dest( fliptri, leftpoint );
8785 apex( fliptri, midpoint );
8786 org( fliptri, rightpoint );
8787 splayroot = circletopinsert( splayroot, &lefttri, leftpoint, midpoint,
8788 rightpoint, nextevent->ykey );
8789 }
8790 }
8791 else {
8792 nextpoint = (point) nextevent->eventptr;
8793 if (( nextpoint[0] == lastpoint[0] ) && ( nextpoint[1] == lastpoint[1] )) {
8794 printf(
8795 "Warning:  A duplicate point at (%.12g, %.12g) appeared and was ignored.\n",
8796 nextpoint[0], nextpoint[1] );
8797 /*  Commented out - would eliminate point from output .node file.
8798         setpointmark(nextpoint, DEADPOINT);
8799  */
8800 check4events = 0;
8801 }
8802 else {
8803 lastpoint = nextpoint;
8804
8805 splayroot = frontlocate( splayroot, &bottommost, nextpoint, &searchtri,
8806 &farrightflag );
8807 /*
8808         triedgecopy(bottommost, searchtri);
8809         farrightflag = 0;
8810         while (!farrightflag && rightofhyperbola(&searchtri, nextpoint)) {
8811           onextself(searchtri);
8812           farrightflag = triedgeequal(searchtri, bottommost);
8813         }
8814  */
8815
8816 check4deadevent( &searchtri, &freeevents, eventheap, &heapsize );
8817
8818 triedgecopy( searchtri, farrighttri );
8819 sym( searchtri, farlefttri );
8820 maketriangle( &lefttri );
8821 maketriangle( &righttri );
8822 dest( farrighttri, connectpoint );
8823 setorg( lefttri, connectpoint );
8824 setdest( lefttri, nextpoint );
8825 setorg( righttri, nextpoint );
8826 setdest( righttri, connectpoint );
8827 bond( lefttri, righttri );
8828 lnextself( lefttri );
8829 lprevself( righttri );
8830 bond( lefttri, righttri );
8831 lnextself( lefttri );
8832 lprevself( righttri );
8833 bond( lefttri, farlefttri );
8834 bond( righttri, farrighttri );
8835 if ( !farrightflag && triedgeequal( farrighttri, bottommost )) {
8836 triedgecopy( lefttri, bottommost );
8837 }
8838
8839 if ( randomnation( SAMPLERATE ) == 0 ) {
8840 splayroot = splayinsert( splayroot, &lefttri, nextpoint );
8841 }
8842 else if ( randomnation( SAMPLERATE ) == 0 ) {
8843 lnext( righttri, inserttri );
8844 splayroot = splayinsert( splayroot, &inserttri, nextpoint );
8845 }
8846 }
8847 }
8848 nextevent->eventptr = (VOID *) freeevents;
8849 freeevents = nextevent;
8850
8851 if ( check4events ) {
8852 apex( farlefttri, leftpoint );
8853 dest( lefttri, midpoint );
8854 apex( lefttri, rightpoint );
8855 lefttest = counterclockwise( leftpoint, midpoint, rightpoint );
8856 if ( lefttest > 0.0 ) {
8857 newevent = freeevents;
8858 freeevents = (struct event *) freeevents->eventptr;
8859 newevent->xkey = xminextreme;
8860 newevent->ykey = circletop( leftpoint, midpoint, rightpoint,
8861 lefttest );
8862 newevent->eventptr = (VOID *) encode( lefttri );
8863 eventheapinsert( eventheap, heapsize, newevent );
8864 heapsize++;
8865 setorg( lefttri, newevent );
8866 }
8867 apex( righttri, leftpoint );
8868 org( righttri, midpoint );
8869 apex( farrighttri, rightpoint );
8870 righttest = counterclockwise( leftpoint, midpoint, rightpoint );
8871 if ( righttest > 0.0 ) {
8872 newevent = freeevents;
8873 freeevents = (struct event *) freeevents->eventptr;
8874 newevent->xkey = xminextreme;
8875 newevent->ykey = circletop( leftpoint, midpoint, rightpoint,
8876 righttest );
8877 newevent->eventptr = (VOID *) encode( farrighttri );
8878 eventheapinsert( eventheap, heapsize, newevent );
8879 heapsize++;
8880 setorg( farrighttri, newevent );
8881 }
8882 }
8883 }
8884
8885 pooldeinit( &splaynodes );
8886 lprevself( bottommost );
8887 return removeghosts( &bottommost );
8888 }
8889
8890 #endif /* not REDUCED */
8891
8892 /**                                                                         **/
8893 /**                                                                         **/
8894 /********* Sweepline Delaunay triangulation ends here                *********/
8895
8896 /********* General mesh construction routines begin here             *********/
8897 /**                                                                         **/
8898 /**                                                                         **/
8899
8900 /*****************************************************************************/
8901 /*                                                                           */
8902 /*  delaunay()   Form a Delaunay triangulation.                              */
8903 /*                                                                           */
8904 /*****************************************************************************/
8905
8906 long delaunay(){
8907 eextras = 0;
8908 initializetrisegpools();
8909
8910 #ifdef
8911 REDUCED
8912 if ( !quiet ) {
8913 printf(
8914 "Constructing Delaunay triangulation by divide-and-conquer method.\n" );
8915 }
8916 return divconqdelaunay();
8917 #else /* not REDUCED */
8918 if ( !quiet ) {
8919 printf( "Constructing Delaunay triangulation " );
8920 if ( incremental ) {
8921 printf( "by incremental method.\n" );
8922 }
8923 else if ( sweepline ) {
8924 printf( "by sweepline method.\n" );
8925 }
8926 else {
8927 printf( "by divide-and-conquer method.\n" );
8928 }
8929 }
8930 if ( incremental ) {
8931 return incrementaldelaunay();
8932 }
8933 else if ( sweepline ) {
8934 return sweeplinedelaunay();
8935 }
8936 else {
8937 return divconqdelaunay();
8938 }
8939 #endif /* not REDUCED */
8940 }
8941
8942 /*****************************************************************************/
8943 /*                                                                           */
8944 /*  reconstruct()   Reconstruct a triangulation from its .ele (and possibly  */
8945 /*                  .poly) file.  Used when the -r switch is used.           */
8946 /*                                                                           */
8947 /*  Reads an .ele file and reconstructs the original mesh.  If the -p switch */
8948 /*  is used, this procedure will also read a .poly file and reconstruct the  */
8949 /*  shell edges of the original mesh.  If the -a switch is used, this        */
8950 /*  procedure will also read an .area file and set a maximum area constraint */
8951 /*  on each triangle.                                                        */
8952 /*                                                                           */
8953 /*  Points that are not corners of triangles, such as nodes on edges of      */
8954 /*  subparametric elements, are discarded.                                   */
8955 /*                                                                           */
8956 /*  This routine finds the adjacencies between triangles (and shell edges)   */
8957 /*  by forming one stack of triangles for each vertex.  Each triangle is on  */
8958 /*  three different stacks simultaneously.  Each triangle's shell edge       */
8959 /*  pointers are used to link the items in each stack.  This memory-saving   */
8960 /*  feature makes the code harder to read.  The most important thing to keep */
8961 /*  in mind is that each triangle is removed from a stack precisely when     */
8962 /*  the corresponding pointer is adjusted to refer to a shell edge rather    */
8963 /*  than the next triangle of the stack.                                     */
8964 /*                                                                           */
8965 /*****************************************************************************/
8966
8967 #ifndef
8968 CDT_ONLY
8969
8970 #ifdef
8971 TRILIBRARY
8972
8973 int reconstruct( trianglelist, triangleattriblist, trianglearealist, elements,
8974 corners, attribs, segmentlist, segmentmarkerlist,
8975 numberofsegments )
8976 int *trianglelist;
8977 REAL *triangleattriblist;
8978 REAL *trianglearealist;
8979 int elements;
8980 int corners;
8981 int attribs;
8982 int *segmentlist;
8983 int *segmentmarkerlist;
8984 int numberofsegments;
8985
8986 #else /* not TRILIBRARY */
8987
8988 long reconstruct( elefilename, areafilename, polyfilename, polyfile )
8989 char *elefilename;
8990 char *areafilename;
8991 char *polyfilename;
8992 FILE *polyfile;
8993
8994 #endif /* not TRILIBRARY */
8995
8996 {
8997 #ifdef
8998 TRILIBRARY
8999 int pointindex;
9000 int attribindex;
9001 #else /* not TRILIBRARY */
9002 FILE *elefile;
9003 FILE *areafile;
9004 char inputline[INPUTLINESIZE];
9005 char *stringptr;
9006 int areaelements;
9007 #endif /* not TRILIBRARY */
9008 struct triedge triangleloop;
9009 struct triedge triangleleft;
9010 struct triedge checktri;
9011 struct triedge checkleft;
9012 struct triedge checkneighbor;
9013 struct edge shelleloop;
9014 triangle *vertexarray;
9015 triangle *prevlink;
9016 triangle nexttri;
9017 point tdest, tapex;
9018 point checkdest, checkapex;
9019 point shorg;
9020 point killpoint;
9021 REAL area;
9022 int corner[3];
9023 int end[2];
9024 int killpointindex;
9025 int incorners;
9026 int segmentmarkers;
9027 int boundmarker;
9028 int aroundpoint;
9029 long hullsize;
9030 int notfound;
9031 int elementnumber, segmentnumber;
9032 int i, j;
9033 triangle ptr;                       /* Temporary variable used by sym(). */
9034
9035 #ifdef
9036 TRILIBRARY
9037 inelements = elements;
9038 incorners = corners;
9039 if ( incorners < 3 ) {
9040 printf( "Error:  Triangles must have at least 3 points.\n" );
9041 exit( 1 );
9042 }
9043 eextras = attribs;
9044 #else /* not TRILIBRARY */
9045 /* Read the triangles from an .ele file. */
9046 if ( !quiet ) {
9047 printf( "Opening %s.\n", elefilename );
9048 }
9049 elefile = fopen( elefilename, "r" );
9050 if ( elefile == (FILE *) NULL ) {
9051 printf( "  Error:  Cannot access file %s.\n", elefilename );
9052 exit( 1 );
9053 }
9054 /* Read number of triangles, number of points per triangle, and */
9055 /*   number of triangle attributes from .ele file.              */
9056 stringptr = readline( inputline, elefile, elefilename );
9057 inelements = (int) strtol( stringptr, &stringptr, 0 );
9058 stringptr = findfield( stringptr );
9059 if ( *stringptr == '\0' ) {
9060 incorners = 3;
9061 }
9062 else {
9063 incorners = (int) strtol( stringptr, &stringptr, 0 );
9064 if ( incorners < 3 ) {
9065 printf( "Error:  Triangles in %s must have at least 3 points.\n",
9066 elefilename );
9067 exit( 1 );
9068 }
9069 }
9070 stringptr = findfield( stringptr );
9071 if ( *stringptr == '\0' ) {
9072 eextras = 0;
9073 }
9074 else {
9075 eextras = (int) strtol( stringptr, &stringptr, 0 );
9076 }
9077 #endif /* not TRILIBRARY */
9078
9079 initializetrisegpools();
9080
9081 /* Create the triangles. */
9082 for ( elementnumber = 1; elementnumber <= inelements; elementnumber++ ) {
9083 maketriangle( &triangleloop );
9084 /* Mark the triangle as living. */
9085 triangleloop.tri[3] = (triangle) triangleloop.tri;
9086 }
9087
9088 if ( poly ) {
9089 #ifdef
9090 TRILIBRARY
9091 insegments = numberofsegments;
9092 segmentmarkers = segmentmarkerlist != (int *) NULL;
9093 #else /* not TRILIBRARY */
9094 /* Read number of segments and number of segment */
9095 /*   boundary markers from .poly file.           */
9096 stringptr = readline( inputline, polyfile, inpolyfilename );
9097 insegments = (int) strtol( stringptr, &stringptr, 0 );
9098 stringptr = findfield( stringptr );
9099 if ( *stringptr == '\0' ) {
9100 segmentmarkers = 0;
9101 }
9102 else {
9103 segmentmarkers = (int) strtol( stringptr, &stringptr, 0 );
9104 }
9105 #endif /* not TRILIBRARY */
9106
9107 /* Create the shell edges. */
9108 for ( segmentnumber = 1; segmentnumber <= insegments; segmentnumber++ ) {
9109 makeshelle( &shelleloop );
9110 /* Mark the shell edge as living. */
9111 shelleloop.sh[2] = (shelle) shelleloop.sh;
9112 }
9113 }
9114
9115 #ifdef
9116 TRILIBRARY
9117 pointindex = 0;
9118 attribindex = 0;
9119 #else /* not TRILIBRARY */
9120 if ( vararea ) {
9121 /* Open an .area file, check for consistency with the .ele file. */
9122 if ( !quiet ) {
9123 printf( "Opening %s.\n", areafilename );
9124 }
9125 areafile = fopen( areafilename, "r" );
9126 if ( areafile == (FILE *) NULL ) {
9127 printf( "  Error:  Cannot access file %s.\n", areafilename );
9128 exit( 1 );
9129 }
9130 stringptr = readline( inputline, areafile, areafilename );
9131 areaelements = (int) strtol( stringptr, &stringptr, 0 );
9132 if ( areaelements != inelements ) {
9133 printf( "Error:  %s and %s disagree on number of triangles.\n",
9134 elefilename, areafilename );
9135 exit( 1 );
9136 }
9137 }
9138 #endif /* not TRILIBRARY */
9139
9140 if ( !quiet ) {
9141 printf( "Reconstructing mesh.\n" );
9142 }
9143 /* Allocate a temporary array that maps each point to some adjacent  */
9144 /*   triangle.  I took care to allocate all the permanent memory for */
9145 /*   triangles and shell edges first.                                */
9146 vertexarray = (triangle *) malloc( points.items * sizeof( triangle ));
9147 if ( vertexarray == (triangle *) NULL ) {
9148 printf( "Error:  Out of memory.\n" );
9149 exit( 1 );
9150 }
9151 /* Each point is initially unrepresented. */
9152 for ( i = 0; i < points.items; i++ ) {
9153 vertexarray[i] = (triangle) dummytri;
9154 }
9155
9156 if ( verbose ) {
9157 printf( "  Assembling triangles.\n" );
9158 }
9159 /* Read the triangles from the .ele file, and link */
9160 /*   together those that share an edge.            */
9161 traversalinit( &triangles );
9162 triangleloop.tri = triangletraverse();
9163 elementnumber = firstnumber;
9164 while ( triangleloop.tri != (triangle *) NULL ) {
9165 #ifdef
9166 TRILIBRARY
9167 /* Copy the triangle's three corners. */
9168 for ( j = 0; j < 3; j++ ) {
9169 corner[j] = trianglelist[pointindex++];
9170 if (( corner[j] < firstnumber ) || ( corner[j] >= firstnumber + inpoints )) {
9171 printf( "Error:  Triangle %d has an invalid vertex index.\n",
9172 elementnumber );
9173 exit( 1 );
9174 }
9175 }
9176 #else /* not TRILIBRARY */
9177 /* Read triangle number and the triangle's three corners. */
9178 stringptr = readline( inputline, elefile, elefilename );
9179 for ( j = 0; j < 3; j++ ) {
9180 stringptr = findfield( stringptr );
9181 if ( *stringptr == '\0' ) {
9182 printf( "Error:  Triangle %d is missing point %d in %s.\n",
9183 elementnumber, j + 1, elefilename );
9184 exit( 1 );
9185 }
9186 else {
9187 corner[j] = (int) strtol( stringptr, &stringptr, 0 );
9188 if (( corner[j] < firstnumber ) ||
9189 ( corner[j] >= firstnumber + inpoints )) {
9190 printf( "Error:  Triangle %d has an invalid vertex index.\n",
9191 elementnumber );
9192 exit( 1 );
9193 }
9194 }
9195 }
9196 #endif /* not TRILIBRARY */
9197
9198 /* Find out about (and throw away) extra nodes. */
9199 for ( j = 3; j < incorners; j++ ) {
9200 #ifdef
9201 TRILIBRARY
9202 killpointindex = trianglelist[pointindex++];
9203 #else /* not TRILIBRARY */
9204 stringptr = findfield( stringptr );
9205 if ( *stringptr != '\0' ) {
9206 killpointindex = (int) strtol( stringptr, &stringptr, 0 );
9207 #endif /* not TRILIBRARY */
9208 if (( killpointindex >= firstnumber ) &&
9209 ( killpointindex < firstnumber + inpoints )) {
9210 /* Delete the non-corner point if it's not already deleted. */
9211 killpoint = getpoint( killpointindex );
9212 if ( pointmark( killpoint ) != DEADPOINT ) {
9213 pointdealloc( killpoint );
9214 }
9215 }
9216 #ifndef
9217 TRILIBRARY
9218 }
9219 #endif /* not TRILIBRARY */
9220 }
9221
9222 /* Read the triangle's attributes. */
9223 for ( j = 0; j < eextras; j++ ) {
9224 #ifdef
9225 TRILIBRARY
9226 setelemattribute( triangleloop, j, triangleattriblist[attribindex++] );
9227 #else /* not TRILIBRARY */
9228 stringptr = findfield( stringptr );
9229 if ( *stringptr == '\0' ) {
9230 setelemattribute( triangleloop, j, 0 );
9231 }
9232 else {
9233 setelemattribute( triangleloop, j,
9234 (REAL) strtod( stringptr, &stringptr ));
9235 }
9236 #endif /* not TRILIBRARY */
9237 }
9238
9239 if ( vararea ) {
9240 #ifdef
9241 TRILIBRARY
9242 area = trianglearealist[elementnumber - firstnumber];
9243 #else /* not TRILIBRARY */
9244 /* Read an area constraint from the .area file. */
9245 stringptr = readline( inputline, areafile, areafilename );
9246 stringptr = findfield( stringptr );
9247 if ( *stringptr == '\0' ) {
9248 area = -1.0;              /* No constraint on this triangle. */
9249 }
9250 else {
9251 area = (REAL) strtod( stringptr, &stringptr );
9252 }
9253 #endif /* not TRILIBRARY */
9254 setareabound( triangleloop, area );
9255 }
9256
9257 /* Set the triangle's vertices. */
9258 triangleloop.orient = 0;
9259 setorg( triangleloop, getpoint( corner[0] ));
9260 setdest( triangleloop, getpoint( corner[1] ));
9261 setapex( triangleloop, getpoint( corner[2] ));
9262 /* Try linking the triangle to others that share these vertices. */
9263 for ( triangleloop.orient = 0; triangleloop.orient < 3;
9264 triangleloop.orient++ ) {
9265 /* Take the number for the origin of triangleloop. */
9266 aroundpoint = corner[triangleloop.orient];
9267 /* Look for other triangles having this vertex. */
9268 nexttri = vertexarray[aroundpoint - firstnumber];
9269 /* Link the current triangle to the next one in the stack. */
9270 triangleloop.tri[6 + triangleloop.orient] = nexttri;
9271 /* Push the current triangle onto the stack. */
9272 vertexarray[aroundpoint - firstnumber] = encode( triangleloop );
9273 decode( nexttri, checktri );
9274 if ( checktri.tri != dummytri ) {
9275 dest( triangleloop, tdest );
9276 apex( triangleloop, tapex );
9277 /* Look for other triangles that share an edge. */
9278 do {
9279 dest( checktri, checkdest );
9280 apex( checktri, checkapex );
9281 if ( tapex == checkdest ) {
9282 /* The two triangles share an edge; bond them together. */
9283 lprev( triangleloop, triangleleft );
9284 bond( triangleleft, checktri );
9285 }
9286 if ( tdest == checkapex ) {
9287 /* The two triangles share an edge; bond them together. */
9288 lprev( checktri, checkleft );
9289 bond( triangleloop, checkleft );
9290 }
9291 /* Find the next triangle in the stack. */
9292 nexttri = checktri.tri[6 + checktri.orient];
9293 decode( nexttri, checktri );
9294 } while ( checktri.tri != dummytri );
9295 }
9296 }
9297 triangleloop.tri = triangletraverse();
9298 elementnumber++;
9299 }
9300
9301 #ifdef
9302 TRILIBRARY
9303 pointindex = 0;
9304 #else /* not TRILIBRARY */
9305 fclose( elefile );
9306 if ( vararea ) {
9307 fclose( areafile );
9308 }
9309 #endif /* not TRILIBRARY */
9310
9311 hullsize = 0;                    /* Prepare to count the boundary edges. */
9312 if ( poly ) {
9313 if ( verbose ) {
9314 printf( "  Marking segments in triangulation.\n" );
9315 }
9316 /* Read the segments from the .poly file, and link them */
9317 /*   to their neighboring triangles.                    */
9318 boundmarker = 0;
9319 traversalinit( &shelles );
9320 shelleloop.sh = shelletraverse();
9321 segmentnumber = firstnumber;
9322 while ( shelleloop.sh != (shelle *) NULL ) {
9323 #ifdef
9324 TRILIBRARY
9325 end[0] = segmentlist[pointindex++];
9326 end[1] = segmentlist[pointindex++];
9327 if ( segmentmarkers ) {
9328 boundmarker = segmentmarkerlist[segmentnumber - firstnumber];
9329 }
9330 #else /* not TRILIBRARY */
9331 /* Read the endpoints of each segment, and possibly a boundary marker. */
9332 stringptr = readline( inputline, polyfile, inpolyfilename );
9333 /* Skip the first (segment number) field. */
9334 stringptr = findfield( stringptr );
9335 if ( *stringptr == '\0' ) {
9336 printf( "Error:  Segment %d has no endpoints in %s.\n", segmentnumber,
9337 polyfilename );
9338 exit( 1 );
9339 }
9340 else {
9341 end[0] = (int) strtol( stringptr, &stringptr, 0 );
9342 }
9343 stringptr = findfield( stringptr );
9344 if ( *stringptr == '\0' ) {
9345 printf( "Error:  Segment %d is missing its second endpoint in %s.\n",
9346 segmentnumber, polyfilename );
9347 exit( 1 );
9348 }
9349 else {
9350 end[1] = (int) strtol( stringptr, &stringptr, 0 );
9351 }
9352 if ( segmentmarkers ) {
9353 stringptr = findfield( stringptr );
9354 if ( *stringptr == '\0' ) {
9355 boundmarker = 0;
9356 }
9357 else {
9358 boundmarker = (int) strtol( stringptr, &stringptr, 0 );
9359 }
9360 }
9361 #endif /* not TRILIBRARY */
9362 for ( j = 0; j < 2; j++ ) {
9363 if (( end[j] < firstnumber ) || ( end[j] >= firstnumber + inpoints )) {
9364 printf( "Error:  Segment %d has an invalid vertex index.\n",
9365 segmentnumber );
9366 exit( 1 );
9367 }
9368 }
9369
9370 /* set the shell edge's vertices. */
9371 shelleloop.shorient = 0;
9372 setsorg( shelleloop, getpoint( end[0] ));
9373 setsdest( shelleloop, getpoint( end[1] ));
9374 setmark( shelleloop, boundmarker );
9375 /* Try linking the shell edge to triangles that share these vertices. */
9376 for ( shelleloop.shorient = 0; shelleloop.shorient < 2;
9377 shelleloop.shorient++ ) {
9378 /* Take the number for the destination of shelleloop. */
9379 aroundpoint = end[1 - shelleloop.shorient];
9380 /* Look for triangles having this vertex. */
9381 prevlink = &vertexarray[aroundpoint - firstnumber];
9382 nexttri = vertexarray[aroundpoint - firstnumber];
9383 decode( nexttri, checktri );
9384 sorg( shelleloop, shorg );
9385 notfound = 1;
9386 /* Look for triangles having this edge.  Note that I'm only       */
9387 /*   comparing each triangle's destination with the shell edge;   */
9388 /*   each triangle's apex is handled through a different vertex.  */
9389 /*   Because each triangle appears on three vertices' lists, each */
9390 /*   occurrence of a triangle on a list can (and does) represent  */
9391 /*   an edge.  In this way, most edges are represented twice, and */
9392 /*   every triangle-segment bond is represented once.             */
9393 while ( notfound && ( checktri.tri != dummytri )) {
9394 dest( checktri, checkdest );
9395 if ( shorg == checkdest ) {
9396 /* We have a match.  Remove this triangle from the list. */
9397 *prevlink = checktri.tri[6 + checktri.orient];
9398 /* Bond the shell edge to the triangle. */
9399 tsbond( checktri, shelleloop );
9400 /* Check if this is a boundary edge. */
9401 sym( checktri, checkneighbor );
9402 if ( checkneighbor.tri == dummytri ) {
9403 /* The next line doesn't insert a shell edge (because there's */
9404 /*   already one there), but it sets the boundary markers of  */
9405 /*   the existing shell edge and its vertices.                */
9406 insertshelle( &checktri, 1 );
9407 hullsize++;
9408 }
9409 notfound = 0;
9410 }
9411 /* Find the next triangle in the stack. */
9412 prevlink = &checktri.tri[6 + checktri.orient];
9413 nexttri = checktri.tri[6 + checktri.orient];
9414 decode( nexttri, checktri );
9415 }
9416 }
9417 shelleloop.sh = shelletraverse();
9418 segmentnumber++;
9419 }
9420 }
9421
9422 /* Mark the remaining edges as not being attached to any shell edge. */
9423 /* Also, count the (yet uncounted) boundary edges.                   */
9424 for ( i = 0; i < points.items; i++ ) {
9425 /* Search the stack of triangles adjacent to a point. */
9426 nexttri = vertexarray[i];
9427 decode( nexttri, checktri );
9428 while ( checktri.tri != dummytri ) {
9429 /* Find the next triangle in the stack before this */
9430 /*   information gets overwritten.                 */
9431 nexttri = checktri.tri[6 + checktri.orient];
9432 /* No adjacent shell edge.  (This overwrites the stack info.) */
9433 tsdissolve( checktri );
9434 sym( checktri, checkneighbor );
9435 if ( checkneighbor.tri == dummytri ) {
9436 insertshelle( &checktri, 1 );
9437 hullsize++;
9438 }
9439 decode( nexttri, checktri );
9440 }
9441 }
9442
9443 free( vertexarray );
9444 return hullsize;
9445 }
9446
9447 #endif /* not CDT_ONLY */
9448
9449 /**                                                                         **/
9450 /**                                                                         **/
9451 /********* General mesh construction routines end here               *********/
9452
9453 /********* Segment (shell edge) insertion begins here                *********/
9454 /**                                                                         **/
9455 /**                                                                         **/
9456
9457 /*****************************************************************************/
9458 /*                                                                           */
9459 /*  finddirection()   Find the first triangle on the path from one point     */
9460 /*                    to another.                                            */
9461 /*                                                                           */
9462 /*  Finds the triangle that intersects a line segment drawn from the         */
9463 /*  origin of `searchtri' to the point `endpoint', and returns the result    */
9464 /*  in `searchtri'.  The origin of `searchtri' does not change, even though  */
9465 /*  the triangle returned may differ from the one passed in.  This routine   */
9466 /*  is used to find the direction to move in to get from one point to        */
9467 /*  another.                                                                 */
9468 /*                                                                           */
9469 /*  The return value notes whether the destination or apex of the found      */
9470 /*  triangle is collinear with the two points in question.                   */
9471 /*                                                                           */
9472 /*****************************************************************************/
9473
9474 enum finddirectionresult finddirection( searchtri, endpoint )
9475 struct triedge *searchtri;
9476 point endpoint;
9477 {
9478 struct triedge checktri;
9479 point startpoint;
9480 point leftpoint, rightpoint;
9481 REAL leftccw, rightccw;
9482 int leftflag, rightflag;
9483 triangle ptr;         /* Temporary variable used by onext() and oprev(). */
9484
9485 org( *searchtri, startpoint );
9486 dest( *searchtri, rightpoint );
9487 apex( *searchtri, leftpoint );
9488 /* Is `endpoint' to the left? */
9489 leftccw = counterclockwise( endpoint, startpoint, leftpoint );
9490 leftflag = leftccw > 0.0;
9491 /* Is `endpoint' to the right? */
9492 rightccw = counterclockwise( startpoint, endpoint, rightpoint );
9493 rightflag = rightccw > 0.0;
9494 if ( leftflag && rightflag ) {
9495 /* `searchtri' faces directly away from `endpoint'.  We could go */
9496 /*   left or right.  Ask whether it's a triangle or a boundary   */
9497 /*   on the left.                                                */
9498 onext( *searchtri, checktri );
9499 if ( checktri.tri == dummytri ) {
9500 leftflag = 0;
9501 }
9502 else {
9503 rightflag = 0;
9504 }
9505 }
9506 while ( leftflag ) {
9507 /* Turn left until satisfied. */
9508 onextself( *searchtri );
9509 if ( searchtri->tri == dummytri ) {
9510 printf( "Internal error in finddirection():  Unable to find a\n" );
9511 printf( "  triangle leading from (%.12g, %.12g) to", startpoint[0],
9512 startpoint[1] );
9513 printf( "  (%.12g, %.12g).\n", endpoint[0], endpoint[1] );
9514 internalerror();
9515 }
9516 apex( *searchtri, leftpoint );
9517 rightccw = leftccw;
9518 leftccw = counterclockwise( endpoint, startpoint, leftpoint );
9519 leftflag = leftccw > 0.0;
9520 }
9521 while ( rightflag ) {
9522 /* Turn right until satisfied. */
9523 oprevself( *searchtri );
9524 if ( searchtri->tri == dummytri ) {
9525 printf( "Internal error in finddirection():  Unable to find a\n" );
9526 printf( "  triangle leading from (%.12g, %.12g) to", startpoint[0],
9527 startpoint[1] );
9528 printf( "  (%.12g, %.12g).\n", endpoint[0], endpoint[1] );
9529 internalerror();
9530 }
9531 dest( *searchtri, rightpoint );
9532 leftccw = rightccw;
9533 rightccw = counterclockwise( startpoint, endpoint, rightpoint );
9534 rightflag = rightccw > 0.0;
9535 }
9536 if ( leftccw == 0.0 ) {
9537 return LEFTCOLLINEAR;
9538 }
9539 else if ( rightccw == 0.0 ) {
9540 return RIGHTCOLLINEAR;
9541 }
9542 else {
9543 return WITHIN;
9544 }
9545 }
9546
9547 /*****************************************************************************/
9548 /*                                                                           */
9549 /*  segmentintersection()   Find the intersection of an existing segment     */
9550 /*                          and a segment that is being inserted.  Insert    */
9551 /*                          a point at the intersection, splitting an        */
9552 /*                          existing shell edge.                             */
9553 /*                                                                           */
9554 /*  The segment being inserted connects the apex of splittri to endpoint2.   */
9555 /*  splitshelle is the shell edge being split, and MUST be opposite          */
9556 /*  splittri.  Hence, the edge being split connects the origin and           */
9557 /*  destination of splittri.                                                 */
9558 /*                                                                           */
9559 /*  On completion, splittri is a handle having the newly inserted            */
9560 /*  intersection point as its origin, and endpoint1 as its destination.      */
9561 /*                                                                           */
9562 /*****************************************************************************/
9563
9564 void segmentintersection( splittri, splitshelle, endpoint2 )
9565 struct triedge *splittri;
9566 struct edge *splitshelle;
9567 point endpoint2;
9568 {
9569 point endpoint1;
9570 point torg, tdest;
9571 point leftpoint, rightpoint;
9572 point newpoint;
9573 enum insertsiteresult success;
9574 enum finddirectionresult collinear;
9575 REAL ex, ey;
9576 REAL tx, ty;
9577 REAL etx, ety;
9578 REAL split, denom;
9579 int i;
9580 triangle ptr;                     /* Temporary variable used by onext(). */
9581
9582 /* Find the other three segment endpoints. */
9583 apex( *splittri, endpoint1 );
9584 org( *splittri, torg );
9585 dest( *splittri, tdest );
9586 /* Segment intersection formulae; see the Antonio reference. */
9587 tx = tdest[0] - torg[0];
9588 ty = tdest[1] - torg[1];
9589 ex = endpoint2[0] - endpoint1[0];
9590 ey = endpoint2[1] - endpoint1[1];
9591 etx = torg[0] - endpoint2[0];
9592 ety = torg[1] - endpoint2[1];
9593 denom = ty * ex - tx * ey;
9594 if ( denom == 0.0 ) {
9595 printf( "Internal error in segmentintersection():" );
9596 printf( "  Attempt to find intersection of parallel segments.\n" );
9597 internalerror();
9598 }
9599 split = ( ey * etx - ex * ety ) / denom;
9600 /* Create the new point. */
9601 newpoint = (point) poolalloc( &points );
9602 /* Interpolate its coordinate and attributes. */
9603 for ( i = 0; i < 2 + nextras; i++ ) {
9604 newpoint[i] = torg[i] + split * ( tdest[i] - torg[i] );
9605 }
9606 setpointmark( newpoint, mark( *splitshelle ));
9607 if ( verbose > 1 ) {
9608 printf(
9609 "  Splitting edge (%.12g, %.12g) (%.12g, %.12g) at (%.12g, %.12g).\n",
9610 torg[0], torg[1], tdest[0], tdest[1], newpoint[0], newpoint[1] );
9611 }
9612 /* Insert the intersection point.  This should always succeed. */
9613 success = insertsite( newpoint, splittri, splitshelle, 0, 0 );
9614 if ( success != SUCCESSFULPOINT ) {
9615 printf( "Internal error in segmentintersection():\n" );
9616 printf( "  Failure to split a segment.\n" );
9617 internalerror();
9618 }
9619 if ( steinerleft > 0 ) {
9620 steinerleft--;
9621 }
9622 /* Inserting the point may have caused edge flips.  We wish to rediscover */
9623 /*   the edge connecting endpoint1 to the new intersection point.         */
9624 collinear = finddirection( splittri, endpoint1 );
9625 dest( *splittri, rightpoint );
9626 apex( *splittri, leftpoint );
9627 if (( leftpoint[0] == endpoint1[0] ) && ( leftpoint[1] == endpoint1[1] )) {
9628 onextself( *splittri );
9629 }
9630 else if (( rightpoint[0] != endpoint1[0] ) ||
9631 ( rightpoint[1] != endpoint1[1] )) {
9632 printf( "Internal error in segmentintersection():\n" );
9633 printf( "  Topological inconsistency after splitting a segment.\n" );
9634 internalerror();
9635 }
9636 /* `splittri' should have destination endpoint1. */
9637 }
9638
9639 /*****************************************************************************/
9640 /*                                                                           */
9641 /*  scoutsegment()   Scout the first triangle on the path from one endpoint  */
9642 /*                   to another, and check for completion (reaching the      */
9643 /*                   second endpoint), a collinear point, and the            */
9644 /*                   intersection of two segments.                           */
9645 /*                                                                           */
9646 /*  Returns one if the entire segment is successfully inserted, and zero if  */
9647 /*  the job must be finished by conformingedge() or constrainededge().       */
9648 /*                                                                           */
9649 /*  If the first triangle on the path has the second endpoint as its         */
9650 /*  destination or apex, a shell edge is inserted and the job is done.       */
9651 /*                                                                           */
9652 /*  If the first triangle on the path has a destination or apex that lies on */
9653 /*  the segment, a shell edge is inserted connecting the first endpoint to   */
9654 /*  the collinear point, and the search is continued from the collinear      */
9655 /*  point.                                                                   */
9656 /*                                                                           */
9657 /*  If the first triangle on the path has a shell edge opposite its origin,  */
9658 /*  then there is a segment that intersects the segment being inserted.      */
9659 /*  Their intersection point is inserted, splitting the shell edge.          */
9660 /*                                                                           */
9661 /*  Otherwise, return zero.                                                  */
9662 /*                                                                           */
9663 /*****************************************************************************/
9664
9665 int scoutsegment( searchtri, endpoint2, newmark )
9666 struct triedge *searchtri;
9667 point endpoint2;
9668 int newmark;
9669 {
9670 struct triedge crosstri;
9671 struct edge crossedge;
9672 point leftpoint, rightpoint;
9673 point endpoint1;
9674 enum finddirectionresult collinear;
9675 shelle sptr;                    /* Temporary variable used by tspivot(). */
9676
9677 collinear = finddirection( searchtri, endpoint2 );
9678 dest( *searchtri, rightpoint );
9679 apex( *searchtri, leftpoint );
9680 if ((( leftpoint[0] == endpoint2[0] ) && ( leftpoint[1] == endpoint2[1] )) ||
9681 (( rightpoint[0] == endpoint2[0] ) && ( rightpoint[1] == endpoint2[1] ))) {
9682 /* The segment is already an edge in the mesh. */
9683 if (( leftpoint[0] == endpoint2[0] ) && ( leftpoint[1] == endpoint2[1] )) {
9684 lprevself( *searchtri );
9685 }
9686 /* Insert a shell edge, if there isn't already one there. */
9687 insertshelle( searchtri, newmark );
9688 return 1;
9689 }
9690 else if ( collinear == LEFTCOLLINEAR ) {
9691 /* We've collided with a point between the segment's endpoints. */
9692 /* Make the collinear point be the triangle's origin. */
9693 lprevself( *searchtri );
9694 insertshelle( searchtri, newmark );
9695 /* Insert the remainder of the segment. */
9696 return scoutsegment( searchtri, endpoint2, newmark );
9697 }
9698 else if ( collinear == RIGHTCOLLINEAR ) {
9699 /* We've collided with a point between the segment's endpoints. */
9700 insertshelle( searchtri, newmark );
9701 /* Make the collinear point be the triangle's origin. */
9702 lnextself( *searchtri );
9703 /* Insert the remainder of the segment. */
9704 return scoutsegment( searchtri, endpoint2, newmark );
9705 }
9706 else {
9707 lnext( *searchtri, crosstri );
9708 tspivot( crosstri, crossedge );
9709 /* Check for a crossing segment. */
9710 if ( crossedge.sh == dummysh ) {
9711 return 0;
9712 }
9713 else {
9714 org( *searchtri, endpoint1 );
9715 /* Insert a point at the intersection. */
9716 segmentintersection( &crosstri, &crossedge, endpoint2 );
9717 triedgecopy( crosstri, *searchtri );
9718 insertshelle( searchtri, newmark );
9719 /* Insert the remainder of the segment. */
9720 return scoutsegment( searchtri, endpoint2, newmark );
9721 }
9722 }
9723 }
9724
9725 /*****************************************************************************/
9726 /*                                                                           */
9727 /*  conformingedge()   Force a segment into a conforming Delaunay            */
9728 /*                     triangulation by inserting a point at its midpoint,   */
9729 /*                     and recursively forcing in the two half-segments if   */
9730 /*                     necessary.                                            */
9731 /*                                                                           */
9732 /*  Generates a sequence of edges connecting `endpoint1' to `endpoint2'.     */
9733 /*  `newmark' is the boundary marker of the segment, assigned to each new    */
9734 /*  splitting point and shell edge.                                          */
9735 /*                                                                           */
9736 /*  Note that conformingedge() does not always maintain the conforming       */
9737 /*  Delaunay property.  Once inserted, segments are locked into place;       */
9738 /*  points inserted later (to force other segments in) may render these      */
9739 /*  fixed segments non-Delaunay.  The conforming Delaunay property will be   */
9740 /*  restored by enforcequality() by splitting encroached segments.           */
9741 /*                                                                           */
9742 /*****************************************************************************/
9743
9744 #ifndef
9745 REDUCED
9746 #ifndef
9747 CDT_ONLY
9748
9749 void conformingedge( endpoint1, endpoint2, newmark )
9750 point endpoint1;
9751 point endpoint2;
9752 int newmark;
9753 {
9754 struct triedge searchtri1, searchtri2;
9755 struct edge brokenshelle;
9756 point newpoint;
9757 point midpoint1, midpoint2;
9758 enum insertsiteresult success;
9759 int result1, result2;
9760 int i;
9761 shelle sptr;                    /* Temporary variable used by tspivot(). */
9762
9763 if ( verbose > 2 ) {
9764 printf( "Forcing segment into triangulation by recursive splitting:\n" );
9765 printf( "  (%.12g, %.12g) (%.12g, %.12g)\n", endpoint1[0], endpoint1[1],
9766 endpoint2[0], endpoint2[1] );
9767 }
9768 /* Create a new point to insert in the middle of the segment. */
9769 newpoint = (point) poolalloc( &points );
9770 /* Interpolate coordinates and attributes. */
9771 for ( i = 0; i < 2 + nextras; i++ ) {
9772 newpoint[i] = 0.5 * ( endpoint1[i] + endpoint2[i] );
9773 }
9774 setpointmark( newpoint, newmark );
9775 /* Find a boundary triangle to search from. */
9776 searchtri1.tri = (triangle *) NULL;
9777 /* Attempt to insert the new point. */
9778 success = insertsite( newpoint, &searchtri1, (struct edge *) NULL, 0, 0 );
9779 if ( success == DUPLICATEPOINT ) {
9780 if ( verbose > 2 ) {
9781 printf( "  Segment intersects existing point (%.12g, %.12g).\n",
9782 newpoint[0], newpoint[1] );
9783 }
9784 /* Use the point that's already there. */
9785 pointdealloc( newpoint );
9786 org( searchtri1, newpoint );
9787 }
9788 else {
9789 if ( success == VIOLATINGPOINT ) {
9790 if ( verbose > 2 ) {
9791 printf( "  Two segments intersect at (%.12g, %.12g).\n",
9792 newpoint[0], newpoint[1] );
9793 }
9794 /* By fluke, we've landed right on another segment.  Split it. */
9795 tspivot( searchtri1, brokenshelle );
9796 success = insertsite( newpoint, &searchtri1, &brokenshelle, 0, 0 );
9797 if ( success != SUCCESSFULPOINT ) {
9798 printf( "Internal error in conformingedge():\n" );
9799 printf( "  Failure to split a segment.\n" );
9800 internalerror();
9801 }
9802 }
9803 /* The point has been inserted successfully. */
9804 if ( steinerleft > 0 ) {
9805 steinerleft--;
9806 }
9807 }
9808 triedgecopy( searchtri1, searchtri2 );
9809 result1 = scoutsegment( &searchtri1, endpoint1, newmark );
9810 result2 = scoutsegment( &searchtri2, endpoint2, newmark );
9811 if ( !result1 ) {
9812 /* The origin of searchtri1 may have changed if a collision with an */
9813 /*   intervening vertex on the segment occurred.                    */
9814 org( searchtri1, midpoint1 );
9815 conformingedge( midpoint1, endpoint1, newmark );
9816 }
9817 if ( !result2 ) {
9818 /* The origin of searchtri2 may have changed if a collision with an */
9819 /*   intervening vertex on the segment occurred.                    */
9820 org( searchtri2, midpoint2 );
9821 conformingedge( midpoint2, endpoint2, newmark );
9822 }
9823 }
9824
9825 #endif /* not CDT_ONLY */
9826 #endif /* not REDUCED */
9827
9828 /*****************************************************************************/
9829 /*                                                                           */
9830 /*  delaunayfixup()   Enforce the Delaunay condition at an edge, fanning out */
9831 /*                    recursively from an existing point.  Pay special       */
9832 /*                    attention to stacking inverted triangles.              */
9833 /*                                                                           */
9834 /*  This is a support routine for inserting segments into a constrained      */
9835 /*  Delaunay triangulation.                                                  */
9836 /*                                                                           */
9837 /*  The origin of fixuptri is treated as if it has just been inserted, and   */
9838 /*  the local Delaunay condition needs to be enforced.  It is only enforced  */
9839 /*  in one sector, however, that being the angular range defined by          */
9840 /*  fixuptri.                                                                */
9841 /*                                                                           */
9842 /*  This routine also needs to make decisions regarding the "stacking" of    */
9843 /*  triangles.  (Read the description of constrainededge() below before      */
9844 /*  reading on here, so you understand the algorithm.)  If the position of   */
9845 /*  the new point (the origin of fixuptri) indicates that the vertex before  */
9846 /*  it on the polygon is a reflex vertex, then "stack" the triangle by       */
9847 /*  doing nothing.  (fixuptri is an inverted triangle, which is how stacked  */
9848 /*  triangles are identified.)                                               */
9849 /*                                                                           */
9850 /*  Otherwise, check whether the vertex before that was a reflex vertex.     */
9851 /*  If so, perform an edge flip, thereby eliminating an inverted triangle    */
9852 /*  (popping it off the stack).  The edge flip may result in the creation    */
9853 /*  of a new inverted triangle, depending on whether or not the new vertex   */
9854 /*  is visible to the vertex three edges behind on the polygon.              */
9855 /*                                                                           */
9856 /*  If neither of the two vertices behind the new vertex are reflex          */
9857 /*  vertices, fixuptri and fartri, the triangle opposite it, are not         */
9858 /*  inverted; hence, ensure that the edge between them is locally Delaunay.  */
9859 /*                                                                           */
9860 /*  `leftside' indicates whether or not fixuptri is to the left of the       */
9861 /*  segment being inserted.  (Imagine that the segment is pointing up from   */
9862 /*  endpoint1 to endpoint2.)                                                 */
9863 /*                                                                           */
9864 /*****************************************************************************/
9865
9866 void delaunayfixup( fixuptri, leftside )
9867 struct triedge *fixuptri;
9868 int leftside;
9869 {
9870 struct triedge neartri;
9871 struct triedge fartri;
9872 struct edge faredge;
9873 point nearpoint, leftpoint, rightpoint, farpoint;
9874 triangle ptr;                       /* Temporary variable used by sym(). */
9875 shelle sptr;                    /* Temporary variable used by tspivot(). */
9876
9877 lnext( *fixuptri, neartri );
9878 sym( neartri, fartri );
9879 /* Check if the edge opposite the origin of fixuptri can be flipped. */
9880 if ( fartri.tri == dummytri ) {
9881 return;
9882 }
9883 tspivot( neartri, faredge );
9884 if ( faredge.sh != dummysh ) {
9885 return;
9886 }
9887 /* Find all the relevant vertices. */
9888 apex( neartri, nearpoint );
9889 org( neartri, leftpoint );
9890 dest( neartri, rightpoint );
9891 apex( fartri, farpoint );
9892 /* Check whether the previous polygon vertex is a reflex vertex. */
9893 if ( leftside ) {
9894 if ( counterclockwise( nearpoint, leftpoint, farpoint ) <= 0.0 ) {
9895 /* leftpoint is a reflex vertex too.  Nothing can */
9896 /*   be done until a convex section is found.     */
9897 return;
9898 }
9899 }
9900 else {
9901 if ( counterclockwise( farpoint, rightpoint, nearpoint ) <= 0.0 ) {
9902 /* rightpoint is a reflex vertex too.  Nothing can */
9903 /*   be done until a convex section is found.      */
9904 return;
9905 }
9906 }
9907 if ( counterclockwise( rightpoint, leftpoint, farpoint ) > 0.0 ) {
9908 /* fartri is not an inverted triangle, and farpoint is not a reflex */
9909 /*   vertex.  As there are no reflex vertices, fixuptri isn't an    */
9910 /*   inverted triangle, either.  Hence, test the edge between the   */
9911 /*   triangles to ensure it is locally Delaunay.                    */
9912 if ( incircle( leftpoint, farpoint, rightpoint, nearpoint ) <= 0.0 ) {
9913 return;
9914 }
9915 /* Not locally Delaunay; go on to an edge flip. */
9916 }      /* else fartri is inverted; remove it from the stack by flipping. */
9917 flip( &neartri );
9918 lprevself( *fixuptri ); /* Restore the origin of fixuptri after the flip. */
9919 /* Recursively process the two triangles that result from the flip. */
9920 delaunayfixup( fixuptri, leftside );
9921 delaunayfixup( &fartri, leftside );
9922 }
9923
9924 /*****************************************************************************/
9925 /*                                                                           */
9926 /*  constrainededge()   Force a segment into a constrained Delaunay          */
9927 /*                      triangulation by deleting the triangles it           */
9928 /*                      intersects, and triangulating the polygons that      */
9929 /*                      form on each side of it.                             */
9930 /*                                                                           */
9931 /*  Generates a single edge connecting `endpoint1' to `endpoint2'.  The      */
9932 /*  triangle `starttri' has `endpoint1' as its origin.  `newmark' is the     */
9933 /*  boundary marker of the segment.                                          */
9934 /*                                                                           */
9935 /*  To insert a segment, every triangle whose interior intersects the        */
9936 /*  segment is deleted.  The union of these deleted triangles is a polygon   */
9937 /*  (which is not necessarily monotone, but is close enough), which is       */
9938 /*  divided into two polygons by the new segment.  This routine's task is    */
9939 /*  to generate the Delaunay triangulation of these two polygons.            */
9940 /*                                                                           */
9941 /*  You might think of this routine's behavior as a two-step process.  The   */
9942 /*  first step is to walk from endpoint1 to endpoint2, flipping each edge    */
9943 /*  encountered.  This step creates a fan of edges connected to endpoint1,   */
9944 /*  including the desired edge to endpoint2.  The second step enforces the   */
9945 /*  Delaunay condition on each side of the segment in an incremental manner: */
9946 /*  proceeding along the polygon from endpoint1 to endpoint2 (this is done   */
9947 /*  independently on each side of the segment), each vertex is "enforced"    */
9948 /*  as if it had just been inserted, but affecting only the previous         */
9949 /*  vertices.  The result is the same as if the vertices had been inserted   */
9950 /*  in the order they appear on the polygon, so the result is Delaunay.      */
9951 /*                                                                           */
9952 /*  In truth, constrainededge() interleaves these two steps.  The procedure  */
9953 /*  walks from endpoint1 to endpoint2, and each time an edge is encountered  */
9954 /*  and flipped, the newly exposed vertex (at the far end of the flipped     */
9955 /*  edge) is "enforced" upon the previously flipped edges, usually affecting */
9956 /*  only one side of the polygon (depending upon which side of the segment   */
9957 /*  the vertex falls on).                                                    */
9958 /*                                                                           */
9959 /*  The algorithm is complicated by the need to handle polygons that are not */
9960 /*  convex.  Although the polygon is not necessarily monotone, it can be     */
9961 /*  triangulated in a manner similar to the stack-based algorithms for       */
9962 /*  monotone polygons.  For each reflex vertex (local concavity) of the      */
9963 /*  polygon, there will be an inverted triangle formed by one of the edge    */
9964 /*  flips.  (An inverted triangle is one with negative area - that is, its   */
9965 /*  vertices are arranged in clockwise order - and is best thought of as a   */
9966 /*  wrinkle in the fabric of the mesh.)  Each inverted triangle can be       */
9967 /*  thought of as a reflex vertex pushed on the stack, waiting to be fixed   */
9968 /*  later.                                                                   */
9969 /*                                                                           */
9970 /*  A reflex vertex is popped from the stack when a vertex is inserted that  */
9971 /*  is visible to the reflex vertex.  (However, if the vertex behind the     */
9972 /*  reflex vertex is not visible to the reflex vertex, a new inverted        */
9973 /*  triangle will take its place on the stack.)  These details are handled   */
9974 /*  by the delaunayfixup() routine above.                                    */
9975 /*                                                                           */
9976 /*****************************************************************************/
9977
9978 void constrainededge( starttri, endpoint2, newmark )
9979 struct triedge *starttri;
9980 point endpoint2;
9981 int newmark;
9982 {
9983 struct triedge fixuptri, fixuptri2;
9984 struct edge fixupedge;
9985 point endpoint1;
9986 point farpoint;
9987 REAL area;
9988 int collision;
9989 int done;
9990 triangle ptr;           /* Temporary variable used by sym() and oprev(). */
9991 shelle sptr;                    /* Temporary variable used by tspivot(). */
9992
9993 org( *starttri, endpoint1 );
9994 lnext( *starttri, fixuptri );
9995 flip( &fixuptri );
9996 /* `collision' indicates whether we have found a point directly */
9997 /*   between endpoint1 and endpoint2.                           */
9998 collision = 0;
9999 done = 0;
10000 do {
10001 org( fixuptri, farpoint );
10002 /* `farpoint' is the extreme point of the polygon we are "digging" */
10003 /*   to get from endpoint1 to endpoint2.                           */
10004 if (( farpoint[0] == endpoint2[0] ) && ( farpoint[1] == endpoint2[1] )) {
10005 oprev( fixuptri, fixuptri2 );
10006 /* Enforce the Delaunay condition around endpoint2. */
10007 delaunayfixup( &fixuptri, 0 );
10008 delaunayfixup( &fixuptri2, 1 );
10009 done = 1;
10010 }
10011 else {
10012 /* Check whether farpoint is to the left or right of the segment */
10013 /*   being inserted, to decide which edge of fixuptri to dig     */
10014 /*   through next.                                               */
10015 area = counterclockwise( endpoint1, endpoint2, farpoint );
10016 if ( area == 0.0 ) {
10017 /* We've collided with a point between endpoint1 and endpoint2. */
10018 collision = 1;
10019 oprev( fixuptri, fixuptri2 );
10020 /* Enforce the Delaunay condition around farpoint. */
10021 delaunayfixup( &fixuptri, 0 );
10022 delaunayfixup( &fixuptri2, 1 );
10023 done = 1;
10024 }
10025 else {
10026 if ( area > 0.0 ) { /* farpoint is to the left of the segment. */
10027 oprev( fixuptri, fixuptri2 );
10028 /* Enforce the Delaunay condition around farpoint, on the */
10029 /*   left side of the segment only.                       */
10030 delaunayfixup( &fixuptri2, 1 );
10031 /* Flip the edge that crosses the segment.  After the edge is */
10032 /*   flipped, one of its endpoints is the fan vertex, and the */
10033 /*   destination of fixuptri is the fan vertex.               */
10034 lprevself( fixuptri );
10035 }
10036 else {           /* farpoint is to the right of the segment. */
10037 delaunayfixup( &fixuptri, 0 );
10038 /* Flip the edge that crosses the segment.  After the edge is */
10039 /*   flipped, one of its endpoints is the fan vertex, and the */
10040 /*   destination of fixuptri is the fan vertex.               */
10041 oprevself( fixuptri );
10042 }
10043 /* Check for two intersecting segments. */
10044 tspivot( fixuptri, fixupedge );
10045 if ( fixupedge.sh == dummysh ) {
10046 flip( &fixuptri ); /* May create an inverted triangle on the left. */
10047 }
10048 else {
10049 /* We've collided with a segment between endpoint1 and endpoint2. */
10050 collision = 1;
10051 /* Insert a point at the intersection. */
10052 segmentintersection( &fixuptri, &fixupedge, endpoint2 );
10053 done = 1;
10054 }
10055 }
10056 }
10057 } while ( !done );
10058 /* Insert a shell edge to make the segment permanent. */
10059 insertshelle( &fixuptri, newmark );
10060 /* If there was a collision with an interceding vertex, install another */
10061 /*   segment connecting that vertex with endpoint2.                     */
10062 if ( collision ) {
10063 /* Insert the remainder of the segment. */
10064 if ( !scoutsegment( &fixuptri, endpoint2, newmark )) {
10065 constrainededge( &fixuptri, endpoint2, newmark );
10066 }
10067 }
10068 }
10069
10070 /*****************************************************************************/
10071 /*                                                                           */
10072 /*  insertsegment()   Insert a PSLG segment into a triangulation.            */
10073 /*                                                                           */
10074 /*****************************************************************************/
10075
10076 void insertsegment( endpoint1, endpoint2, newmark )
10077 point endpoint1;
10078 point endpoint2;
10079 int newmark;
10080 {
10081 struct triedge searchtri1, searchtri2;
10082 triangle encodedtri;
10083 point checkpoint;
10084 triangle ptr;                       /* Temporary variable used by sym(). */
10085
10086 if ( verbose > 1 ) {
10087 printf( "  Connecting (%.12g, %.12g) to (%.12g, %.12g).\n",
10088 endpoint1[0], endpoint1[1], endpoint2[0], endpoint2[1] );
10089 }
10090
10091 /* Find a triangle whose origin is the segment's first endpoint. */
10092 checkpoint = (point) NULL;
10093 encodedtri = point2tri( endpoint1 );
10094 if ( encodedtri != (triangle) NULL ) {
10095 decode( encodedtri, searchtri1 );
10096 org( searchtri1, checkpoint );
10097 }
10098 if ( checkpoint != endpoint1 ) {
10099 /* Find a boundary triangle to search from. */
10100 searchtri1.tri = dummytri;
10101 searchtri1.orient = 0;
10102 symself( searchtri1 );
10103 /* Search for the segment's first endpoint by point location. */
10104 if ( locate( endpoint1, &searchtri1 ) != ONVERTEX ) {
10105 printf(
10106 "Internal error in insertsegment():  Unable to locate PSLG point\n" );
10107 printf( "  (%.12g, %.12g) in triangulation.\n",
10108 endpoint1[0], endpoint1[1] );
10109 internalerror();
10110 }
10111 }
10112 /* Remember this triangle to improve subsequent point location. */
10113 triedgecopy( searchtri1, recenttri );
10114 /* Scout the beginnings of a path from the first endpoint */
10115 /*   toward the second.                                   */
10116 if ( scoutsegment( &searchtri1, endpoint2, newmark )) {
10117 /* The segment was easily inserted. */
10118 return;
10119 }
10120 /* The first endpoint may have changed if a collision with an intervening */
10121 /*   vertex on the segment occurred.                                      */
10122 org( searchtri1, endpoint1 );
10123
10124 /* Find a triangle whose origin is the segment's second endpoint. */
10125 checkpoint = (point) NULL;
10126 encodedtri = point2tri( endpoint2 );
10127 if ( encodedtri != (triangle) NULL ) {
10128 decode( encodedtri, searchtri2 );
10129 org( searchtri2, checkpoint );
10130 }
10131 if ( checkpoint != endpoint2 ) {
10132 /* Find a boundary triangle to search from. */
10133 searchtri2.tri = dummytri;
10134 searchtri2.orient = 0;
10135 symself( searchtri2 );
10136 /* Search for the segment's second endpoint by point location. */
10137 if ( locate( endpoint2, &searchtri2 ) != ONVERTEX ) {
10138 printf(
10139 "Internal error in insertsegment():  Unable to locate PSLG point\n" );
10140 printf( "  (%.12g, %.12g) in triangulation.\n",
10141 endpoint2[0], endpoint2[1] );
10142 internalerror();
10143 }
10144 }
10145 /* Remember this triangle to improve subsequent point location. */
10146 triedgecopy( searchtri2, recenttri );
10147 /* Scout the beginnings of a path from the second endpoint */
10148 /*   toward the first.                                     */
10149 if ( scoutsegment( &searchtri2, endpoint1, newmark )) {
10150 /* The segment was easily inserted. */
10151 return;
10152 }
10153 /* The second endpoint may have changed if a collision with an intervening */
10154 /*   vertex on the segment occurred.                                       */
10155 org( searchtri2, endpoint2 );
10156
10157 #ifndef
10158 REDUCED
10159 #ifndef
10160 CDT_ONLY
10161 if ( splitseg ) {
10162 /* Insert vertices to force the segment into the triangulation. */
10163 conformingedge( endpoint1, endpoint2, newmark );
10164 }
10165 else {
10166 #endif /* not CDT_ONLY */
10167 #endif /* not REDUCED */
10168 /* Insert the segment directly into the triangulation. */
10169 constrainededge( &searchtri1, endpoint2, newmark );
10170 #ifndef
10171 REDUCED
10172 #ifndef
10173 CDT_ONLY
10174 }
10175 #endif /* not CDT_ONLY */
10176 #endif /* not REDUCED */
10177 }
10178
10179 /*****************************************************************************/
10180 /*                                                                           */
10181 /*  markhull()   Cover the convex hull of a triangulation with shell edges.  */
10182 /*                                                                           */
10183 /*****************************************************************************/
10184
10185 void markhull(){
10186 struct triedge hulltri;
10187 struct triedge nexttri;
10188 struct triedge starttri;
10189 triangle ptr;           /* Temporary variable used by sym() and oprev(). */
10190
10191 /* Find a triangle handle on the hull. */
10192 hulltri.tri = dummytri;
10193 hulltri.orient = 0;
10194 symself( hulltri );
10195 /* Remember where we started so we know when to stop. */
10196 triedgecopy( hulltri, starttri );
10197 /* Go once counterclockwise around the convex hull. */
10198 do {
10199 /* Create a shell edge if there isn't already one here. */
10200 insertshelle( &hulltri, 1 );
10201 /* To find the next hull edge, go clockwise around the next vertex. */
10202 lnextself( hulltri );
10203 oprev( hulltri, nexttri );
10204 while ( nexttri.tri != dummytri ) {
10205 triedgecopy( nexttri, hulltri );
10206 oprev( hulltri, nexttri );
10207 }
10208 } while ( !triedgeequal( hulltri, starttri ));
10209 }
10210
10211 /*****************************************************************************/
10212 /*                                                                           */
10213 /*  formskeleton()   Create the shell edges of a triangulation, including    */
10214 /*                   PSLG edges and edges on the convex hull.                */
10215 /*                                                                           */
10216 /*  The PSLG edges are read from a .poly file.  The return value is the      */
10217 /*  number of segments in the file.                                          */
10218 /*                                                                           */
10219 /*****************************************************************************/
10220
10221 #ifdef
10222 TRILIBRARY
10223
10224 int formskeleton( segmentlist, segmentmarkerlist, numberofsegments )
10225 int *segmentlist;
10226 int *segmentmarkerlist;
10227 int numberofsegments;
10228
10229 #else /* not TRILIBRARY */
10230
10231 int formskeleton( polyfile, polyfilename )
10232 FILE * polyfile;
10233 char *polyfilename;
10234
10235 #endif /* not TRILIBRARY */
10236
10237 {
10238 #ifdef
10239 TRILIBRARY
10240 char polyfilename[6];
10241 int index;
10242 #else /* not TRILIBRARY */
10243 char inputline[INPUTLINESIZE];
10244 char *stringptr;
10245 #endif /* not TRILIBRARY */
10246 point endpoint1, endpoint2;
10247 int segments;
10248 int segmentmarkers;
10249 int end1, end2;
10250 int boundmarker;
10251 int i;
10252
10253 if ( poly ) {
10254 if ( !quiet ) {
10255 printf( "Inserting segments into Delaunay triangulation.\n" );
10256 }
10257 #ifdef
10258 TRILIBRARY
10259 strcpy( polyfilename, "input" );
10260 segments = numberofsegments;
10261 segmentmarkers = segmentmarkerlist != (int *) NULL;
10262 index = 0;
10263 #else /* not TRILIBRARY */
10264 /* Read the segments from a .poly file. */
10265 /* Read number of segments and number of boundary markers. */
10266 stringptr = readline( inputline, polyfile, polyfilename );
10267 segments = (int) strtol( stringptr, &stringptr, 0 );
10268 stringptr = findfield( stringptr );
10269 if ( *stringptr == '\0' ) {
10270 segmentmarkers = 0;
10271 }
10272 else {
10273 segmentmarkers = (int) strtol( stringptr, &stringptr, 0 );
10274 }
10275 #endif /* not TRILIBRARY */
10276 /* If segments are to be inserted, compute a mapping */
10277 /*   from points to triangles.                       */
10278 if ( segments > 0 ) {
10279 if ( verbose ) {
10280 printf( "  Inserting PSLG segments.\n" );
10281 }
10282 makepointmap();
10283 }
10284
10285 boundmarker = 0;
10286 /* Read and insert the segments. */
10287 for ( i = 1; i <= segments; i++ ) {
10288 #ifdef
10289 TRILIBRARY
10290 end1 = segmentlist[index++];
10291 end2 = segmentlist[index++];
10292 if ( segmentmarkers ) {
10293 boundmarker = segmentmarkerlist[i - 1];
10294 }
10295 #else /* not TRILIBRARY */
10296 stringptr = readline( inputline, polyfile, inpolyfilename );
10297 stringptr = findfield( stringptr );
10298 if ( *stringptr == '\0' ) {
10299 printf( "Error:  Segment %d has no endpoints in %s.\n", i,
10300 polyfilename );
10301 exit( 1 );
10302 }
10303 else {
10304 end1 = (int) strtol( stringptr, &stringptr, 0 );
10305 }
10306 stringptr = findfield( stringptr );
10307 if ( *stringptr == '\0' ) {
10308 printf( "Error:  Segment %d is missing its second endpoint in %s.\n", i,
10309 polyfilename );
10310 exit( 1 );
10311 }
10312 else {
10313 end2 = (int) strtol( stringptr, &stringptr, 0 );
10314 }
10315 if ( segmentmarkers ) {
10316 stringptr = findfield( stringptr );
10317 if ( *stringptr == '\0' ) {
10318 boundmarker = 0;
10319 }
10320 else {
10321 boundmarker = (int) strtol( stringptr, &stringptr, 0 );
10322 }
10323 }
10324 #endif /* not TRILIBRARY */
10325 if (( end1 < firstnumber ) || ( end1 >= firstnumber + inpoints )) {
10326 if ( !quiet ) {
10327 printf( "Warning:  Invalid first endpoint of segment %d in %s.\n", i,
10328 polyfilename );
10329 }
10330 }
10331 else if (( end2 < firstnumber ) || ( end2 >= firstnumber + inpoints )) {
10332 if ( !quiet ) {
10333 printf( "Warning:  Invalid second endpoint of segment %d in %s.\n", i,
10334 polyfilename );
10335 }
10336 }
10337 else {
10338 endpoint1 = getpoint( end1 );
10339 endpoint2 = getpoint( end2 );
10340 if (( endpoint1[0] == endpoint2[0] ) && ( endpoint1[1] == endpoint2[1] )) {
10341 if ( !quiet ) {
10342 printf( "Warning:  Endpoints of segment %d are coincident in %s.\n",
10343 i, polyfilename );
10344 }
10345 }
10346 else {
10347 insertsegment( endpoint1, endpoint2, boundmarker );
10348 }
10349 }
10350 }
10351 }
10352 else {
10353 segments = 0;
10354 }
10355 if ( convex || !poly ) {
10356 /* Enclose the convex hull with shell edges. */
10357 if ( verbose ) {
10358 printf( "  Enclosing convex hull with segments.\n" );
10359 }
10360 markhull();
10361 }
10362 return segments;
10363 }
10364
10365 /**                                                                         **/
10366 /**                                                                         **/
10367 /********* Segment (shell edge) insertion ends here                  *********/
10368
10369 /********* Carving out holes and concavities begins here             *********/
10370 /**                                                                         **/
10371 /**                                                                         **/
10372
10373 /*****************************************************************************/
10374 /*                                                                           */
10375 /*  infecthull()   Virally infect all of the triangles of the convex hull    */
10376 /*                 that are not protected by shell edges.  Where there are   */
10377 /*                 shell edges, set boundary markers as appropriate.         */
10378 /*                                                                           */
10379 /*****************************************************************************/
10380
10381 void infecthull(){
10382 struct triedge hulltri;
10383 struct triedge nexttri;
10384 struct triedge starttri;
10385 struct edge hulledge;
10386 triangle **deadtri;
10387 point horg, hdest;
10388 triangle ptr;                       /* Temporary variable used by sym(). */
10389 shelle sptr;                    /* Temporary variable used by tspivot(). */
10390
10391 if ( verbose ) {
10392 printf( "  Marking concavities (external triangles) for elimination.\n" );
10393 }
10394 /* Find a triangle handle on the hull. */
10395 hulltri.tri = dummytri;
10396 hulltri.orient = 0;
10397 symself( hulltri );
10398 /* Remember where we started so we know when to stop. */
10399 triedgecopy( hulltri, starttri );
10400 /* Go once counterclockwise around the convex hull. */
10401 do {
10402 /* Ignore triangles that are already infected. */
10403 if ( !infected( hulltri )) {
10404 /* Is the triangle protected by a shell edge? */
10405 tspivot( hulltri, hulledge );
10406 if ( hulledge.sh == dummysh ) {
10407 /* The triangle is not protected; infect it. */
10408 infect( hulltri );
10409 deadtri = (triangle **) poolalloc( &viri );
10410 *deadtri = hulltri.tri;
10411 }
10412 else {
10413 /* The triangle is protected; set boundary markers if appropriate. */
10414 if ( mark( hulledge ) == 0 ) {
10415 setmark( hulledge, 1 );
10416 org( hulltri, horg );
10417 dest( hulltri, hdest );
10418 if ( pointmark( horg ) == 0 ) {
10419 setpointmark( horg, 1 );
10420 }
10421 if ( pointmark( hdest ) == 0 ) {
10422 setpointmark( hdest, 1 );
10423 }
10424 }
10425 }
10426 }
10427 /* To find the next hull edge, go clockwise around the next vertex. */
10428 lnextself( hulltri );
10429 oprev( hulltri, nexttri );
10430 while ( nexttri.tri != dummytri ) {
10431 triedgecopy( nexttri, hulltri );
10432 oprev( hulltri, nexttri );
10433 }
10434 } while ( !triedgeequal( hulltri, starttri ));
10435 }
10436
10437 /*****************************************************************************/
10438 /*                                                                           */
10439 /*  plague()   Spread the virus from all infected triangles to any neighbors */
10440 /*             not protected by shell edges.  Delete all infected triangles. */
10441 /*                                                                           */
10442 /*  This is the procedure that actually creates holes and concavities.       */
10443 /*                                                                           */
10444 /*  This procedure operates in two phases.  The first phase identifies all   */
10445 /*  the triangles that will die, and marks them as infected.  They are       */
10446 /*  marked to ensure that each triangle is added to the virus pool only      */
10447 /*  once, so the procedure will terminate.                                   */
10448 /*                                                                           */
10449 /*  The second phase actually eliminates the infected triangles.  It also    */
10450 /*  eliminates orphaned points.                                              */
10451 /*                                                                           */
10452 /*****************************************************************************/
10453
10454 void plague(){
10455 struct triedge testtri;
10456 struct triedge neighbor;
10457 triangle **virusloop;
10458 triangle **deadtri;
10459 struct edge neighborshelle;
10460 point testpoint;
10461 point norg, ndest;
10462 point deadorg, deaddest, deadapex;
10463 int killorg;
10464 triangle ptr;           /* Temporary variable used by sym() and onext(). */
10465 shelle sptr;                    /* Temporary variable used by tspivot(). */
10466
10467 if ( verbose ) {
10468 printf( "  Marking neighbors of marked triangles.\n" );
10469 }
10470 /* Loop through all the infected triangles, spreading the virus to */
10471 /*   their neighbors, then to their neighbors' neighbors.          */
10472 traversalinit( &viri );
10473 virusloop = (triangle **) traverse( &viri );
10474 while ( virusloop != (triangle **) NULL ) {
10475 testtri.tri = *virusloop;
10476 /* A triangle is marked as infected by messing with one of its shell */
10477 /*   edges, setting it to an illegal value.  Hence, we have to       */
10478 /*   temporarily uninfect this triangle so that we can examine its   */
10479 /*   adjacent shell edges.                                           */
10480 uninfect( testtri );
10481 if ( verbose > 2 ) {
10482 /* Assign the triangle an orientation for convenience in */
10483 /*   checking its points.                                */
10484 testtri.orient = 0;
10485 org( testtri, deadorg );
10486 dest( testtri, deaddest );
10487 apex( testtri, deadapex );
10488 printf( "    Checking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
10489 deadorg[0], deadorg[1], deaddest[0], deaddest[1],
10490 deadapex[0], deadapex[1] );
10491 }
10492 /* Check each of the triangle's three neighbors. */
10493 for ( testtri.orient = 0; testtri.orient < 3; testtri.orient++ ) {
10494 /* Find the neighbor. */
10495 sym( testtri, neighbor );
10496 /* Check for a shell between the triangle and its neighbor. */
10497 tspivot( testtri, neighborshelle );
10498 /* Check if the neighbor is nonexistent or already infected. */
10499 if (( neighbor.tri == dummytri ) || infected( neighbor )) {
10500 if ( neighborshelle.sh != dummysh ) {
10501 /* There is a shell edge separating the triangle from its */
10502 /*   neighbor, but both triangles are dying, so the shell */
10503 /*   edge dies too.                                       */
10504 shelledealloc( neighborshelle.sh );
10505 if ( neighbor.tri != dummytri ) {
10506 /* Make sure the shell edge doesn't get deallocated again */
10507 /*   later when the infected neighbor is visited.         */
10508 uninfect( neighbor );
10509 tsdissolve( neighbor );
10510 infect( neighbor );
10511 }
10512 }
10513 }
10514 else {               /* The neighbor exists and is not infected. */
10515 if ( neighborshelle.sh == dummysh ) {
10516 /* There is no shell edge protecting the neighbor, so */
10517 /*   the neighbor becomes infected.                   */
10518 if ( verbose > 2 ) {
10519 org( neighbor, deadorg );
10520 dest( neighbor, deaddest );
10521 apex( neighbor, deadapex );
10522 printf(
10523 "    Marking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
10524 deadorg[0], deadorg[1], deaddest[0], deaddest[1],
10525 deadapex[0], deadapex[1] );
10526 }
10527 infect( neighbor );
10528 /* Ensure that the neighbor's neighbors will be infected. */
10529 deadtri = (triangle **) poolalloc( &viri );
10530 *deadtri = neighbor.tri;
10531 }
10532 else {         /* The neighbor is protected by a shell edge. */
10533 /* Remove this triangle from the shell edge. */
10534 stdissolve( neighborshelle );
10535 /* The shell edge becomes a boundary.  Set markers accordingly. */
10536 if ( mark( neighborshelle ) == 0 ) {
10537 setmark( neighborshelle, 1 );
10538 }
10539 org( neighbor, norg );
10540 dest( neighbor, ndest );
10541 if ( pointmark( norg ) == 0 ) {
10542 setpointmark( norg, 1 );
10543 }
10544 if ( pointmark( ndest ) == 0 ) {
10545 setpointmark( ndest, 1 );
10546 }
10547 }
10548 }
10549 }
10550 /* Remark the triangle as infected, so it doesn't get added to the */
10551 /*   virus pool again.                                             */
10552 infect( testtri );
10553 virusloop = (triangle **) traverse( &viri );
10554 }
10555
10556 if ( verbose ) {
10557 printf( "  Deleting marked triangles.\n" );
10558 }
10559 traversalinit( &viri );
10560 virusloop = (triangle **) traverse( &viri );
10561 while ( virusloop != (triangle **) NULL ) {
10562 testtri.tri = *virusloop;
10563
10564 /* Check each of the three corners of the triangle for elimination. */
10565 /*   This is done by walking around each point, checking if it is   */
10566 /*   still connected to at least one live triangle.                 */
10567 for ( testtri.orient = 0; testtri.orient < 3; testtri.orient++ ) {
10568 org( testtri, testpoint );
10569 /* Check if the point has already been tested. */
10570 if ( testpoint != (point) NULL ) {
10571 killorg = 1;
10572 /* Mark the corner of the triangle as having been tested. */
10573 setorg( testtri, NULL );
10574 /* Walk counterclockwise about the point. */
10575 onext( testtri, neighbor );
10576 /* Stop upon reaching a boundary or the starting triangle. */
10577 while (( neighbor.tri != dummytri )
10578 && ( !triedgeequal( neighbor, testtri ))) {
10579 if ( infected( neighbor )) {
10580 /* Mark the corner of this triangle as having been tested. */
10581 setorg( neighbor, NULL );
10582 }
10583 else {
10584 /* A live triangle.  The point survives. */
10585 killorg = 0;
10586 }
10587 /* Walk counterclockwise about the point. */
10588 onextself( neighbor );
10589 }
10590 /* If we reached a boundary, we must walk clockwise as well. */
10591 if ( neighbor.tri == dummytri ) {
10592 /* Walk clockwise about the point. */
10593 oprev( testtri, neighbor );
10594 /* Stop upon reaching a boundary. */
10595 while ( neighbor.tri != dummytri ) {
10596 if ( infected( neighbor )) {
10597 /* Mark the corner of this triangle as having been tested. */
10598 setorg( neighbor, NULL );
10599 }
10600 else {
10601 /* A live triangle.  The point survives. */
10602 killorg = 0;
10603 }
10604 /* Walk clockwise about the point. */
10605 oprevself( neighbor );
10606 }
10607 }
10608 if ( killorg ) {
10609 if ( verbose > 1 ) {
10610 printf( "    Deleting point (%.12g, %.12g)\n",
10611 testpoint[0], testpoint[1] );
10612 }
10613 pointdealloc( testpoint );
10614 }
10615 }
10616 }
10617
10618 /* Record changes in the number of boundary edges, and disconnect */
10619 /*   dead triangles from their neighbors.                         */
10620 for ( testtri.orient = 0; testtri.orient < 3; testtri.orient++ ) {
10621 sym( testtri, neighbor );
10622 if ( neighbor.tri == dummytri ) {
10623 /* There is no neighboring triangle on this edge, so this edge    */
10624 /*   is a boundary edge.  This triangle is being deleted, so this */
10625 /*   boundary edge is deleted.                                    */
10626 hullsize--;
10627 }
10628 else {
10629 /* Disconnect the triangle from its neighbor. */
10630 dissolve( neighbor );
10631 /* There is a neighboring triangle on this edge, so this edge */
10632 /*   becomes a boundary edge when this triangle is deleted.   */
10633 hullsize++;
10634 }
10635 }
10636 /* Return the dead triangle to the pool of triangles. */
10637 triangledealloc( testtri.tri );
10638 virusloop = (triangle **) traverse( &viri );
10639 }
10640 /* Empty the virus pool. */
10641 poolrestart( &viri );
10642 }
10643
10644 /*****************************************************************************/
10645 /*                                                                           */
10646 /*  regionplague()   Spread regional attributes and/or area constraints      */
10647 /*                   (from a .poly file) throughout the mesh.                */
10648 /*                                                                           */
10649 /*  This procedure operates in two phases.  The first phase spreads an       */
10650 /*  attribute and/or an area constraint through a (segment-bounded) region.  */
10651 /*  The triangles are marked to ensure that each triangle is added to the    */
10652 /*  virus pool only once, so the procedure will terminate.                   */
10653 /*                                                                           */
10654 /*  The second phase uninfects all infected triangles, returning them to     */
10655 /*  normal.                                                                  */
10656 /*                                                                           */
10657 /*****************************************************************************/
10658
10659 void regionplague( attribute, area )
10660 REAL attribute;
10661 REAL area;
10662 {
10663 struct triedge testtri;
10664 struct triedge neighbor;
10665 triangle **virusloop;
10666 triangle **regiontri;
10667 struct edge neighborshelle;
10668 point regionorg, regiondest, regionapex;
10669 triangle ptr;           /* Temporary variable used by sym() and onext(). */
10670 shelle sptr;                    /* Temporary variable used by tspivot(). */
10671
10672 if ( verbose > 1 ) {
10673 printf( "  Marking neighbors of marked triangles.\n" );
10674 }
10675 /* Loop through all the infected triangles, spreading the attribute      */
10676 /*   and/or area constraint to their neighbors, then to their neighbors' */
10677 /*   neighbors.                                                          */
10678 traversalinit( &viri );
10679 virusloop = (triangle **) traverse( &viri );
10680 while ( virusloop != (triangle **) NULL ) {
10681 testtri.tri = *virusloop;
10682 /* A triangle is marked as infected by messing with one of its shell */
10683 /*   edges, setting it to an illegal value.  Hence, we have to       */
10684 /*   temporarily uninfect this triangle so that we can examine its   */
10685 /*   adjacent shell edges.                                           */
10686 uninfect( testtri );
10687 if ( regionattrib ) {
10688 /* Set an attribute. */
10689 setelemattribute( testtri, eextras, attribute );
10690 }
10691 if ( vararea ) {
10692 /* Set an area constraint. */
10693 setareabound( testtri, area );
10694 }
10695 if ( verbose > 2 ) {
10696 /* Assign the triangle an orientation for convenience in */
10697 /*   checking its points.                                */
10698 testtri.orient = 0;
10699 org( testtri, regionorg );
10700 dest( testtri, regiondest );
10701 apex( testtri, regionapex );
10702 printf( "    Checking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
10703 regionorg[0], regionorg[1], regiondest[0], regiondest[1],
10704 regionapex[0], regionapex[1] );
10705 }
10706 /* Check each of the triangle's three neighbors. */
10707 for ( testtri.orient = 0; testtri.orient < 3; testtri.orient++ ) {
10708 /* Find the neighbor. */
10709 sym( testtri, neighbor );
10710 /* Check for a shell between the triangle and its neighbor. */
10711 tspivot( testtri, neighborshelle );
10712 /* Make sure the neighbor exists, is not already infected, and */
10713 /*   isn't protected by a shell edge.                          */
10714 if (( neighbor.tri != dummytri ) && !infected( neighbor )
10715 && ( neighborshelle.sh == dummysh )) {
10716 if ( verbose > 2 ) {
10717 org( neighbor, regionorg );
10718 dest( neighbor, regiondest );
10719 apex( neighbor, regionapex );
10720 printf( "    Marking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
10721 regionorg[0], regionorg[1], regiondest[0], regiondest[1],
10722 regionapex[0], regionapex[1] );
10723 }
10724 /* Infect the neighbor. */
10725 infect( neighbor );
10726 /* Ensure that the neighbor's neighbors will be infected. */
10727 regiontri = (triangle **) poolalloc( &viri );
10728 *regiontri = neighbor.tri;
10729 }
10730 }
10731 /* Remark the triangle as infected, so it doesn't get added to the */
10732 /*   virus pool again.                                             */
10733 infect( testtri );
10734 virusloop = (triangle **) traverse( &viri );
10735 }
10736
10737 /* Uninfect all triangles. */
10738 if ( verbose > 1 ) {
10739 printf( "  Unmarking marked triangles.\n" );
10740 }
10741 traversalinit( &viri );
10742 virusloop = (triangle **) traverse( &viri );
10743 while ( virusloop != (triangle **) NULL ) {
10744 testtri.tri = *virusloop;
10745 uninfect( testtri );
10746 virusloop = (triangle **) traverse( &viri );
10747 }
10748 /* Empty the virus pool. */
10749 poolrestart( &viri );
10750 }
10751
10752 /*****************************************************************************/
10753 /*                                                                           */
10754 /*  carveholes()   Find the holes and infect them.  Find the area            */
10755 /*                 constraints and infect them.  Infect the convex hull.     */
10756 /*                 Spread the infection and kill triangles.  Spread the      */
10757 /*                 area constraints.                                         */
10758 /*                                                                           */
10759 /*  This routine mainly calls other routines to carry out all these          */
10760 /*  functions.                                                               */
10761 /*                                                                           */
10762 /*****************************************************************************/
10763
10764 void carveholes( holelist, holes, regionlist, regions )
10765 REAL * holelist;
10766 int holes;
10767 REAL *regionlist;
10768 int regions;
10769 {
10770 struct triedge searchtri;
10771 struct triedge triangleloop;
10772 struct triedge *regiontris;
10773 triangle **holetri;
10774 triangle **regiontri;
10775 point searchorg, searchdest;
10776 enum locateresult intersect;
10777 int i;
10778 triangle ptr;                       /* Temporary variable used by sym(). */
10779
10780 if ( !( quiet || ( noholes && convex ))) {
10781 printf( "Removing unwanted triangles.\n" );
10782 if ( verbose && ( holes > 0 )) {
10783 printf( "  Marking holes for elimination.\n" );
10784 }
10785 }
10786
10787 if ( regions > 0 ) {
10788 /* Allocate storage for the triangles in which region points fall. */
10789 regiontris = (struct triedge *) malloc( regions * sizeof( struct triedge ));
10790 if ( regiontris == (struct triedge *) NULL ) {
10791 printf( "Error:  Out of memory.\n" );
10792 exit( 1 );
10793 }
10794 }
10795
10796 if ((( holes > 0 ) && !noholes ) || !convex || ( regions > 0 )) {
10797 /* Initialize a pool of viri to be used for holes, concavities, */
10798 /*   regional attributes, and/or regional area constraints.     */
10799 poolinit( &viri, sizeof( triangle * ), VIRUSPERBLOCK, POINTER, 0 );
10800 }
10801
10802 if ( !convex ) {
10803 /* Mark as infected any unprotected triangles on the boundary. */
10804 /*   This is one way by which concavities are created.         */
10805 infecthull();
10806 }
10807
10808 if (( holes > 0 ) && !noholes ) {
10809 /* Infect each triangle in which a hole lies. */
10810 for ( i = 0; i < 2 * holes; i += 2 ) {
10811 /* Ignore holes that aren't within the bounds of the mesh. */
10812 if (( holelist[i] >= xmin ) && ( holelist[i] <= xmax )
10813 && ( holelist[i + 1] >= ymin ) && ( holelist[i + 1] <= ymax )) {
10814 /* Start searching from some triangle on the outer boundary. */
10815 searchtri.tri = dummytri;
10816 searchtri.orient = 0;
10817 symself( searchtri );
10818 /* Ensure that the hole is to the left of this boundary edge; */
10819 /*   otherwise, locate() will falsely report that the hole    */
10820 /*   falls within the starting triangle.                      */
10821 org( searchtri, searchorg );
10822 dest( searchtri, searchdest );
10823 if ( counterclockwise( searchorg, searchdest, &holelist[i] ) > 0.0 ) {
10824 /* Find a triangle that contains the hole. */
10825 intersect = locate( &holelist[i], &searchtri );
10826 if (( intersect != OUTSIDE ) && ( !infected( searchtri ))) {
10827 /* Infect the triangle.  This is done by marking the triangle */
10828 /*   as infect and including the triangle in the virus pool.  */
10829 infect( searchtri );
10830 holetri = (triangle **) poolalloc( &viri );
10831 *holetri = searchtri.tri;
10832 }
10833 }
10834 }
10835 }
10836 }
10837
10838 /* Now, we have to find all the regions BEFORE we carve the holes, because */
10839 /*   locate() won't work when the triangulation is no longer convex.       */
10840 /*   (Incidentally, this is the reason why regional attributes and area    */
10841 /*   constraints can't be used when refining a preexisting mesh, which     */
10842 /*   might not be convex; they can only be used with a freshly             */
10843 /*   triangulated PSLG.)                                                   */
10844 if ( regions > 0 ) {
10845 /* Find the starting triangle for each region. */
10846 for ( i = 0; i < regions; i++ ) {
10847 regiontris[i].tri = dummytri;
10848 /* Ignore region points that aren't within the bounds of the mesh. */
10849 if (( regionlist[4 * i] >= xmin ) && ( regionlist[4 * i] <= xmax ) &&
10850 ( regionlist[4 * i + 1] >= ymin ) && ( regionlist[4 * i + 1] <= ymax )) {
10851 /* Start searching from some triangle on the outer boundary. */
10852 searchtri.tri = dummytri;
10853 searchtri.orient = 0;
10854 symself( searchtri );
10855 /* Ensure that the region point is to the left of this boundary */
10856 /*   edge; otherwise, locate() will falsely report that the     */
10857 /*   region point falls within the starting triangle.           */
10858 org( searchtri, searchorg );
10859 dest( searchtri, searchdest );
10860 if ( counterclockwise( searchorg, searchdest, &regionlist[4 * i] ) >
10861 0.0 ) {
10862 /* Find a triangle that contains the region point. */
10863 intersect = locate( &regionlist[4 * i], &searchtri );
10864 if (( intersect != OUTSIDE ) && ( !infected( searchtri ))) {
10865 /* Record the triangle for processing after the */
10866 /*   holes have been carved.                    */
10867 triedgecopy( searchtri, regiontris[i] );
10868 }
10869 }
10870 }
10871 }
10872 }
10873
10874 if ( viri.items > 0 ) {
10875 /* Carve the holes and concavities. */
10876 plague();
10877 }
10878 /* The virus pool should be empty now. */
10879
10880 if ( regions > 0 ) {
10881 if ( !quiet ) {
10882 if ( regionattrib ) {
10883 if ( vararea ) {
10884 printf( "Spreading regional attributes and area constraints.\n" );
10885 }
10886 else {
10887 printf( "Spreading regional attributes.\n" );
10888 }
10889 }
10890 else {
10891 printf( "Spreading regional area constraints.\n" );
10892 }
10893 }
10894 if ( regionattrib && !refine ) {
10895 /* Assign every triangle a regional attribute of zero. */
10896 traversalinit( &triangles );
10897 triangleloop.orient = 0;
10898 triangleloop.tri = triangletraverse();
10899 while ( triangleloop.tri != (triangle *) NULL ) {
10900 setelemattribute( triangleloop, eextras, 0.0 );
10901 triangleloop.tri = triangletraverse();
10902 }
10903 }
10904 for ( i = 0; i < regions; i++ ) {
10905 if ( regiontris[i].tri != dummytri ) {
10906 /* Make sure the triangle under consideration still exists. */
10907 /*   It may have been eaten by the virus.                   */
10908 if ( regiontris[i].tri[3] != (triangle) NULL ) {
10909 /* Put one triangle in the virus pool. */
10910 infect( regiontris[i] );
10911 regiontri = (triangle **) poolalloc( &viri );
10912 *regiontri = regiontris[i].tri;
10913 /* Apply one region's attribute and/or area constraint. */
10914 regionplague( regionlist[4 * i + 2], regionlist[4 * i + 3] );
10915 /* The virus pool should be empty now. */
10916 }
10917 }
10918 }
10919 if ( regionattrib && !refine ) {
10920 /* Note the fact that each triangle has an additional attribute. */
10921 eextras++;
10922 }
10923 }
10924
10925 /* Free up memory. */
10926 if ((( holes > 0 ) && !noholes ) || !convex || ( regions > 0 )) {
10927 pooldeinit( &viri );
10928 }
10929 if ( regions > 0 ) {
10930 free( regiontris );
10931 }
10932 }
10933
10934 /**                                                                         **/
10935 /**                                                                         **/
10936 /********* Carving out holes and concavities ends here               *********/
10937
10938 /********* Mesh quality maintenance begins here                      *********/
10939 /**                                                                         **/
10940 /**                                                                         **/
10941
10942 /*****************************************************************************/
10943 /*                                                                           */
10944 /*  tallyencs()   Traverse the entire list of shell edges, check each edge   */
10945 /*                to see if it is encroached.  If so, add it to the list.    */
10946 /*                                                                           */
10947 /*****************************************************************************/
10948
10949 #ifndef
10950 CDT_ONLY
10951
10952 void tallyencs(){
10953 struct edge edgeloop;
10954 int dummy;
10955
10956 traversalinit( &shelles );
10957 edgeloop.shorient = 0;
10958 edgeloop.sh = shelletraverse();
10959 while ( edgeloop.sh != (shelle *) NULL ) {
10960 /* If the segment is encroached, add it to the list. */
10961 dummy = checkedge4encroach( &edgeloop );
10962 edgeloop.sh = shelletraverse();
10963 }
10964 }
10965
10966 #endif /* not CDT_ONLY */
10967
10968 /*****************************************************************************/
10969 /*                                                                           */
10970 /*  precisionerror()  Print an error message for precision problems.         */
10971 /*                                                                           */
10972 /*****************************************************************************/
10973
10974 #ifndef
10975 CDT_ONLY
10976
10977 void precisionerror(){
10978 printf( "Try increasing the area criterion and/or reducing the minimum\n" );
10979 printf( "  allowable angle so that tiny triangles are not created.\n" );
10980 #ifdef
10981 SINGLE
10982 printf( "Alternatively, try recompiling me with double precision\n" );
10983 printf( "  arithmetic (by removing \"#define SINGLE\" from the\n" );
10984 printf( "  source file or \"-DSINGLE\" from the makefile).\n" );
10985 #endif /* SINGLE */
10986 }
10987
10988 #endif /* not CDT_ONLY */
10989
10990 /*****************************************************************************/
10991 /*                                                                           */
10992 /*  repairencs()   Find and repair all the encroached segments.              */
10993 /*                                                                           */
10994 /*  Encroached segments are repaired by splitting them by inserting a point  */
10995 /*  at or near their centers.                                                */
10996 /*                                                                           */
10997 /*  `flaws' is a flag that specifies whether one should take note of new     */
10998 /*  encroached segments and bad triangles that result from inserting points  */
10999 /*  to repair existing encroached segments.                                  */
11000 /*                                                                           */
11001 /*  When a segment is split, the two resulting subsegments are always        */
11002 /*  tested to see if they are encroached upon, regardless of the value       */
11003 /*  of `flaws'.                                                              */
11004 /*                                                                           */
11005 /*****************************************************************************/
11006
11007 #ifndef
11008 CDT_ONLY
11009
11010 void repairencs( flaws )
11011 int flaws;
11012 {
11013 struct triedge enctri;
11014 struct triedge testtri;
11015 struct edge *encloop;
11016 struct edge testsh;
11017 point eorg, edest;
11018 point newpoint;
11019 enum insertsiteresult success;
11020 REAL segmentlength, nearestpoweroftwo;
11021 REAL split;
11022 int acuteorg, acutedest;
11023 int dummy;
11024 int i;
11025 triangle ptr;                   /* Temporary variable used by stpivot(). */
11026 shelle sptr;                      /* Temporary variable used by snext(). */
11027
11028 while (( badsegments.items > 0 ) && ( steinerleft != 0 )) {
11029 traversalinit( &badsegments );
11030 encloop = badsegmenttraverse();
11031 while (( encloop != (struct edge *) NULL ) && ( steinerleft != 0 )) {
11032 /* To decide where to split a segment, we need to know if the  */
11033 /*   segment shares an endpoint with an adjacent segment.      */
11034 /*   The concern is that, if we simply split every encroached  */
11035 /*   segment in its center, two adjacent segments with a small */
11036 /*   angle between them might lead to an infinite loop; each   */
11037 /*   point added to split one segment will encroach upon the   */
11038 /*   other segment, which must then be split with a point that */
11039 /*   will encroach upon the first segment, and so on forever.  */
11040 /* To avoid this, imagine a set of concentric circles, whose   */
11041 /*   radii are powers of two, about each segment endpoint.     */
11042 /*   These concentric circles determine where the segment is   */
11043 /*   split.  (If both endpoints are shared with adjacent       */
11044 /*   segments, split the segment in the middle, and apply the  */
11045 /*   concentric shells for later splittings.)                  */
11046
11047 /* Is the origin shared with another segment? */
11048 stpivot( *encloop, enctri );
11049 lnext( enctri, testtri );
11050 tspivot( testtri, testsh );
11051 acuteorg = testsh.sh != dummysh;
11052 /* Is the destination shared with another segment? */
11053 lnextself( testtri );
11054 tspivot( testtri, testsh );
11055 acutedest = testsh.sh != dummysh;
11056 /* Now, check the other side of the segment, if there's a triangle */
11057 /*   there.                                                        */
11058 sym( enctri, testtri );
11059 if ( testtri.tri != dummytri ) {
11060 /* Is the destination shared with another segment? */
11061 lnextself( testtri );
11062 tspivot( testtri, testsh );
11063 acutedest = acutedest || ( testsh.sh != dummysh );
11064 /* Is the origin shared with another segment? */
11065 lnextself( testtri );
11066 tspivot( testtri, testsh );
11067 acuteorg = acuteorg || ( testsh.sh != dummysh );
11068 }
11069
11070 sorg( *encloop, eorg );
11071 sdest( *encloop, edest );
11072 /* Use the concentric circles if exactly one endpoint is shared */
11073 /*   with another adjacent segment.                             */
11074 if ( acuteorg ^ acutedest ) {
11075 segmentlength = sqrt(( edest[0] - eorg[0] ) * ( edest[0] - eorg[0] )
11076 + ( edest[1] - eorg[1] ) * ( edest[1] - eorg[1] ));
11077 /* Find the power of two nearest the segment's length. */
11078 nearestpoweroftwo = 1.0;
11079 while ( segmentlength > SQUAREROOTTWO * nearestpoweroftwo ) {
11080 nearestpoweroftwo *= 2.0;
11081 }
11082 while ( segmentlength < ( 0.5 * SQUAREROOTTWO ) * nearestpoweroftwo ) {
11083 nearestpoweroftwo *= 0.5;
11084 }
11085 /* Where do we split the segment? */
11086 split = 0.5 * nearestpoweroftwo / segmentlength;
11087 if ( acutedest ) {
11088 split = 1.0 - split;
11089 }
11090 }
11091 else {
11092 /* If we're not worried about adjacent segments, split */
11093 /*   this segment in the middle.                       */
11094 split = 0.5;
11095 }
11096
11097 /* Create the new point. */
11098 newpoint = (point) poolalloc( &points );
11099 /* Interpolate its coordinate and attributes. */
11100 for ( i = 0; i < 2 + nextras; i++ ) {
11101 newpoint[i] = ( 1.0 - split ) * eorg[i] + split * edest[i];
11102 }
11103 setpointmark( newpoint, mark( *encloop ));
11104 if ( verbose > 1 ) {
11105 printf(
11106 "  Splitting edge (%.12g, %.12g) (%.12g, %.12g) at (%.12g, %.12g).\n",
11107 eorg[0], eorg[1], edest[0], edest[1], newpoint[0], newpoint[1] );
11108 }
11109 /* Check whether the new point lies on an endpoint. */
11110 if ((( newpoint[0] == eorg[0] ) && ( newpoint[1] == eorg[1] ))
11111 || (( newpoint[0] == edest[0] ) && ( newpoint[1] == edest[1] ))) {
11112 printf( "Error:  Ran out of precision at (%.12g, %.12g).\n",
11113 newpoint[0], newpoint[1] );
11114 printf( "I attempted to split a segment to a smaller size than can\n" );
11115 printf( "  be accommodated by the finite precision of floating point\n"
11116 );
11117 printf( "  arithmetic.\n" );
11118 precisionerror();
11119 exit( 1 );
11120 }
11121 /* Insert the splitting point.  This should always succeed. */
11122 success = insertsite( newpoint, &enctri, encloop, flaws, flaws );
11123 if (( success != SUCCESSFULPOINT ) && ( success != ENCROACHINGPOINT )) {
11124 printf( "Internal error in repairencs():\n" );
11125 printf( "  Failure to split a segment.\n" );
11126 internalerror();
11127 }
11128 if ( steinerleft > 0 ) {
11129 steinerleft--;
11130 }
11131 /* Check the two new subsegments to see if they're encroached. */
11132 dummy = checkedge4encroach( encloop );
11133 snextself( *encloop );
11134 dummy = checkedge4encroach( encloop );
11135
11136 badsegmentdealloc( encloop );
11137 encloop = badsegmenttraverse();
11138 }
11139 }
11140 }
11141
11142 #endif /* not CDT_ONLY */
11143
11144 /*****************************************************************************/
11145 /*                                                                           */
11146 /*  tallyfaces()   Test every triangle in the mesh for quality measures.     */
11147 /*                                                                           */
11148 /*****************************************************************************/
11149
11150 #ifndef
11151 CDT_ONLY
11152
11153 void tallyfaces(){
11154 struct triedge triangleloop;
11155
11156 if ( verbose ) {
11157 printf( "  Making a list of bad triangles.\n" );
11158 }
11159 traversalinit( &triangles );
11160 triangleloop.orient = 0;
11161 triangleloop.tri = triangletraverse();
11162 while ( triangleloop.tri != (triangle *) NULL ) {
11163 /* If the triangle is bad, enqueue it. */
11164 testtriangle( &triangleloop );
11165 triangleloop.tri = triangletraverse();
11166 }
11167 }
11168
11169 #endif /* not CDT_ONLY */
11170
11171 /*****************************************************************************/
11172 /*                                                                           */
11173 /*  findcircumcenter()   Find the circumcenter of a triangle.                */
11174 /*                                                                           */
11175 /*  The result is returned both in terms of x-y coordinates and xi-eta       */
11176 /*  coordinates.  The xi-eta coordinate system is defined in terms of the    */
11177 /*  triangle:  the origin of the triangle is the origin of the coordinate    */
11178 /*  system; the destination of the triangle is one unit along the xi axis;   */
11179 /*  and the apex of the triangle is one unit along the eta axis.             */
11180 /*                                                                           */
11181 /*  The return value indicates which edge of the triangle is shortest.       */
11182 /*                                                                           */
11183 /*****************************************************************************/
11184
11185 enum circumcenterresult findcircumcenter( torg, tdest, tapex, circumcenter,
11186 xi, eta )
11187 point torg;
11188 point tdest;
11189 point tapex;
11190 point circumcenter;
11191 REAL *xi;
11192 REAL *eta;
11193 {
11194 REAL xdo, ydo, xao, yao, xad, yad;
11195 REAL dodist, aodist, addist;
11196 REAL denominator;
11197 REAL dx, dy;
11198
11199 circumcentercount++;
11200
11201 /* Compute the circumcenter of the triangle. */
11202 xdo = tdest[0] - torg[0];
11203 ydo = tdest[1] - torg[1];
11204 xao = tapex[0] - torg[0];
11205 yao = tapex[1] - torg[1];
11206 dodist = xdo * xdo + ydo * ydo;
11207 aodist = xao * xao + yao * yao;
11208 if ( noexact ) {
11209 denominator = (REAL)( 0.5 / ( xdo * yao - xao * ydo ));
11210 }
11211 else {
11212 /* Use the counterclockwise() routine to ensure a positive (and */
11213 /*   reasonably accurate) result, avoiding any possibility of   */
11214 /*   division by zero.                                          */
11215 denominator = (REAL)( 0.5 / counterclockwise( tdest, tapex, torg ));
11216 /* Don't count the above as an orientation test. */
11217 counterclockcount--;
11218 }
11219 circumcenter[0] = torg[0] - ( ydo * aodist - yao * dodist ) * denominator;
11220 circumcenter[1] = torg[1] + ( xdo * aodist - xao * dodist ) * denominator;
11221
11222 /* To interpolate point attributes for the new point inserted at  */
11223 /*   the circumcenter, define a coordinate system with a xi-axis, */
11224 /*   directed from the triangle's origin to its destination, and  */
11225 /*   an eta-axis, directed from its origin to its apex.           */
11226 /*   Calculate the xi and eta coordinates of the circumcenter.    */
11227 dx = circumcenter[0] - torg[0];
11228 dy = circumcenter[1] - torg[1];
11229 *xi = (REAL)(( dx * yao - xao * dy ) * ( 2.0 * denominator ));
11230 *eta = (REAL)(( xdo * dy - dx * ydo ) * ( 2.0 * denominator ));
11231
11232 xad = tapex[0] - tdest[0];
11233 yad = tapex[1] - tdest[1];
11234 addist = xad * xad + yad * yad;
11235 if (( addist < dodist ) && ( addist < aodist )) {
11236 return OPPOSITEORG;
11237 }
11238 else if ( dodist < aodist ) {
11239 return OPPOSITEAPEX;
11240 }
11241 else {
11242 return OPPOSITEDEST;
11243 }
11244 }
11245
11246 /*****************************************************************************/
11247 /*                                                                           */
11248 /*  splittriangle()   Inserts a point at the circumcenter of a triangle.     */
11249 /*                    Deletes the newly inserted point if it encroaches upon */
11250 /*                    a segment.                                             */
11251 /*                                                                           */
11252 /*****************************************************************************/
11253
11254 #ifndef
11255 CDT_ONLY
11256
11257 void splittriangle( badtri )
11258 struct badface *badtri;
11259 {
11260 point borg, bdest, bapex;
11261 point newpoint;
11262 REAL xi, eta;
11263 enum insertsiteresult success;
11264 enum circumcenterresult shortedge;
11265 int errorflag;
11266 int i;
11267
11268 org( badtri->badfacetri, borg );
11269 dest( badtri->badfacetri, bdest );
11270 apex( badtri->badfacetri, bapex );
11271 /* Make sure that this triangle is still the same triangle it was      */
11272 /*   when it was tested and determined to be of bad quality.           */
11273 /*   Subsequent transformations may have made it a different triangle. */
11274 if (( borg == badtri->faceorg ) && ( bdest == badtri->facedest ) &&
11275 ( bapex == badtri->faceapex )) {
11276 if ( verbose > 1 ) {
11277 printf( "  Splitting this triangle at its circumcenter:\n" );
11278 printf( "    (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n", borg[0],
11279 borg[1], bdest[0], bdest[1], bapex[0], bapex[1] );
11280 }
11281 errorflag = 0;
11282 /* Create a new point at the triangle's circumcenter. */
11283 newpoint = (point) poolalloc( &points );
11284 shortedge = findcircumcenter( borg, bdest, bapex, newpoint, &xi, &eta );
11285 /* Check whether the new point lies on a triangle vertex. */
11286 if ((( newpoint[0] == borg[0] ) && ( newpoint[1] == borg[1] ))
11287 || (( newpoint[0] == bdest[0] ) && ( newpoint[1] == bdest[1] ))
11288 || (( newpoint[0] == bapex[0] ) && ( newpoint[1] == bapex[1] ))) {
11289 if ( !quiet ) {
11290 printf( "Warning:  New point (%.12g, %.12g) falls on existing vertex.\n"
11291 , newpoint[0], newpoint[1] );
11292 errorflag = 1;
11293 }
11294 pointdealloc( newpoint );
11295 }
11296 else {
11297 for ( i = 2; i < 2 + nextras; i++ ) {
11298 /* Interpolate the point attributes at the circumcenter. */
11299 newpoint[i] = borg[i] + xi * ( bdest[i] - borg[i] )
11300 + eta * ( bapex[i] - borg[i] );
11301 }
11302 /* The new point must be in the interior, and have a marker of zero. */
11303 setpointmark( newpoint, 0 );
11304 /* Ensure that the handle `badtri->badfacetri' represents the shortest */
11305 /*   edge of the triangle.  This ensures that the circumcenter must    */
11306 /*   fall to the left of this edge, so point location will work.       */
11307 if ( shortedge == OPPOSITEORG ) {
11308 lnextself( badtri->badfacetri );
11309 }
11310 else if ( shortedge == OPPOSITEDEST ) {
11311 lprevself( badtri->badfacetri );
11312 }
11313 /* Insert the circumcenter, searching from the edge of the triangle, */
11314 /*   and maintain the Delaunay property of the triangulation.        */
11315 success = insertsite( newpoint, &( badtri->badfacetri ),
11316 (struct edge *) NULL, 1, 1 );
11317 if ( success == SUCCESSFULPOINT ) {
11318 if ( steinerleft > 0 ) {
11319 steinerleft--;
11320 }
11321 }
11322 else if ( success == ENCROACHINGPOINT ) {
11323 /* If the newly inserted point encroaches upon a segment, delete it. */
11324 deletesite( &( badtri->badfacetri ));
11325 }
11326 else if ( success == VIOLATINGPOINT ) {
11327 /* Failed to insert the new point, but some segment was */
11328 /*   marked as being encroached.                        */
11329 pointdealloc( newpoint );
11330 }
11331 else {                              /* success == DUPLICATEPOINT */
11332 /* Failed to insert the new point because a vertex is already there. */
11333 if ( !quiet ) {
11334 printf(
11335 "Warning:  New point (%.12g, %.12g) falls on existing vertex.\n"
11336 , newpoint[0], newpoint[1] );
11337 errorflag = 1;
11338 }
11339 pointdealloc( newpoint );
11340 }
11341 }
11342 if ( errorflag ) {
11343 if ( verbose ) {
11344 printf( "  The new point is at the circumcenter of triangle\n" );
11345 printf( "    (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
11346 borg[0], borg[1], bdest[0], bdest[1], bapex[0], bapex[1] );
11347 }
11348 printf( "This probably means that I am trying to refine triangles\n" );
11349 printf( "  to a smaller size than can be accommodated by the finite\n" );
11350 printf( "  precision of floating point arithmetic.  (You can be\n" );
11351 printf( "  sure of this if I fail to terminate.)\n" );
11352 precisionerror();
11353 }
11354 }
11355 /* Return the bad triangle to the pool. */
11356 pooldealloc( &badtriangles, (VOID *) badtri );
11357 }
11358
11359 #endif /* not CDT_ONLY */
11360
11361 /*****************************************************************************/
11362 /*                                                                           */
11363 /*  enforcequality()   Remove all the encroached edges and bad triangles     */
11364 /*                     from the triangulation.                               */
11365 /*                                                                           */
11366 /*****************************************************************************/
11367
11368 #ifndef
11369 CDT_ONLY
11370
11371 void enforcequality(){
11372 int i;
11373
11374 if ( !quiet ) {
11375 printf( "Adding Steiner points to enforce quality.\n" );
11376 }
11377 /* Initialize the pool of encroached segments. */
11378 poolinit( &badsegments, sizeof( struct edge ), BADSEGMENTPERBLOCK, POINTER, 0 );
11379 if ( verbose ) {
11380 printf( "  Looking for encroached segments.\n" );
11381 }
11382 /* Test all segments to see if they're encroached. */
11383 tallyencs();
11384 if ( verbose && ( badsegments.items > 0 )) {
11385 printf( "  Splitting encroached segments.\n" );
11386 }
11387 /* Note that steinerleft == -1 if an unlimited number */
11388 /*   of Steiner points is allowed.                    */
11389 while (( badsegments.items > 0 ) && ( steinerleft != 0 )) {
11390 /* Fix the segments without noting newly encroached segments or   */
11391 /*   bad triangles.  The reason we don't want to note newly       */
11392 /*   encroached segments is because some encroached segments are  */
11393 /*   likely to be noted multiple times, and would then be blindly */
11394 /*   split multiple times.  I should fix that some time.          */
11395 repairencs( 0 );
11396 /* Now, find all the segments that became encroached while adding */
11397 /*   points to split encroached segments.                         */
11398 tallyencs();
11399 }
11400 /* At this point, if we haven't run out of Steiner points, the */
11401 /*   triangulation should be (conforming) Delaunay.            */
11402
11403 /* Next, we worry about enforcing triangle quality. */
11404 if (( minangle > 0.0 ) || vararea || fixedarea ) {
11405 /* Initialize the pool of bad triangles. */
11406 poolinit( &badtriangles, sizeof( struct badface ), BADTRIPERBLOCK, POINTER,
11407 0 );
11408 /* Initialize the queues of bad triangles. */
11409 for ( i = 0; i < 64; i++ ) {
11410 queuefront[i] = (struct badface *) NULL;
11411 queuetail[i] = &queuefront[i];
11412 }
11413 /* Test all triangles to see if they're bad. */
11414 tallyfaces();
11415 if ( verbose ) {
11416 printf( "  Splitting bad triangles.\n" );
11417 }
11418 while (( badtriangles.items > 0 ) && ( steinerleft != 0 )) {
11419 /* Fix one bad triangle by inserting a point at its circumcenter. */
11420 splittriangle( dequeuebadtri());
11421 /* Fix any encroached segments that may have resulted.  Record */
11422 /*   any new bad triangles or encroached segments that result. */
11423 if ( badsegments.items > 0 ) {
11424 repairencs( 1 );
11425 }
11426 }
11427 }
11428 /* At this point, if we haven't run out of Steiner points, the */
11429 /*   triangulation should be (conforming) Delaunay and have no */
11430 /*   low-quality triangles.                                    */
11431
11432 /* Might we have run out of Steiner points too soon? */
11433 if ( !quiet && ( badsegments.items > 0 ) && ( steinerleft == 0 )) {
11434 printf( "\nWarning:  I ran out of Steiner points, but the mesh has\n" );
11435 if ( badsegments.items == 1 ) {
11436 printf( "  an encroached segment, and therefore might not be truly\n" );
11437 }
11438 else {
11439 printf( "  %ld encroached segments, and therefore might not be truly\n",
11440 badsegments.items );
11441 }
11442 printf( "  Delaunay.  If the Delaunay property is important to you,\n" );
11443 printf( "  try increasing the number of Steiner points (controlled by\n" );
11444 printf( "  the -S switch) slightly and try again.\n\n" );
11445 }
11446 }
11447
11448 #endif /* not CDT_ONLY */
11449
11450 /**                                                                         **/
11451 /**                                                                         **/
11452 /********* Mesh quality maintenance ends here                        *********/
11453
11454 /*****************************************************************************/
11455 /*                                                                           */
11456 /*  highorder()   Create extra nodes for quadratic subparametric elements.   */
11457 /*                                                                           */
11458 /*****************************************************************************/
11459
11460 void highorder(){
11461 struct triedge triangleloop, trisym;
11462 struct edge checkmark;
11463 point newpoint;
11464 point torg, tdest;
11465 int i;
11466 triangle ptr;                       /* Temporary variable used by sym(). */
11467 shelle sptr;                    /* Temporary variable used by tspivot(). */
11468
11469 if ( !quiet ) {
11470 printf( "Adding vertices for second-order triangles.\n" );
11471 }
11472 /* The following line ensures that dead items in the pool of nodes    */
11473 /*   cannot be allocated for the extra nodes associated with high     */
11474 /*   order elements.  This ensures that the primary nodes (at the     */
11475 /*   corners of elements) will occur earlier in the output files, and */
11476 /*   have lower indices, than the extra nodes.                        */
11477 points.deaditemstack = (VOID *) NULL;
11478
11479 traversalinit( &triangles );
11480 triangleloop.tri = triangletraverse();
11481 /* To loop over the set of edges, loop over all triangles, and look at   */
11482 /*   the three edges of each triangle.  If there isn't another triangle  */
11483 /*   adjacent to the edge, operate on the edge.  If there is another     */
11484 /*   adjacent triangle, operate on the edge only if the current triangle */
11485 /*   has a smaller pointer than its neighbor.  This way, each edge is    */
11486 /*   considered only once.                                               */
11487 while ( triangleloop.tri != (triangle *) NULL ) {
11488 for ( triangleloop.orient = 0; triangleloop.orient < 3;
11489 triangleloop.orient++ ) {
11490 sym( triangleloop, trisym );
11491 if (( triangleloop.tri < trisym.tri ) || ( trisym.tri == dummytri )) {
11492 org( triangleloop, torg );
11493 dest( triangleloop, tdest );
11494 /* Create a new node in the middle of the edge.  Interpolate */
11495 /*   its attributes.                                         */
11496 newpoint = (point) poolalloc( &points );
11497 for ( i = 0; i < 2 + nextras; i++ ) {
11498 newpoint[i] = (REAL)( 0.5 * ( torg[i] + tdest[i] ));
11499 }
11500 /* Set the new node's marker to zero or one, depending on */
11501 /*   whether it lies on a boundary.                       */
11502 setpointmark( newpoint, trisym.tri == dummytri );
11503 if ( useshelles ) {
11504 tspivot( triangleloop, checkmark );
11505 /* If this edge is a segment, transfer the marker to the new node. */
11506 if ( checkmark.sh != dummysh ) {
11507 setpointmark( newpoint, mark( checkmark ));
11508 }
11509 }
11510 if ( verbose > 1 ) {
11511 printf( "  Creating (%.12g, %.12g).\n", newpoint[0], newpoint[1] );
11512 }
11513 /* Record the new node in the (one or two) adjacent elements. */
11514 triangleloop.tri[highorderindex + triangleloop.orient] =
11515 (triangle) newpoint;
11516 if ( trisym.tri != dummytri ) {
11517 trisym.tri[highorderindex + trisym.orient] = (triangle) newpoint;
11518 }
11519 }
11520 }
11521 triangleloop.tri = triangletraverse();
11522 }
11523 }
11524
11525 /********* File I/O routines begin here                              *********/
11526 /**                                                                         **/
11527 /**                                                                         **/
11528
11529 /*****************************************************************************/
11530 /*                                                                           */
11531 /*  readline()   Read a nonempty line from a file.                           */
11532 /*                                                                           */
11533 /*  A line is considered "nonempty" if it contains something that looks like */
11534 /*  a number.                                                                */
11535 /*                                                                           */
11536 /*****************************************************************************/
11537
11538 #ifndef
11539 TRILIBRARY
11540
11541 char *readline( string, infile, infilename )
11542 char *string;
11543 FILE *infile;
11544 char *infilename;
11545 {
11546 char *result;
11547
11548 /* Search for something that looks like a number. */
11549 do {
11550 result = fgets( string, INPUTLINESIZE, infile );
11551 if ( result == (char *) NULL ) {
11552 printf( "  Error:  Unexpected end of file in %s.\n", infilename );
11553 exit( 1 );
11554 }
11555 /* Skip anything that doesn't look like a number, a comment, */
11556 /*   or the end of a line.                                   */
11557 while (( *result != '\0' ) && ( *result != '#' )
11558 && ( *result != '.' ) && ( *result != '+' ) && ( *result != '-' )
11559 && (( *result < '0' ) || ( *result > '9' ))) {
11560 result++;
11561 }
11562 /* If it's a comment or end of line, read another line and try again. */
11563 } while (( *result == '#' ) || ( *result == '\0' ));
11564 return result;
11565 }
11566
11567 #endif /* not TRILIBRARY */
11568
11569 /*****************************************************************************/
11570 /*                                                                           */
11571 /*  findfield()   Find the next field of a string.                           */
11572 /*                                                                           */
11573 /*  Jumps past the current field by searching for whitespace, then jumps     */
11574 /*  past the whitespace to find the next field.                              */
11575 /*                                                                           */
11576 /*****************************************************************************/
11577
11578 #ifndef
11579 TRILIBRARY
11580
11581 char *findfield( string )
11582 char *string;
11583 {
11584 char *result;
11585
11586 result = string;
11587 /* Skip the current field.  Stop upon reaching whitespace. */
11588 while (( *result != '\0' ) && ( *result != '#' )
11589 && ( *result != ' ' ) && ( *result != '\t' )) {
11590 result++;
11591 }
11592 /* Now skip the whitespace and anything else that doesn't look like a */
11593 /*   number, a comment, or the end of a line.                         */
11594 while (( *result != '\0' ) && ( *result != '#' )
11595 && ( *result != '.' ) && ( *result != '+' ) && ( *result != '-' )
11596 && (( *result < '0' ) || ( *result > '9' ))) {
11597 result++;
11598 }
11599 /* Check for a comment (prefixed with `#'). */
11600 if ( *result == '#' ) {
11601 *result = '\0';
11602 }
11603 return result;
11604 }
11605
11606 #endif /* not TRILIBRARY */
11607
11608 /*****************************************************************************/
11609 /*                                                                           */
11610 /*  readnodes()   Read the points from a file, which may be a .node or .poly */
11611 /*                file.                                                      */
11612 /*                                                                           */
11613 /*****************************************************************************/
11614
11615 #ifndef
11616 TRILIBRARY
11617
11618 void readnodes( nodefilename, polyfilename, polyfile )
11619 char *nodefilename;
11620 char *polyfilename;
11621 FILE **polyfile;
11622 {
11623 FILE *infile;
11624 point pointloop;
11625 char inputline[INPUTLINESIZE];
11626 char *stringptr;
11627 char *infilename;
11628 REAL x, y;
11629 int firstnode;
11630 int nodemarkers;
11631 int currentmarker;
11632 int i, j;
11633
11634 if ( poly ) {
11635 /* Read the points from a .poly file. */
11636 if ( !quiet ) {
11637 printf( "Opening %s.\n", polyfilename );
11638 }
11639 *polyfile = fopen( polyfilename, "r" );
11640 if ( *polyfile == (FILE *) NULL ) {
11641 printf( "  Error:  Cannot access file %s.\n", polyfilename );
11642 exit( 1 );
11643 }
11644 /* Read number of points, number of dimensions, number of point */
11645 /*   attributes, and number of boundary markers.                */
11646 stringptr = readline( inputline, *polyfile, polyfilename );
11647 inpoints = (int) strtol( stringptr, &stringptr, 0 );
11648 stringptr = findfield( stringptr );
11649 if ( *stringptr == '\0' ) {
11650 mesh_dim = 2;
11651 }
11652 else {
11653 mesh_dim = (int) strtol( stringptr, &stringptr, 0 );
11654 }
11655 stringptr = findfield( stringptr );
11656 if ( *stringptr == '\0' ) {
11657 nextras = 0;
11658 }
11659 else {
11660 nextras = (int) strtol( stringptr, &stringptr, 0 );
11661 }
11662 stringptr = findfield( stringptr );
11663 if ( *stringptr == '\0' ) {
11664 nodemarkers = 0;
11665 }
11666 else {
11667 nodemarkers = (int) strtol( stringptr, &stringptr, 0 );
11668 }
11669 if ( inpoints > 0 ) {
11670 infile = *polyfile;
11671 infilename = polyfilename;
11672 readnodefile = 0;
11673 }
11674 else {
11675 /* If the .poly file claims there are zero points, that means that */
11676 /*   the points should be read from a separate .node file.         */
11677 readnodefile = 1;
11678 infilename = innodefilename;
11679 }
11680 }
11681 else {
11682 readnodefile = 1;
11683 infilename = innodefilename;
11684 *polyfile = (FILE *) NULL;
11685 }
11686
11687 if ( readnodefile ) {
11688 /* Read the points from a .node file. */
11689 if ( !quiet ) {
11690 printf( "Opening %s.\n", innodefilename );
11691 }
11692 infile = fopen( innodefilename, "r" );
11693 if ( infile == (FILE *) NULL ) {
11694 printf( "  Error:  Cannot access file %s.\n", innodefilename );
11695 exit( 1 );
11696 }
11697 /* Read number of points, number of dimensions, number of point */
11698 /*   attributes, and number of boundary markers.                */
11699 stringptr = readline( inputline, infile, innodefilename );
11700 inpoints = (int) strtol( stringptr, &stringptr, 0 );
11701 stringptr = findfield( stringptr );
11702 if ( *stringptr == '\0' ) {
11703 mesh_dim = 2;
11704 }
11705 else {
11706 mesh_dim = (int) strtol( stringptr, &stringptr, 0 );
11707 }
11708 stringptr = findfield( stringptr );
11709 if ( *stringptr == '\0' ) {
11710 nextras = 0;
11711 }
11712 else {
11713 nextras = (int) strtol( stringptr, &stringptr, 0 );
11714 }
11715 stringptr = findfield( stringptr );
11716 if ( *stringptr == '\0' ) {
11717 nodemarkers = 0;
11718 }
11719 else {
11720 nodemarkers = (int) strtol( stringptr, &stringptr, 0 );
11721 }
11722 }
11723
11724 if ( inpoints < 3 ) {
11725 printf( "Error:  Input must have at least three input points.\n" );
11726 exit( 1 );
11727 }
11728 if ( mesh_dim != 2 ) {
11729 printf( "Error:  Triangle only works with two-dimensional meshes.\n" );
11730 exit( 1 );
11731 }
11732
11733 initializepointpool();
11734
11735 /* Read the points. */
11736 for ( i = 0; i < inpoints; i++ ) {
11737 pointloop = (point) poolalloc( &points );
11738 stringptr = readline( inputline, infile, infilename );
11739 if ( i == 0 ) {
11740 firstnode = (int) strtol( stringptr, &stringptr, 0 );
11741 if (( firstnode == 0 ) || ( firstnode == 1 )) {
11742 firstnumber = firstnode;
11743 }
11744 }
11745 stringptr = findfield( stringptr );
11746 if ( *stringptr == '\0' ) {
11747 printf( "Error:  Point %d has no x coordinate.\n", firstnumber + i );
11748 exit( 1 );
11749 }
11750 x = (REAL) strtod( stringptr, &stringptr );
11751 stringptr = findfield( stringptr );
11752 if ( *stringptr == '\0' ) {
11753 printf( "Error:  Point %d has no y coordinate.\n", firstnumber + i );
11754 exit( 1 );
11755 }
11756 y = (REAL) strtod( stringptr, &stringptr );
11757 pointloop[0] = x;
11758 pointloop[1] = y;
11759 /* Read the point attributes. */
11760 for ( j = 2; j < 2 + nextras; j++ ) {
11761 stringptr = findfield( stringptr );
11762 if ( *stringptr == '\0' ) {
11763 pointloop[j] = 0.0;
11764 }
11765 else {
11766 pointloop[j] = (REAL) strtod( stringptr, &stringptr );
11767 }
11768 }
11769 if ( nodemarkers ) {
11770 /* Read a point marker. */
11771 stringptr = findfield( stringptr );
11772 if ( *stringptr == '\0' ) {
11773 setpointmark( pointloop, 0 );
11774 }
11775 else {
11776 currentmarker = (int) strtol( stringptr, &stringptr, 0 );
11777 setpointmark( pointloop, currentmarker );
11778 }
11779 }
11780 else {
11781 /* If no markers are specified in the file, they default to zero. */
11782 setpointmark( pointloop, 0 );
11783 }
11784 /* Determine the smallest and largest x and y coordinates. */
11785 if ( i == 0 ) {
11786 xmin = xmax = x;
11787 ymin = ymax = y;
11788 }
11789 else {
11790 xmin = ( x < xmin ) ? x : xmin;
11791 xmax = ( x > xmax ) ? x : xmax;
11792 ymin = ( y < ymin ) ? y : ymin;
11793 ymax = ( y > ymax ) ? y : ymax;
11794 }
11795 }
11796 if ( readnodefile ) {
11797 fclose( infile );
11798 }
11799
11800 /* Nonexistent x value used as a flag to mark circle events in sweepline */
11801 /*   Delaunay algorithm.                                                 */
11802 xminextreme = 10 * xmin - 9 * xmax;
11803 }
11804
11805 #endif /* not TRILIBRARY */
11806
11807 /*****************************************************************************/
11808 /*                                                                           */
11809 /*  transfernodes()   Read the points from memory.                           */
11810 /*                                                                           */
11811 /*****************************************************************************/
11812
11813 #ifdef
11814 TRILIBRARY
11815
11816 void transfernodes( pointlist, pointattriblist, pointmarkerlist, numberofpoints,
11817 numberofpointattribs )
11818 REAL * pointlist;
11819 REAL *pointattriblist;
11820 int *pointmarkerlist;
11821 int numberofpoints;
11822 int numberofpointattribs;
11823 {
11824 point pointloop;
11825 REAL x, y;
11826 int i, j;
11827 int coordindex;
11828 int attribindex;
11829
11830 inpoints = numberofpoints;
11831 mesh_dim = 2;
11832 nextras = numberofpointattribs;
11833 readnodefile = 0;
11834 if ( inpoints < 3 ) {
11835 printf( "Error:  Input must have at least three input points.\n" );
11836 exit( 1 );
11837 }
11838
11839 initializepointpool();
11840
11841 /* Read the points. */
11842 coordindex = 0;
11843 attribindex = 0;
11844 for ( i = 0; i < inpoints; i++ ) {
11845 pointloop = (point) poolalloc( &points );
11846 /* Read the point coordinates. */
11847 x = pointloop[0] = pointlist[coordindex++];
11848 y = pointloop[1] = pointlist[coordindex++];
11849 /* Read the point attributes. */
11850 for ( j = 0; j < numberofpointattribs; j++ ) {
11851 pointloop[2 + j] = pointattriblist[attribindex++];
11852 }
11853 if ( pointmarkerlist != (int *) NULL ) {
11854 /* Read a point marker. */
11855 setpointmark( pointloop, pointmarkerlist[i] );
11856 }
11857 else {
11858 /* If no markers are specified, they default to zero. */
11859 setpointmark( pointloop, 0 );
11860 }
11861 x = pointloop[0];
11862 y = pointloop[1];
11863 /* Determine the smallest and largest x and y coordinates. */
11864 if ( i == 0 ) {
11865 xmin = xmax = x;
11866 ymin = ymax = y;
11867 }
11868 else {
11869 xmin = ( x < xmin ) ? x : xmin;
11870 xmax = ( x > xmax ) ? x : xmax;
11871 ymin = ( y < ymin ) ? y : ymin;
11872 ymax = ( y > ymax ) ? y : ymax;
11873 }
11874 }
11875
11876 /* Nonexistent x value used as a flag to mark circle events in sweepline */
11877 /*   Delaunay algorithm.                                                 */
11878 xminextreme = 10 * xmin - 9 * xmax;
11879 }
11880
11881 #endif /* TRILIBRARY */
11882
11883 /*****************************************************************************/
11884 /*                                                                           */
11885 /*  readholes()   Read the holes, and possibly regional attributes and area  */
11886 /*                constraints, from a .poly file.                            */
11887 /*                                                                           */
11888 /*****************************************************************************/
11889
11890 #ifndef
11891 TRILIBRARY
11892
11893 void readholes( polyfile, polyfilename, hlist, holes, rlist, regions )
11894 FILE * polyfile;
11895 char *polyfilename;
11896 REAL **hlist;
11897 int *holes;
11898 REAL **rlist;
11899 int *regions;
11900 {
11901 REAL *holelist;
11902 REAL *regionlist;
11903 char inputline[INPUTLINESIZE];
11904 char *stringptr;
11905 int index;
11906 int i;
11907
11908 /* Read the holes. */
11909 stringptr = readline( inputline, polyfile, polyfilename );
11910 *holes = (int) strtol( stringptr, &stringptr, 0 );
11911 if ( *holes > 0 ) {
11912 holelist = (REAL *) malloc( 2 * *holes * sizeof( REAL ));
11913 *hlist = holelist;
11914 if ( holelist == (REAL *) NULL ) {
11915 printf( "Error:  Out of memory.\n" );
11916 exit( 1 );
11917 }
11918 for ( i = 0; i < 2 * *holes; i += 2 ) {
11919 stringptr = readline( inputline, polyfile, polyfilename );
11920 stringptr = findfield( stringptr );
11921 if ( *stringptr == '\0' ) {
11922 printf( "Error:  Hole %d has no x coordinate.\n",
11923 firstnumber + ( i >> 1 ));
11924 exit( 1 );
11925 }
11926 else {
11927 holelist[i] = (REAL) strtod( stringptr, &stringptr );
11928 }
11929 stringptr = findfield( stringptr );
11930 if ( *stringptr == '\0' ) {
11931 printf( "Error:  Hole %d has no y coordinate.\n",
11932 firstnumber + ( i >> 1 ));
11933 exit( 1 );
11934 }
11935 else {
11936 holelist[i + 1] = (REAL) strtod( stringptr, &stringptr );
11937 }
11938 }
11939 }
11940 else {
11941 *hlist = (REAL *) NULL;
11942 }
11943
11944 #ifndef
11945 CDT_ONLY
11946 if (( regionattrib || vararea ) && !refine ) {
11947 /* Read the area constraints. */
11948 stringptr = readline( inputline, polyfile, polyfilename );
11949 *regions = (int) strtol( stringptr, &stringptr, 0 );
11950 if ( *regions > 0 ) {
11951 regionlist = (REAL *) malloc( 4 * *regions * sizeof( REAL ));
11952 *rlist = regionlist;
11953 if ( regionlist == (REAL *) NULL ) {
11954 printf( "Error:  Out of memory.\n" );
11955 exit( 1 );
11956 }
11957 index = 0;
11958 for ( i = 0; i < *regions; i++ ) {
11959 stringptr = readline( inputline, polyfile, polyfilename );
11960 stringptr = findfield( stringptr );
11961 if ( *stringptr == '\0' ) {
11962 printf( "Error:  Region %d has no x coordinate.\n",
11963 firstnumber + i );
11964 exit( 1 );
11965 }
11966 else {
11967 regionlist[index++] = (REAL) strtod( stringptr, &stringptr );
11968 }
11969 stringptr = findfield( stringptr );
11970 if ( *stringptr == '\0' ) {
11971 printf( "Error:  Region %d has no y coordinate.\n",
11972 firstnumber + i );
11973 exit( 1 );
11974 }
11975 else {
11976 regionlist[index++] = (REAL) strtod( stringptr, &stringptr );
11977 }
11978 stringptr = findfield( stringptr );
11979 if ( *stringptr == '\0' ) {
11980 printf(
11981 "Error:  Region %d has no region attribute or area constraint.\n",
11982 firstnumber + i );
11983 exit( 1 );
11984 }
11985 else {
11986 regionlist[index++] = (REAL) strtod( stringptr, &stringptr );
11987 }
11988 stringptr = findfield( stringptr );
11989 if ( *stringptr == '\0' ) {
11990 regionlist[index] = regionlist[index - 1];
11991 }
11992 else {
11993 regionlist[index] = (REAL) strtod( stringptr, &stringptr );
11994 }
11995 index++;
11996 }
11997 }
11998 }
11999 else {
12000 /* Set `*regions' to zero to avoid an accidental free() later. */
12001 *regions = 0;
12002 *rlist = (REAL *) NULL;
12003 }
12004 #endif /* not CDT_ONLY */
12005
12006 fclose( polyfile );
12007 }
12008
12009 #endif /* not TRILIBRARY */
12010
12011 /*****************************************************************************/
12012 /*                                                                           */
12013 /*  finishfile()   Write the command line to the output file so the user     */
12014 /*                 can remember how the file was generated.  Close the file. */
12015 /*                                                                           */
12016 /*****************************************************************************/
12017
12018 #ifndef
12019 TRILIBRARY
12020
12021 void finishfile( outfile, argc, argv )
12022 FILE * outfile;
12023 int argc;
12024 char **argv;
12025 {
12026 int i;
12027
12028 fprintf( outfile, "# Generated by" );
12029 for ( i = 0; i < argc; i++ ) {
12030 fprintf( outfile, " " );
12031 fputs( argv[i], outfile );
12032 }
12033 fprintf( outfile, "\n" );
12034 fclose( outfile );
12035 }
12036
12037 #endif /* not TRILIBRARY */
12038
12039 /*****************************************************************************/
12040 /*                                                                           */
12041 /*  writenodes()   Number the points and write them to a .node file.         */
12042 /*                                                                           */
12043 /*  To save memory, the point numbers are written over the shell markers     */
12044 /*  after the points are written to a file.                                  */
12045 /*                                                                           */
12046 /*****************************************************************************/
12047
12048 #ifdef
12049 TRILIBRARY
12050
12051 void writenodes( pointlist, pointattriblist, pointmarkerlist )
12052 REAL * *pointlist;
12053 REAL **pointattriblist;
12054 int **pointmarkerlist;
12055
12056 #else /* not TRILIBRARY */
12057
12058 void writenodes( nodefilename, argc, argv )
12059 char *nodefilename;
12060 int argc;
12061 char **argv;
12062
12063 #endif /* not TRILIBRARY */
12064
12065 {
12066 #ifdef
12067 TRILIBRARY
12068 REAL *plist;
12069 REAL *palist;
12070 int *pmlist;
12071 int coordindex;
12072 int attribindex;
12073 #else /* not TRILIBRARY */
12074 FILE *outfile;
12075 #endif /* not TRILIBRARY */
12076 point pointloop;
12077 int pointnumber;
12078 int i;
12079
12080 #ifdef
12081 TRILIBRARY
12082 if ( !quiet ) {
12083 printf( "Writing points.\n" );
12084 }
12085 /* Allocate memory for output points if necessary. */
12086 if ( *pointlist == (REAL *) NULL ) {
12087 *pointlist = (REAL *) malloc( points.items * 2 * sizeof( REAL ));
12088 if ( *pointlist == (REAL *) NULL ) {
12089 printf( "Error:  Out of memory.\n" );
12090 exit( 1 );
12091 }
12092 }
12093 /* Allocate memory for output point attributes if necessary. */
12094 if (( nextras > 0 ) && ( *pointattriblist == (REAL *) NULL )) {
12095 *pointattriblist = (REAL *) malloc( points.items * nextras * sizeof( REAL ));
12096 if ( *pointattriblist == (REAL *) NULL ) {
12097 printf( "Error:  Out of memory.\n" );
12098 exit( 1 );
12099 }
12100 }
12101 /* Allocate memory for output point markers if necessary. */
12102 if ( !nobound && ( *pointmarkerlist == (int *) NULL )) {
12103 *pointmarkerlist = (int *) malloc( points.items * sizeof( int ));
12104 if ( *pointmarkerlist == (int *) NULL ) {
12105 printf( "Error:  Out of memory.\n" );
12106 exit( 1 );
12107 }
12108 }
12109 plist = *pointlist;
12110 palist = *pointattriblist;
12111 pmlist = *pointmarkerlist;
12112 coordindex = 0;
12113 attribindex = 0;
12114 #else /* not TRILIBRARY */
12115 if ( !quiet ) {
12116 printf( "Writing %s.\n", nodefilename );
12117 }
12118 outfile = fopen( nodefilename, "w" );
12119 if ( outfile == (FILE *) NULL ) {
12120 printf( "  Error:  Cannot create file %s.\n", nodefilename );
12121 exit( 1 );
12122 }
12123 /* Number of points, number of dimensions, number of point attributes, */
12124 /*   and number of boundary markers (zero or one).                     */
12125 fprintf( outfile, "%ld  %d  %d  %d\n", points.items, mesh_dim, nextras,
12126 1 - nobound );
12127 #endif /* not TRILIBRARY */
12128
12129 traversalinit( &points );
12130 pointloop = pointtraverse();
12131 pointnumber = firstnumber;
12132 while ( pointloop != (point) NULL ) {
12133 #ifdef
12134 TRILIBRARY
12135 /* X and y coordinates. */
12136 plist[coordindex++] = pointloop[0];
12137 plist[coordindex++] = pointloop[1];
12138 /* Point attributes. */
12139 for ( i = 0; i < nextras; i++ ) {
12140 palist[attribindex++] = pointloop[2 + i];
12141 }
12142 if ( !nobound ) {
12143 /* Copy the boundary marker. */
12144 pmlist[pointnumber - firstnumber] = pointmark( pointloop );
12145 }
12146 #else /* not TRILIBRARY */
12147 /* Point number, x and y coordinates. */
12148 fprintf( outfile, "%4d    %.17g  %.17g", pointnumber, pointloop[0],
12149 pointloop[1] );
12150 for ( i = 0; i < nextras; i++ ) {
12151 /* Write an attribute. */
12152 fprintf( outfile, "  %.17g", pointloop[i + 2] );
12153 }
12154 if ( nobound ) {
12155 fprintf( outfile, "\n" );
12156 }
12157 else {
12158 /* Write the boundary marker. */
12159 fprintf( outfile, "    %d\n", pointmark( pointloop ));
12160 }
12161 #endif /* not TRILIBRARY */
12162
12163 setpointmark( pointloop, pointnumber );
12164 pointloop = pointtraverse();
12165 pointnumber++;
12166 }
12167
12168 #ifndef
12169 TRILIBRARY
12170 finishfile( outfile, argc, argv );
12171 #endif /* not TRILIBRARY */
12172 }
12173
12174 /*****************************************************************************/
12175 /*                                                                           */
12176 /*  numbernodes()   Number the points.                                       */
12177 /*                                                                           */
12178 /*  Each point is assigned a marker equal to its number.                     */
12179 /*                                                                           */
12180 /*  Used when writenodes() is not called because no .node file is written.   */
12181 /*                                                                           */
12182 /*****************************************************************************/
12183
12184 void numbernodes(){
12185 point pointloop;
12186 int pointnumber;
12187
12188 traversalinit( &points );
12189 pointloop = pointtraverse();
12190 pointnumber = firstnumber;
12191 while ( pointloop != (point) NULL ) {
12192 setpointmark( pointloop, pointnumber );
12193 pointloop = pointtraverse();
12194 pointnumber++;
12195 }
12196 }
12197
12198 /*****************************************************************************/
12199 /*                                                                           */
12200 /*  writeelements()   Write the triangles to an .ele file.                   */
12201 /*                                                                           */
12202 /*****************************************************************************/
12203
12204 #ifdef
12205 TRILIBRARY
12206
12207 void writeelements( trianglelist, triangleattriblist )
12208 int **trianglelist;
12209 REAL **triangleattriblist;
12210
12211 #else /* not TRILIBRARY */
12212
12213 void writeelements( elefilename, argc, argv )
12214 char *elefilename;
12215 int argc;
12216 char **argv;
12217
12218 #endif /* not TRILIBRARY */
12219
12220 {
12221 #ifdef
12222 TRILIBRARY
12223 int *tlist;
12224 REAL *talist;
12225 int pointindex;
12226 int attribindex;
12227 #else /* not TRILIBRARY */
12228 FILE *outfile;
12229 #endif /* not TRILIBRARY */
12230 struct triedge triangleloop;
12231 point p1, p2, p3;
12232 point mid1, mid2, mid3;
12233 int elementnumber;
12234 int i;
12235
12236 #ifdef
12237 TRILIBRARY
12238 if ( !quiet ) {
12239 printf( "Writing triangles.\n" );
12240 }
12241 /* Allocate memory for output triangles if necessary. */
12242 if ( *trianglelist == (int *) NULL ) {
12243 *trianglelist = (int *) malloc( triangles.items *
12244 (( order + 1 ) * ( order + 2 ) / 2 ) * sizeof( int ));
12245 if ( *trianglelist == (int *) NULL ) {
12246 printf( "Error:  Out of memory.\n" );
12247 exit( 1 );
12248 }
12249 }
12250 /* Allocate memory for output triangle attributes if necessary. */
12251 if (( eextras > 0 ) && ( *triangleattriblist == (REAL *) NULL )) {
12252 *triangleattriblist = (REAL *) malloc( triangles.items * eextras *
12253 sizeof( REAL ));
12254 if ( *triangleattriblist == (REAL *) NULL ) {
12255 printf( "Error:  Out of memory.\n" );
12256 exit( 1 );
12257 }
12258 }
12259 tlist = *trianglelist;
12260 talist = *triangleattriblist;
12261 pointindex = 0;
12262 attribindex = 0;
12263 #else /* not TRILIBRARY */
12264 if ( !quiet ) {
12265 printf( "Writing %s.\n", elefilename );
12266 }
12267 outfile = fopen( elefilename, "w" );
12268 if ( outfile == (FILE *) NULL ) {
12269 printf( "  Error:  Cannot create file %s.\n", elefilename );
12270 exit( 1 );
12271 }
12272 /* Number of triangles, points per triangle, attributes per triangle. */
12273 fprintf( outfile, "%ld  %d  %d\n", triangles.items,
12274 ( order + 1 ) * ( order + 2 ) / 2, eextras );
12275 #endif /* not TRILIBRARY */
12276
12277 traversalinit( &triangles );
12278 triangleloop.tri = triangletraverse();
12279 triangleloop.orient = 0;
12280 elementnumber = firstnumber;
12281 while ( triangleloop.tri != (triangle *) NULL ) {
12282 org( triangleloop, p1 );
12283 dest( triangleloop, p2 );
12284 apex( triangleloop, p3 );
12285 if ( order == 1 ) {
12286 #ifdef
12287 TRILIBRARY
12288 tlist[pointindex++] = pointmark( p1 );
12289 tlist[pointindex++] = pointmark( p2 );
12290 tlist[pointindex++] = pointmark( p3 );
12291 #else /* not TRILIBRARY */
12292 /* Triangle number, indices for three points. */
12293 fprintf( outfile, "%4d    %4d  %4d  %4d", elementnumber,
12294 pointmark( p1 ), pointmark( p2 ), pointmark( p3 ));
12295 #endif /* not TRILIBRARY */
12296 }
12297 else {
12298 mid1 = (point) triangleloop.tri[highorderindex + 1];
12299 mid2 = (point) triangleloop.tri[highorderindex + 2];
12300 mid3 = (point) triangleloop.tri[highorderindex];
12301 #ifdef
12302 TRILIBRARY
12303 tlist[pointindex++] = pointmark( p1 );
12304 tlist[pointindex++] = pointmark( p2 );
12305 tlist[pointindex++] = pointmark( p3 );
12306 tlist[pointindex++] = pointmark( mid1 );
12307 tlist[pointindex++] = pointmark( mid2 );
12308 tlist[pointindex++] = pointmark( mid3 );
12309 #else /* not TRILIBRARY */
12310 /* Triangle number, indices for six points. */
12311 fprintf( outfile, "%4d    %4d  %4d  %4d  %4d  %4d  %4d", elementnumber,
12312 pointmark( p1 ), pointmark( p2 ), pointmark( p3 ), pointmark( mid1 ),
12313 pointmark( mid2 ), pointmark( mid3 ));
12314 #endif /* not TRILIBRARY */
12315 }
12316
12317 #ifdef
12318 TRILIBRARY
12319 for ( i = 0; i < eextras; i++ ) {
12320 talist[attribindex++] = elemattribute( triangleloop, i );
12321 }
12322 #else /* not TRILIBRARY */
12323 for ( i = 0; i < eextras; i++ ) {
12324 fprintf( outfile, "  %.17g", elemattribute( triangleloop, i ));
12325 }
12326 fprintf( outfile, "\n" );
12327 #endif /* not TRILIBRARY */
12328
12329 triangleloop.tri = triangletraverse();
12330 elementnumber++;
12331 }
12332
12333 #ifndef
12334 TRILIBRARY
12335 finishfile( outfile, argc, argv );
12336 #endif /* not TRILIBRARY */
12337 }
12338
12339 /*****************************************************************************/
12340 /*                                                                           */
12341 /*  writepoly()   Write the segments and holes to a .poly file.              */
12342 /*                                                                           */
12343 /*****************************************************************************/
12344
12345 #ifdef
12346 TRILIBRARY
12347
12348 void writepoly( segmentlist, segmentmarkerlist )
12349 int **segmentlist;
12350 int **segmentmarkerlist;
12351
12352 #else /* not TRILIBRARY */
12353
12354 void writepoly( polyfilename, holelist, holes, regionlist, regions, argc, argv )
12355 char *polyfilename;
12356 REAL *holelist;
12357 int holes;
12358 REAL *regionlist;
12359 int regions;
12360 int argc;
12361 char **argv;
12362
12363 #endif /* not TRILIBRARY */
12364
12365 {
12366 #ifdef
12367 TRILIBRARY
12368 int *slist;
12369 int *smlist;
12370 int index;
12371 #else /* not TRILIBRARY */
12372 FILE *outfile;
12373 int i;
12374 #endif /* not TRILIBRARY */
12375 struct edge shelleloop;
12376 point endpoint1, endpoint2;
12377 int shellenumber;
12378
12379 #ifdef
12380 TRILIBRARY
12381 if ( !quiet ) {
12382 printf( "Writing segments.\n" );
12383 }
12384 /* Allocate memory for output segments if necessary. */
12385 if ( *segmentlist == (int *) NULL ) {
12386 *segmentlist = (int *) malloc( shelles.items * 2 * sizeof( int ));
12387 if ( *segmentlist == (int *) NULL ) {
12388 printf( "Error:  Out of memory.\n" );
12389 exit( 1 );
12390 }
12391 }
12392 /* Allocate memory for output segment markers if necessary. */
12393 if ( !nobound && ( *segmentmarkerlist == (int *) NULL )) {
12394 *segmentmarkerlist = (int *) malloc( shelles.items * sizeof( int ));
12395 if ( *segmentmarkerlist == (int *) NULL ) {
12396 printf( "Error:  Out of memory.\n" );
12397 exit( 1 );
12398 }
12399 }
12400 slist = *segmentlist;
12401 smlist = *segmentmarkerlist;
12402 index = 0;
12403 #else /* not TRILIBRARY */
12404 if ( !quiet ) {
12405 printf( "Writing %s.\n", polyfilename );
12406 }
12407 outfile = fopen( polyfilename, "w" );
12408 if ( outfile == (FILE *) NULL ) {
12409 printf( "  Error:  Cannot create file %s.\n", polyfilename );
12410 exit( 1 );
12411 }
12412 /* The zero indicates that the points are in a separate .node file. */
12413 /*   Followed by number of dimensions, number of point attributes,  */
12414 /*   and number of boundary markers (zero or one).                  */
12415 fprintf( outfile, "%d  %d  %d  %d\n", 0, mesh_dim, nextras, 1 - nobound );
12416 /* Number of segments, number of boundary markers (zero or one). */
12417 fprintf( outfile, "%ld  %d\n", shelles.items, 1 - nobound );
12418 #endif /* not TRILIBRARY */
12419
12420 traversalinit( &shelles );
12421 shelleloop.sh = shelletraverse();
12422 shelleloop.shorient = 0;
12423 shellenumber = firstnumber;
12424 while ( shelleloop.sh != (shelle *) NULL ) {
12425 sorg( shelleloop, endpoint1 );
12426 sdest( shelleloop, endpoint2 );
12427 #ifdef
12428 TRILIBRARY
12429 /* Copy indices of the segment's two endpoints. */
12430 slist[index++] = pointmark( endpoint1 );
12431 slist[index++] = pointmark( endpoint2 );
12432 if ( !nobound ) {
12433 /* Copy the boundary marker. */
12434 smlist[shellenumber - firstnumber] = mark( shelleloop );
12435 }
12436 #else /* not TRILIBRARY */
12437 /* Segment number, indices of its two endpoints, and possibly a marker. */
12438 if ( nobound ) {
12439 fprintf( outfile, "%4d    %4d  %4d\n", shellenumber,
12440 pointmark( endpoint1 ), pointmark( endpoint2 ));
12441 }
12442 else {
12443 fprintf( outfile, "%4d    %4d  %4d    %4d\n", shellenumber,
12444 pointmark( endpoint1 ), pointmark( endpoint2 ), mark( shelleloop ));
12445 }
12446 #endif /* not TRILIBRARY */
12447
12448 shelleloop.sh = shelletraverse();
12449 shellenumber++;
12450 }
12451
12452 #ifndef
12453 TRILIBRARY
12454 #ifndef
12455 CDT_ONLY
12456 fprintf( outfile, "%d\n", holes );
12457 if ( holes > 0 ) {
12458 for ( i = 0; i < holes; i++ ) {
12459 /* Hole number, x and y coordinates. */
12460 fprintf( outfile, "%4d   %.17g  %.17g\n", firstnumber + i,
12461 holelist[2 * i], holelist[2 * i + 1] );
12462 }
12463 }
12464 if ( regions > 0 ) {
12465 fprintf( outfile, "%d\n", regions );
12466 for ( i = 0; i < regions; i++ ) {
12467 /* Region number, x and y coordinates, attribute, maximum area. */
12468 fprintf( outfile, "%4d   %.17g  %.17g  %.17g  %.17g\n", firstnumber + i,
12469 regionlist[4 * i], regionlist[4 * i + 1],
12470 regionlist[4 * i + 2], regionlist[4 * i + 3] );
12471 }
12472 }
12473 #endif /* not CDT_ONLY */
12474
12475 finishfile( outfile, argc, argv );
12476 #endif /* not TRILIBRARY */
12477 }
12478
12479 /*****************************************************************************/
12480 /*                                                                           */
12481 /*  writeedges()   Write the edges to a .edge file.                          */
12482 /*                                                                           */
12483 /*****************************************************************************/
12484
12485 #ifdef
12486 TRILIBRARY
12487
12488 void writeedges( edgelist, edgemarkerlist )
12489 int **edgelist;
12490 int **edgemarkerlist;
12491
12492 #else /* not TRILIBRARY */
12493
12494 void writeedges( edgefilename, argc, argv )
12495 char *edgefilename;
12496 int argc;
12497 char **argv;
12498
12499 #endif /* not TRILIBRARY */
12500
12501 {
12502 #ifdef
12503 TRILIBRARY
12504 int *elist;
12505 int *emlist;
12506 int index;
12507 #else /* not TRILIBRARY */
12508 FILE *outfile;
12509 #endif /* not TRILIBRARY */
12510 struct triedge triangleloop, trisym;
12511 struct edge checkmark;
12512 point p1, p2;
12513 int edgenumber;
12514 triangle ptr;                       /* Temporary variable used by sym(). */
12515 shelle sptr;                    /* Temporary variable used by tspivot(). */
12516
12517 #ifdef
12518 TRILIBRARY
12519 if ( !quiet ) {
12520 printf( "Writing edges.\n" );
12521 }
12522 /* Allocate memory for edges if necessary. */
12523 if ( *edgelist == (int *) NULL ) {
12524 *edgelist = (int *) malloc( edges * 2 * sizeof( int ));
12525 if ( *edgelist == (int *) NULL ) {
12526 printf( "Error:  Out of memory.\n" );
12527 exit( 1 );
12528 }
12529 }
12530 /* Allocate memory for edge markers if necessary. */
12531 if ( !nobound && ( *edgemarkerlist == (int *) NULL )) {
12532 *edgemarkerlist = (int *) malloc( edges * sizeof( int ));
12533 if ( *edgemarkerlist == (int *) NULL ) {
12534 printf( "Error:  Out of memory.\n" );
12535 exit( 1 );
12536 }
12537 }
12538 elist = *edgelist;
12539 emlist = *edgemarkerlist;
12540 index = 0;
12541 #else /* not TRILIBRARY */
12542 if ( !quiet ) {
12543 printf( "Writing %s.\n", edgefilename );
12544 }
12545 outfile = fopen( edgefilename, "w" );
12546 if ( outfile == (FILE *) NULL ) {
12547 printf( "  Error:  Cannot create file %s.\n", edgefilename );
12548 exit( 1 );
12549 }
12550 /* Number of edges, number of boundary markers (zero or one). */
12551 fprintf( outfile, "%ld  %d\n", edges, 1 - nobound );
12552 #endif /* not TRILIBRARY */
12553
12554 traversalinit( &triangles );
12555 triangleloop.tri = triangletraverse();
12556 edgenumber = firstnumber;
12557 /* To loop over the set of edges, loop over all triangles, and look at   */
12558 /*   the three edges of each triangle.  If there isn't another triangle  */
12559 /*   adjacent to the edge, operate on the edge.  If there is another     */
12560 /*   adjacent triangle, operate on the edge only if the current triangle */
12561 /*   has a smaller pointer than its neighbor.  This way, each edge is    */
12562 /*   considered only once.                                               */
12563 while ( triangleloop.tri != (triangle *) NULL ) {
12564 for ( triangleloop.orient = 0; triangleloop.orient < 3;
12565 triangleloop.orient++ ) {
12566 sym( triangleloop, trisym );
12567 if (( triangleloop.tri < trisym.tri ) || ( trisym.tri == dummytri )) {
12568 org( triangleloop, p1 );
12569 dest( triangleloop, p2 );
12570 #ifdef
12571 TRILIBRARY
12572 elist[index++] = pointmark( p1 );
12573 elist[index++] = pointmark( p2 );
12574 #endif /* TRILIBRARY */
12575 if ( nobound ) {
12576 #ifndef
12577 TRILIBRARY
12578 /* Edge number, indices of two endpoints. */
12579 fprintf( outfile, "%4d   %d  %d\n", edgenumber,
12580 pointmark( p1 ), pointmark( p2 ));
12581 #endif /* not TRILIBRARY */
12582 }
12583 else {
12584 /* Edge number, indices of two endpoints, and a boundary marker. */
12585 /*   If there's no shell edge, the boundary marker is zero.      */
12586 if ( useshelles ) {
12587 tspivot( triangleloop, checkmark );
12588 if ( checkmark.sh == dummysh ) {
12589 #ifdef
12590 TRILIBRARY
12591 emlist[edgenumber - firstnumber] = 0;
12592 #else /* not TRILIBRARY */
12593 fprintf( outfile, "%4d   %d  %d  %d\n", edgenumber,
12594 pointmark( p1 ), pointmark( p2 ), 0 );
12595 #endif /* not TRILIBRARY */
12596 }
12597 else {
12598 #ifdef
12599 TRILIBRARY
12600 emlist[edgenumber - firstnumber] = mark( checkmark );
12601 #else /* not TRILIBRARY */
12602 fprintf( outfile, "%4d   %d  %d  %d\n", edgenumber,
12603 pointmark( p1 ), pointmark( p2 ), mark( checkmark ));
12604 #endif /* not TRILIBRARY */
12605 }
12606 }
12607 else {
12608 #ifdef
12609 TRILIBRARY
12610 emlist[edgenumber - firstnumber] = trisym.tri == dummytri;
12611 #else /* not TRILIBRARY */
12612 fprintf( outfile, "%4d   %d  %d  %d\n", edgenumber,
12613 pointmark( p1 ), pointmark( p2 ), trisym.tri == dummytri );
12614 #endif /* not TRILIBRARY */
12615 }
12616 }
12617 edgenumber++;
12618 }
12619 }
12620 triangleloop.tri = triangletraverse();
12621 }
12622
12623 #ifndef
12624 TRILIBRARY
12625 finishfile( outfile, argc, argv );
12626 #endif /* not TRILIBRARY */
12627 }
12628
12629 /*****************************************************************************/
12630 /*                                                                           */
12631 /*  writevoronoi()   Write the Voronoi diagram to a .v.node and .v.edge      */
12632 /*                   file.                                                   */
12633 /*                                                                           */
12634 /*  The Voronoi diagram is the geometric dual of the Delaunay triangulation. */
12635 /*  Hence, the Voronoi vertices are listed by traversing the Delaunay        */
12636 /*  triangles, and the Voronoi edges are listed by traversing the Delaunay   */
12637 /*  edges.                                                                   */
12638 /*                                                                           */
12639 /*  WARNING:  In order to assign numbers to the Voronoi vertices, this       */
12640 /*  procedure messes up the shell edges or the extra nodes of every          */
12641 /*  element.  Hence, you should call this procedure last.                    */
12642 /*                                                                           */
12643 /*****************************************************************************/
12644
12645 #ifdef
12646 TRILIBRARY
12647
12648 void writevoronoi( vpointlist, vpointattriblist, vpointmarkerlist, vedgelist,
12649 vedgemarkerlist, vnormlist )
12650 REAL * *vpointlist;
12651 REAL **vpointattriblist;
12652 int **vpointmarkerlist;
12653 int **vedgelist;
12654 int **vedgemarkerlist;
12655 REAL **vnormlist;
12656
12657 #else /* not TRILIBRARY */
12658
12659 void writevoronoi( vnodefilename, vedgefilename, argc, argv )
12660 char *vnodefilename;
12661 char *vedgefilename;
12662 int argc;
12663 char **argv;
12664
12665 #endif /* not TRILIBRARY */
12666
12667 {
12668 #ifdef
12669 TRILIBRARY
12670 REAL *plist;
12671 REAL *palist;
12672 int *elist;
12673 REAL *normlist;
12674 int coordindex;
12675 int attribindex;
12676 #else /* not TRILIBRARY */
12677 FILE *outfile;
12678 #endif /* not TRILIBRARY */
12679 struct triedge triangleloop, trisym;
12680 point torg, tdest, tapex;
12681 REAL circumcenter[2];
12682 REAL xi, eta;
12683 int vnodenumber, vedgenumber;
12684 int p1, p2;
12685 int i;
12686 triangle ptr;                       /* Temporary variable used by sym(). */
12687
12688 #ifdef
12689 TRILIBRARY
12690 if ( !quiet ) {
12691 printf( "Writing Voronoi vertices.\n" );
12692 }
12693 /* Allocate memory for Voronoi vertices if necessary. */
12694 if ( *vpointlist == (REAL *) NULL ) {
12695 *vpointlist = (REAL *) malloc( triangles.items * 2 * sizeof( REAL ));
12696 if ( *vpointlist == (REAL *) NULL ) {
12697 printf( "Error:  Out of memory.\n" );
12698 exit( 1 );
12699 }
12700 }
12701 /* Allocate memory for Voronoi vertex attributes if necessary. */
12702 if ( *vpointattriblist == (REAL *) NULL ) {
12703 *vpointattriblist = (REAL *) malloc( triangles.items * nextras *
12704 sizeof( REAL ));
12705 if ( *vpointattriblist == (REAL *) NULL ) {
12706 printf( "Error:  Out of memory.\n" );
12707 exit( 1 );
12708 }
12709 }
12710 *vpointmarkerlist = (int *) NULL;
12711 plist = *vpointlist;
12712 palist = *vpointattriblist;
12713 coordindex = 0;
12714 attribindex = 0;
12715 #else /* not TRILIBRARY */
12716 if ( !quiet ) {
12717 printf( "Writing %s.\n", vnodefilename );
12718 }
12719 outfile = fopen( vnodefilename, "w" );
12720 if ( outfile == (FILE *) NULL ) {
12721 printf( "  Error:  Cannot create file %s.\n", vnodefilename );
12722 exit( 1 );
12723 }
12724 /* Number of triangles, two dimensions, number of point attributes, */
12725 /*   zero markers.                                                  */
12726 fprintf( outfile, "%ld  %d  %d  %d\n", triangles.items, 2, nextras, 0 );
12727 #endif /* not TRILIBRARY */
12728
12729 traversalinit( &triangles );
12730 triangleloop.tri = triangletraverse();
12731 triangleloop.orient = 0;
12732 vnodenumber = firstnumber;
12733 while ( triangleloop.tri != (triangle *) NULL ) {
12734 org( triangleloop, torg );
12735 dest( triangleloop, tdest );
12736 apex( triangleloop, tapex );
12737 findcircumcenter( torg, tdest, tapex, circumcenter, &xi, &eta );
12738 #ifdef
12739 TRILIBRARY
12740 /* X and y coordinates. */
12741 plist[coordindex++] = circumcenter[0];
12742 plist[coordindex++] = circumcenter[1];
12743 for ( i = 2; i < 2 + nextras; i++ ) {
12744 /* Interpolate the point attributes at the circumcenter. */
12745 palist[attribindex++] = torg[i] + xi * ( tdest[i] - torg[i] )
12746 + eta * ( tapex[i] - torg[i] );
12747 }
12748 #else /* not TRILIBRARY */
12749 /* Voronoi vertex number, x and y coordinates. */
12750 fprintf( outfile, "%4d    %.17g  %.17g", vnodenumber, circumcenter[0],
12751 circumcenter[1] );
12752 for ( i = 2; i < 2 + nextras; i++ ) {
12753 /* Interpolate the point attributes at the circumcenter. */
12754 fprintf( outfile, "  %.17g", torg[i] + xi * ( tdest[i] - torg[i] )
12755 + eta * ( tapex[i] - torg[i] ));
12756 }
12757 fprintf( outfile, "\n" );
12758 #endif /* not TRILIBRARY */
12759
12760 *(int *) ( triangleloop.tri + 6 ) = vnodenumber;
12761 triangleloop.tri = triangletraverse();
12762 vnodenumber++;
12763 }
12764
12765 #ifndef
12766 TRILIBRARY
12767 finishfile( outfile, argc, argv );
12768 #endif /* not TRILIBRARY */
12769
12770 #ifdef
12771 TRILIBRARY
12772 if ( !quiet ) {
12773 printf( "Writing Voronoi edges.\n" );
12774 }
12775 /* Allocate memory for output Voronoi edges if necessary. */
12776 if ( *vedgelist == (int *) NULL ) {
12777 *vedgelist = (int *) malloc( edges * 2 * sizeof( int ));
12778 if ( *vedgelist == (int *) NULL ) {
12779 printf( "Error:  Out of memory.\n" );
12780 exit( 1 );
12781 }
12782 }
12783 *vedgemarkerlist = (int *) NULL;
12784 /* Allocate memory for output Voronoi norms if necessary. */
12785 if ( *vnormlist == (REAL *) NULL ) {
12786 *vnormlist = (REAL *) malloc( edges * 2 * sizeof( REAL ));
12787 if ( *vnormlist == (REAL *) NULL ) {
12788 printf( "Error:  Out of memory.\n" );
12789 exit( 1 );
12790 }
12791 }
12792 elist = *vedgelist;
12793 normlist = *vnormlist;
12794 coordindex = 0;
12795 #else /* not TRILIBRARY */
12796 if ( !quiet ) {
12797 printf( "Writing %s.\n", vedgefilename );
12798 }
12799 outfile = fopen( vedgefilename, "w" );
12800 if ( outfile == (FILE *) NULL ) {
12801 printf( "  Error:  Cannot create file %s.\n", vedgefilename );
12802 exit( 1 );
12803 }
12804 /* Number of edges, zero boundary markers. */
12805 fprintf( outfile, "%ld  %d\n", edges, 0 );
12806 #endif /* not TRILIBRARY */
12807
12808 traversalinit( &triangles );
12809 triangleloop.tri = triangletraverse();
12810 vedgenumber = firstnumber;
12811 /* To loop over the set of edges, loop over all triangles, and look at   */
12812 /*   the three edges of each triangle.  If there isn't another triangle  */
12813 /*   adjacent to the edge, operate on the edge.  If there is another     */
12814 /*   adjacent triangle, operate on the edge only if the current triangle */
12815 /*   has a smaller pointer than its neighbor.  This way, each edge is    */
12816 /*   considered only once.                                               */
12817 while ( triangleloop.tri != (triangle *) NULL ) {
12818 for ( triangleloop.orient = 0; triangleloop.orient < 3;
12819 triangleloop.orient++ ) {
12820 sym( triangleloop, trisym );
12821 if (( triangleloop.tri < trisym.tri ) || ( trisym.tri == dummytri )) {
12822 /* Find the number of this triangle (and Voronoi vertex). */
12823 p1 = *(int *) ( triangleloop.tri + 6 );
12824 if ( trisym.tri == dummytri ) {
12825 org( triangleloop, torg );
12826 dest( triangleloop, tdest );
12827 #ifdef
12828 TRILIBRARY
12829 /* Copy an infinite ray.  Index of one endpoint, and -1. */
12830 elist[coordindex] = p1;
12831 normlist[coordindex++] = tdest[1] - torg[1];
12832 elist[coordindex] = -1;
12833 normlist[coordindex++] = torg[0] - tdest[0];
12834 #else /* not TRILIBRARY */
12835 /* Write an infinite ray.  Edge number, index of one endpoint, -1, */
12836 /*   and x and y coordinates of a vector representing the          */
12837 /*   direction of the ray.                                         */
12838 fprintf( outfile, "%4d   %d  %d   %.17g  %.17g\n", vedgenumber,
12839 p1, -1, tdest[1] - torg[1], torg[0] - tdest[0] );
12840 #endif /* not TRILIBRARY */
12841 }
12842 else {
12843 /* Find the number of the adjacent triangle (and Voronoi vertex). */
12844 p2 = *(int *) ( trisym.tri + 6 );
12845 /* Finite edge.  Write indices of two endpoints. */
12846 #ifdef
12847 TRILIBRARY
12848 elist[coordindex] = p1;
12849 normlist[coordindex++] = 0.0;
12850 elist[coordindex] = p2;
12851 normlist[coordindex++] = 0.0;
12852 #else /* not TRILIBRARY */
12853 fprintf( outfile, "%4d   %d  %d\n", vedgenumber, p1, p2 );
12854 #endif /* not TRILIBRARY */
12855 }
12856 vedgenumber++;
12857 }
12858 }
12859 triangleloop.tri = triangletraverse();
12860 }
12861
12862 #ifndef
12863 TRILIBRARY
12864 finishfile( outfile, argc, argv );
12865 #endif /* not TRILIBRARY */
12866 }
12867
12868 #ifdef
12869 TRILIBRARY
12870
12871 void writeneighbors( neighborlist )
12872 int **neighborlist;
12873
12874 #else /* not TRILIBRARY */
12875
12876 void writeneighbors( neighborfilename, argc, argv )
12877 char *neighborfilename;
12878 int argc;
12879 char **argv;
12880
12881 #endif /* not TRILIBRARY */
12882
12883 {
12884 #ifdef
12885 TRILIBRARY
12886 int *nlist;
12887 int index;
12888 #else /* not TRILIBRARY */
12889 FILE *outfile;
12890 #endif /* not TRILIBRARY */
12891 struct triedge triangleloop, trisym;
12892 int elementnumber;
12893 int neighbor1, neighbor2, neighbor3;
12894 triangle ptr;                       /* Temporary variable used by sym(). */
12895
12896 #ifdef
12897 TRILIBRARY
12898 if ( !quiet ) {
12899 printf( "Writing neighbors.\n" );
12900 }
12901 /* Allocate memory for neighbors if necessary. */
12902 if ( *neighborlist == (int *) NULL ) {
12903 *neighborlist = (int *) malloc( triangles.items * 3 * sizeof( int ));
12904 if ( *neighborlist == (int *) NULL ) {
12905 printf( "Error:  Out of memory.\n" );
12906 exit( 1 );
12907 }
12908 }
12909 nlist = *neighborlist;
12910 index = 0;
12911 #else /* not TRILIBRARY */
12912 if ( !quiet ) {
12913 printf( "Writing %s.\n", neighborfilename );
12914 }
12915 outfile = fopen( neighborfilename, "w" );
12916 if ( outfile == (FILE *) NULL ) {
12917 printf( "  Error:  Cannot create file %s.\n", neighborfilename );
12918 exit( 1 );
12919 }
12920 /* Number of triangles, three edges per triangle. */
12921 fprintf( outfile, "%ld  %d\n", triangles.items, 3 );
12922 #endif /* not TRILIBRARY */
12923
12924 traversalinit( &triangles );
12925 triangleloop.tri = triangletraverse();
12926 triangleloop.orient = 0;
12927 elementnumber = firstnumber;
12928 while ( triangleloop.tri != (triangle *) NULL ) {
12929 *(int *) ( triangleloop.tri + 6 ) = elementnumber;
12930 triangleloop.tri = triangletraverse();
12931 elementnumber++;
12932 }
12933 *(int *) ( dummytri + 6 ) = -1;
12934
12935 traversalinit( &triangles );
12936 triangleloop.tri = triangletraverse();
12937 elementnumber = firstnumber;
12938 while ( triangleloop.tri != (triangle *) NULL ) {
12939 triangleloop.orient = 1;
12940 sym( triangleloop, trisym );
12941 neighbor1 = *(int *) ( trisym.tri + 6 );
12942 triangleloop.orient = 2;
12943 sym( triangleloop, trisym );
12944 neighbor2 = *(int *) ( trisym.tri + 6 );
12945 triangleloop.orient = 0;
12946 sym( triangleloop, trisym );
12947 neighbor3 = *(int *) ( trisym.tri + 6 );
12948 #ifdef
12949 TRILIBRARY
12950 nlist[index++] = neighbor1;
12951 nlist[index++] = neighbor2;
12952 nlist[index++] = neighbor3;
12953 #else /* not TRILIBRARY */
12954 /* Triangle number, neighboring triangle numbers. */
12955 fprintf( outfile, "%4d    %d  %d  %d\n", elementnumber,
12956 neighbor1, neighbor2, neighbor3 );
12957 #endif /* not TRILIBRARY */
12958
12959 triangleloop.tri = triangletraverse();
12960 elementnumber++;
12961 }
12962
12963 #ifndef
12964 TRILIBRARY
12965 finishfile( outfile, argc, argv );
12966 #endif /* TRILIBRARY */
12967 }
12968
12969 /*****************************************************************************/
12970 /*                                                                           */
12971 /*  writeoff()   Write the triangulation to an .off file.                    */
12972 /*                                                                           */
12973 /*  OFF stands for the Object File Format, a format used by the Geometry     */
12974 /*  Center's Geomview package.                                               */
12975 /*                                                                           */
12976 /*****************************************************************************/
12977
12978 #ifndef
12979 TRILIBRARY
12980
12981 void writeoff( offfilename, argc, argv )
12982 char *offfilename;
12983 int argc;
12984 char **argv;
12985 {
12986 FILE *outfile;
12987 struct triedge triangleloop;
12988 point pointloop;
12989 point p1, p2, p3;
12990
12991 if ( !quiet ) {
12992 printf( "Writing %s.\n", offfilename );
12993 }
12994 outfile = fopen( offfilename, "w" );
12995 if ( outfile == (FILE *) NULL ) {
12996 printf( "  Error:  Cannot create file %s.\n", offfilename );
12997 exit( 1 );
12998 }
12999 /* Number of points, triangles, and edges. */
13000 fprintf( outfile, "OFF\n%ld  %ld  %ld\n", points.items, triangles.items,
13001 edges );
13002
13003 /* Write the points. */
13004 traversalinit( &points );
13005 pointloop = pointtraverse();
13006 while ( pointloop != (point) NULL ) {
13007 /* The "0.0" is here because the OFF format uses 3D coordinates. */
13008 fprintf( outfile, " %.17g  %.17g  %.17g\n", pointloop[0],
13009 pointloop[1], 0.0 );
13010 pointloop = pointtraverse();
13011 }
13012
13013 /* Write the triangles. */
13014 traversalinit( &triangles );
13015 triangleloop.tri = triangletraverse();
13016 triangleloop.orient = 0;
13017 while ( triangleloop.tri != (triangle *) NULL ) {
13018 org( triangleloop, p1 );
13019 dest( triangleloop, p2 );
13020 apex( triangleloop, p3 );
13021 /* The "3" means a three-vertex polygon. */
13022 fprintf( outfile, " 3   %4d  %4d  %4d\n", pointmark( p1 ) - 1,
13023 pointmark( p2 ) - 1, pointmark( p3 ) - 1 );
13024 triangleloop.tri = triangletraverse();
13025 }
13026 finishfile( outfile, argc, argv );
13027 }
13028
13029 #endif /* not TRILIBRARY */
13030
13031 /**                                                                         **/
13032 /**                                                                         **/
13033 /********* File I/O routines end here                                *********/
13034
13035 /*****************************************************************************/
13036 /*                                                                           */
13037 /*  quality_statistics()   Print statistics about the quality of the mesh.   */
13038 /*                                                                           */
13039 /*****************************************************************************/
13040
13041 void quality_statistics(){
13042 struct triedge triangleloop;
13043 point p[3];
13044 REAL cossquaretable[8];
13045 REAL ratiotable[16];
13046 REAL dx[3], dy[3];
13047 REAL edgelength[3];
13048 REAL dotproduct;
13049 REAL cossquare;
13050 REAL triarea;
13051 REAL shortest, longest;
13052 REAL trilongest2;
13053 REAL smallestarea, biggestarea;
13054 REAL triminaltitude2;
13055 REAL minaltitude;
13056 REAL triaspect2;
13057 REAL worstaspect;
13058 REAL smallestangle, biggestangle;
13059 REAL radconst, degconst;
13060 int angletable[18];
13061 int aspecttable[16];
13062 int aspectindex;
13063 int tendegree;
13064 int acutebiggest;
13065 int i, ii, j, k;
13066
13067 printf( "Mesh quality statistics:\n\n" );
13068 radconst = (REAL)( PI / 18.0 );
13069 degconst = (REAL)( 180.0 / PI );
13070 for ( i = 0; i < 8; i++ ) {
13071 cossquaretable[i] = (REAL)( cos( radconst * (REAL) ( i + 1 )));
13072 cossquaretable[i] = cossquaretable[i] * cossquaretable[i];
13073 }
13074 for ( i = 0; i < 18; i++ ) {
13075 angletable[i] = 0;
13076 }
13077
13078 ratiotable[0]  =      1.5;      ratiotable[1]  =     2.0;
13079 ratiotable[2]  =      2.5;      ratiotable[3]  =     3.0;
13080 ratiotable[4]  =      4.0;      ratiotable[5]  =     6.0;
13081 ratiotable[6]  =     10.0;      ratiotable[7]  =    15.0;
13082 ratiotable[8]  =     25.0;      ratiotable[9]  =    50.0;
13083 ratiotable[10] =    100.0;      ratiotable[11] =   300.0;
13084 ratiotable[12] =   1000.0;      ratiotable[13] = 10000.0;
13085 ratiotable[14] = 100000.0;      ratiotable[15] =     0.0;
13086 for ( i = 0; i < 16; i++ ) {
13087 aspecttable[i] = 0;
13088 }
13089
13090 worstaspect = 0.0;
13091 minaltitude = xmax - xmin + ymax - ymin;
13092 minaltitude = minaltitude * minaltitude;
13093 shortest = minaltitude;
13094 longest = 0.0;
13095 smallestarea = minaltitude;
13096 biggestarea = 0.0;
13097 worstaspect = 0.0;
13098 smallestangle = 0.0;
13099 biggestangle = 2.0;
13100 acutebiggest = 1;
13101
13102 traversalinit( &triangles );
13103 triangleloop.tri = triangletraverse();
13104 triangleloop.orient = 0;
13105 while ( triangleloop.tri != (triangle *) NULL ) {
13106 org( triangleloop, p[0] );
13107 dest( triangleloop, p[1] );
13108 apex( triangleloop, p[2] );
13109 trilongest2 = 0.0;
13110
13111 for ( i = 0; i < 3; i++ ) {
13112 j = plus1mod3[i];
13113 k = minus1mod3[i];
13114 dx[i] = p[j][0] - p[k][0];
13115 dy[i] = p[j][1] - p[k][1];
13116 edgelength[i] = dx[i] * dx[i] + dy[i] * dy[i];
13117 if ( edgelength[i] > trilongest2 ) {
13118 trilongest2 = edgelength[i];
13119 }
13120 if ( edgelength[i] > longest ) {
13121 longest = edgelength[i];
13122 }
13123 if ( edgelength[i] < shortest ) {
13124 shortest = edgelength[i];
13125 }
13126 }
13127
13128 triarea = counterclockwise( p[0], p[1], p[2] );
13129 if ( triarea < smallestarea ) {
13130 smallestarea = triarea;
13131 }
13132 if ( triarea > biggestarea ) {
13133 biggestarea = triarea;
13134 }
13135 triminaltitude2 = triarea * triarea / trilongest2;
13136 if ( triminaltitude2 < minaltitude ) {
13137 minaltitude = triminaltitude2;
13138 }
13139 triaspect2 = trilongest2 / triminaltitude2;
13140 if ( triaspect2 > worstaspect ) {
13141 worstaspect = triaspect2;
13142 }
13143 aspectindex = 0;
13144 while (( triaspect2 > ratiotable[aspectindex] * ratiotable[aspectindex] )
13145 && ( aspectindex < 15 )) {
13146 aspectindex++;
13147 }
13148 aspecttable[aspectindex]++;
13149
13150 for ( i = 0; i < 3; i++ ) {
13151 j = plus1mod3[i];
13152 k = minus1mod3[i];
13153 dotproduct = dx[j] * dx[k] + dy[j] * dy[k];
13154 cossquare = dotproduct * dotproduct / ( edgelength[j] * edgelength[k] );
13155 tendegree = 8;
13156 for ( ii = 7; ii >= 0; ii-- ) {
13157 if ( cossquare > cossquaretable[ii] ) {
13158 tendegree = ii;
13159 }
13160 }
13161 if ( dotproduct <= 0.0 ) {
13162 angletable[tendegree]++;
13163 if ( cossquare > smallestangle ) {
13164 smallestangle = cossquare;
13165 }
13166 if ( acutebiggest && ( cossquare < biggestangle )) {
13167 biggestangle = cossquare;
13168 }
13169 }
13170 else {
13171 angletable[17 - tendegree]++;
13172 if ( acutebiggest || ( cossquare > biggestangle )) {
13173 biggestangle = cossquare;
13174 acutebiggest = 0;
13175 }
13176 }
13177 }
13178 triangleloop.tri = triangletraverse();
13179 }
13180
13181 shortest = (REAL)sqrt( shortest );
13182 longest = (REAL)sqrt( longest );
13183 minaltitude = (REAL)sqrt( minaltitude );
13184 worstaspect = (REAL)sqrt( worstaspect );
13185 smallestarea *= 2.0;
13186 biggestarea *= 2.0;
13187 if ( smallestangle >= 1.0 ) {
13188 smallestangle = 0.0;
13189 }
13190 else {
13191 smallestangle = (REAL)( degconst * acos( sqrt( smallestangle )));
13192 }
13193 if ( biggestangle >= 1.0 ) {
13194 biggestangle = 180.0;
13195 }
13196 else {
13197 if ( acutebiggest ) {
13198 biggestangle = (REAL)( degconst * acos( sqrt( biggestangle )));
13199 }
13200 else {
13201 biggestangle = (REAL)( 180.0 - degconst * acos( sqrt( biggestangle )));
13202 }
13203 }
13204
13205 printf( "  Smallest area: %16.5g   |  Largest area: %16.5g\n",
13206 smallestarea, biggestarea );
13207 printf( "  Shortest edge: %16.5g   |  Longest edge: %16.5g\n",
13208 shortest, longest );
13209 printf( "  Shortest altitude: %12.5g   |  Largest aspect ratio: %8.5g\n\n",
13210 minaltitude, worstaspect );
13211 printf( "  Aspect ratio histogram:\n" );
13212 printf( "  1.1547 - %-6.6g    :  %8d    | %6.6g - %-6.6g     :  %8d\n",
13213 ratiotable[0], aspecttable[0], ratiotable[7], ratiotable[8],
13214 aspecttable[8] );
13215 for ( i = 1; i < 7; i++ ) {
13216 printf( "  %6.6g - %-6.6g    :  %8d    | %6.6g - %-6.6g     :  %8d\n",
13217 ratiotable[i - 1], ratiotable[i], aspecttable[i],
13218 ratiotable[i + 7], ratiotable[i + 8], aspecttable[i + 8] );
13219 }
13220 printf( "  %6.6g - %-6.6g    :  %8d    | %6.6g -            :  %8d\n",
13221 ratiotable[6], ratiotable[7], aspecttable[7], ratiotable[14],
13222 aspecttable[15] );
13223 printf(
13224 "  (Triangle aspect ratio is longest edge divided by shortest altitude)\n\n" );
13225 printf( "  Smallest angle: %15.5g   |  Largest angle: %15.5g\n\n",
13226 smallestangle, biggestangle );
13227 printf( "  Angle histogram:\n" );
13228 for ( i = 0; i < 9; i++ ) {
13229 printf( "    %3d - %3d degrees:  %8d    |    %3d - %3d degrees:  %8d\n",
13230 i * 10, i * 10 + 10, angletable[i],
13231 i * 10 + 90, i * 10 + 100, angletable[i + 9] );
13232 }
13233 printf( "\n" );
13234 }
13235
13236 /*****************************************************************************/
13237 /*                                                                           */
13238 /*  statistics()   Print all sorts of cool facts.                            */
13239 /*                                                                           */
13240 /*****************************************************************************/
13241
13242 void statistics(){
13243 printf( "\nStatistics:\n\n" );
13244 printf( "  Input points: %d\n", inpoints );
13245 if ( refine ) {
13246 printf( "  Input triangles: %d\n", inelements );
13247 }
13248 if ( poly ) {
13249 printf( "  Input segments: %d\n", insegments );
13250 if ( !refine ) {
13251 printf( "  Input holes: %d\n", holes );
13252 }
13253 }
13254
13255 printf( "\n  Mesh points: %ld\n", points.items );
13256 printf( "  Mesh triangles: %ld\n", triangles.items );
13257 printf( "  Mesh edges: %ld\n", edges );
13258 if ( poly || refine ) {
13259 printf( "  Mesh boundary edges: %ld\n", hullsize );
13260 printf( "  Mesh segments: %ld\n\n", shelles.items );
13261 }
13262 else {
13263 printf( "  Mesh convex hull edges: %ld\n\n", hullsize );
13264 }
13265 if ( verbose ) {
13266 quality_statistics();
13267 printf( "Memory allocation statistics:\n\n" );
13268 printf( "  Maximum number of points: %ld\n", points.maxitems );
13269 printf( "  Maximum number of triangles: %ld\n", triangles.maxitems );
13270 if ( shelles.maxitems > 0 ) {
13271 printf( "  Maximum number of segments: %ld\n", shelles.maxitems );
13272 }
13273 if ( viri.maxitems > 0 ) {
13274 printf( "  Maximum number of viri: %ld\n", viri.maxitems );
13275 }
13276 if ( badsegments.maxitems > 0 ) {
13277 printf( "  Maximum number of encroached segments: %ld\n",
13278 badsegments.maxitems );
13279 }
13280 if ( badtriangles.maxitems > 0 ) {
13281 printf( "  Maximum number of bad triangles: %ld\n",
13282 badtriangles.maxitems );
13283 }
13284 if ( splaynodes.maxitems > 0 ) {
13285 printf( "  Maximum number of splay tree nodes: %ld\n",
13286 splaynodes.maxitems );
13287 }
13288 printf( "  Approximate heap memory use (bytes): %ld\n\n",
13289 points.maxitems * points.itembytes
13290 + triangles.maxitems * triangles.itembytes
13291 + shelles.maxitems * shelles.itembytes
13292 + viri.maxitems * viri.itembytes
13293 + badsegments.maxitems * badsegments.itembytes
13294 + badtriangles.maxitems * badtriangles.itembytes
13295 + splaynodes.maxitems * splaynodes.itembytes );
13296
13297 printf( "Algorithmic statistics:\n\n" );
13298 printf( "  Number of incircle tests: %ld\n", incirclecount );
13299 printf( "  Number of orientation tests: %ld\n", counterclockcount );
13300 if ( hyperbolacount > 0 ) {
13301 printf( "  Number of right-of-hyperbola tests: %ld\n",
13302 hyperbolacount );
13303 }
13304 if ( circumcentercount > 0 ) {
13305 printf( "  Number of circumcenter computations: %ld\n",
13306 circumcentercount );
13307 }
13308 if ( circletopcount > 0 ) {
13309 printf( "  Number of circle top computations: %ld\n",
13310 circletopcount );
13311 }
13312 printf( "\n" );
13313 }
13314 }
13315
13316 /*****************************************************************************/
13317 /*                                                                           */
13318 /*  main() or triangulate()   Gosh, do everything.                           */
13319 /*                                                                           */
13320 /*  The sequence is roughly as follows.  Many of these steps can be skipped, */
13321 /*  depending on the command line switches.                                  */
13322 /*                                                                           */
13323 /*  - Initialize constants and parse the command line.                       */
13324 /*  - Read the points from a file and either                                 */
13325 /*    - triangulate them (no -r), or                                         */
13326 /*    - read an old mesh from files and reconstruct it (-r).                 */
13327 /*  - Insert the PSLG segments (-p), and possibly segments on the convex     */
13328 /*      hull (-c).                                                           */
13329 /*  - Read the holes (-p), regional attributes (-pA), and regional area      */
13330 /*      constraints (-pa).  Carve the holes and concavities, and spread the  */
13331 /*      regional attributes and area constraints.                            */
13332 /*  - Enforce the constraints on minimum angle (-q) and maximum area (-a).   */
13333 /*      Also enforce the conforming Delaunay property (-q and -a).           */
13334 /*  - Compute the number of edges in the resulting mesh.                     */
13335 /*  - Promote the mesh's linear triangles to higher order elements (-o).     */
13336 /*  - Write the output files and print the statistics.                       */
13337 /*  - Check the consistency and Delaunay property of the mesh (-C).          */
13338 /*                                                                           */
13339 /*****************************************************************************/
13340
13341 #ifdef
13342 TRILIBRARY
13343
13344 void triangulate( triswitches, in, out, vorout )
13345 char *triswitches;
13346 struct triangulateio *in;
13347 struct triangulateio *out;
13348 struct triangulateio *vorout;
13349
13350 #else /* not TRILIBRARY */
13351
13352 int main( argc, argv )
13353 int argc;
13354 char **argv;
13355
13356 #endif /* not TRILIBRARY */
13357
13358 {
13359 REAL *holearray;                                      /* Array of holes. */
13360 REAL *regionarray; /* Array of regional attributes and area constraints. */
13361 #ifndef
13362 TRILIBRARY
13363 FILE *polyfile;
13364 #endif /* not TRILIBRARY */
13365 #ifndef
13366 NO_TIMER
13367 /* Variables for timing the performance of Triangle.  The types are */
13368 /*   defined in sys/time.h.                                         */
13369 struct timeval tv0, tv1, tv2, tv3, tv4, tv5, tv6;
13370 struct timezone tz;
13371 #endif /* NO_TIMER */
13372
13373 #ifndef
13374 NO_TIMER
13375 gettimeofday( &tv0, &tz );
13376 #endif /* NO_TIMER */
13377
13378 triangleinit();
13379 #ifdef
13380 TRILIBRARY
13381 parsecommandline( 1, &triswitches );
13382 #else /* not TRILIBRARY */
13383 parsecommandline( argc, argv );
13384 #endif /* not TRILIBRARY */
13385
13386 #ifdef
13387 TRILIBRARY
13388 transfernodes( in->pointlist, in->pointattributelist, in->pointmarkerlist,
13389 in->numberofpoints, in->numberofpointattributes );
13390 #else /* not TRILIBRARY */
13391 readnodes( innodefilename, inpolyfilename, &polyfile );
13392 #endif /* not TRILIBRARY */
13393
13394 #ifndef
13395 NO_TIMER
13396 if ( !quiet ) {
13397 gettimeofday( &tv1, &tz );
13398 }
13399 #endif /* NO_TIMER */
13400
13401 #ifdef
13402 CDT_ONLY
13403 hullsize = delaunay();                        /* Triangulate the points. */
13404 #else /* not CDT_ONLY */
13405 if ( refine ) {
13406 /* Read and reconstruct a mesh. */
13407 #ifdef
13408 TRILIBRARY
13409 hullsize = reconstruct( in->trianglelist, in->triangleattributelist,
13410 in->trianglearealist, in->numberoftriangles,
13411 in->numberofcorners, in->numberoftriangleattributes,
13412 in->segmentlist, in->segmentmarkerlist,
13413 in->numberofsegments );
13414 #else /* not TRILIBRARY */
13415 hullsize = reconstruct( inelefilename, areafilename, inpolyfilename,
13416 polyfile );
13417 #endif /* not TRILIBRARY */
13418 }
13419 else {
13420 hullsize = delaunay();                    /* Triangulate the points. */
13421 }
13422 #endif /* not CDT_ONLY */
13423
13424 #ifndef
13425 NO_TIMER
13426 if ( !quiet ) {
13427 gettimeofday( &tv2, &tz );
13428 if ( refine ) {
13429 printf( "Mesh reconstruction" );
13430 }
13431 else {
13432 printf( "Delaunay" );
13433 }
13434 printf( " milliseconds:  %ld\n", 1000l * ( tv2.tv_sec - tv1.tv_sec )
13435 + ( tv2.tv_usec - tv1.tv_usec ) / 1000l );
13436 }
13437 #endif /* NO_TIMER */
13438
13439 /* Ensure that no point can be mistaken for a triangular bounding */
13440 /*   box point in insertsite().                                   */
13441 infpoint1 = (point) NULL;
13442 infpoint2 = (point) NULL;
13443 infpoint3 = (point) NULL;
13444
13445 if ( useshelles ) {
13446 checksegments = 1;              /* Segments will be introduced next. */
13447 if ( !refine ) {
13448 /* Insert PSLG segments and/or convex hull segments. */
13449 #ifdef
13450 TRILIBRARY
13451 insegments = formskeleton( in->segmentlist, in->segmentmarkerlist,
13452 in->numberofsegments );
13453 #else /* not TRILIBRARY */
13454 insegments = formskeleton( polyfile, inpolyfilename );
13455 #endif /* not TRILIBRARY */
13456 }
13457 }
13458
13459 #ifndef
13460 NO_TIMER
13461 if ( !quiet ) {
13462 gettimeofday( &tv3, &tz );
13463 if ( useshelles && !refine ) {
13464 printf( "Segment milliseconds:  %ld\n",
13465 1000l * ( tv3.tv_sec - tv2.tv_sec )
13466 + ( tv3.tv_usec - tv2.tv_usec ) / 1000l );
13467 }
13468 }
13469 #endif /* NO_TIMER */
13470
13471 if ( poly ) {
13472 #ifdef
13473 TRILIBRARY
13474 holearray = in->holelist;
13475 holes = in->numberofholes;
13476 regionarray = in->regionlist;
13477 regions = in->numberofregions;
13478 #else /* not TRILIBRARY */
13479 readholes( polyfile, inpolyfilename, &holearray, &holes,
13480 &regionarray, &regions );
13481 #endif /* not TRILIBRARY */
13482 if ( !refine ) {
13483 /* Carve out holes and concavities. */
13484 carveholes( holearray, holes, regionarray, regions );
13485 }
13486 }
13487 else {
13488 /* Without a PSLG, there can be no holes or regional attributes   */
13489 /*   or area constraints.  The following are set to zero to avoid */
13490 /*   an accidental free() later.                                  */
13491 holes = 0;
13492 regions = 0;
13493 }
13494
13495 #ifndef
13496 NO_TIMER
13497 if ( !quiet ) {
13498 gettimeofday( &tv4, &tz );
13499 if ( poly && !refine ) {
13500 printf( "Hole milliseconds:  %ld\n", 1000l * ( tv4.tv_sec - tv3.tv_sec )
13501 + ( tv4.tv_usec - tv3.tv_usec ) / 1000l );
13502 }
13503 }
13504 #endif /* NO_TIMER */
13505
13506 #ifndef
13507 CDT_ONLY
13508 if ( quality ) {
13509 enforcequality();             /* Enforce angle and area constraints. */
13510 }
13511 #endif /* not CDT_ONLY */
13512
13513 #ifndef
13514 NO_TIMER
13515 if ( !quiet ) {
13516 gettimeofday( &tv5, &tz );
13517 #ifndef
13518 CDT_ONLY
13519 if ( quality ) {
13520 printf( "Quality milliseconds:  %ld\n",
13521 1000l * ( tv5.tv_sec - tv4.tv_sec )
13522 + ( tv5.tv_usec - tv4.tv_usec ) / 1000l );
13523 }
13524 #endif /* not CDT_ONLY */
13525 }
13526 #endif /* NO_TIMER */
13527
13528 /* Compute the number of edges. */
13529 edges = ( 3l * triangles.items + hullsize ) / 2l;
13530
13531 if ( order > 1 ) {
13532 highorder();         /* Promote elements to higher polynomial order. */
13533 }
13534 if ( !quiet ) {
13535 printf( "\n" );
13536 }
13537
13538 #ifdef
13539 TRILIBRARY
13540 out->numberofpoints = points.items;
13541 out->numberofpointattributes = nextras;
13542 out->numberoftriangles = triangles.items;
13543 out->numberofcorners = ( order + 1 ) * ( order + 2 ) / 2;
13544 out->numberoftriangleattributes = eextras;
13545 out->numberofedges = edges;
13546 if ( useshelles ) {
13547 out->numberofsegments = shelles.items;
13548 }
13549 else {
13550 out->numberofsegments = hullsize;
13551 }
13552 if ( vorout != (struct triangulateio *) NULL ) {
13553 vorout->numberofpoints = triangles.items;
13554 vorout->numberofpointattributes = nextras;
13555 vorout->numberofedges = edges;
13556 }
13557 #endif /* TRILIBRARY */
13558 /* If not using iteration numbers, don't write a .node file if one was */
13559 /*   read, because the original one would be overwritten!              */
13560 if ( nonodewritten || ( noiterationnum && readnodefile )) {
13561 if ( !quiet ) {
13562 #ifdef
13563 TRILIBRARY
13564 printf( "NOT writing points.\n" );
13565 #else /* not TRILIBRARY */
13566 printf( "NOT writing a .node file.\n" );
13567 #endif /* not TRILIBRARY */
13568 }
13569 numbernodes();             /* We must remember to number the points. */
13570 }
13571 else {
13572 #ifdef
13573 TRILIBRARY
13574 writenodes( &out->pointlist, &out->pointattributelist,
13575 &out->pointmarkerlist );
13576 #else /* not TRILIBRARY */
13577 writenodes( outnodefilename, argc, argv ); /* Numbers the points too. */
13578 #endif /* TRILIBRARY */
13579 }
13580 if ( noelewritten ) {
13581 if ( !quiet ) {
13582 #ifdef
13583 TRILIBRARY
13584 printf( "NOT writing triangles.\n" );
13585 #else /* not TRILIBRARY */
13586 printf( "NOT writing an .ele file.\n" );
13587 #endif /* not TRILIBRARY */
13588 }
13589 }
13590 else {
13591 #ifdef
13592 TRILIBRARY
13593 writeelements( &out->trianglelist, &out->triangleattributelist );
13594 #else /* not TRILIBRARY */
13595 writeelements( outelefilename, argc, argv );
13596 #endif /* not TRILIBRARY */
13597 }
13598 /* The -c switch (convex switch) causes a PSLG to be written */
13599 /*   even if none was read.                                  */
13600 if ( poly || convex ) {
13601 /* If not using iteration numbers, don't overwrite the .poly file. */
13602 if ( nopolywritten || noiterationnum ) {
13603 if ( !quiet ) {
13604 #ifdef
13605 TRILIBRARY
13606 printf( "NOT writing segments.\n" );
13607 #else /* not TRILIBRARY */
13608 printf( "NOT writing a .poly file.\n" );
13609 #endif /* not TRILIBRARY */
13610 }
13611 }
13612 else {
13613 #ifdef
13614 TRILIBRARY
13615 writepoly( &out->segmentlist, &out->segmentmarkerlist );
13616 out->numberofholes = holes;
13617 out->numberofregions = regions;
13618 if ( poly ) {
13619 out->holelist = in->holelist;
13620 out->regionlist = in->regionlist;
13621 }
13622 else {
13623 out->holelist = (REAL *) NULL;
13624 out->regionlist = (REAL *) NULL;
13625 }
13626 #else /* not TRILIBRARY */
13627 writepoly( outpolyfilename, holearray, holes, regionarray, regions,
13628 argc, argv );
13629 #endif /* not TRILIBRARY */
13630 }
13631 }
13632 #ifndef
13633 TRILIBRARY
13634 #ifndef
13635 CDT_ONLY
13636 if ( regions > 0 ) {
13637 free( regionarray );
13638 }
13639 #endif /* not CDT_ONLY */
13640 if ( holes > 0 ) {
13641 free( holearray );
13642 }
13643 if ( geomview ) {
13644 writeoff( offfilename, argc, argv );
13645 }
13646 #endif /* not TRILIBRARY */
13647 if ( edgesout ) {
13648 #ifdef
13649 TRILIBRARY
13650 writeedges( &out->edgelist, &out->edgemarkerlist );
13651 #else /* not TRILIBRARY */
13652 writeedges( edgefilename, argc, argv );
13653 #endif /* not TRILIBRARY */
13654 }
13655 if ( voronoi ) {
13656 #ifdef
13657 TRILIBRARY
13658 writevoronoi( &vorout->pointlist, &vorout->pointattributelist,
13659 &vorout->pointmarkerlist, &vorout->edgelist,
13660 &vorout->edgemarkerlist, &vorout->normlist );
13661 #else /* not TRILIBRARY */
13662 writevoronoi( vnodefilename, vedgefilename, argc, argv );
13663 #endif /* not TRILIBRARY */
13664 }
13665 if ( neighbors ) {
13666 #ifdef
13667 TRILIBRARY
13668 writeneighbors( &out->neighborlist );
13669 #else /* not TRILIBRARY */
13670 writeneighbors( neighborfilename, argc, argv );
13671 #endif /* not TRILIBRARY */
13672 }
13673
13674 if ( !quiet ) {
13675 #ifndef
13676 NO_TIMER
13677 gettimeofday( &tv6, &tz );
13678 printf( "\nOutput milliseconds:  %ld\n",
13679 1000l * ( tv6.tv_sec - tv5.tv_sec )
13680 + ( tv6.tv_usec - tv5.tv_usec ) / 1000l );
13681 printf( "Total running milliseconds:  %ld\n",
13682 1000l * ( tv6.tv_sec - tv0.tv_sec )
13683 + ( tv6.tv_usec - tv0.tv_usec ) / 1000l );
13684 #endif /* NO_TIMER */
13685
13686 statistics();
13687 }
13688
13689 #ifndef
13690 REDUCED
13691 if ( docheck ) {
13692 checkmesh();
13693 checkdelaunay();
13694 }
13695 #endif /* not REDUCED */
13696
13697 triangledeinit();
13698 #ifndef
13699 TRILIBRARY
13700 return 0;
13701 #endif /* not TRILIBRARY */
13702 }