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