Chaste  Release::3.4
triangle.cpp
Go to the documentation of this file.
1 
8 /*****************************************************************************/
9 /* */
10 /* 888888888 ,o, / 888 */
11 /* 888 88o88o " o8888o 88o8888o o88888o 888 o88888o */
12 /* 888 888 888 88b 888 888 888 888 888 d888 88b */
13 /* 888 888 888 o88^o888 888 888 "88888" 888 8888oo888 */
14 /* 888 888 888 C888 888 888 888 / 888 q888 */
15 /* 888 888 888 "88o^888 888 888 Cb 888 "88oooo" */
16 /* "8oo8D */
17 /* */
18 /* A Two-Dimensional Quality Mesh Generator and Delaunay Triangulator. */
19 /* (triangle.c) */
20 /* */
21 /* Version 1.6 */
22 /* July 28, 2005 */
23 /* */
24 /* Copyright 1993, 1995, 1997, 1998, 2002, 2005 */
25 /* Jonathan Richard Shewchuk */
26 /* 2360 Woolsey #H */
27 /* Berkeley, California 94705-1927 */
28 /* jrs@cs.berkeley.edu */
29 /* */
30 /* This program may be freely redistributed under the condition that the */
31 /* copyright notices (including this entire header and the copyright */
32 /* notice printed when the `-h' switch is selected) are not removed, and */
33 /* no compensation is received. Private, research, and institutional */
34 /* use is free. You may distribute modified versions of this code UNDER */
35 /* THE CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE TO IT IN THE */
36 /* SAME FILE REMAIN UNDER COPYRIGHT OF THE ORIGINAL AUTHOR, BOTH SOURCE */
37 /* AND OBJECT CODE ARE MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR */
38 /* NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution of this code as */
39 /* part of a commercial system is permissible ONLY BY DIRECT ARRANGEMENT */
40 /* WITH THE AUTHOR. (If you are not directly supplying this code to a */
41 /* customer, and you are instead telling them how they can obtain it for */
42 /* free, then you are not required to make any arrangement with me.) */
43 /* */
44 /* Hypertext instructions for Triangle are available on the Web at */
45 /* */
46 /* http://www.cs.cmu.edu/~quake/triangle.html */
47 /* */
48 /* Disclaimer: Neither I nor Carnegie Mellon warrant this code in any way */
49 /* whatsoever. This code is provided "as-is". Use at your own risk. */
50 /* */
51 /* Some of the references listed below are marked with an asterisk. [*] */
52 /* These references are available for downloading from the Web page */
53 /* */
54 /* http://www.cs.cmu.edu/~quake/triangle.research.html */
55 /* */
56 /* Three papers discussing aspects of Triangle are available. A short */
57 /* overview appears in "Triangle: Engineering a 2D Quality Mesh */
58 /* Generator and Delaunay Triangulator," in Applied Computational */
59 /* Geometry: Towards Geometric Engineering, Ming C. Lin and Dinesh */
60 /* Manocha, editors, Lecture Notes in Computer Science volume 1148, */
61 /* pages 203-222, Springer-Verlag, Berlin, May 1996 (from the First ACM */
62 /* Workshop on Applied Computational Geometry). [*] */
63 /* */
64 /* The algorithms are discussed in the greatest detail in "Delaunay */
65 /* Refinement Algorithms for Triangular Mesh Generation," Computational */
66 /* Geometry: Theory and Applications 22(1-3):21-74, May 2002. [*] */
67 /* */
68 /* More detail about the data structures may be found in my dissertation: */
69 /* "Delaunay Refinement Mesh Generation," Ph.D. thesis, Technical Report */
70 /* CMU-CS-97-137, School of Computer Science, Carnegie Mellon University, */
71 /* Pittsburgh, Pennsylvania, 18 May 1997. [*] */
72 /* */
73 /* Triangle was created as part of the Quake Project in the School of */
74 /* Computer Science at Carnegie Mellon University. For further */
75 /* information, see Hesheng Bao, Jacobo Bielak, Omar Ghattas, Loukas F. */
76 /* Kallivokas, David R. O'Hallaron, Jonathan R. Shewchuk, and Jifeng Xu, */
77 /* "Large-scale Simulation of Elastic Wave Propagation in Heterogeneous */
78 /* Media on Parallel Computers," Computer Methods in Applied Mechanics */
79 /* and Engineering 152(1-2):85-102, 22 January 1998. */
80 /* */
81 /* Triangle's Delaunay refinement algorithm for quality mesh generation is */
82 /* a hybrid of one due to Jim Ruppert, "A Delaunay Refinement Algorithm */
83 /* for Quality 2-Dimensional Mesh Generation," Journal of Algorithms */
84 /* 18(3):548-585, May 1995 [*], and one due to L. Paul Chew, "Guaranteed- */
85 /* Quality Mesh Generation for Curved Surfaces," Proceedings of the Ninth */
86 /* Annual Symposium on Computational Geometry (San Diego, California), */
87 /* pages 274-280, Association for Computing Machinery, May 1993, */
88 /* http://portal.acm.org/citation.cfm?id=161150 . */
89 /* */
90 /* The Delaunay refinement algorithm has been modified so that it meshes */
91 /* domains with small input angles well, as described in Gary L. Miller, */
92 /* Steven E. Pav, and Noel J. Walkington, "When and Why Ruppert's */
93 /* Algorithm Works," Twelfth International Meshing Roundtable, pages */
94 /* 91-102, Sandia National Laboratories, September 2003. [*] */
95 /* */
96 /* My implementation of the divide-and-conquer and incremental Delaunay */
97 /* triangulation algorithms follows closely the presentation of Guibas */
98 /* and Stolfi, even though I use a triangle-based data structure instead */
99 /* of their quad-edge data structure. (In fact, I originally implemented */
100 /* Triangle using the quad-edge data structure, but the switch to a */
101 /* triangle-based data structure sped Triangle by a factor of two.) The */
102 /* mesh manipulation primitives and the two aforementioned Delaunay */
103 /* triangulation algorithms are described by Leonidas J. Guibas and Jorge */
104 /* Stolfi, "Primitives for the Manipulation of General Subdivisions and */
105 /* the Computation of Voronoi Diagrams," ACM Transactions on Graphics */
106 /* 4(2):74-123, April 1985, http://portal.acm.org/citation.cfm?id=282923 .*/
107 /* */
108 /* Their O(n log n) divide-and-conquer algorithm is adapted from Der-Tsai */
109 /* Lee and Bruce J. Schachter, "Two Algorithms for Constructing the */
110 /* Delaunay Triangulation," International Journal of Computer and */
111 /* Information Science 9(3):219-242, 1980. Triangle's improvement of the */
112 /* divide-and-conquer algorithm by alternating between vertical and */
113 /* horizontal cuts was introduced by Rex A. Dwyer, "A Faster Divide-and- */
114 /* Conquer Algorithm for Constructing Delaunay Triangulations," */
115 /* Algorithmica 2(2):137-151, 1987. */
116 /* */
117 /* The incremental insertion algorithm was first proposed by C. L. Lawson, */
118 /* "Software for C1 Surface Interpolation," in Mathematical Software III, */
119 /* John R. Rice, editor, Academic Press, New York, pp. 161-194, 1977. */
120 /* For point location, I use the algorithm of Ernst P. Mucke, Isaac */
121 /* Saias, and Binhai Zhu, "Fast Randomized Point Location Without */
122 /* Preprocessing in Two- and Three-Dimensional Delaunay Triangulations," */
123 /* Proceedings of the Twelfth Annual Symposium on Computational Geometry, */
124 /* ACM, May 1996. [*] If I were to randomize the order of vertex */
125 /* insertion (I currently don't bother), their result combined with the */
126 /* result of Kenneth L. Clarkson and Peter W. Shor, "Applications of */
127 /* Random Sampling in Computational Geometry II," Discrete & */
128 /* Computational Geometry 4(1):387-421, 1989, would yield an expected */
129 /* O(n^{4/3}) bound on running time. */
130 /* */
131 /* The O(n log n) sweepline Delaunay triangulation algorithm is taken from */
132 /* Steven Fortune, "A Sweepline Algorithm for Voronoi Diagrams", */
133 /* Algorithmica 2(2):153-174, 1987. A random sample of edges on the */
134 /* boundary of the triangulation are maintained in a splay tree for the */
135 /* purpose of point location. Splay trees are described by Daniel */
136 /* Dominic Sleator and Robert Endre Tarjan, "Self-Adjusting Binary Search */
137 /* Trees," Journal of the ACM 32(3):652-686, July 1985, */
138 /* http://portal.acm.org/citation.cfm?id=3835 . */
139 /* */
140 /* The algorithms for exact computation of the signs of determinants are */
141 /* described in Jonathan Richard Shewchuk, "Adaptive Precision Floating- */
142 /* Point Arithmetic and Fast Robust Geometric Predicates," Discrete & */
143 /* Computational Geometry 18(3):305-363, October 1997. (Also available */
144 /* as Technical Report CMU-CS-96-140, School of Computer Science, */
145 /* Carnegie Mellon University, Pittsburgh, Pennsylvania, May 1996.) [*] */
146 /* An abbreviated version appears as Jonathan Richard Shewchuk, "Robust */
147 /* Adaptive Floating-Point Geometric Predicates," Proceedings of the */
148 /* Twelfth Annual Symposium on Computational Geometry, ACM, May 1996. [*] */
149 /* Many of the ideas for my exact arithmetic routines originate with */
150 /* Douglas M. Priest, "Algorithms for Arbitrary Precision Floating Point */
151 /* Arithmetic," Tenth Symposium on Computer Arithmetic, pp. 132-143, IEEE */
152 /* Computer Society Press, 1991. [*] Many of the ideas for the correct */
153 /* evaluation of the signs of determinants are taken from Steven Fortune */
154 /* and Christopher J. Van Wyk, "Efficient Exact Arithmetic for Computa- */
155 /* tional Geometry," Proceedings of the Ninth Annual Symposium on */
156 /* Computational Geometry, ACM, pp. 163-172, May 1993, and from Steven */
157 /* Fortune, "Numerical Stability of Algorithms for 2D Delaunay Triangu- */
158 /* lations," International Journal of Computational Geometry & Applica- */
159 /* tions 5(1-2):193-213, March-June 1995. */
160 /* */
161 /* The method of inserting new vertices off-center (not precisely at the */
162 /* circumcenter of every poor-quality triangle) is from Alper Ungor, */
163 /* "Off-centers: A New Type of Steiner Points for Computing Size-Optimal */
164 /* Quality-Guaranteed Delaunay Triangulations," Proceedings of LATIN */
165 /* 2004 (Buenos Aires, Argentina), April 2004. */
166 /* */
167 /* For definitions of and results involving Delaunay triangulations, */
168 /* constrained and conforming versions thereof, and other aspects of */
169 /* triangular mesh generation, see the excellent survey by Marshall Bern */
170 /* and David Eppstein, "Mesh Generation and Optimal Triangulation," in */
171 /* Computing and Euclidean Geometry, Ding-Zhu Du and Frank Hwang, */
172 /* editors, World Scientific, Singapore, pp. 23-90, 1992. [*] */
173 /* */
174 /* The time for incrementally adding PSLG (planar straight line graph) */
175 /* segments to create a constrained Delaunay triangulation is probably */
176 /* O(t^2) per segment in the worst case and O(t) per segment in the */
177 /* common case, where t is the number of triangles that intersect the */
178 /* segment before it is inserted. This doesn't count point location, */
179 /* which can be much more expensive. I could improve this to O(d log d) */
180 /* time, but d is usually quite small, so it's not worth the bother. */
181 /* (This note does not apply when the -s switch is used, invoking a */
182 /* different method is used to insert segments.) */
183 /* */
184 /* The time for deleting a vertex from a Delaunay triangulation is O(d^2) */
185 /* in the worst case and O(d) in the common case, where d is the degree */
186 /* of the vertex being deleted. I could improve this to O(d log d) time, */
187 /* but d is usually quite small, so it's not worth the bother. */
188 /* */
189 /* Ruppert's Delaunay refinement algorithm typically generates triangles */
190 /* at a linear rate (constant time per triangle) after the initial */
191 /* triangulation is formed. There may be pathological cases where */
192 /* quadratic time is required, but these never arise in practice. */
193 /* */
194 /* The geometric predicates (circumcenter calculations, segment */
195 /* intersection formulae, etc.) appear in my "Lecture Notes on Geometric */
196 /* Robustness" at http://www.cs.berkeley.edu/~jrs/mesh . */
197 /* */
198 /* If you make any improvements to this code, please please please let me */
199 /* know, so that I may obtain the improvements. Even if you don't change */
200 /* the code, I'd still love to hear what it's being used for. */
201 /* */
202 /*****************************************************************************/
203 
204 /* For single precision (which will save some memory and reduce paging), */
205 /* define the symbol SINGLE by using the -DSINGLE compiler switch or by */
206 /* writing "#define SINGLE" below. */
207 /* */
208 /* For double precision (which will allow you to refine meshes to a smaller */
209 /* edge length), leave SINGLE undefined. */
210 /* */
211 /* Double precision uses more memory, but improves the resolution of the */
212 /* meshes you can generate with Triangle. It also reduces the likelihood */
213 /* of a floating exception due to overflow. Finally, it is much faster */
214 /* than single precision on 64-bit architectures like the DEC Alpha. I */
215 /* recommend double precision unless you want to generate a mesh for which */
216 /* you do not have enough memory. */
217 
218 /* #define SINGLE */
219 
220 #ifdef SINGLE
221 #define REAL float
222 #else /* not SINGLE */
223 #define REAL double
224 #endif /* not SINGLE */
225 
226 /* If yours is not a Unix system, define the NO_TIMER compiler switch to */
227 /* remove the Unix-specific timing code. */
228 
229 /* #define NO_TIMER */
230 
231 /* To insert lots of self-checks for internal errors, define the SELF_CHECK */
232 /* symbol. This will slow down the program significantly. It is best to */
233 /* define the symbol using the -DSELF_CHECK compiler switch, but you could */
234 /* write "#define SELF_CHECK" below. If you are modifying this code, I */
235 /* recommend you turn self-checks on until your work is debugged. */
236 
237 /* #define SELF_CHECK */
238 
239 /* To compile Triangle as a callable object library (triangle.o), define the */
240 /* TRILIBRARY symbol. Read the file triangle.h for details on how to call */
241 /* the procedure triangulate() that results. */
242 
243 /* #define TRILIBRARY */
244 
245 /* It is possible to generate a smaller version of Triangle using one or */
246 /* both of the following symbols. Define the REDUCED symbol to eliminate */
247 /* all features that are primarily of research interest; specifically, the */
248 /* -i, -F, -s, and -C switches. Define the CDT_ONLY symbol to eliminate */
249 /* all meshing algorithms above and beyond constrained Delaunay */
250 /* triangulation; specifically, the -r, -q, -a, -u, -D, -S, and -s */
251 /* switches. These reductions are most likely to be useful when */
252 /* generating an object library (triangle.o) by defining the TRILIBRARY */
253 /* symbol. */
254 
255 /* #define REDUCED */
256 /* #define CDT_ONLY */
257 
258 /* On some machines, my exact arithmetic routines might be defeated by the */
259 /* use of internal extended precision floating-point registers. The best */
260 /* way to solve this problem is to set the floating-point registers to use */
261 /* single or double precision internally. On 80x86 processors, this may */
262 /* be accomplished by setting the CPU86 symbol for the Microsoft C */
263 /* compiler, or the LINUX symbol for the gcc compiler running on Linux. */
264 /* */
265 /* An inferior solution is to declare certain values as `volatile', thus */
266 /* forcing them to be stored to memory and rounded off. Unfortunately, */
267 /* this solution might slow Triangle down quite a bit. To use volatile */
268 /* values, write "#define INEXACT volatile" below. Normally, however, */
269 /* INEXACT should be defined to be nothing. ("#define INEXACT".) */
270 /* */
271 /* For more discussion, see http://www.cs.cmu.edu/~quake/robust.pc.html . */
272 /* For yet more discussion, see Section 5 of my paper, "Adaptive Precision */
273 /* Floating-Point Arithmetic and Fast Robust Geometric Predicates" (also */
274 /* available as Section 6.6 of my dissertation). */
275 
276 /* #define CPU86 */
277 /* #define LINUX */
278 
279 #define INEXACT /* Nothing */
280 /* #define INEXACT volatile */
281 
282 /* Maximum number of characters in a file name (including the null). */
283 
284 #define FILENAMESIZE 2048
285 
286 /* Maximum number of characters in a line read from a file (including the */
287 /* null). */
288 
289 #define INPUTLINESIZE 1024
290 
291 /* For efficiency, a variety of data structures are allocated in bulk. The */
292 /* following constants determine how many of each structure is allocated */
293 /* at once. */
294 
295 #define TRIPERBLOCK 4092 /* Number of triangles allocated at once. */
296 #define SUBSEGPERBLOCK 508 /* Number of subsegments allocated at once. */
297 #define VERTEXPERBLOCK 4092 /* Number of vertices allocated at once. */
298 #define VIRUSPERBLOCK 1020 /* Number of virus triangles allocated at once. */
299 /* Number of encroached subsegments allocated at once. */
300 #define BADSUBSEGPERBLOCK 252
301 /* Number of skinny triangles allocated at once. */
302 #define BADTRIPERBLOCK 4092
303 /* Number of flipped triangles allocated at once. */
304 #define FLIPSTACKERPERBLOCK 252
305 /* Number of splay tree nodes allocated at once. */
306 #define SPLAYNODEPERBLOCK 508
307 
308 /* The vertex types. A DEADVERTEX has been deleted entirely. An */
309 /* UNDEADVERTEX is not part of the mesh, but is written to the output */
310 /* .node file and affects the node indexing in the other output files. */
311 
312 #define INPUTVERTEX 0
313 #define SEGMENTVERTEX 1
314 #define FREEVERTEX 2
315 #define DEADVERTEX -32768
316 #define UNDEADVERTEX -32767
317 
318 /* The next line is used to outsmart some very stupid compilers. If your */
319 /* compiler is smarter, feel free to replace the "int" with "void". */
320 /* Not that it matters. */
321 
322 /*Windows_Port_Begins*/
323 #ifdef _MSC_VER
324 #else
325  /*This gave me a whole lot of grief with Windows SDK*/
326  #define VOID int
327 #endif
328 /*Windows_Port_Begins*/
329 
330 /* Two constants for algorithms based on random sampling. Both constants */
331 /* have been chosen empirically to optimize their respective algorithms. */
332 
333 /* Used for the point location scheme of Mucke, Saias, and Zhu, to decide */
334 /* how large a random sample of triangles to inspect. */
335 
336 #define SAMPLEFACTOR 11
337 
338 /* Used in Fortune's sweepline Delaunay algorithm to determine what fraction */
339 /* of boundary edges should be maintained in the splay tree for point */
340 /* location on the front. */
341 
342 #define SAMPLERATE 10
343 
344 /* A number that speaks for itself, every kissable digit. */
345 
346 #define PI 3.141592653589793238462643383279502884197169399375105820974944592308
347 
348 /* Another fave. */
349 
350 #define SQUAREROOTTWO 1.4142135623730950488016887242096980785696718753769480732
351 
352 /* And here's one for those of you who are intimidated by math. */
353 
354 #define ONETHIRD 0.333333333333333333333333333333333333333333333333333333333333
355 
356 #include <stdio.h>
357 #include <stdlib.h>
358 #include <string.h>
359 #include <math.h>
360 #ifndef NO_TIMER
361 #ifdef _MSC_VER
362 #include <time.h>
363 #include <WinSock2.h>
364 #include <windows.h>
365 //The portion below is adapted from http://www.suacommunity.com/dictionary/gettimeofday-entry.php
366 #if defined(_MSC_EXTENSIONS)
367  #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
368 #else
369  #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
370 #endif
371 
372 struct timezone
373 {
374  int tz_minuteswest; /* minutes W of Greenwich */
375  int tz_dsttime; /* type of dst correction */
376 };
377 
378 // Definition of a gettimeofday function
379 
380 int gettimeofday(struct timeval *tv, struct timezone *tz)
381 {
382  // Define a structure to receive the current Windows filetime
383  FILETIME ft;
384 
385  // Initialize the present time to 0 and the timezone to UTC
386  unsigned __int64 tmpres = 0;
387  static int tzflag = 0;
388 
389  if (NULL != tv)
390  {
391  GetSystemTimeAsFileTime(&ft);
392 
393  // The GetSystemTimeAsFileTime returns the number of 100 nanosecond
394  // intervals since Jan 1, 1601 in a structure. Copy the high bits to
395  // the 64 bit tmpres, shift it left by 32 then or in the low 32 bits.
396  tmpres |= ft.dwHighDateTime;
397  tmpres <<= 32;
398  tmpres |= ft.dwLowDateTime;
399 
400  // Convert to microseconds by dividing by 10
401  tmpres /= 10;
402 
403  // The Unix epoch starts on Jan 1 1970. Need to subtract the difference
404  // in seconds from Jan 1 1601.
405  tmpres -= DELTA_EPOCH_IN_MICROSECS;
406 
407  // Finally change microseconds to seconds and place in the seconds value.
408  // The modulus picks up the microseconds.
409  tv->tv_sec = (long)(tmpres / 1000000UL);
410  tv->tv_usec = (long)(tmpres % 1000000UL);
411  }
412 
413  if (NULL != tz)
414  {
415  if (!tzflag)
416  {
417  _tzset();
418  tzflag++;
419  }
420 
421  // Adjust for the timezone west of Greenwich
422  tz->tz_minuteswest = _timezone / 60;
423  tz->tz_dsttime = _daylight;
424  }
425  return 0;
426 }
427 #else
428 #include <sys/time.h>
429 #endif
430 #endif /* not NO_TIMER */
431 #ifdef CPU86
432 #include <float.h>
433 #endif /* CPU86 */
434 #ifdef LINUX
435 #include <fpu_control.h>
436 #endif /* LINUX */
437 #ifdef TRILIBRARY
438 #include "triangle.h"
439 #endif /* TRILIBRARY */
440 
441 /* A few forward declarations. */
442 
443 #ifndef TRILIBRARY
444 char *readline();
445 char *findfield();
446 #endif /* not TRILIBRARY */
447 
448 /* Labels that signify the result of point location. The result of a */
449 /* search indicates that the point falls in the interior of a triangle, on */
450 /* an edge, on a vertex, or outside the mesh. */
451 
452 enum locateresult {INTRIANGLE, ONEDGE, ONVERTEX, OUTSIDE};
453 
454 /* Labels that signify the result of vertex insertion. The result indicates */
455 /* that the vertex was inserted with complete success, was inserted but */
456 /* encroaches upon a subsegment, was not inserted because it lies on a */
457 /* segment, or was not inserted because another vertex occupies the same */
458 /* location. */
459 
460 enum insertvertexresult {SUCCESSFULVERTEX, ENCROACHINGVERTEX, VIOLATINGVERTEX,
461  DUPLICATEVERTEX};
462 
463 /* Labels that signify the result of direction finding. The result */
464 /* indicates that a segment connecting the two query points falls within */
465 /* the direction triangle, along the left edge of the direction triangle, */
466 /* or along the right edge of the direction triangle. */
467 
468 enum finddirectionresult {WITHIN, LEFTCOLLINEAR, RIGHTCOLLINEAR};
469 
470 /*****************************************************************************/
471 /* */
472 /* The basic mesh data structures */
473 /* */
474 /* There are three: vertices, triangles, and subsegments (abbreviated */
475 /* `subseg'). These three data structures, linked by pointers, comprise */
476 /* the mesh. A vertex simply represents a mesh vertex and its properties. */
477 /* A triangle is a triangle. A subsegment is a special data structure used */
478 /* to represent an impenetrable edge of the mesh (perhaps on the outer */
479 /* boundary, on the boundary of a hole, or part of an internal boundary */
480 /* separating two triangulated regions). Subsegments represent boundaries, */
481 /* defined by the user, that triangles may not lie across. */
482 /* */
483 /* A triangle consists of a list of three vertices, a list of three */
484 /* adjoining triangles, a list of three adjoining subsegments (when */
485 /* segments exist), an arbitrary number of optional user-defined */
486 /* floating-point attributes, and an optional area constraint. The latter */
487 /* is an upper bound on the permissible area of each triangle in a region, */
488 /* used for mesh refinement. */
489 /* */
490 /* For a triangle on a boundary of the mesh, some or all of the neighboring */
491 /* triangles may not be present. For a triangle in the interior of the */
492 /* mesh, often no neighboring subsegments are present. Such absent */
493 /* triangles and subsegments are never represented by NULL pointers; they */
494 /* are represented by two special records: `dummytri', the triangle that */
495 /* fills "outer space", and `dummysub', the omnipresent subsegment. */
496 /* `dummytri' and `dummysub' are used for several reasons; for instance, */
497 /* they can be dereferenced and their contents examined without violating */
498 /* protected memory. */
499 /* */
500 /* However, it is important to understand that a triangle includes other */
501 /* information as well. The pointers to adjoining vertices, triangles, and */
502 /* subsegments are ordered in a way that indicates their geometric relation */
503 /* to each other. Furthermore, each of these pointers contains orientation */
504 /* information. Each pointer to an adjoining triangle indicates which face */
505 /* of that triangle is contacted. Similarly, each pointer to an adjoining */
506 /* subsegment indicates which side of that subsegment is contacted, and how */
507 /* the subsegment is oriented relative to the triangle. */
508 /* */
509 /* The data structure representing a subsegment may be thought to be */
510 /* abutting the edge of one or two triangle data structures: either */
511 /* sandwiched between two triangles, or resting against one triangle on an */
512 /* exterior boundary or hole boundary. */
513 /* */
514 /* A subsegment consists of a list of four vertices--the vertices of the */
515 /* subsegment, and the vertices of the segment it is a part of--a list of */
516 /* two adjoining subsegments, and a list of two adjoining triangles. One */
517 /* of the two adjoining triangles may not be present (though there should */
518 /* always be one), and neighboring subsegments might not be present. */
519 /* Subsegments also store a user-defined integer "boundary marker". */
520 /* Typically, this integer is used to indicate what boundary conditions are */
521 /* to be applied at that location in a finite element simulation. */
522 /* */
523 /* Like triangles, subsegments maintain information about the relative */
524 /* orientation of neighboring objects. */
525 /* */
526 /* Vertices are relatively simple. A vertex is a list of floating-point */
527 /* numbers, starting with the x, and y coordinates, followed by an */
528 /* arbitrary number of optional user-defined floating-point attributes, */
529 /* followed by an integer boundary marker. During the segment insertion */
530 /* phase, there is also a pointer from each vertex to a triangle that may */
531 /* contain it. Each pointer is not always correct, but when one is, it */
532 /* speeds up segment insertion. These pointers are assigned values once */
533 /* at the beginning of the segment insertion phase, and are not used or */
534 /* updated except during this phase. Edge flipping during segment */
535 /* insertion will render some of them incorrect. Hence, don't rely upon */
536 /* them for anything. */
537 /* */
538 /* Other than the exception mentioned above, vertices have no information */
539 /* about what triangles, subfacets, or subsegments they are linked to. */
540 /* */
541 /*****************************************************************************/
542 
543 /*****************************************************************************/
544 /* */
545 /* Handles */
546 /* */
547 /* The oriented triangle (`otri') and oriented subsegment (`osub') data */
548 /* structures defined below do not themselves store any part of the mesh. */
549 /* The mesh itself is made of `triangle's, `subseg's, and `vertex's. */
550 /* */
551 /* Oriented triangles and oriented subsegments will usually be referred to */
552 /* as "handles." A handle is essentially a pointer into the mesh; it */
553 /* allows you to "hold" one particular part of the mesh. Handles are used */
554 /* to specify the regions in which one is traversing and modifying the mesh.*/
555 /* A single `triangle' may be held by many handles, or none at all. (The */
556 /* latter case is not a memory leak, because the triangle is still */
557 /* connected to other triangles in the mesh.) */
558 /* */
559 /* An `otri' is a handle that holds a triangle. It holds a specific edge */
560 /* of the triangle. An `osub' is a handle that holds a subsegment. It */
561 /* holds either the left or right side of the subsegment. */
562 /* */
563 /* Navigation about the mesh is accomplished through a set of mesh */
564 /* manipulation primitives, further below. Many of these primitives take */
565 /* a handle and produce a new handle that holds the mesh near the first */
566 /* handle. Other primitives take two handles and glue the corresponding */
567 /* parts of the mesh together. The orientation of the handles is */
568 /* important. For instance, when two triangles are glued together by the */
569 /* bond() primitive, they are glued at the edges on which the handles lie. */
570 /* */
571 /* Because vertices have no information about which triangles they are */
572 /* attached to, I commonly represent a vertex by use of a handle whose */
573 /* origin is the vertex. A single handle can simultaneously represent a */
574 /* triangle, an edge, and a vertex. */
575 /* */
576 /*****************************************************************************/
577 
578 /* The triangle data structure. Each triangle contains three pointers to */
579 /* adjoining triangles, plus three pointers to vertices, plus three */
580 /* pointers to subsegments (declared below; these pointers are usually */
581 /* `dummysub'). It may or may not also contain user-defined attributes */
582 /* and/or a floating-point "area constraint." It may also contain extra */
583 /* pointers for nodes, when the user asks for high-order elements. */
584 /* Because the size and structure of a `triangle' is not decided until */
585 /* runtime, I haven't simply declared the type `triangle' as a struct. */
586 
587 typedef REAL **triangle; /* Really: typedef triangle *triangle */
588 
589 /* An oriented triangle: includes a pointer to a triangle and orientation. */
590 /* The orientation denotes an edge of the triangle. Hence, there are */
591 /* three possible orientations. By convention, each edge always points */
592 /* counterclockwise about the corresponding triangle. */
593 
594 struct otri {
595  triangle *tri;
596  int orient; /* Ranges from 0 to 2. */
597 };
598 
599 /* The subsegment data structure. Each subsegment contains two pointers to */
600 /* adjoining subsegments, plus four pointers to vertices, plus two */
601 /* pointers to adjoining triangles, plus one boundary marker, plus one */
602 /* segment number. */
603 
604 typedef REAL **subseg; /* Really: typedef subseg *subseg */
605 
606 /* An oriented subsegment: includes a pointer to a subsegment and an */
607 /* orientation. The orientation denotes a side of the edge. Hence, there */
608 /* are two possible orientations. By convention, the edge is always */
609 /* directed so that the "side" denoted is the right side of the edge. */
610 
611 struct osub {
612  subseg *ss;
613  int ssorient; /* Ranges from 0 to 1. */
614 };
615 
616 /* The vertex data structure. Each vertex is actually an array of REALs. */
617 /* The number of REALs is unknown until runtime. An integer boundary */
618 /* marker, and sometimes a pointer to a triangle, is appended after the */
619 /* REALs. */
620 
621 typedef REAL *vertex;
622 
623 /* A queue used to store encroached subsegments. Each subsegment's vertices */
624 /* are stored so that we can check whether a subsegment is still the same. */
625 
626 struct badsubseg {
627  subseg encsubseg; /* An encroached subsegment. */
628  vertex subsegorg, subsegdest; /* Its two vertices. */
629 };
630 
631 /* A queue used to store bad triangles. The key is the square of the cosine */
632 /* of the smallest angle of the triangle. Each triangle's vertices are */
633 /* stored so that one can check whether a triangle is still the same. */
634 
635 struct badtriang {
636  triangle poortri; /* A skinny or too-large triangle. */
637  REAL key; /* cos^2 of smallest (apical) angle. */
638  vertex triangorg, triangdest, triangapex; /* Its three vertices. */
639  struct badtriang *nexttriang; /* Pointer to next bad triangle. */
640 };
641 
642 /* A stack of triangles flipped during the most recent vertex insertion. */
643 /* The stack is used to undo the vertex insertion if the vertex encroaches */
644 /* upon a subsegment. */
645 
646 struct flipstacker {
647  triangle flippedtri; /* A recently flipped triangle. */
648  struct flipstacker* prevflip; /* Previous flip in the stack. */
649 };
650 
651 /* A node in a heap used to store events for the sweepline Delaunay */
652 /* algorithm. Nodes do not point directly to their parents or children in */
653 /* the heap. Instead, each node knows its position in the heap, and can */
654 /* look up its parent and children in a separate array. The `eventptr' */
655 /* points either to a `vertex' or to a triangle (in encoded format, so */
656 /* that an orientation is included). In the latter case, the origin of */
657 /* the oriented triangle is the apex of a "circle event" of the sweepline */
658 /* algorithm. To distinguish site events from circle events, all circle */
659 /* events are given an invalid (smaller than `xmin') x-coordinate `xkey'. */
660 
661 struct event {
662  REAL xkey, ykey; /* Coordinates of the event. */
663  VOID *eventptr; /* Can be a vertex or the location of a circle event. */
664  int heapposition; /* Marks this event's position in the heap. */
665 };
666 
667 /* A node in the splay tree. Each node holds an oriented ghost triangle */
668 /* that represents a boundary edge of the growing triangulation. When a */
669 /* circle event covers two boundary edges with a triangle, so that they */
670 /* are no longer boundary edges, those edges are not immediately deleted */
671 /* from the tree; rather, they are lazily deleted when they are next */
672 /* encountered. (Since only a random sample of boundary edges are kept */
673 /* in the tree, lazy deletion is faster.) `keydest' is used to verify */
674 /* that a triangle is still the same as when it entered the splay tree; if */
675 /* it has been rotated (due to a circle event), it no longer represents a */
676 /* boundary edge and should be deleted. */
677 
678 struct splaynode {
679  struct otri keyedge; /* Lprev of an edge on the front. */
680  vertex keydest; /* Used to verify that splay node is still live. */
681  struct splaynode *lchild, *rchild; /* Children in splay tree. */
682 };
683 
684 /* A type used to allocate memory. firstblock is the first block of items. */
685 /* nowblock is the block from which items are currently being allocated. */
686 /* nextitem points to the next slab of free memory for an item. */
687 /* deaditemstack is the head of a linked list (stack) of deallocated items */
688 /* that can be recycled. unallocateditems is the number of items that */
689 /* remain to be allocated from nowblock. */
690 /* */
691 /* Traversal is the process of walking through the entire list of items, and */
692 /* is separate from allocation. Note that a traversal will visit items on */
693 /* the "deaditemstack" stack as well as live items. pathblock points to */
694 /* the block currently being traversed. pathitem points to the next item */
695 /* to be traversed. pathitemsleft is the number of items that remain to */
696 /* be traversed in pathblock. */
697 /* */
698 /* alignbytes determines how new records should be aligned in memory. */
699 /* itembytes is the length of a record in bytes (after rounding up). */
700 /* itemsperblock is the number of items allocated at once in a single */
701 /* block. itemsfirstblock is the number of items in the first block, */
702 /* which can vary from the others. items is the number of currently */
703 /* allocated items. maxitems is the maximum number of items that have */
704 /* been allocated at once; it is the current number of items plus the */
705 /* number of records kept on deaditemstack. */
706 
707 struct memorypool {
708  VOID **firstblock, **nowblock;
709  VOID *nextitem;
710  VOID *deaditemstack;
711  VOID **pathblock;
712  VOID* pathitem;
713  int alignbytes;
714  int itembytes;
715  int itemsperblock;
716  int itemsfirstblock;
717  long items, maxitems;
718  int unallocateditems;
719  int pathitemsleft;
720 };
721 
722 
723 /* Global constants. */
724 
725 REAL splitter; /* Used to split REAL factors for exact multiplication. */
726 REAL epsilon; /* Floating-point machine epsilon. */
727 REAL resulterrbound;
728 REAL ccwerrboundA, ccwerrboundB, ccwerrboundC;
729 REAL iccerrboundA, iccerrboundB, iccerrboundC;
730 REAL o3derrboundA, o3derrboundB, o3derrboundC;
731 
732 /* Random number seed is not constant, but I've made it global anyway. */
733 
734 unsigned long randomseed; /* Current random number seed. */
735 
736 
737 /* Mesh data structure. Triangle operates on only one mesh, but the mesh */
738 /* structure is used (instead of global variables) to allow reentrancy. */
739 
740 struct mesh {
741 
742 /* Variables used to allocate memory for triangles, subsegments, vertices, */
743 /* viri (triangles being eaten), encroached segments, bad (skinny or too */
744 /* large) triangles, and splay tree nodes. */
745 
746  struct memorypool triangles;
747  struct memorypool subsegs;
748  struct memorypool vertices;
749  struct memorypool viri;
750  struct memorypool badsubsegs;
751  struct memorypool badtriangles;
752  struct memorypool flipstackers;
753  struct memorypool splaynodes;
754 
755 /* Variables that maintain the bad triangle queues. The queues are */
756 /* ordered from 4095 (highest priority) to 0 (lowest priority). */
757 
758  struct badtriang *queuefront[4096];
759  struct badtriang *queuetail[4096];
760  int nextnonemptyq[4096];
761  int firstnonemptyq;
762 
763 /* Variable that maintains the stack of recently flipped triangles. */
764 
765  struct flipstacker *lastflip;
766 
767 /* Other variables. */
768 
769  REAL xmin, xmax, ymin, ymax; /* x and y bounds. */
770  REAL xminextreme; /* Nonexistent x value used as a flag in sweepline. */
771  int invertices; /* Number of input vertices. */
772  int inelements; /* Number of input triangles. */
773  int insegments; /* Number of input segments. */
774  int holes; /* Number of input holes. */
775  int regions; /* Number of input regions. */
776  int undeads; /* Number of input vertices that don't appear in the mesh. */
777  long edges; /* Number of output edges. */
778  int mesh_dim; /* Dimension (ought to be 2). */
779  int nextras; /* Number of attributes per vertex. */
780  int eextras; /* Number of attributes per triangle. */
781  long hullsize; /* Number of edges in convex hull. */
782  int steinerleft; /* Number of Steiner points not yet used. */
783  int vertexmarkindex; /* Index to find boundary marker of a vertex. */
784  int vertex2triindex; /* Index to find a triangle adjacent to a vertex. */
785  int highorderindex; /* Index to find extra nodes for high-order elements. */
786  int elemattribindex; /* Index to find attributes of a triangle. */
787  int areaboundindex; /* Index to find area bound of a triangle. */
788  int checksegments; /* Are there segments in the triangulation yet? */
789  int checkquality; /* Has quality triangulation begun yet? */
790  int readnodefile; /* Has a .node file been read? */
791  long samples; /* Number of random samples for point location. */
792 
793  long incirclecount; /* Number of incircle tests performed. */
794  long counterclockcount; /* Number of counterclockwise tests performed. */
795  long orient3dcount; /* Number of 3D orientation tests performed. */
796  long hyperbolacount; /* Number of right-of-hyperbola tests performed. */
797  long circumcentercount; /* Number of circumcenter calculations performed. */
798  long circletopcount; /* Number of circle top calculations performed. */
799 
800 /* Triangular bounding box vertices. */
801 
802  vertex infvertex1, infvertex2, infvertex3;
803 
804 /* Pointer to the `triangle' that occupies all of "outer space." */
805 
806  triangle *dummytri;
807  triangle *dummytribase; /* Keep base address so we can free() it later. */
808 
809 /* Pointer to the omnipresent subsegment. Referenced by any triangle or */
810 /* subsegment that isn't really connected to a subsegment at that */
811 /* location. */
812 
813  subseg *dummysub;
814  subseg *dummysubbase; /* Keep base address so we can free() it later. */
815 
816 /* Pointer to a recently visited triangle. Improves point location if */
817 /* proximate vertices are inserted sequentially. */
818 
819  struct otri recenttri;
820 
821 }; /* End of `struct mesh'. */
822 
823 
824 /* Data structure for command line switches and file names. This structure */
825 /* is used (instead of global variables) to allow reentrancy. */
826 
827 struct behavior {
828 
829 /* Switches for the triangulator. */
830 /* poly: -p switch. refine: -r switch. */
831 /* quality: -q switch. */
832 /* minangle: minimum angle bound, specified after -q switch. */
833 /* goodangle: cosine squared of minangle. */
834 /* offconstant: constant used to place off-center Steiner points. */
835 /* vararea: -a switch without number. */
836 /* fixedarea: -a switch with number. */
837 /* maxarea: maximum area bound, specified after -a switch. */
838 /* usertest: -u switch. */
839 /* regionattrib: -A switch. convex: -c switch. */
840 /* weighted: 1 for -w switch, 2 for -W switch. jettison: -j switch */
841 /* firstnumber: inverse of -z switch. All items are numbered starting */
842 /* from `firstnumber'. */
843 /* edgesout: -e switch. voronoi: -v switch. */
844 /* neighbors: -n switch. geomview: -g switch. */
845 /* nobound: -B switch. nopolywritten: -P switch. */
846 /* nonodewritten: -N switch. noelewritten: -E switch. */
847 /* noiterationnum: -I switch. noholes: -O switch. */
848 /* noexact: -X switch. */
849 /* order: element order, specified after -o switch. */
850 /* nobisect: count of how often -Y switch is selected. */
851 /* steiner: maximum number of Steiner points, specified after -S switch. */
852 /* incremental: -i switch. sweepline: -F switch. */
853 /* dwyer: inverse of -l switch. */
854 /* splitseg: -s switch. */
855 /* conformdel: -D switch. docheck: -C switch. */
856 /* quiet: -Q switch. verbose: count of how often -V switch is selected. */
857 /* usesegments: -p, -r, -q, or -c switch; determines whether segments are */
858 /* used at all. */
859 /* */
860 /* Read the instructions to find out the meaning of these switches. */
861 
862  int poly, refine, quality, vararea, fixedarea, usertest;
863  int regionattrib, convex, weighted, jettison;
864  int firstnumber;
865  int edgesout, voronoi, neighbors, geomview;
866  int nobound, nopolywritten, nonodewritten, noelewritten, noiterationnum;
867  int noholes, noexact, conformdel;
868  int incremental, sweepline, dwyer;
869  int splitseg;
870  int docheck;
871  int quiet, verbose;
872  int usesegments;
873  int order;
874  int nobisect;
875  int steiner;
876  REAL minangle, goodangle, offconstant;
877  REAL maxarea;
878 
879 /* Variables for file names. */
880 
881 #ifndef TRILIBRARY
882  char innodefilename[FILENAMESIZE];
883  char inelefilename[FILENAMESIZE];
884  char inpolyfilename[FILENAMESIZE];
885  char areafilename[FILENAMESIZE];
886  char outnodefilename[FILENAMESIZE];
887  char outelefilename[FILENAMESIZE];
888  char outpolyfilename[FILENAMESIZE];
889  char edgefilename[FILENAMESIZE];
890  char vnodefilename[FILENAMESIZE];
891  char vedgefilename[FILENAMESIZE];
892  char neighborfilename[FILENAMESIZE];
893  char offfilename[FILENAMESIZE];
894 #endif /* not TRILIBRARY */
895 
896 }; /* End of `struct behavior'. */
897 
898 
899 /*****************************************************************************/
900 /* */
901 /* Mesh manipulation primitives. Each triangle contains three pointers to */
902 /* other triangles, with orientations. Each pointer points not to the */
903 /* first byte of a triangle, but to one of the first three bytes of a */
904 /* triangle. It is necessary to extract both the triangle itself and the */
905 /* orientation. To save memory, I keep both pieces of information in one */
906 /* pointer. To make this possible, I assume that all triangles are aligned */
907 /* to four-byte boundaries. The decode() routine below decodes a pointer, */
908 /* extracting an orientation (in the range 0 to 2) and a pointer to the */
909 /* beginning of a triangle. The encode() routine compresses a pointer to a */
910 /* triangle and an orientation into a single pointer. My assumptions that */
911 /* triangles are four-byte-aligned and that the `unsigned long' type is */
912 /* long enough to hold a pointer are two of the few kludges in this program.*/
913 /* */
914 /* Subsegments are manipulated similarly. A pointer to a subsegment */
915 /* carries both an address and an orientation in the range 0 to 1. */
916 /* */
917 /* The other primitives take an oriented triangle or oriented subsegment, */
918 /* and return an oriented triangle or oriented subsegment or vertex; or */
919 /* they change the connections in the data structure. */
920 /* */
921 /* Below, triangles and subsegments are denoted by their vertices. The */
922 /* triangle abc has origin (org) a, destination (dest) b, and apex (apex) */
923 /* c. These vertices occur in counterclockwise order about the triangle. */
924 /* The handle abc may simultaneously denote vertex a, edge ab, and triangle */
925 /* abc. */
926 /* */
927 /* Similarly, the subsegment ab has origin (sorg) a and destination (sdest) */
928 /* b. If ab is thought to be directed upward (with b directly above a), */
929 /* then the handle ab is thought to grasp the right side of ab, and may */
930 /* simultaneously denote vertex a and edge ab. */
931 /* */
932 /* An asterisk (*) denotes a vertex whose identity is unknown. */
933 /* */
934 /* Given this notation, a partial list of mesh manipulation primitives */
935 /* follows. */
936 /* */
937 /* */
938 /* For triangles: */
939 /* */
940 /* sym: Find the abutting triangle; same edge. */
941 /* sym(abc) -> ba* */
942 /* */
943 /* lnext: Find the next edge (counterclockwise) of a triangle. */
944 /* lnext(abc) -> bca */
945 /* */
946 /* lprev: Find the previous edge (clockwise) of a triangle. */
947 /* lprev(abc) -> cab */
948 /* */
949 /* onext: Find the next edge counterclockwise with the same origin. */
950 /* onext(abc) -> ac* */
951 /* */
952 /* oprev: Find the next edge clockwise with the same origin. */
953 /* oprev(abc) -> a*b */
954 /* */
955 /* dnext: Find the next edge counterclockwise with the same destination. */
956 /* dnext(abc) -> *ba */
957 /* */
958 /* dprev: Find the next edge clockwise with the same destination. */
959 /* dprev(abc) -> cb* */
960 /* */
961 /* rnext: Find the next edge (counterclockwise) of the adjacent triangle. */
962 /* rnext(abc) -> *a* */
963 /* */
964 /* rprev: Find the previous edge (clockwise) of the adjacent triangle. */
965 /* rprev(abc) -> b** */
966 /* */
967 /* org: Origin dest: Destination apex: Apex */
968 /* org(abc) -> a dest(abc) -> b apex(abc) -> c */
969 /* */
970 /* bond: Bond two triangles together at the resepective handles. */
971 /* bond(abc, bad) */
972 /* */
973 /* */
974 /* For subsegments: */
975 /* */
976 /* ssym: Reverse the orientation of a subsegment. */
977 /* ssym(ab) -> ba */
978 /* */
979 /* spivot: Find adjoining subsegment with the same origin. */
980 /* spivot(ab) -> a* */
981 /* */
982 /* snext: Find next subsegment in sequence. */
983 /* snext(ab) -> b* */
984 /* */
985 /* sorg: Origin sdest: Destination */
986 /* sorg(ab) -> a sdest(ab) -> b */
987 /* */
988 /* sbond: Bond two subsegments together at the respective origins. */
989 /* sbond(ab, ac) */
990 /* */
991 /* */
992 /* For interacting tetrahedra and subfacets: */
993 /* */
994 /* tspivot: Find a subsegment abutting a triangle. */
995 /* tspivot(abc) -> ba */
996 /* */
997 /* stpivot: Find a triangle abutting a subsegment. */
998 /* stpivot(ab) -> ba* */
999 /* */
1000 /* tsbond: Bond a triangle to a subsegment. */
1001 /* tsbond(abc, ba) */
1002 /* */
1003 /*****************************************************************************/
1004 
1005 /********* Mesh manipulation primitives begin here *********/
1009 /* Fast lookup arrays to speed some of the mesh manipulation primitives. */
1010 
1011 int plus1mod3[3] = {1, 2, 0};
1012 int minus1mod3[3] = {2, 0, 1};
1013 
1014 /********* Primitives for triangles *********/
1015 /* */
1016 /* */
1017 
1018 /* decode() converts a pointer to an oriented triangle. The orientation is */
1019 /* extracted from the two least significant bits of the pointer. */
1020 
1021 #define decode(ptr, otri) \
1022  (otri).orient = (int) ((unsigned long) (ptr) & (unsigned long) 3l); \
1023  (otri).tri = (triangle *) \
1024  ((unsigned long) (ptr) ^ (unsigned long) (otri).orient)
1025 
1026 /* encode() compresses an oriented triangle into a single pointer. It */
1027 /* relies on the assumption that all triangles are aligned to four-byte */
1028 /* boundaries, so the two least significant bits of (otri).tri are zero. */
1029 
1030 #define encode(otri) \
1031  (triangle) ((unsigned long) (otri).tri | (unsigned long) (otri).orient)
1032 
1033 /* The following handle manipulation primitives are all described by Guibas */
1034 /* and Stolfi. However, Guibas and Stolfi use an edge-based data */
1035 /* structure, whereas I use a triangle-based data structure. */
1036 
1037 /* sym() finds the abutting triangle, on the same edge. Note that the edge */
1038 /* direction is necessarily reversed, because the handle specified by an */
1039 /* oriented triangle is directed counterclockwise around the triangle. */
1040 
1041 #define sym(otri1, otri2) \
1042  ptr = (otri1).tri[(otri1).orient]; \
1043  decode(ptr, otri2);
1044 
1045 #define symself(otri) \
1046  ptr = (otri).tri[(otri).orient]; \
1047  decode(ptr, otri);
1048 
1049 /* lnext() finds the next edge (counterclockwise) of a triangle. */
1050 
1051 #define lnext(otri1, otri2) \
1052  (otri2).tri = (otri1).tri; \
1053  (otri2).orient = plus1mod3[(otri1).orient]
1054 
1055 #define lnextself(otri) \
1056  (otri).orient = plus1mod3[(otri).orient]
1057 
1058 /* lprev() finds the previous edge (clockwise) of a triangle. */
1059 
1060 #define lprev(otri1, otri2) \
1061  (otri2).tri = (otri1).tri; \
1062  (otri2).orient = minus1mod3[(otri1).orient]
1063 
1064 #define lprevself(otri) \
1065  (otri).orient = minus1mod3[(otri).orient]
1066 
1067 /* onext() spins counterclockwise around a vertex; that is, it finds the */
1068 /* next edge with the same origin in the counterclockwise direction. This */
1069 /* edge is part of a different triangle. */
1070 
1071 #define onext(otri1, otri2) \
1072  lprev(otri1, otri2); \
1073  symself(otri2);
1074 
1075 #define onextself(otri) \
1076  lprevself(otri); \
1077  symself(otri);
1078 
1079 /* oprev() spins clockwise around a vertex; that is, it finds the next edge */
1080 /* with the same origin in the clockwise direction. This edge is part of */
1081 /* a different triangle. */
1082 
1083 #define oprev(otri1, otri2) \
1084  sym(otri1, otri2); \
1085  lnextself(otri2);
1086 
1087 #define oprevself(otri) \
1088  symself(otri); \
1089  lnextself(otri);
1090 
1091 /* dnext() spins counterclockwise around a vertex; that is, it finds the */
1092 /* next edge with the same destination in the counterclockwise direction. */
1093 /* This edge is part of a different triangle. */
1094 
1095 #define dnext(otri1, otri2) \
1096  sym(otri1, otri2); \
1097  lprevself(otri2);
1098 
1099 #define dnextself(otri) \
1100  symself(otri); \
1101  lprevself(otri);
1102 
1103 /* dprev() spins clockwise around a vertex; that is, it finds the next edge */
1104 /* with the same destination in the clockwise direction. This edge is */
1105 /* part of a different triangle. */
1106 
1107 #define dprev(otri1, otri2) \
1108  lnext(otri1, otri2); \
1109  symself(otri2);
1110 
1111 #define dprevself(otri) \
1112  lnextself(otri); \
1113  symself(otri);
1114 
1115 /* rnext() moves one edge counterclockwise about the adjacent triangle. */
1116 /* (It's best understood by reading Guibas and Stolfi. It involves */
1117 /* changing triangles twice.) */
1118 
1119 #define rnext(otri1, otri2) \
1120  sym(otri1, otri2); \
1121  lnextself(otri2); \
1122  symself(otri2);
1123 
1124 #define rnextself(otri) \
1125  symself(otri); \
1126  lnextself(otri); \
1127  symself(otri);
1128 
1129 /* rprev() moves one edge clockwise about the adjacent triangle. */
1130 /* (It's best understood by reading Guibas and Stolfi. It involves */
1131 /* changing triangles twice.) */
1132 
1133 #define rprev(otri1, otri2) \
1134  sym(otri1, otri2); \
1135  lprevself(otri2); \
1136  symself(otri2);
1137 
1138 #define rprevself(otri) \
1139  symself(otri); \
1140  lprevself(otri); \
1141  symself(otri);
1142 
1143 /* These primitives determine or set the origin, destination, or apex of a */
1144 /* triangle. */
1145 
1146 #define org(otri, vertexptr) \
1147  vertexptr = (vertex) (otri).tri[plus1mod3[(otri).orient] + 3]
1148 
1149 #define dest(otri, vertexptr) \
1150  vertexptr = (vertex) (otri).tri[minus1mod3[(otri).orient] + 3]
1151 
1152 #define apex(otri, vertexptr) \
1153  vertexptr = (vertex) (otri).tri[(otri).orient + 3]
1154 
1155 #define setorg(otri, vertexptr) \
1156  (otri).tri[plus1mod3[(otri).orient] + 3] = (triangle) vertexptr
1157 
1158 #define setdest(otri, vertexptr) \
1159  (otri).tri[minus1mod3[(otri).orient] + 3] = (triangle) vertexptr
1160 
1161 #define setapex(otri, vertexptr) \
1162  (otri).tri[(otri).orient + 3] = (triangle) vertexptr
1163 
1164 /* Bond two triangles together. */
1165 
1166 #define bond(otri1, otri2) \
1167  (otri1).tri[(otri1).orient] = encode(otri2); \
1168  (otri2).tri[(otri2).orient] = encode(otri1)
1169 
1170 /* Dissolve a bond (from one side). Note that the other triangle will still */
1171 /* think it's connected to this triangle. Usually, however, the other */
1172 /* triangle is being deleted entirely, or bonded to another triangle, so */
1173 /* it doesn't matter. */
1174 
1175 #define dissolve(otri) \
1176  (otri).tri[(otri).orient] = (triangle) m->dummytri
1177 
1178 /* Copy an oriented triangle. */
1179 
1180 #define otricopy(otri1, otri2) \
1181  (otri2).tri = (otri1).tri; \
1182  (otri2).orient = (otri1).orient
1183 
1184 /* Test for equality of oriented triangles. */
1185 
1186 #define otriequal(otri1, otri2) \
1187  (((otri1).tri == (otri2).tri) && \
1188  ((otri1).orient == (otri2).orient))
1189 
1190 /* Primitives to infect or cure a triangle with the virus. These rely on */
1191 /* the assumption that all subsegments are aligned to four-byte boundaries.*/
1192 
1193 #define infect(otri) \
1194  (otri).tri[6] = (triangle) \
1195  ((unsigned long) (otri).tri[6] | (unsigned long) 2l)
1196 
1197 #define uninfect(otri) \
1198  (otri).tri[6] = (triangle) \
1199  ((unsigned long) (otri).tri[6] & ~ (unsigned long) 2l)
1200 
1201 /* Test a triangle for viral infection. */
1202 
1203 #define infected(otri) \
1204  (((unsigned long) (otri).tri[6] & (unsigned long) 2l) != 0l)
1205 
1206 /* Check or set a triangle's attributes. */
1207 
1208 #define elemattribute(otri, attnum) \
1209  ((REAL *) (otri).tri)[m->elemattribindex + (attnum)]
1210 
1211 #define setelemattribute(otri, attnum, value) \
1212  ((REAL *) (otri).tri)[m->elemattribindex + (attnum)] = value
1213 
1214 /* Check or set a triangle's maximum area bound. */
1215 
1216 #define areabound(otri) ((REAL *) (otri).tri)[m->areaboundindex]
1217 
1218 #define setareabound(otri, value) \
1219  ((REAL *) (otri).tri)[m->areaboundindex] = value
1220 
1221 /* Check or set a triangle's deallocation. Its second pointer is set to */
1222 /* NULL to indicate that it is not allocated. (Its first pointer is used */
1223 /* for the stack of dead items.) Its fourth pointer (its first vertex) */
1224 /* is set to NULL in case a `badtriang' structure points to it. */
1225 
1226 #define deadtri(tria) ((tria)[1] == (triangle) NULL)
1227 
1228 #define killtri(tria) \
1229  (tria)[1] = (triangle) NULL; \
1230  (tria)[3] = (triangle) NULL
1231 
1232 /********* Primitives for subsegments *********/
1233 /* */
1234 /* */
1235 
1236 /* sdecode() converts a pointer to an oriented subsegment. The orientation */
1237 /* is extracted from the least significant bit of the pointer. The two */
1238 /* least significant bits (one for orientation, one for viral infection) */
1239 /* are masked out to produce the real pointer. */
1240 
1241 #define sdecode(sptr, osub) \
1242  (osub).ssorient = (int) ((unsigned long) (sptr) & (unsigned long) 1l); \
1243  (osub).ss = (subseg *) \
1244  ((unsigned long) (sptr) & ~ (unsigned long) 3l)
1245 
1246 /* sencode() compresses an oriented subsegment into a single pointer. It */
1247 /* relies on the assumption that all subsegments are aligned to two-byte */
1248 /* boundaries, so the least significant bit of (osub).ss is zero. */
1249 
1250 #define sencode(osub) \
1251  (subseg) ((unsigned long) (osub).ss | (unsigned long) (osub).ssorient)
1252 
1253 /* ssym() toggles the orientation of a subsegment. */
1254 
1255 #define ssym(osub1, osub2) \
1256  (osub2).ss = (osub1).ss; \
1257  (osub2).ssorient = 1 - (osub1).ssorient
1258 
1259 #define ssymself(osub) \
1260  (osub).ssorient = 1 - (osub).ssorient
1261 
1262 /* spivot() finds the other subsegment (from the same segment) that shares */
1263 /* the same origin. */
1264 
1265 #define spivot(osub1, osub2) \
1266  sptr = (osub1).ss[(osub1).ssorient]; \
1267  sdecode(sptr, osub2)
1268 
1269 #define spivotself(osub) \
1270  sptr = (osub).ss[(osub).ssorient]; \
1271  sdecode(sptr, osub)
1272 
1273 /* snext() finds the next subsegment (from the same segment) in sequence; */
1274 /* one whose origin is the input subsegment's destination. */
1275 
1276 #define snext(osub1, osub2) \
1277  sptr = (osub1).ss[1 - (osub1).ssorient]; \
1278  sdecode(sptr, osub2)
1279 
1280 #define snextself(osub) \
1281  sptr = (osub).ss[1 - (osub).ssorient]; \
1282  sdecode(sptr, osub)
1283 
1284 /* These primitives determine or set the origin or destination of a */
1285 /* subsegment or the segment that includes it. */
1286 
1287 #define sorg(osub, vertexptr) \
1288  vertexptr = (vertex) (osub).ss[2 + (osub).ssorient]
1289 
1290 #define sdest(osub, vertexptr) \
1291  vertexptr = (vertex) (osub).ss[3 - (osub).ssorient]
1292 
1293 #define setsorg(osub, vertexptr) \
1294  (osub).ss[2 + (osub).ssorient] = (subseg) vertexptr
1295 
1296 #define setsdest(osub, vertexptr) \
1297  (osub).ss[3 - (osub).ssorient] = (subseg) vertexptr
1298 
1299 #define segorg(osub, vertexptr) \
1300  vertexptr = (vertex) (osub).ss[4 + (osub).ssorient]
1301 
1302 #define segdest(osub, vertexptr) \
1303  vertexptr = (vertex) (osub).ss[5 - (osub).ssorient]
1304 
1305 #define setsegorg(osub, vertexptr) \
1306  (osub).ss[4 + (osub).ssorient] = (subseg) vertexptr
1307 
1308 #define setsegdest(osub, vertexptr) \
1309  (osub).ss[5 - (osub).ssorient] = (subseg) vertexptr
1310 
1311 /* These primitives read or set a boundary marker. Boundary markers are */
1312 /* used to hold user-defined tags for setting boundary conditions in */
1313 /* finite element solvers. */
1314 
1315 #define mark(osub) (* (int *) ((osub).ss + 8))
1316 
1317 #define setmark(osub, value) \
1318  * (int *) ((osub).ss + 8) = value
1319 
1320 /* Bond two subsegments together. */
1321 
1322 #define sbond(osub1, osub2) \
1323  (osub1).ss[(osub1).ssorient] = sencode(osub2); \
1324  (osub2).ss[(osub2).ssorient] = sencode(osub1)
1325 
1326 /* Dissolve a subsegment bond (from one side). Note that the other */
1327 /* subsegment will still think it's connected to this subsegment. */
1328 
1329 #define sdissolve(osub) \
1330  (osub).ss[(osub).ssorient] = (subseg) m->dummysub
1331 
1332 /* Copy a subsegment. */
1333 
1334 #define subsegcopy(osub1, osub2) \
1335  (osub2).ss = (osub1).ss; \
1336  (osub2).ssorient = (osub1).ssorient
1337 
1338 /* Test for equality of subsegments. */
1339 
1340 #define subsegequal(osub1, osub2) \
1341  (((osub1).ss == (osub2).ss) && \
1342  ((osub1).ssorient == (osub2).ssorient))
1343 
1344 /* Check or set a subsegment's deallocation. Its second pointer is set to */
1345 /* NULL to indicate that it is not allocated. (Its first pointer is used */
1346 /* for the stack of dead items.) Its third pointer (its first vertex) */
1347 /* is set to NULL in case a `badsubseg' structure points to it. */
1348 
1349 #define deadsubseg(sub) ((sub)[1] == (subseg) NULL)
1350 
1351 #define killsubseg(sub) \
1352  (sub)[1] = (subseg) NULL; \
1353  (sub)[2] = (subseg) NULL
1354 
1355 /********* Primitives for interacting triangles and subsegments *********/
1356 /* */
1357 /* */
1358 
1359 /* tspivot() finds a subsegment abutting a triangle. */
1360 
1361 #define tspivot(otri, osub) \
1362  sptr = (subseg) (otri).tri[6 + (otri).orient]; \
1363  sdecode(sptr, osub)
1364 
1365 /* stpivot() finds a triangle abutting a subsegment. It requires that the */
1366 /* variable `ptr' of type `triangle' be defined. */
1367 
1368 #define stpivot(osub, otri) \
1369  ptr = (triangle) (osub).ss[6 + (osub).ssorient]; \
1370  decode(ptr, otri)
1371 
1372 /* Bond a triangle to a subsegment. */
1373 
1374 #define tsbond(otri, osub) \
1375  (otri).tri[6 + (otri).orient] = (triangle) sencode(osub); \
1376  (osub).ss[6 + (osub).ssorient] = (subseg) encode(otri)
1377 
1378 /* Dissolve a bond (from the triangle side). */
1379 
1380 #define tsdissolve(otri) \
1381  (otri).tri[6 + (otri).orient] = (triangle) m->dummysub
1382 
1383 /* Dissolve a bond (from the subsegment side). */
1384 
1385 #define stdissolve(osub) \
1386  (osub).ss[6 + (osub).ssorient] = (subseg) m->dummytri
1387 
1388 /********* Primitives for vertices *********/
1389 /* */
1390 /* */
1391 
1392 #define vertexmark(vx) ((int *) (vx))[m->vertexmarkindex]
1393 
1394 #define setvertexmark(vx, value) \
1395  ((int *) (vx))[m->vertexmarkindex] = value
1396 
1397 #define vertextype(vx) ((int *) (vx))[m->vertexmarkindex + 1]
1398 
1399 #define setvertextype(vx, value) \
1400  ((int *) (vx))[m->vertexmarkindex + 1] = value
1401 
1402 #define vertex2tri(vx) ((triangle *) (vx))[m->vertex2triindex]
1403 
1404 #define setvertex2tri(vx, value) \
1405  ((triangle *) (vx))[m->vertex2triindex] = value
1406 
1409 /********* Mesh manipulation primitives end here *********/
1410 
1411 /********* User-defined triangle evaluation routine begins here *********/
1415 /*****************************************************************************/
1416 /* */
1417 /* triunsuitable() Determine if a triangle is unsuitable, and thus must */
1418 /* be further refined. */
1419 /* */
1420 /* You may write your own procedure that decides whether or not a selected */
1421 /* triangle is too big (and needs to be refined). There are two ways to do */
1422 /* this. */
1423 /* */
1424 /* (1) Modify the procedure `triunsuitable' below, then recompile */
1425 /* Triangle. */
1426 /* */
1427 /* (2) Define the symbol EXTERNAL_TEST (either by adding the definition */
1428 /* to this file, or by using the appropriate compiler switch). This way, */
1429 /* you can compile triangle.c separately from your test. Write your own */
1430 /* `triunsuitable' procedure in a separate C file (using the same prototype */
1431 /* as below). Compile it and link the object code with triangle.o. */
1432 /* */
1433 /* This procedure returns 1 if the triangle is too large and should be */
1434 /* refined; 0 otherwise. */
1435 /* */
1436 /*****************************************************************************/
1437 
1438 #ifdef EXTERNAL_TEST
1439 
1440 int triunsuitable();
1441 
1442 #else /* not EXTERNAL_TEST */
1443 
1444 #ifdef ANSI_DECLARATORS
1445 int triunsuitable(vertex triorg, vertex tridest, vertex triapex, REAL area)
1446 #else /* not ANSI_DECLARATORS */
1447 int triunsuitable(triorg, tridest, triapex, area)
1448 vertex triorg; /* The triangle's origin vertex. */
1449 vertex tridest; /* The triangle's destination vertex. */
1450 vertex triapex; /* The triangle's apex vertex. */
1451 REAL area; /* The area of the triangle. */
1452 #endif /* not ANSI_DECLARATORS */
1453 
1454 {
1455  REAL dxoa, dxda, dxod;
1456  REAL dyoa, dyda, dyod;
1457  REAL oalen, dalen, odlen;
1458  REAL maxlen;
1459 
1460  dxoa = triorg[0] - triapex[0];
1461  dyoa = triorg[1] - triapex[1];
1462  dxda = tridest[0] - triapex[0];
1463  dyda = tridest[1] - triapex[1];
1464  dxod = triorg[0] - tridest[0];
1465  dyod = triorg[1] - tridest[1];
1466  /* Find the squares of the lengths of the triangle's three edges. */
1467  oalen = dxoa * dxoa + dyoa * dyoa;
1468  dalen = dxda * dxda + dyda * dyda;
1469  odlen = dxod * dxod + dyod * dyod;
1470  /* Find the square of the length of the longest edge. */
1471  maxlen = (dalen > oalen) ? dalen : oalen;
1472  maxlen = (odlen > maxlen) ? odlen : maxlen;
1473 
1474  if (maxlen > 0.05 * (triorg[0] * triorg[0] + triorg[1] * triorg[1]) + 0.02) {
1475  return 1;
1476  } else {
1477  return 0;
1478  }
1479 }
1480 
1481 #endif /* not EXTERNAL_TEST */
1482 
1485 /********* User-defined triangle evaluation routine ends here *********/
1486 
1487 /********* Memory allocation and program exit wrappers begin here *********/
1491 #ifdef ANSI_DECLARATORS
1492 void triexit(int status)
1493 #else /* not ANSI_DECLARATORS */
1494 void triexit(status)
1495 int status;
1496 #endif /* not ANSI_DECLARATORS */
1497 
1498 {
1499  exit(status);
1500 }
1501 
1502 #ifdef ANSI_DECLARATORS
1503 VOID *trimalloc(int size)
1504 #else /* not ANSI_DECLARATORS */
1505 VOID *trimalloc(size)
1506 int size;
1507 #endif /* not ANSI_DECLARATORS */
1508 
1509 {
1510  VOID *memptr;
1511 
1512  memptr = (VOID *) malloc((unsigned int) size);
1513  if (memptr == (VOID *) NULL) {
1514  printf("Error: Out of memory.\n");
1515  triexit(1);
1516  }
1517  return(memptr);
1518 }
1519 
1520 #ifdef ANSI_DECLARATORS
1521 void trifree(VOID *memptr)
1522 #else /* not ANSI_DECLARATORS */
1523 void trifree(memptr)
1524 VOID *memptr;
1525 #endif /* not ANSI_DECLARATORS */
1526 
1527 {
1528  free(memptr);
1529 }
1530 
1533 /********* Memory allocation and program exit wrappers end here *********/
1534 
1535 /********* User interaction routines begin here *********/
1539 /*****************************************************************************/
1540 /* */
1541 /* syntax() Print list of command line switches. */
1542 /* */
1543 /*****************************************************************************/
1544 
1545 #ifndef TRILIBRARY
1546 
1547 void syntax()
1548 {
1549 #ifdef CDT_ONLY
1550 #ifdef REDUCED
1551  printf("triangle [-pAcjevngBPNEIOXzo_lQVh] input_file\n");
1552 #else /* not REDUCED */
1553  printf("triangle [-pAcjevngBPNEIOXzo_iFlCQVh] input_file\n");
1554 #endif /* not REDUCED */
1555 #else /* not CDT_ONLY */
1556 #ifdef REDUCED
1557  printf("triangle [-prq__a__uAcDjevngBPNEIOXzo_YS__lQVh] input_file\n");
1558 #else /* not REDUCED */
1559  printf("triangle [-prq__a__uAcDjevngBPNEIOXzo_YS__iFlsCQVh] input_file\n");
1560 #endif /* not REDUCED */
1561 #endif /* not CDT_ONLY */
1562 
1563  printf(" -p Triangulates a Planar Straight Line Graph (.poly file).\n");
1564 #ifndef CDT_ONLY
1565  printf(" -r Refines a previously generated mesh.\n");
1566  printf(
1567  " -q Quality mesh generation. A minimum angle may be specified.\n");
1568  printf(" -a Applies a maximum triangle area constraint.\n");
1569  printf(" -u Applies a user-defined triangle constraint.\n");
1570 #endif /* not CDT_ONLY */
1571  printf(
1572  " -A Applies attributes to identify triangles in certain regions.\n");
1573  printf(" -c Encloses the convex hull with segments.\n");
1574 #ifndef CDT_ONLY
1575  printf(" -D Conforming Delaunay: all triangles are truly Delaunay.\n");
1576 #endif /* not CDT_ONLY */
1577 /*
1578  printf(" -w Weighted Delaunay triangulation.\n");
1579  printf(" -W Regular triangulation (lower hull of a height field).\n");
1580 */
1581  printf(" -j Jettison unused vertices from output .node file.\n");
1582  printf(" -e Generates an edge list.\n");
1583  printf(" -v Generates a Voronoi diagram.\n");
1584  printf(" -n Generates a list of triangle neighbors.\n");
1585  printf(" -g Generates an .off file for Geomview.\n");
1586  printf(" -B Suppresses output of boundary information.\n");
1587  printf(" -P Suppresses output of .poly file.\n");
1588  printf(" -N Suppresses output of .node file.\n");
1589  printf(" -E Suppresses output of .ele file.\n");
1590  printf(" -I Suppresses mesh iteration numbers.\n");
1591  printf(" -O Ignores holes in .poly file.\n");
1592  printf(" -X Suppresses use of exact arithmetic.\n");
1593  printf(" -z Numbers all items starting from zero (rather than one).\n");
1594  printf(" -o2 Generates second-order subparametric elements.\n");
1595 #ifndef CDT_ONLY
1596  printf(" -Y Suppresses boundary segment splitting.\n");
1597  printf(" -S Specifies maximum number of added Steiner points.\n");
1598 #endif /* not CDT_ONLY */
1599 #ifndef REDUCED
1600  printf(" -i Uses incremental method, rather than divide-and-conquer.\n");
1601  printf(" -F Uses Fortune's sweepline algorithm, rather than d-and-c.\n");
1602 #endif /* not REDUCED */
1603  printf(" -l Uses vertical cuts only, rather than alternating cuts.\n");
1604 #ifndef REDUCED
1605 #ifndef CDT_ONLY
1606  printf(
1607  " -s Force segments into mesh by splitting (instead of using CDT).\n");
1608 #endif /* not CDT_ONLY */
1609  printf(" -C Check consistency of final mesh.\n");
1610 #endif /* not REDUCED */
1611  printf(" -Q Quiet: No terminal output except errors.\n");
1612  printf(" -V Verbose: Detailed information on what I'm doing.\n");
1613  printf(" -h Help: Detailed instructions for Triangle.\n");
1614  triexit(0);
1615 }
1616 
1617 #endif /* not TRILIBRARY */
1618 
1619 /*****************************************************************************/
1620 /* */
1621 /* info() Print out complete instructions. */
1622 /* */
1623 /*****************************************************************************/
1624 
1625 #ifndef TRILIBRARY
1626 
1627 void info()
1628 {
1629  printf("Triangle\n");
1630  printf(
1631 "A Two-Dimensional Quality Mesh Generator and Delaunay Triangulator.\n");
1632  printf("Version 1.6\n\n");
1633  printf(
1634 "Copyright 1993, 1995, 1997, 1998, 2002, 2005 Jonathan Richard Shewchuk\n");
1635  printf("2360 Woolsey #H / Berkeley, California 94705-1927\n");
1636  printf("Bugs/comments to jrs@cs.berkeley.edu\n");
1637  printf(
1638 "Created as part of the Quake project (tools for earthquake simulation).\n");
1639  printf(
1640 "Supported in part by NSF Grant CMS-9318163 and an NSERC 1967 Scholarship.\n");
1641  printf("There is no warranty whatsoever. Use at your own risk.\n");
1642 #ifdef SINGLE
1643  printf("This executable is compiled for single precision arithmetic.\n\n\n");
1644 #else /* not SINGLE */
1645  printf("This executable is compiled for double precision arithmetic.\n\n\n");
1646 #endif /* not SINGLE */
1647  printf(
1648 "Triangle generates exact Delaunay triangulations, constrained Delaunay\n");
1649  printf(
1650 "triangulations, conforming Delaunay triangulations, Voronoi diagrams, and\n");
1651  printf(
1652 "high-quality triangular meshes. The latter can be generated with no small\n"
1653 );
1654  printf(
1655 "or large angles, and are thus suitable for finite element analysis. If no\n"
1656 );
1657  printf(
1658 "command line switch is specified, your .node input file is read, and the\n");
1659  printf(
1660 "Delaunay triangulation is returned in .node and .ele output files. The\n");
1661  printf("command syntax is:\n\n");
1662  printf("triangle [-prq__a__uAcDjevngBPNEIOXzo_YS__iFlsCQVh] input_file\n\n");
1663  printf(
1664 "Underscores indicate that numbers may optionally follow certain switches.\n");
1665  printf(
1666 "Do not leave any space between a switch and its numeric parameter.\n");
1667  printf(
1668 "input_file must be a file with extension .node, or extension .poly if the\n");
1669  printf(
1670 "-p switch is used. If -r is used, you must supply .node and .ele files,\n");
1671  printf(
1672 "and possibly a .poly file and an .area file as well. The formats of these\n"
1673 );
1674  printf("files are described below.\n\n");
1675  printf("Command Line Switches:\n\n");
1676  printf(
1677 " -p Reads a Planar Straight Line Graph (.poly file), which can specify\n"
1678 );
1679  printf(
1680 " vertices, segments, holes, regional attributes, and regional area\n");
1681  printf(
1682 " constraints. Generates a constrained Delaunay triangulation (CDT)\n"
1683 );
1684  printf(
1685 " fitting the input; or, if -s, -q, -a, or -u is used, a conforming\n");
1686  printf(
1687 " constrained Delaunay triangulation (CCDT). If you want a truly\n");
1688  printf(
1689 " Delaunay (not just constrained Delaunay) triangulation, use -D as\n");
1690  printf(
1691 " well. When -p is not used, Triangle reads a .node file by default.\n"
1692 );
1693  printf(
1694 " -r Refines a previously generated mesh. The mesh is read from a .node\n"
1695 );
1696  printf(
1697 " file and an .ele file. If -p is also used, a .poly file is read\n");
1698  printf(
1699 " and used to constrain segments in the mesh. If -a is also used\n");
1700  printf(
1701 " (with no number following), an .area file is read and used to\n");
1702  printf(
1703 " impose area constraints on the mesh. Further details on refinement\n"
1704 );
1705  printf(" appear below.\n");
1706  printf(
1707 " -q Quality mesh generation by Delaunay refinement (a hybrid of Paul\n");
1708  printf(
1709 " Chew's and Jim Ruppert's algorithms). Adds vertices to the mesh to\n"
1710 );
1711  printf(
1712 " ensure that all angles are between 20 and 140 degrees. An\n");
1713  printf(
1714 " alternative bound on the minimum angle, replacing 20 degrees, may\n");
1715  printf(
1716 " be specified after the `q'. The specified angle may include a\n");
1717  printf(
1718 " decimal point, but not exponential notation. Note that a bound of\n"
1719 );
1720  printf(
1721 " theta degrees on the smallest angle also implies a bound of\n");
1722  printf(
1723 " (180 - 2 theta) on the largest angle. If the minimum angle is 28.6\n"
1724 );
1725  printf(
1726 " degrees or smaller, Triangle is mathematically guaranteed to\n");
1727  printf(
1728 " terminate (assuming infinite precision arithmetic--Triangle may\n");
1729  printf(
1730 " fail to terminate if you run out of precision). In practice,\n");
1731  printf(
1732 " Triangle often succeeds for minimum angles up to 34 degrees. For\n");
1733  printf(
1734 " some meshes, however, you might need to reduce the minimum angle to\n"
1735 );
1736  printf(
1737 " avoid problems associated with insufficient floating-point\n");
1738  printf(" precision.\n");
1739  printf(
1740 " -a Imposes a maximum triangle area. If a number follows the `a', no\n");
1741  printf(
1742 " triangle is generated whose area is larger than that number. If no\n"
1743 );
1744  printf(
1745 " number is specified, an .area file (if -r is used) or .poly file\n");
1746  printf(
1747 " (if -r is not used) specifies a set of maximum area constraints.\n");
1748  printf(
1749 " An .area file contains a separate area constraint for each\n");
1750  printf(
1751 " triangle, and is useful for refining a finite element mesh based on\n"
1752 );
1753  printf(
1754 " a posteriori error estimates. A .poly file can optionally contain\n"
1755 );
1756  printf(
1757 " an area constraint for each segment-bounded region, thereby\n");
1758  printf(
1759 " controlling triangle densities in a first triangulation of a PSLG.\n"
1760 );
1761  printf(
1762 " You can impose both a fixed area constraint and a varying area\n");
1763  printf(
1764 " constraint by invoking the -a switch twice, once with and once\n");
1765  printf(
1766 " without a number following. Each area specified may include a\n");
1767  printf(" decimal point.\n");
1768  printf(
1769 " -u Imposes a user-defined constraint on triangle size. There are two\n"
1770 );
1771  printf(
1772 " ways to use this feature. One is to edit the triunsuitable()\n");
1773  printf(
1774 " procedure in triangle.c to encode any constraint you like, then\n");
1775  printf(
1776 " recompile Triangle. The other is to compile triangle.c with the\n");
1777  printf(
1778 " EXTERNAL_TEST symbol set (compiler switch -DEXTERNAL_TEST), then\n");
1779  printf(
1780 " link Triangle with a separate object file that implements\n");
1781  printf(
1782 " triunsuitable(). In either case, the -u switch causes the user-\n");
1783  printf(" defined test to be applied to every triangle.\n");
1784  printf(
1785 " -A Assigns an additional floating-point attribute to each triangle\n");
1786  printf(
1787 " that identifies what segment-bounded region each triangle belongs\n");
1788  printf(
1789 " to. Attributes are assigned to regions by the .poly file. If a\n");
1790  printf(
1791 " region is not explicitly marked by the .poly file, triangles in\n");
1792  printf(
1793 " that region are assigned an attribute of zero. The -A switch has\n");
1794  printf(
1795 " an effect only when the -p switch is used and the -r switch is not.\n"
1796 );
1797  printf(
1798 " -c Creates segments on the convex hull of the triangulation. If you\n");
1799  printf(
1800 " are triangulating a vertex set, this switch causes a .poly file to\n"
1801 );
1802  printf(
1803 " be written, containing all edges of the convex hull. If you are\n");
1804  printf(
1805 " triangulating a PSLG, this switch specifies that the whole convex\n");
1806  printf(
1807 " hull of the PSLG should be triangulated, regardless of what\n");
1808  printf(
1809 " segments the PSLG has. If you do not use this switch when\n");
1810  printf(
1811 " triangulating a PSLG, Triangle assumes that you have identified the\n"
1812 );
1813  printf(
1814 " region to be triangulated by surrounding it with segments of the\n");
1815  printf(
1816 " input PSLG. Beware: if you are not careful, this switch can cause\n"
1817 );
1818  printf(
1819 " the introduction of an extremely thin angle between a PSLG segment\n"
1820 );
1821  printf(
1822 " and a convex hull segment, which can cause overrefinement (and\n");
1823  printf(
1824 " possibly failure if Triangle runs out of precision). If you are\n");
1825  printf(
1826 " refining a mesh, the -c switch works differently: it causes a\n");
1827  printf(
1828 " .poly file to be written containing the boundary edges of the mesh\n"
1829 );
1830  printf(" (useful if no .poly file was read).\n");
1831  printf(
1832 " -D Conforming Delaunay triangulation: use this switch if you want to\n"
1833 );
1834  printf(
1835 " ensure that all the triangles in the mesh are Delaunay, and not\n");
1836  printf(
1837 " merely constrained Delaunay; or if you want to ensure that all the\n"
1838 );
1839  printf(
1840 " Voronoi vertices lie within the triangulation. (Some finite volume\n"
1841 );
1842  printf(
1843 " methods have this requirement.) This switch invokes Ruppert's\n");
1844  printf(
1845 " original algorithm, which splits every subsegment whose diametral\n");
1846  printf(
1847 " circle is encroached. It usually increases the number of vertices\n"
1848 );
1849  printf(" and triangles.\n");
1850  printf(
1851 " -j Jettisons vertices that are not part of the final triangulation\n");
1852  printf(
1853 " from the output .node file. By default, Triangle copies all\n");
1854  printf(
1855 " vertices in the input .node file to the output .node file, in the\n");
1856  printf(
1857 " same order, so their indices do not change. The -j switch prevents\n"
1858 );
1859  printf(
1860 " duplicated input vertices, or vertices `eaten' by holes, from\n");
1861  printf(
1862 " appearing in the output .node file. Thus, if two input vertices\n");
1863  printf(
1864 " have exactly the same coordinates, only the first appears in the\n");
1865  printf(
1866 " output. If any vertices are jettisoned, the vertex numbering in\n");
1867  printf(
1868 " the output .node file differs from that of the input .node file.\n");
1869  printf(
1870 " -e Outputs (to an .edge file) a list of edges of the triangulation.\n");
1871  printf(
1872 " -v Outputs the Voronoi diagram associated with the triangulation.\n");
1873  printf(
1874 " Does not attempt to detect degeneracies, so some Voronoi vertices\n");
1875  printf(
1876 " may be duplicated. See the discussion of Voronoi diagrams below.\n");
1877  printf(
1878 " -n Outputs (to a .neigh file) a list of triangles neighboring each\n");
1879  printf(" triangle.\n");
1880  printf(
1881 " -g Outputs the mesh to an Object File Format (.off) file, suitable for\n"
1882 );
1883  printf(" viewing with the Geometry Center's Geomview package.\n");
1884  printf(
1885 " -B No boundary markers in the output .node, .poly, and .edge output\n");
1886  printf(
1887 " files. See the detailed discussion of boundary markers below.\n");
1888  printf(
1889 " -P No output .poly file. Saves disk space, but you lose the ability\n");
1890  printf(
1891 " to maintain constraining segments on later refinements of the mesh.\n"
1892 );
1893  printf(" -N No output .node file.\n");
1894  printf(" -E No output .ele file.\n");
1895  printf(
1896 " -I No iteration numbers. Suppresses the output of .node and .poly\n");
1897  printf(
1898 " files, so your input files won't be overwritten. (If your input is\n"
1899 );
1900  printf(
1901 " a .poly file only, a .node file is written.) Cannot be used with\n");
1902  printf(
1903 " the -r switch, because that would overwrite your input .ele file.\n");
1904  printf(
1905 " Shouldn't be used with the -q, -a, -u, or -s switch if you are\n");
1906  printf(
1907 " using a .node file for input, because no .node file is written, so\n"
1908 );
1909  printf(" there is no record of any added Steiner points.\n");
1910  printf(" -O No holes. Ignores the holes in the .poly file.\n");
1911  printf(
1912 " -X No exact arithmetic. Normally, Triangle uses exact floating-point\n"
1913 );
1914  printf(
1915 " arithmetic for certain tests if it thinks the inexact tests are not\n"
1916 );
1917  printf(
1918 " accurate enough. Exact arithmetic ensures the robustness of the\n");
1919  printf(
1920 " triangulation algorithms, despite floating-point roundoff error.\n");
1921  printf(
1922 " Disabling exact arithmetic with the -X switch causes a small\n");
1923  printf(
1924 " improvement in speed and creates the possibility that Triangle will\n"
1925 );
1926  printf(" fail to produce a valid mesh. Not recommended.\n");
1927  printf(
1928 " -z Numbers all items starting from zero (rather than one). Note that\n"
1929 );
1930  printf(
1931 " this switch is normally overridden by the value used to number the\n"
1932 );
1933  printf(
1934 " first vertex of the input .node or .poly file. However, this\n");
1935  printf(
1936 " switch is useful when calling Triangle from another program.\n");
1937  printf(
1938 " -o2 Generates second-order subparametric elements with six nodes each.\n"
1939 );
1940  printf(
1941 " -Y No new vertices on the boundary. This switch is useful when the\n");
1942  printf(
1943 " mesh boundary must be preserved so that it conforms to some\n");
1944  printf(
1945 " adjacent mesh. Be forewarned that you will probably sacrifice much\n"
1946 );
1947  printf(
1948 " of the quality of the mesh; Triangle will try, but the resulting\n");
1949  printf(
1950 " mesh may contain poorly shaped triangles. Works well if all the\n");
1951  printf(
1952 " boundary vertices are closely spaced. Specify this switch twice\n");
1953  printf(
1954 " (`-YY') to prevent all segment splitting, including internal\n");
1955  printf(" boundaries.\n");
1956  printf(
1957 " -S Specifies the maximum number of Steiner points (vertices that are\n");
1958  printf(
1959 " not in the input, but are added to meet the constraints on minimum\n"
1960 );
1961  printf(
1962 " angle and maximum area). The default is to allow an unlimited\n");
1963  printf(
1964 " number. If you specify this switch with no number after it,\n");
1965  printf(
1966 " the limit is set to zero. Triangle always adds vertices at segment\n"
1967 );
1968  printf(
1969 " intersections, even if it needs to use more vertices than the limit\n"
1970 );
1971  printf(
1972 " you set. When Triangle inserts segments by splitting (-s), it\n");
1973  printf(
1974 " always adds enough vertices to ensure that all the segments of the\n"
1975 );
1976  printf(" PLSG are recovered, ignoring the limit if necessary.\n");
1977  printf(
1978 " -i Uses an incremental rather than a divide-and-conquer algorithm to\n");
1979  printf(
1980 " construct a Delaunay triangulation. Try it if the divide-and-\n");
1981  printf(" conquer algorithm fails.\n");
1982  printf(
1983 " -F Uses Steven Fortune's sweepline algorithm to construct a Delaunay\n");
1984  printf(
1985 " triangulation. Warning: does not use exact arithmetic for all\n");
1986  printf(" calculations. An exact result is not guaranteed.\n");
1987  printf(
1988 " -l Uses only vertical cuts in the divide-and-conquer algorithm. By\n");
1989  printf(
1990 " default, Triangle alternates between vertical and horizontal cuts,\n"
1991 );
1992  printf(
1993 " which usually improve the speed except with vertex sets that are\n");
1994  printf(
1995 " small or short and wide. This switch is primarily of theoretical\n");
1996  printf(" interest.\n");
1997  printf(
1998 " -s Specifies that segments should be forced into the triangulation by\n"
1999 );
2000  printf(
2001 " recursively splitting them at their midpoints, rather than by\n");
2002  printf(
2003 " generating a constrained Delaunay triangulation. Segment splitting\n"
2004 );
2005  printf(
2006 " is true to Ruppert's original algorithm, but can create needlessly\n"
2007 );
2008  printf(
2009 " small triangles. This switch is primarily of theoretical interest.\n"
2010 );
2011  printf(
2012 " -C Check the consistency of the final mesh. Uses exact arithmetic for\n"
2013 );
2014  printf(
2015 " checking, even if the -X switch is used. Useful if you suspect\n");
2016  printf(" Triangle is buggy.\n");
2017  printf(
2018 " -Q Quiet: Suppresses all explanation of what Triangle is doing,\n");
2019  printf(" unless an error occurs.\n");
2020  printf(
2021 " -V Verbose: Gives detailed information about what Triangle is doing.\n"
2022 );
2023  printf(
2024 " Add more `V's for increasing amount of detail. `-V' is most\n");
2025  printf(
2026 " useful; itgives information on algorithmic progress and much more\n");
2027  printf(
2028 " detailed statistics. `-VV' gives vertex-by-vertex details, and\n");
2029  printf(
2030 " prints so much that Triangle runs much more slowly. `-VVVV' gives\n"
2031 );
2032  printf(" information only a debugger could love.\n");
2033  printf(" -h Help: Displays these instructions.\n");
2034  printf("\n");
2035  printf("Definitions:\n");
2036  printf("\n");
2037  printf(
2038 " A Delaunay triangulation of a vertex set is a triangulation whose\n");
2039  printf(
2040 " vertices are the vertex set, that covers the convex hull of the vertex\n");
2041  printf(
2042 " set. A Delaunay triangulation has the property that no vertex lies\n");
2043  printf(
2044 " inside the circumscribing circle (circle that passes through all three\n");
2045  printf(" vertices) of any triangle in the triangulation.\n\n");
2046  printf(
2047 " A Voronoi diagram of a vertex set is a subdivision of the plane into\n");
2048  printf(
2049 " polygonal cells (some of which may be unbounded, meaning infinitely\n");
2050  printf(
2051 " large), where each cell is the set of points in the plane that are closer\n"
2052 );
2053  printf(
2054 " to some input vertex than to any other input vertex. The Voronoi diagram\n"
2055 );
2056  printf(" is a geometric dual of the Delaunay triangulation.\n\n");
2057  printf(
2058 " A Planar Straight Line Graph (PSLG) is a set of vertices and segments.\n");
2059  printf(
2060 " Segments are simply edges, whose endpoints are all vertices in the PSLG.\n"
2061 );
2062  printf(
2063 " Segments may intersect each other only at their endpoints. The file\n");
2064  printf(" format for PSLGs (.poly files) is described below.\n\n");
2065  printf(
2066 " A constrained Delaunay triangulation (CDT) of a PSLG is similar to a\n");
2067  printf(
2068 " Delaunay triangulation, but each PSLG segment is present as a single edge\n"
2069 );
2070  printf(
2071 " of the CDT. (A constrained Delaunay triangulation is not truly a\n");
2072  printf(
2073 " Delaunay triangulation, because some of its triangles might not be\n");
2074  printf(
2075 " Delaunay.) By definition, a CDT does not have any vertices other than\n");
2076  printf(
2077 " those specified in the input PSLG. Depending on context, a CDT might\n");
2078  printf(
2079 " cover the convex hull of the PSLG, or it might cover only a segment-\n");
2080  printf(" bounded region (e.g. a polygon).\n\n");
2081  printf(
2082 " A conforming Delaunay triangulation of a PSLG is a triangulation in which\n"
2083 );
2084  printf(
2085 " each triangle is truly Delaunay, and each PSLG segment is represented by\n"
2086 );
2087  printf(
2088 " a linear contiguous sequence of edges of the triangulation. New vertices\n"
2089 );
2090  printf(
2091 " (not part of the PSLG) may appear, and each input segment may have been\n");
2092  printf(
2093 " subdivided into shorter edges (subsegments) by these additional vertices.\n"
2094 );
2095  printf(
2096 " The new vertices are frequently necessary to maintain the Delaunay\n");
2097  printf(" property while ensuring that every segment is represented.\n\n");
2098  printf(
2099 " A conforming constrained Delaunay triangulation (CCDT) of a PSLG is a\n");
2100  printf(
2101 " triangulation of a PSLG whose triangles are constrained Delaunay. New\n");
2102  printf(" vertices may appear, and input segments may be subdivided into\n");
2103  printf(
2104 " subsegments, but not to guarantee that segments are respected; rather, to\n"
2105 );
2106  printf(
2107 " improve the quality of the triangles. The high-quality meshes produced\n");
2108  printf(
2109 " by the -q switch are usually CCDTs, but can be made conforming Delaunay\n");
2110  printf(" with the -D switch.\n\n");
2111  printf("File Formats:\n\n");
2112  printf(
2113 " All files may contain comments prefixed by the character '#'. Vertices,\n"
2114 );
2115  printf(
2116 " triangles, edges, holes, and maximum area constraints must be numbered\n");
2117  printf(
2118 " consecutively, starting from either 1 or 0. Whichever you choose, all\n");
2119  printf(
2120 " input files must be consistent; if the vertices are numbered from 1, so\n");
2121  printf(
2122 " must be all other objects. Triangle automatically detects your choice\n");
2123  printf(
2124 " while reading the .node (or .poly) file. (When calling Triangle from\n");
2125  printf(
2126 " another program, use the -z switch if you wish to number objects from\n");
2127  printf(" zero.) Examples of these file formats are given below.\n\n");
2128  printf(" .node files:\n");
2129  printf(
2130 " First line: <# of vertices> <dimension (must be 2)> <# of attributes>\n"
2131 );
2132  printf(
2133 " <# of boundary markers (0 or 1)>\n"
2134 );
2135  printf(
2136 " Remaining lines: <vertex #> <x> <y> [attributes] [boundary marker]\n");
2137  printf("\n");
2138  printf(
2139 " The attributes, which are typically floating-point values of physical\n");
2140  printf(
2141 " quantities (such as mass or conductivity) associated with the nodes of\n"
2142 );
2143  printf(
2144 " a finite element mesh, are copied unchanged to the output mesh. If -q,\n"
2145 );
2146  printf(
2147 " -a, -u, -D, or -s is selected, each new Steiner point added to the mesh\n"
2148 );
2149  printf(" has attributes assigned to it by linear interpolation.\n\n");
2150  printf(
2151 " If the fourth entry of the first line is `1', the last column of the\n");
2152  printf(
2153 " remainder of the file is assumed to contain boundary markers. Boundary\n"
2154 );
2155  printf(
2156 " markers are used to identify boundary vertices and vertices resting on\n"
2157 );
2158  printf(
2159 " PSLG segments; a complete description appears in a section below. The\n"
2160 );
2161  printf(
2162 " .node file produced by Triangle contains boundary markers in the last\n");
2163  printf(" column unless they are suppressed by the -B switch.\n\n");
2164  printf(" .ele files:\n");
2165  printf(
2166 " First line: <# of triangles> <nodes per triangle> <# of attributes>\n");
2167  printf(
2168 " Remaining lines: <triangle #> <node> <node> <node> ... [attributes]\n");
2169  printf("\n");
2170  printf(
2171 " Nodes are indices into the corresponding .node file. The first three\n");
2172  printf(
2173 " nodes are the corner vertices, and are listed in counterclockwise order\n"
2174 );
2175  printf(
2176 " around each triangle. (The remaining nodes, if any, depend on the type\n"
2177 );
2178  printf(" of finite element used.)\n\n");
2179  printf(
2180 " The attributes are just like those of .node files. Because there is no\n"
2181 );
2182  printf(
2183 " simple mapping from input to output triangles, Triangle attempts to\n");
2184  printf(
2185 " interpolate attributes, and may cause a lot of diffusion of attributes\n"
2186 );
2187  printf(
2188 " among nearby triangles as the triangulation is refined. Attributes do\n"
2189 );
2190  printf(" not diffuse across segments, so attributes used to identify\n");
2191  printf(" segment-bounded regions remain intact.\n\n");
2192  printf(
2193 " In .ele files produced by Triangle, each triangular element has three\n");
2194  printf(
2195 " nodes (vertices) unless the -o2 switch is used, in which case\n");
2196  printf(
2197 " subparametric quadratic elements with six nodes each are generated.\n");
2198  printf(
2199 " The first three nodes are the corners in counterclockwise order, and\n");
2200  printf(
2201 " the fourth, fifth, and sixth nodes lie on the midpoints of the edges\n");
2202  printf(
2203 " opposite the first, second, and third vertices, respectively.\n");
2204  printf("\n");
2205  printf(" .poly files:\n");
2206  printf(
2207 " First line: <# of vertices> <dimension (must be 2)> <# of attributes>\n"
2208 );
2209  printf(
2210 " <# of boundary markers (0 or 1)>\n"
2211 );
2212  printf(
2213 " Following lines: <vertex #> <x> <y> [attributes] [boundary marker]\n");
2214  printf(" One line: <# of segments> <# of boundary markers (0 or 1)>\n");
2215  printf(
2216 " Following lines: <segment #> <endpoint> <endpoint> [boundary marker]\n");
2217  printf(" One line: <# of holes>\n");
2218  printf(" Following lines: <hole #> <x> <y>\n");
2219  printf(
2220 " Optional line: <# of regional attributes and/or area constraints>\n");
2221  printf(
2222 " Optional following lines: <region #> <x> <y> <attribute> <max area>\n");
2223  printf("\n");
2224  printf(
2225 " A .poly file represents a PSLG, as well as some additional information.\n"
2226 );
2227  printf(
2228 " The first section lists all the vertices, and is identical to the\n");
2229  printf(
2230 " format of .node files. <# of vertices> may be set to zero to indicate\n"
2231 );
2232  printf(
2233 " that the vertices are listed in a separate .node file; .poly files\n");
2234  printf(
2235 " produced by Triangle always have this format. A vertex set represented\n"
2236 );
2237  printf(
2238 " this way has the advantage that it may easily be triangulated with or\n");
2239  printf(
2240 " without segments (depending on whether the -p switch is invoked).\n");
2241  printf("\n");
2242  printf(
2243 " The second section lists the segments. Segments are edges whose\n");
2244  printf(
2245 " presence in the triangulation is enforced. (Depending on the choice of\n"
2246 );
2247  printf(
2248 " switches, segment might be subdivided into smaller edges). Each\n");
2249  printf(
2250 " segment is specified by listing the indices of its two endpoints. This\n"
2251 );
2252  printf(
2253 " means that you must include its endpoints in the vertex list. Each\n");
2254  printf(" segment, like each point, may have a boundary marker.\n\n");
2255  printf(
2256 " If -q, -a, -u, and -s are not selected, Triangle produces a constrained\n"
2257 );
2258  printf(
2259 " Delaunay triangulation (CDT), in which each segment appears as a single\n"
2260 );
2261  printf(
2262 " edge in the triangulation. If -q, -a, -u, or -s is selected, Triangle\n"
2263 );
2264  printf(
2265 " produces a conforming constrained Delaunay triangulation (CCDT), in\n");
2266  printf(
2267 " which segments may be subdivided into smaller edges. If -D is\n");
2268  printf(
2269 " selected, Triangle produces a conforming Delaunay triangulation, so\n");
2270  printf(
2271 " that every triangle is Delaunay, and not just constrained Delaunay.\n");
2272  printf("\n");
2273  printf(
2274 " The third section lists holes (and concavities, if -c is selected) in\n");
2275  printf(
2276 " the triangulation. Holes are specified by identifying a point inside\n");
2277  printf(
2278 " each hole. After the triangulation is formed, Triangle creates holes\n");
2279  printf(
2280 " by eating triangles, spreading out from each hole point until its\n");
2281  printf(
2282 " progress is blocked by segments in the PSLG. You must be careful to\n");
2283  printf(
2284 " enclose each hole in segments, or your whole triangulation might be\n");
2285  printf(
2286 " eaten away. If the two triangles abutting a segment are eaten, the\n");
2287  printf(
2288 " segment itself is also eaten. Do not place a hole directly on a\n");
2289  printf(" segment; if you do, Triangle chooses one side of the segment\n");
2290  printf(" arbitrarily.\n\n");
2291  printf(
2292 " The optional fourth section lists regional attributes (to be assigned\n");
2293  printf(
2294 " to all triangles in a region) and regional constraints on the maximum\n");
2295  printf(
2296 " triangle area. Triangle reads this section only if the -A switch is\n");
2297  printf(
2298 " used or the -a switch is used without a number following it, and the -r\n"
2299 );
2300  printf(
2301 " switch is not used. Regional attributes and area constraints are\n");
2302  printf(
2303 " propagated in the same manner as holes: you specify a point for each\n");
2304  printf(
2305 " attribute and/or constraint, and the attribute and/or constraint\n");
2306  printf(
2307 " affects the whole region (bounded by segments) containing the point.\n");
2308  printf(
2309 " If two values are written on a line after the x and y coordinate, the\n");
2310  printf(
2311 " first such value is assumed to be a regional attribute (but is only\n");
2312  printf(
2313 " applied if the -A switch is selected), and the second value is assumed\n"
2314 );
2315  printf(
2316 " to be a regional area constraint (but is only applied if the -a switch\n"
2317 );
2318  printf(
2319 " is selected). You may specify just one value after the coordinates,\n");
2320  printf(
2321 " which can serve as both an attribute and an area constraint, depending\n"
2322 );
2323  printf(
2324 " on the choice of switches. If you are using the -A and -a switches\n");
2325  printf(
2326 " simultaneously and wish to assign an attribute to some region without\n");
2327  printf(" imposing an area constraint, use a negative maximum area.\n\n");
2328  printf(
2329 " When a triangulation is created from a .poly file, you must either\n");
2330  printf(
2331 " enclose the entire region to be triangulated in PSLG segments, or\n");
2332  printf(
2333 " use the -c switch, which automatically creates extra segments that\n");
2334  printf(
2335 " enclose the convex hull of the PSLG. If you do not use the -c switch,\n"
2336 );
2337  printf(
2338 " Triangle eats all triangles that are not enclosed by segments; if you\n");
2339  printf(
2340 " are not careful, your whole triangulation may be eaten away. If you do\n"
2341 );
2342  printf(
2343 " use the -c switch, you can still produce concavities by the appropriate\n"
2344 );
2345  printf(
2346 " placement of holes just inside the boundary of the convex hull.\n");
2347  printf("\n");
2348  printf(
2349 " An ideal PSLG has no intersecting segments, nor any vertices that lie\n");
2350  printf(
2351 " upon segments (except, of course, the endpoints of each segment). You\n"
2352 );
2353  printf(
2354 " aren't required to make your .poly files ideal, but you should be aware\n"
2355 );
2356  printf(
2357 " of what can go wrong. Segment intersections are relatively safe--\n");
2358  printf(
2359 " Triangle calculates the intersection points for you and adds them to\n");
2360  printf(
2361 " the triangulation--as long as your machine's floating-point precision\n");
2362  printf(
2363 " doesn't become a problem. You are tempting the fates if you have three\n"
2364 );
2365  printf(
2366 " segments that cross at the same location, and expect Triangle to figure\n"
2367 );
2368  printf(
2369 " out where the intersection point is. Thanks to floating-point roundoff\n"
2370 );
2371  printf(
2372 " error, Triangle will probably decide that the three segments intersect\n"
2373 );
2374  printf(
2375 " at three different points, and you will find a minuscule triangle in\n");
2376  printf(
2377 " your output--unless Triangle tries to refine the tiny triangle, uses\n");
2378  printf(
2379 " up the last bit of machine precision, and fails to terminate at all.\n");
2380  printf(
2381 " You're better off putting the intersection point in the input files,\n");
2382  printf(
2383 " and manually breaking up each segment into two. Similarly, if you\n");
2384  printf(
2385 " place a vertex at the middle of a segment, and hope that Triangle will\n"
2386 );
2387  printf(
2388 " break up the segment at that vertex, you might get lucky. On the other\n"
2389 );
2390  printf(
2391 " hand, Triangle might decide that the vertex doesn't lie precisely on\n");
2392  printf(
2393 " the segment, and you'll have a needle-sharp triangle in your output--or\n"
2394 );
2395  printf(" a lot of tiny triangles if you're generating a quality mesh.\n");
2396  printf("\n");
2397  printf(
2398 " When Triangle reads a .poly file, it also writes a .poly file, which\n");
2399  printf(
2400 " includes all the subsegments--the edges that are parts of input\n");
2401  printf(
2402 " segments. If the -c switch is used, the output .poly file also\n");
2403  printf(
2404 " includes all of the edges on the convex hull. Hence, the output .poly\n"
2405 );
2406  printf(
2407 " file is useful for finding edges associated with input segments and for\n"
2408 );
2409  printf(
2410 " setting boundary conditions in finite element simulations. Moreover,\n");
2411  printf(
2412 " you will need the output .poly file if you plan to refine the output\n");
2413  printf(
2414 " mesh, and don't want segments to be missing in later triangulations.\n");
2415  printf("\n");
2416  printf(" .area files:\n");
2417  printf(" First line: <# of triangles>\n");
2418  printf(" Following lines: <triangle #> <maximum area>\n");
2419  printf("\n");
2420  printf(
2421 " An .area file associates with each triangle a maximum area that is used\n"
2422 );
2423  printf(
2424 " for mesh refinement. As with other file formats, every triangle must\n");
2425  printf(
2426 " be represented, and the triangles must be numbered consecutively. A\n");
2427  printf(
2428 " triangle may be left unconstrained by assigning it a negative maximum\n");
2429  printf(" area.\n\n");
2430  printf(" .edge files:\n");
2431  printf(" First line: <# of edges> <# of boundary markers (0 or 1)>\n");
2432  printf(
2433 " Following lines: <edge #> <endpoint> <endpoint> [boundary marker]\n");
2434  printf("\n");
2435  printf(
2436 " Endpoints are indices into the corresponding .node file. Triangle can\n"
2437 );
2438  printf(
2439 " produce .edge files (use the -e switch), but cannot read them. The\n");
2440  printf(
2441 " optional column of boundary markers is suppressed by the -B switch.\n");
2442  printf("\n");
2443  printf(
2444 " In Voronoi diagrams, one also finds a special kind of edge that is an\n");
2445  printf(
2446 " infinite ray with only one endpoint. For these edges, a different\n");
2447  printf(" format is used:\n\n");
2448  printf(" <edge #> <endpoint> -1 <direction x> <direction y>\n\n");
2449  printf(
2450 " The `direction' is a floating-point vector that indicates the direction\n"
2451 );
2452  printf(" of the infinite ray.\n\n");
2453  printf(" .neigh files:\n");
2454  printf(
2455 " First line: <# of triangles> <# of neighbors per triangle (always 3)>\n"
2456 );
2457  printf(
2458 " Following lines: <triangle #> <neighbor> <neighbor> <neighbor>\n");
2459  printf("\n");
2460  printf(
2461 " Neighbors are indices into the corresponding .ele file. An index of -1\n"
2462 );
2463  printf(
2464 " indicates no neighbor (because the triangle is on an exterior\n");
2465  printf(
2466 " boundary). The first neighbor of triangle i is opposite the first\n");
2467  printf(" corner of triangle i, and so on.\n\n");
2468  printf(
2469 " Triangle can produce .neigh files (use the -n switch), but cannot read\n"
2470 );
2471  printf(" them.\n\n");
2472  printf("Boundary Markers:\n\n");
2473  printf(
2474 " Boundary markers are tags used mainly to identify which output vertices\n");
2475  printf(
2476 " and edges are associated with which PSLG segment, and to identify which\n");
2477  printf(
2478 " vertices and edges occur on a boundary of the triangulation. A common\n");
2479  printf(
2480 " use is to determine where boundary conditions should be applied to a\n");
2481  printf(
2482 " finite element mesh. You can prevent boundary markers from being written\n"
2483 );
2484  printf(" into files produced by Triangle by using the -B switch.\n\n");
2485  printf(
2486 " The boundary marker associated with each segment in an output .poly file\n"
2487 );
2488  printf(" and each edge in an output .edge file is chosen as follows:\n");
2489  printf(
2490 " - If an output edge is part or all of a PSLG segment with a nonzero\n");
2491  printf(
2492 " boundary marker, then the edge is assigned the same marker.\n");
2493  printf(
2494 " - Otherwise, if the edge lies on a boundary of the triangulation\n");
2495  printf(
2496 " (even the boundary of a hole), then the edge is assigned the marker\n");
2497  printf(" one (1).\n");
2498  printf(" - Otherwise, the edge is assigned the marker zero (0).\n");
2499  printf(
2500 " The boundary marker associated with each vertex in an output .node file\n");
2501  printf(" is chosen as follows:\n");
2502  printf(
2503 " - If a vertex is assigned a nonzero boundary marker in the input file,\n"
2504 );
2505  printf(
2506 " then it is assigned the same marker in the output .node file.\n");
2507  printf(
2508 " - Otherwise, if the vertex lies on a PSLG segment (even if it is an\n");
2509  printf(
2510 " endpoint of the segment) with a nonzero boundary marker, then the\n");
2511  printf(
2512 " vertex is assigned the same marker. If the vertex lies on several\n");
2513  printf(" such segments, one of the markers is chosen arbitrarily.\n");
2514  printf(
2515 " - Otherwise, if the vertex occurs on a boundary of the triangulation,\n");
2516  printf(" then the vertex is assigned the marker one (1).\n");
2517  printf(" - Otherwise, the vertex is assigned the marker zero (0).\n");
2518  printf("\n");
2519  printf(
2520 " If you want Triangle to determine for you which vertices and edges are on\n"
2521 );
2522  printf(
2523 " the boundary, assign them the boundary marker zero (or use no markers at\n"
2524 );
2525  printf(
2526 " all) in your input files. In the output files, all boundary vertices,\n");
2527  printf(" edges, and segments will be assigned the value one.\n\n");
2528  printf("Triangulation Iteration Numbers:\n\n");
2529  printf(
2530 " Because Triangle can read and refine its own triangulations, input\n");
2531  printf(
2532 " and output files have iteration numbers. For instance, Triangle might\n");
2533  printf(
2534 " read the files mesh.3.node, mesh.3.ele, and mesh.3.poly, refine the\n");
2535  printf(
2536 " triangulation, and output the files mesh.4.node, mesh.4.ele, and\n");
2537  printf(" mesh.4.poly. Files with no iteration number are treated as if\n");
2538  printf(
2539 " their iteration number is zero; hence, Triangle might read the file\n");
2540  printf(
2541 " points.node, triangulate it, and produce the files points.1.node and\n");
2542  printf(" points.1.ele.\n\n");
2543  printf(
2544 " Iteration numbers allow you to create a sequence of successively finer\n");
2545  printf(
2546 " meshes suitable for multigrid methods. They also allow you to produce a\n"
2547 );
2548  printf(
2549 " sequence of meshes using error estimate-driven mesh refinement.\n");
2550  printf("\n");
2551  printf(
2552 " If you're not using refinement or quality meshing, and you don't like\n");
2553  printf(
2554 " iteration numbers, use the -I switch to disable them. This switch also\n");
2555  printf(
2556 " disables output of .node and .poly files to prevent your input files from\n"
2557 );
2558  printf(
2559 " being overwritten. (If the input is a .poly file that contains its own\n");
2560  printf(
2561 " points, a .node file is written. This can be quite convenient for\n");
2562  printf(" computing CDTs or quality meshes.)\n\n");
2563  printf("Examples of How to Use Triangle:\n\n");
2564  printf(
2565 " `triangle dots' reads vertices from dots.node, and writes their Delaunay\n"
2566 );
2567  printf(
2568 " triangulation to dots.1.node and dots.1.ele. (dots.1.node is identical\n");
2569  printf(
2570 " to dots.node.) `triangle -I dots' writes the triangulation to dots.ele\n");
2571  printf(
2572 " instead. (No additional .node file is needed, so none is written.)\n");
2573  printf("\n");
2574  printf(
2575 " `triangle -pe object.1' reads a PSLG from object.1.poly (and possibly\n");
2576  printf(
2577 " object.1.node, if the vertices are omitted from object.1.poly) and writes\n"
2578 );
2579  printf(
2580 " its constrained Delaunay triangulation to object.2.node and object.2.ele.\n"
2581 );
2582  printf(
2583 " The segments are copied to object.2.poly, and all edges are written to\n");
2584  printf(" object.2.edge.\n\n");
2585  printf(
2586 " `triangle -pq31.5a.1 object' reads a PSLG from object.poly (and possibly\n"
2587 );
2588  printf(
2589 " object.node), generates a mesh whose angles are all between 31.5 and 117\n"
2590 );
2591  printf(
2592 " degrees and whose triangles all have areas of 0.1 or less, and writes the\n"
2593 );
2594  printf(
2595 " mesh to object.1.node and object.1.ele. Each segment may be broken up\n");
2596  printf(" into multiple subsegments; these are written to object.1.poly.\n");
2597  printf("\n");
2598  printf(
2599 " Here is a sample file `box.poly' describing a square with a square hole:\n"
2600 );
2601  printf("\n");
2602  printf(
2603 " # A box with eight vertices in 2D, no attributes, one boundary marker.\n"
2604 );
2605  printf(" 8 2 0 1\n");
2606  printf(" # Outer box has these vertices:\n");
2607  printf(" 1 0 0 0\n");
2608  printf(" 2 0 3 0\n");
2609  printf(" 3 3 0 0\n");
2610  printf(" 4 3 3 33 # A special marker for this vertex.\n");
2611  printf(" # Inner square has these vertices:\n");
2612  printf(" 5 1 1 0\n");
2613  printf(" 6 1 2 0\n");
2614  printf(" 7 2 1 0\n");
2615  printf(" 8 2 2 0\n");
2616  printf(" # Five segments with boundary markers.\n");
2617  printf(" 5 1\n");
2618  printf(" 1 1 2 5 # Left side of outer box.\n");
2619  printf(" # Square hole has these segments:\n");
2620  printf(" 2 5 7 0\n");
2621  printf(" 3 7 8 0\n");
2622  printf(" 4 8 6 10\n");
2623  printf(" 5 6 5 0\n");
2624  printf(" # One hole in the middle of the inner square.\n");
2625  printf(" 1\n");
2626  printf(" 1 1.5 1.5\n");
2627  printf("\n");
2628  printf(
2629 " Note that some segments are missing from the outer square, so you must\n");
2630  printf(
2631 " use the `-c' switch. After `triangle -pqc box.poly', here is the output\n"
2632 );
2633  printf(
2634 " file `box.1.node', with twelve vertices. The last four vertices were\n");
2635  printf(
2636 " added to meet the angle constraint. Vertices 1, 2, and 9 have markers\n");
2637  printf(
2638 " from segment 1. Vertices 6 and 8 have markers from segment 4. All the\n");
2639  printf(
2640 " other vertices but 4 have been marked to indicate that they lie on a\n");
2641  printf(" boundary.\n\n");
2642  printf(" 12 2 0 1\n");
2643  printf(" 1 0 0 5\n");
2644  printf(" 2 0 3 5\n");
2645  printf(" 3 3 0 1\n");
2646  printf(" 4 3 3 33\n");
2647  printf(" 5 1 1 1\n");
2648  printf(" 6 1 2 10\n");
2649  printf(" 7 2 1 1\n");
2650  printf(" 8 2 2 10\n");
2651  printf(" 9 0 1.5 5\n");
2652  printf(" 10 1.5 0 1\n");
2653  printf(" 11 3 1.5 1\n");
2654  printf(" 12 1.5 3 1\n");
2655  printf(" # Generated by triangle -pqc box.poly\n");
2656  printf("\n");
2657  printf(" Here is the output file `box.1.ele', with twelve triangles.\n");
2658  printf("\n");
2659  printf(" 12 3 0\n");
2660  printf(" 1 5 6 9\n");
2661  printf(" 2 10 3 7\n");
2662  printf(" 3 6 8 12\n");
2663  printf(" 4 9 1 5\n");
2664  printf(" 5 6 2 9\n");
2665  printf(" 6 7 3 11\n");
2666  printf(" 7 11 4 8\n");
2667  printf(" 8 7 5 10\n");
2668  printf(" 9 12 2 6\n");
2669  printf(" 10 8 7 11\n");
2670  printf(" 11 5 1 10\n");
2671  printf(" 12 8 4 12\n");
2672  printf(" # Generated by triangle -pqc box.poly\n\n");
2673  printf(
2674 " Here is the output file `box.1.poly'. Note that segments have been added\n"
2675 );
2676  printf(
2677 " to represent the convex hull, and some segments have been subdivided by\n");
2678  printf(
2679 " newly added vertices. Note also that <# of vertices> is set to zero to\n");
2680  printf(" indicate that the vertices should be read from the .node file.\n");
2681  printf("\n");
2682  printf(" 0 2 0 1\n");
2683  printf(" 12 1\n");
2684  printf(" 1 1 9 5\n");
2685  printf(" 2 5 7 1\n");
2686  printf(" 3 8 7 1\n");
2687  printf(" 4 6 8 10\n");
2688  printf(" 5 5 6 1\n");
2689  printf(" 6 3 10 1\n");
2690  printf(" 7 4 11 1\n");
2691  printf(" 8 2 12 1\n");
2692  printf(" 9 9 2 5\n");
2693  printf(" 10 10 1 1\n");
2694  printf(" 11 11 3 1\n");
2695  printf(" 12 12 4 1\n");
2696  printf(" 1\n");
2697  printf(" 1 1.5 1.5\n");
2698  printf(" # Generated by triangle -pqc box.poly\n");
2699  printf("\n");
2700  printf("Refinement and Area Constraints:\n");
2701  printf("\n");
2702  printf(
2703 " The -r switch causes a mesh (.node and .ele files) to be read and\n");
2704  printf(
2705 " refined. If the -p switch is also used, a .poly file is read and used to\n"
2706 );
2707  printf(
2708 " specify edges that are constrained and cannot be eliminated (although\n");
2709  printf(
2710 " they can be subdivided into smaller edges) by the refinement process.\n");
2711  printf("\n");
2712  printf(
2713 " When you refine a mesh, you generally want to impose tighter constraints.\n"
2714 );
2715  printf(
2716 " One way to accomplish this is to use -q with a larger angle, or -a\n");
2717  printf(
2718 " followed by a smaller area than you used to generate the mesh you are\n");
2719  printf(
2720 " refining. Another way to do this is to create an .area file, which\n");
2721  printf(
2722 " specifies a maximum area for each triangle, and use the -a switch\n");
2723  printf(
2724 " (without a number following). Each triangle's area constraint is applied\n"
2725 );
2726  printf(
2727 " to that triangle. Area constraints tend to diffuse as the mesh is\n");
2728  printf(
2729 " refined, so if there are large variations in area constraint between\n");
2730  printf(
2731 " adjacent triangles, you may not get the results you want. In that case,\n"
2732 );
2733  printf(
2734 " consider instead using the -u switch and writing a C procedure that\n");
2735  printf(" determines which triangles are too large.\n\n");
2736  printf(
2737 " If you are refining a mesh composed of linear (three-node) elements, the\n"
2738 );
2739  printf(
2740 " output mesh contains all the nodes present in the input mesh, in the same\n"
2741 );
2742  printf(
2743 " order, with new nodes added at the end of the .node file. However, the\n");
2744  printf(
2745 " refinement is not hierarchical: there is no guarantee that each output\n");
2746  printf(
2747 " element is contained in a single input element. Often, an output element\n"
2748 );
2749  printf(
2750 " can overlap two or three input elements, and some input edges are not\n");
2751  printf(
2752 " present in the output mesh. Hence, a sequence of refined meshes forms a\n"
2753 );
2754  printf(
2755 " hierarchy of nodes, but not a hierarchy of elements. If you refine a\n");
2756  printf(
2757 " mesh of higher-order elements, the hierarchical property applies only to\n"
2758 );
2759  printf(
2760 " the nodes at the corners of an element; the midpoint nodes on each edge\n");
2761  printf(" are discarded before the mesh is refined.\n\n");
2762  printf(
2763 " Maximum area constraints in .poly files operate differently from those in\n"
2764 );
2765  printf(
2766 " .area files. A maximum area in a .poly file applies to the whole\n");
2767  printf(
2768 " (segment-bounded) region in which a point falls, whereas a maximum area\n");
2769  printf(
2770 " in an .area file applies to only one triangle. Area constraints in .poly\n"
2771 );
2772  printf(
2773 " files are used only when a mesh is first generated, whereas area\n");
2774  printf(
2775 " constraints in .area files are used only to refine an existing mesh, and\n"
2776 );
2777  printf(
2778 " are typically based on a posteriori error estimates resulting from a\n");
2779  printf(" finite element simulation on that mesh.\n\n");
2780  printf(
2781 " `triangle -rq25 object.1' reads object.1.node and object.1.ele, then\n");
2782  printf(
2783 " refines the triangulation to enforce a 25 degree minimum angle, and then\n"
2784 );
2785  printf(
2786 " writes the refined triangulation to object.2.node and object.2.ele.\n");
2787  printf("\n");
2788  printf(
2789 " `triangle -rpaa6.2 z.3' reads z.3.node, z.3.ele, z.3.poly, and z.3.area.\n"
2790 );
2791  printf(
2792 " After reconstructing the mesh and its subsegments, Triangle refines the\n");
2793  printf(
2794 " mesh so that no triangle has area greater than 6.2, and furthermore the\n");
2795  printf(
2796 " triangles satisfy the maximum area constraints in z.3.area. No angle\n");
2797  printf(
2798 " bound is imposed at all. The output is written to z.4.node, z.4.ele, and\n"
2799 );
2800  printf(" z.4.poly.\n\n");
2801  printf(
2802 " The sequence `triangle -qa1 x', `triangle -rqa.3 x.1', `triangle -rqa.1\n");
2803  printf(
2804 " x.2' creates a sequence of successively finer meshes x.1, x.2, and x.3,\n");
2805  printf(" suitable for multigrid.\n\n");
2806  printf("Convex Hulls and Mesh Boundaries:\n\n");
2807  printf(
2808 " If the input is a vertex set (not a PSLG), Triangle produces its convex\n");
2809  printf(
2810 " hull as a by-product in the output .poly file if you use the -c switch.\n");
2811  printf(
2812 " There are faster algorithms for finding a two-dimensional convex hull\n");
2813  printf(" than triangulation, of course, but this one comes for free.\n\n");
2814  printf(
2815 " If the input is an unconstrained mesh (you are using the -r switch but\n");
2816  printf(
2817 " not the -p switch), Triangle produces a list of its boundary edges\n");
2818  printf(
2819 " (including hole boundaries) as a by-product when you use the -c switch.\n");
2820  printf(
2821 " If you also use the -p switch, the output .poly file contains all the\n");
2822  printf(" segments from the input .poly file as well.\n\n");
2823  printf("Voronoi Diagrams:\n\n");
2824  printf(
2825 " The -v switch produces a Voronoi diagram, in files suffixed .v.node and\n");
2826  printf(
2827 " .v.edge. For example, `triangle -v points' reads points.node, produces\n");
2828  printf(
2829 " its Delaunay triangulation in points.1.node and points.1.ele, and\n");
2830  printf(
2831 " produces its Voronoi diagram in points.1.v.node and points.1.v.edge. The\n"
2832 );
2833  printf(
2834 " .v.node file contains a list of all Voronoi vertices, and the .v.edge\n");
2835  printf(
2836 " file contains a list of all Voronoi edges, some of which may be infinite\n"
2837 );
2838  printf(
2839 " rays. (The choice of filenames makes it easy to run the set of Voronoi\n");
2840  printf(" vertices through Triangle, if so desired.)\n\n");
2841  printf(
2842 " This implementation does not use exact arithmetic to compute the Voronoi\n"
2843 );
2844  printf(
2845 " vertices, and does not check whether neighboring vertices are identical.\n"
2846 );
2847  printf(
2848 " Be forewarned that if the Delaunay triangulation is degenerate or\n");
2849  printf(
2850 " near-degenerate, the Voronoi diagram may have duplicate vertices or\n");
2851  printf(" crossing edges.\n\n");
2852  printf(
2853 " The result is a valid Voronoi diagram only if Triangle's output is a true\n"
2854 );
2855  printf(
2856 " Delaunay triangulation. The Voronoi output is usually meaningless (and\n");
2857  printf(
2858 " may contain crossing edges and other pathology) if the output is a CDT or\n"
2859 );
2860  printf(
2861 " CCDT, or if it has holes or concavities. If the triangulated domain is\n");
2862  printf(
2863 " convex and has no holes, you can use -D switch to force Triangle to\n");
2864  printf(
2865 " construct a conforming Delaunay triangulation instead of a CCDT, so the\n");
2866  printf(" Voronoi diagram will be valid.\n\n");
2867  printf("Mesh Topology:\n\n");
2868  printf(
2869 " You may wish to know which triangles are adjacent to a certain Delaunay\n");
2870  printf(
2871 " edge in an .edge file, which Voronoi cells are adjacent to a certain\n");
2872  printf(
2873 " Voronoi edge in a .v.edge file, or which Voronoi cells are adjacent to\n");
2874  printf(
2875 " each other. All of this information can be found by cross-referencing\n");
2876  printf(
2877 " output files with the recollection that the Delaunay triangulation and\n");
2878  printf(" the Voronoi diagram are planar duals.\n\n");
2879  printf(
2880 " Specifically, edge i of an .edge file is the dual of Voronoi edge i of\n");
2881  printf(
2882 " the corresponding .v.edge file, and is rotated 90 degrees counterclock-\n");
2883  printf(
2884 " wise from the Voronoi edge. Triangle j of an .ele file is the dual of\n");
2885  printf(
2886 " vertex j of the corresponding .v.node file. Voronoi cell k is the dual\n");
2887  printf(" of vertex k of the corresponding .node file.\n\n");
2888  printf(
2889 " Hence, to find the triangles adjacent to a Delaunay edge, look at the\n");
2890  printf(
2891 " vertices of the corresponding Voronoi edge. If the endpoints of a\n");
2892  printf(
2893 " Voronoi edge are Voronoi vertices 2 and 6 respectively, then triangles 2\n"
2894 );
2895  printf(
2896 " and 6 adjoin the left and right sides of the corresponding Delaunay edge,\n"
2897 );
2898  printf(
2899 " respectively. To find the Voronoi cells adjacent to a Voronoi edge, look\n"
2900 );
2901  printf(
2902 " at the endpoints of the corresponding Delaunay edge. If the endpoints of\n"
2903 );
2904  printf(
2905 " a Delaunay edge are input vertices 7 and 12, then Voronoi cells 7 and 12\n"
2906 );
2907  printf(
2908 " adjoin the right and left sides of the corresponding Voronoi edge,\n");
2909  printf(
2910 " respectively. To find which Voronoi cells are adjacent to each other,\n");
2911  printf(" just read the list of Delaunay edges.\n\n");
2912  printf(
2913 " Triangle does not write a list of the edges adjoining each Voronoi cell,\n"
2914 );
2915  printf(
2916 " but you can reconstructed it straightforwardly. For instance, to find\n");
2917  printf(
2918 " all the edges of Voronoi cell 1, search the output .edge file for every\n");
2919  printf(
2920 " edge that has input vertex 1 as an endpoint. The corresponding dual\n");
2921  printf(
2922 " edges in the output .v.edge file form the boundary of Voronoi cell 1.\n");
2923  printf("\n");
2924  printf(
2925 " For each Voronoi vertex, the .neigh file gives a list of the three\n");
2926  printf(
2927 " Voronoi vertices attached to it. You might find this more convenient\n");
2928  printf(" than the .v.edge file.\n\n");
2929  printf("Quadratic Elements:\n\n");
2930  printf(
2931 " Triangle generates meshes with subparametric quadratic elements if the\n");
2932  printf(
2933 " -o2 switch is specified. Quadratic elements have six nodes per element,\n"
2934 );
2935  printf(
2936 " rather than three. `Subparametric' means that the edges of the triangles\n"
2937 );
2938  printf(
2939 " are always straight, so that subparametric quadratic elements are\n");
2940  printf(
2941 " geometrically identical to linear elements, even though they can be used\n"
2942 );
2943  printf(
2944 " with quadratic interpolating functions. The three extra nodes of an\n");
2945  printf(
2946 " element fall at the midpoints of the three edges, with the fourth, fifth,\n"
2947 );
2948  printf(
2949 " and sixth nodes appearing opposite the first, second, and third corners\n");
2950  printf(" respectively.\n\n");
2951  printf("Domains with Small Angles:\n\n");
2952  printf(
2953 " If two input segments adjoin each other at a small angle, clearly the -q\n"
2954 );
2955  printf(
2956 " switch cannot remove the small angle. Moreover, Triangle may have no\n");
2957  printf(
2958 " choice but to generate additional triangles whose smallest angles are\n");
2959  printf(
2960 " smaller than the specified bound. However, these triangles only appear\n");
2961  printf(
2962 " between input segments separated by small angles. Moreover, if you\n");
2963  printf(
2964 " request a minimum angle of theta degrees, Triangle will generally produce\n"
2965 );
2966  printf(
2967 " no angle larger than 180 - 2 theta, even if it is forced to compromise on\n"
2968 );
2969  printf(" the minimum angle.\n\n");
2970  printf("Statistics:\n\n");
2971  printf(
2972 " After generating a mesh, Triangle prints a count of entities in the\n");
2973  printf(
2974 " output mesh, including the number of vertices, triangles, edges, exterior\n"
2975 );
2976  printf(
2977 " boundary edges (i.e. subsegments on the boundary of the triangulation,\n");
2978  printf(
2979 " including hole boundaries), interior boundary edges (i.e. subsegments of\n"
2980 );
2981  printf(
2982 " input segments not on the boundary), and total subsegments. If you've\n");
2983  printf(
2984 " forgotten the statistics for an existing mesh, run Triangle on that mesh\n"
2985 );
2986  printf(
2987 " with the -rNEP switches to read the mesh and print the statistics without\n"
2988 );
2989  printf(
2990 " writing any files. Use -rpNEP if you've got a .poly file for the mesh.\n");
2991  printf("\n");
2992  printf(
2993 " The -V switch produces extended statistics, including a rough estimate\n");
2994  printf(
2995 " of memory use, the number of calls to geometric predicates, and\n");
2996  printf(
2997 " histograms of the angles and the aspect ratios of the triangles in the\n");
2998  printf(" mesh.\n\n");
2999  printf("Exact Arithmetic:\n\n");
3000  printf(
3001 " Triangle uses adaptive exact arithmetic to perform what computational\n");
3002  printf(
3003 " geometers call the `orientation' and `incircle' tests. If the floating-\n"
3004 );
3005  printf(
3006 " point arithmetic of your machine conforms to the IEEE 754 standard (as\n");
3007  printf(
3008 " most workstations do), and does not use extended precision internal\n");
3009  printf(
3010 " floating-point registers, then your output is guaranteed to be an\n");
3011  printf(
3012 " absolutely true Delaunay or constrained Delaunay triangulation, roundoff\n"
3013 );
3014  printf(
3015 " error notwithstanding. The word `adaptive' implies that these arithmetic\n"
3016 );
3017  printf(
3018 " routines compute the result only to the precision necessary to guarantee\n"
3019 );
3020  printf(
3021 " correctness, so they are usually nearly as fast as their approximate\n");
3022  printf(" counterparts.\n\n");
3023  printf(
3024 " May CPUs, including Intel x86 processors, have extended precision\n");
3025  printf(
3026 " floating-point registers. These must be reconfigured so their precision\n"
3027 );
3028  printf(
3029 " is reduced to memory precision. Triangle does this if it is compiled\n");
3030  printf(" correctly. See the makefile for details.\n\n");
3031  printf(
3032 " The exact tests can be disabled with the -X switch. On most inputs, this\n"
3033 );
3034  printf(
3035 " switch reduces the computation time by about eight percent--it's not\n");
3036  printf(
3037 " worth the risk. There are rare difficult inputs (having many collinear\n");
3038  printf(
3039 " and cocircular vertices), however, for which the difference in speed\n");
3040  printf(
3041 " could be a factor of two. Be forewarned that these are precisely the\n");
3042  printf(
3043 " inputs most likely to cause errors if you use the -X switch. Hence, the\n"
3044 );
3045  printf(" -X switch is not recommended.\n\n");
3046  printf(
3047 " Unfortunately, the exact tests don't solve every numerical problem.\n");
3048  printf(
3049 " Exact arithmetic is not used to compute the positions of new vertices,\n");
3050  printf(
3051 " because the bit complexity of vertex coordinates would grow without\n");
3052  printf(
3053 " bound. Hence, segment intersections aren't computed exactly; in very\n");
3054  printf(
3055 " unusual cases, roundoff error in computing an intersection point might\n");
3056  printf(
3057 " actually lead to an inverted triangle and an invalid triangulation.\n");
3058  printf(
3059 " (This is one reason to specify your own intersection points in your .poly\n"
3060 );
3061  printf(
3062 " files.) Similarly, exact arithmetic is not used to compute the vertices\n"
3063 );
3064  printf(" of the Voronoi diagram.\n\n");
3065  printf(
3066 " Another pair of problems not solved by the exact arithmetic routines is\n");
3067  printf(
3068 " underflow and overflow. If Triangle is compiled for double precision\n");
3069  printf(
3070 " arithmetic, I believe that Triangle's geometric predicates work correctly\n"
3071 );
3072  printf(
3073 " if the exponent of every input coordinate falls in the range [-148, 201].\n"
3074 );
3075  printf(
3076 " Underflow can silently prevent the orientation and incircle tests from\n");
3077  printf(
3078 " being performed exactly, while overflow typically causes a floating\n");
3079  printf(" exception.\n\n");
3080  printf("Calling Triangle from Another Program:\n\n");
3081  printf(" Read the file triangle.h for details.\n\n");
3082  printf("Troubleshooting:\n\n");
3083  printf(" Please read this section before mailing me bugs.\n\n");
3084  printf(" `My output mesh has no triangles!'\n\n");
3085  printf(
3086 " If you're using a PSLG, you've probably failed to specify a proper set\n"
3087 );
3088  printf(
3089 " of bounding segments, or forgotten to use the -c switch. Or you may\n");
3090  printf(
3091 " have placed a hole badly, thereby eating all your triangles. To test\n");
3092  printf(" these possibilities, try again with the -c and -O switches.\n");
3093  printf(
3094 " Alternatively, all your input vertices may be collinear, in which case\n"
3095 );
3096  printf(" you can hardly expect to triangulate them.\n\n");
3097  printf(" `Triangle doesn't terminate, or just crashes.'\n\n");
3098  printf(
3099 " Bad things can happen when triangles get so small that the distance\n");
3100  printf(
3101 " between their vertices isn't much larger than the precision of your\n");
3102  printf(
3103 " machine's arithmetic. If you've compiled Triangle for single-precision\n"
3104 );
3105  printf(
3106 " arithmetic, you might do better by recompiling it for double-precision.\n"
3107 );
3108  printf(
3109 " Then again, you might just have to settle for more lenient constraints\n"
3110 );
3111  printf(
3112 " on the minimum angle and the maximum area than you had planned.\n");
3113  printf("\n");
3114  printf(
3115 " You can minimize precision problems by ensuring that the origin lies\n");
3116  printf(
3117 " inside your vertex set, or even inside the densest part of your\n");
3118  printf(
3119 " mesh. If you're triangulating an object whose x-coordinates all fall\n");
3120  printf(
3121 " between 6247133 and 6247134, you're not leaving much floating-point\n");
3122  printf(" precision for Triangle to work with.\n\n");
3123  printf(
3124 " Precision problems can occur covertly if the input PSLG contains two\n");
3125  printf(
3126 " segments that meet (or intersect) at an extremely small angle, or if\n");
3127  printf(
3128 " such an angle is introduced by the -c switch. If you don't realize\n");
3129  printf(
3130 " that a tiny angle is being formed, you might never discover why\n");
3131  printf(
3132 " Triangle is crashing. To check for this possibility, use the -S switch\n"
3133 );
3134  printf(
3135 " (with an appropriate limit on the number of Steiner points, found by\n");
3136  printf(
3137 " trial-and-error) to stop Triangle early, and view the output .poly file\n"
3138 );
3139  printf(
3140 " with Show Me (described below). Look carefully for regions where dense\n"
3141 );
3142  printf(
3143 " clusters of vertices are forming and for small angles between segments.\n"
3144 );
3145  printf(
3146 " Zoom in closely, as such segments might look like a single segment from\n"
3147 );
3148  printf(" a distance.\n\n");
3149  printf(
3150 " If some of the input values are too large, Triangle may suffer a\n");
3151  printf(
3152 " floating exception due to overflow when attempting to perform an\n");
3153  printf(
3154 " orientation or incircle test. (Read the section on exact arithmetic\n");
3155  printf(
3156 " above.) Again, I recommend compiling Triangle for double (rather\n");
3157  printf(" than single) precision arithmetic.\n\n");
3158  printf(
3159 " Unexpected problems can arise if you use quality meshing (-q, -a, or\n");
3160  printf(
3161 " -u) with an input that is not segment-bounded--that is, if your input\n");
3162  printf(
3163 " is a vertex set, or you're using the -c switch. If the convex hull of\n"
3164 );
3165  printf(
3166 " your input vertices has collinear vertices on its boundary, an input\n");
3167  printf(
3168 " vertex that you think lies on the convex hull might actually lie just\n");
3169  printf(
3170 " inside the convex hull. If so, the vertex and the nearby convex hull\n");
3171  printf(
3172 " edge form an extremely thin triangle. When Triangle tries to refine\n");
3173  printf(
3174 " the mesh to enforce angle and area constraints, Triangle might generate\n"
3175 );
3176  printf(
3177 " extremely tiny triangles, or it might fail because of insufficient\n");
3178  printf(" floating-point precision.\n\n");
3179  printf(
3180 " `The numbering of the output vertices doesn't match the input vertices.'\n"
3181 );
3182  printf("\n");
3183  printf(
3184 " You may have had duplicate input vertices, or you may have eaten some\n");
3185  printf(
3186 " of your input vertices with a hole, or by placing them outside the area\n"
3187 );
3188  printf(
3189 " enclosed by segments. In any case, you can solve the problem by not\n");
3190  printf(" using the -j switch.\n\n");
3191  printf(
3192 " `Triangle executes without incident, but when I look at the resulting\n");
3193  printf(
3194 " mesh, it has overlapping triangles or other geometric inconsistencies.'\n");
3195  printf("\n");
3196  printf(
3197 " If you select the -X switch, Triangle occasionally makes mistakes due\n");
3198  printf(
3199 " to floating-point roundoff error. Although these errors are rare,\n");
3200  printf(
3201 " don't use the -X switch. If you still have problems, please report the\n"
3202 );
3203  printf(" bug.\n\n");
3204  printf(
3205 " `Triangle executes without incident, but when I look at the resulting\n");
3206  printf(" Voronoi diagram, it has overlapping edges or other geometric\n");
3207  printf(" inconsistencies.'\n");
3208  printf("\n");
3209  printf(
3210 " If your input is a PSLG (-p), you can only expect a meaningful Voronoi\n"
3211 );
3212  printf(
3213 " diagram if the domain you are triangulating is convex and free of\n");
3214  printf(
3215 " holes, and you use the -D switch to construct a conforming Delaunay\n");
3216  printf(" triangulation (instead of a CDT or CCDT).\n\n");
3217  printf(
3218 " Strange things can happen if you've taken liberties with your PSLG. Do\n");
3219  printf(
3220 " you have a vertex lying in the middle of a segment? Triangle sometimes\n");
3221  printf(
3222 " copes poorly with that sort of thing. Do you want to lay out a collinear\n"
3223 );
3224  printf(
3225 " row of evenly spaced, segment-connected vertices? Have you simply\n");
3226  printf(
3227 " defined one long segment connecting the leftmost vertex to the rightmost\n"
3228 );
3229  printf(
3230 " vertex, and a bunch of vertices lying along it? This method occasionally\n"
3231 );
3232  printf(
3233 " works, especially with horizontal and vertical lines, but often it\n");
3234  printf(
3235 " doesn't, and you'll have to connect each adjacent pair of vertices with a\n"
3236 );
3237  printf(" separate segment. If you don't like it, tough.\n\n");
3238  printf(
3239 " Furthermore, if you have segments that intersect other than at their\n");
3240  printf(
3241 " endpoints, try not to let the intersections fall extremely close to PSLG\n"
3242 );
3243  printf(" vertices or each other.\n\n");
3244  printf(
3245 " If you have problems refining a triangulation not produced by Triangle:\n");
3246  printf(
3247 " Are you sure the triangulation is geometrically valid? Is it formatted\n");
3248  printf(
3249 " correctly for Triangle? Are the triangles all listed so the first three\n"
3250 );
3251  printf(
3252 " vertices are their corners in counterclockwise order? Are all of the\n");
3253  printf(
3254 " triangles constrained Delaunay? Triangle's Delaunay refinement algorithm\n"
3255 );
3256  printf(" assumes that it starts with a CDT.\n\n");
3257  printf("Show Me:\n\n");
3258  printf(
3259 " Triangle comes with a separate program named `Show Me', whose primary\n");
3260  printf(
3261 " purpose is to draw meshes on your screen or in PostScript. Its secondary\n"
3262 );
3263  printf(
3264 " purpose is to check the validity of your input files, and do so more\n");
3265  printf(
3266 " thoroughly than Triangle does. Unlike Triangle, Show Me requires that\n");
3267  printf(
3268 " you have the X Windows system. Sorry, Microsoft Windows users.\n");
3269  printf("\n");
3270  printf("Triangle on the Web:\n");
3271  printf("\n");
3272  printf(" To see an illustrated version of these instructions, check out\n");
3273  printf("\n");
3274  printf(" http://www.cs.cmu.edu/~quake/triangle.html\n");
3275  printf("\n");
3276  printf("A Brief Plea:\n");
3277  printf("\n");
3278  printf(
3279 " If you use Triangle, and especially if you use it to accomplish real\n");
3280  printf(
3281 " work, I would like very much to hear from you. A short letter or email\n");
3282  printf(
3283 " (to jrs@cs.berkeley.edu) describing how you use Triangle will mean a lot\n"
3284 );
3285  printf(
3286 " to me. The more people I know are using this program, the more easily I\n"
3287 );
3288  printf(
3289 " can justify spending time on improvements, which in turn will benefit\n");
3290  printf(
3291 " you. Also, I can put you on a list to receive email whenever a new\n");
3292  printf(" version of Triangle is available.\n\n");
3293  printf(
3294 " If you use a mesh generated by Triangle in a publication, please include\n"
3295 );
3296  printf(
3297 " an acknowledgment as well. And please spell Triangle with a capital `T'!\n"
3298 );
3299  printf(
3300 " If you want to include a citation, use `Jonathan Richard Shewchuk,\n");
3301  printf(
3302 " ``Triangle: Engineering a 2D Quality Mesh Generator and Delaunay\n");
3303  printf(
3304 " Triangulator,'' in Applied Computational Geometry: Towards Geometric\n");
3305  printf(
3306 " Engineering (Ming C. Lin and Dinesh Manocha, editors), volume 1148 of\n");
3307  printf(
3308 " Lecture Notes in Computer Science, pages 203-222, Springer-Verlag,\n");
3309  printf(
3310 " Berlin, May 1996. (From the First ACM Workshop on Applied Computational\n"
3311 );
3312  printf(" Geometry.)'\n\n");
3313  printf("Research credit:\n\n");
3314  printf(
3315 " Of course, I can take credit for only a fraction of the ideas that made\n");
3316  printf(
3317 " this mesh generator possible. Triangle owes its existence to the efforts\n"
3318 );
3319  printf(
3320 " of many fine computational geometers and other researchers, including\n");
3321  printf(
3322 " Marshall Bern, L. Paul Chew, Kenneth L. Clarkson, Boris Delaunay, Rex A.\n"
3323 );
3324  printf(
3325 " Dwyer, David Eppstein, Steven Fortune, Leonidas J. Guibas, Donald E.\n");
3326  printf(
3327 " Knuth, Charles L. Lawson, Der-Tsai Lee, Gary L. Miller, Ernst P. Mucke,\n");
3328  printf(
3329 " Steven E. Pav, Douglas M. Priest, Jim Ruppert, Isaac Saias, Bruce J.\n");
3330  printf(
3331 " Schachter, Micha Sharir, Peter W. Shor, Daniel D. Sleator, Jorge Stolfi,\n"
3332 );
3333  printf(" Robert E. Tarjan, Alper Ungor, Christopher J. Van Wyk, Noel J.\n");
3334  printf(
3335 " Walkington, and Binhai Zhu. See the comments at the beginning of the\n");
3336  printf(" source code for references.\n\n");
3337  triexit(0);
3338 }
3339 
3340 #endif /* not TRILIBRARY */
3341 
3342 /*****************************************************************************/
3343 /* */
3344 /* internalerror() Ask the user to send me the defective product. Exit. */
3345 /* */
3346 /*****************************************************************************/
3347 
3348 void internalerror()
3349 {
3350  printf(" Please report this bug to jrs@cs.berkeley.edu\n");
3351  printf(" Include the message above, your input data set, and the exact\n");
3352  printf(" command line you used to run Triangle.\n");
3353  triexit(1);
3354 }
3355 
3356 /*****************************************************************************/
3357 /* */
3358 /* parsecommandline() Read the command line, identify switches, and set */
3359 /* up options and file names. */
3360 /* */
3361 /*****************************************************************************/
3362 
3363 #ifdef ANSI_DECLARATORS
3364 void parsecommandline(int argc, char **argv, struct behavior *b)
3365 #else /* not ANSI_DECLARATORS */
3366 void parsecommandline(argc, argv, b)
3367 int argc;
3368 char **argv;
3369 struct behavior *b;
3370 #endif /* not ANSI_DECLARATORS */
3371 
3372 {
3373 #ifdef TRILIBRARY
3374 #define STARTINDEX 0
3375 #else /* not TRILIBRARY */
3376 #define STARTINDEX 1
3377  int increment;
3378  int meshnumber;
3379 #endif /* not TRILIBRARY */
3380  int i, j, k;
3381  char workstring[FILENAMESIZE];
3382 
3383  b->poly = b->refine = b->quality = 0;
3384  b->vararea = b->fixedarea = b->usertest = 0;
3385  b->regionattrib = b->convex = b->weighted = b->jettison = 0;
3386  b->firstnumber = 1;
3387  b->edgesout = b->voronoi = b->neighbors = b->geomview = 0;
3388  b->nobound = b->nopolywritten = b->nonodewritten = b->noelewritten = 0;
3389  b->noiterationnum = 0;
3390  b->noholes = b->noexact = 0;
3391  b->incremental = b->sweepline = 0;
3392  b->dwyer = 1;
3393  b->splitseg = 0;
3394  b->docheck = 0;
3395  b->nobisect = 0;
3396  b->conformdel = 0;
3397  b->steiner = -1;
3398  b->order = 1;
3399  b->minangle = 0.0;
3400  b->maxarea = -1.0;
3401  b->quiet = b->verbose = 0;
3402 #ifndef TRILIBRARY
3403  b->innodefilename[0] = '\0';
3404 #endif /* not TRILIBRARY */
3405 
3406  for (i = STARTINDEX; i < argc; i++) {
3407 #ifndef TRILIBRARY
3408  if (argv[i][0] == '-') {
3409 #endif /* not TRILIBRARY */
3410  for (j = STARTINDEX; argv[i][j] != '\0'; j++) {
3411  if (argv[i][j] == 'p') {
3412  b->poly = 1;
3413  }
3414 #ifndef CDT_ONLY
3415  if (argv[i][j] == 'r') {
3416  b->refine = 1;
3417  }
3418  if (argv[i][j] == 'q') {
3419  b->quality = 1;
3420  if (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) ||
3421  (argv[i][j + 1] == '.')) {
3422  k = 0;
3423  while (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) ||
3424  (argv[i][j + 1] == '.')) {
3425  j++;
3426  workstring[k] = argv[i][j];
3427  k++;
3428  }
3429  workstring[k] = '\0';
3430  b->minangle = (REAL) strtod(workstring, (char **) NULL);
3431  } else {
3432  b->minangle = 20.0;
3433  }
3434  }
3435  if (argv[i][j] == 'a') {
3436  b->quality = 1;
3437  if (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) ||
3438  (argv[i][j + 1] == '.')) {
3439  b->fixedarea = 1;
3440  k = 0;
3441  while (((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) ||
3442  (argv[i][j + 1] == '.')) {
3443  j++;
3444  workstring[k] = argv[i][j];
3445  k++;
3446  }
3447  workstring[k] = '\0';
3448  b->maxarea = (REAL) strtod(workstring, (char **) NULL);
3449  if (b->maxarea <= 0.0) {
3450  printf("Error: Maximum area must be greater than zero.\n");
3451  triexit(1);
3452  }
3453  } else {
3454  b->vararea = 1;
3455  }
3456  }
3457  if (argv[i][j] == 'u') {
3458  b->quality = 1;
3459  b->usertest = 1;
3460  }
3461 #endif /* not CDT_ONLY */
3462  if (argv[i][j] == 'A') {
3463  b->regionattrib = 1;
3464  }
3465  if (argv[i][j] == 'c') {
3466  b->convex = 1;
3467  }
3468  if (argv[i][j] == 'w') {
3469  b->weighted = 1;
3470  }
3471  if (argv[i][j] == 'W') {
3472  b->weighted = 2;
3473  }
3474  if (argv[i][j] == 'j') {
3475  b->jettison = 1;
3476  }
3477  if (argv[i][j] == 'z') {
3478  b->firstnumber = 0;
3479  }
3480  if (argv[i][j] == 'e') {
3481  b->edgesout = 1;
3482  }
3483  if (argv[i][j] == 'v') {
3484  b->voronoi = 1;
3485  }
3486  if (argv[i][j] == 'n') {
3487  b->neighbors = 1;
3488  }
3489  if (argv[i][j] == 'g') {
3490  b->geomview = 1;
3491  }
3492  if (argv[i][j] == 'B') {
3493  b->nobound = 1;
3494  }
3495  if (argv[i][j] == 'P') {
3496  b->nopolywritten = 1;
3497  }
3498  if (argv[i][j] == 'N') {
3499  b->nonodewritten = 1;
3500  }
3501  if (argv[i][j] == 'E') {
3502  b->noelewritten = 1;
3503  }
3504 #ifndef TRILIBRARY
3505  if (argv[i][j] == 'I') {
3506  b->noiterationnum = 1;
3507  }
3508 #endif /* not TRILIBRARY */
3509  if (argv[i][j] == 'O') {
3510  b->noholes = 1;
3511  }
3512  if (argv[i][j] == 'X') {
3513  b->noexact = 1;
3514  }
3515  if (argv[i][j] == 'o') {
3516  if (argv[i][j + 1] == '2') {
3517  j++;
3518  b->order = 2;
3519  }
3520  }
3521 #ifndef CDT_ONLY
3522  if (argv[i][j] == 'Y') {
3523  b->nobisect++;
3524  }
3525  if (argv[i][j] == 'S') {
3526  b->steiner = 0;
3527  while ((argv[i][j + 1] >= '0') && (argv[i][j + 1] <= '9')) {
3528  j++;
3529  b->steiner = b->steiner * 10 + (int) (argv[i][j] - '0');
3530  }
3531  }
3532 #endif /* not CDT_ONLY */
3533 #ifndef REDUCED
3534  if (argv[i][j] == 'i') {
3535  b->incremental = 1;
3536  }
3537  if (argv[i][j] == 'F') {
3538  b->sweepline = 1;
3539  }
3540 #endif /* not REDUCED */
3541  if (argv[i][j] == 'l') {
3542  b->dwyer = 0;
3543  }
3544 #ifndef REDUCED
3545 #ifndef CDT_ONLY
3546  if (argv[i][j] == 's') {
3547  b->splitseg = 1;
3548  }
3549  if ((argv[i][j] == 'D') || (argv[i][j] == 'L')) {
3550  b->quality = 1;
3551  b->conformdel = 1;
3552  }
3553 #endif /* not CDT_ONLY */
3554  if (argv[i][j] == 'C') {
3555  b->docheck = 1;
3556  }
3557 #endif /* not REDUCED */
3558  if (argv[i][j] == 'Q') {
3559  b->quiet = 1;
3560  }
3561  if (argv[i][j] == 'V') {
3562  b->verbose++;
3563  }
3564 #ifndef TRILIBRARY
3565  if ((argv[i][j] == 'h') || (argv[i][j] == 'H') ||
3566  (argv[i][j] == '?')) {
3567  info();
3568  }
3569 #endif /* not TRILIBRARY */
3570  }
3571 #ifndef TRILIBRARY
3572  } else {
3573  strncpy(b->innodefilename, argv[i], FILENAMESIZE - 1);
3574  b->innodefilename[FILENAMESIZE - 1] = '\0';
3575  }
3576 #endif /* not TRILIBRARY */
3577  }
3578 #ifndef TRILIBRARY
3579  if (b->innodefilename[0] == '\0') {
3580  syntax();
3581  }
3582  if (!strcmp(&b->innodefilename[strlen(b->innodefilename) - 5], ".node")) {
3583  b->innodefilename[strlen(b->innodefilename) - 5] = '\0';
3584  }
3585  if (!strcmp(&b->innodefilename[strlen(b->innodefilename) - 5], ".poly")) {
3586  b->innodefilename[strlen(b->innodefilename) - 5] = '\0';
3587  b->poly = 1;
3588  }
3589 #ifndef CDT_ONLY
3590  if (!strcmp(&b->innodefilename[strlen(b->innodefilename) - 4], ".ele")) {
3591  b->innodefilename[strlen(b->innodefilename) - 4] = '\0';
3592  b->refine = 1;
3593  }
3594  if (!strcmp(&b->innodefilename[strlen(b->innodefilename) - 5], ".area")) {
3595  b->innodefilename[strlen(b->innodefilename) - 5] = '\0';
3596  b->refine = 1;
3597  b->quality = 1;
3598  b->vararea = 1;
3599  }
3600 #endif /* not CDT_ONLY */
3601 #endif /* not TRILIBRARY */
3602  b->usesegments = b->poly || b->refine || b->quality || b->convex;
3603  b->goodangle = cos(b->minangle * PI / 180.0);
3604  if (b->goodangle == 1.0) {
3605  b->offconstant = 0.0;
3606  } else {
3607  b->offconstant = 0.475 * sqrt((1.0 + b->goodangle) / (1.0 - b->goodangle));
3608  }
3609  b->goodangle *= b->goodangle;
3610  if (b->refine && b->noiterationnum) {
3611  printf(
3612  "Error: You cannot use the -I switch when refining a triangulation.\n");
3613  triexit(1);
3614  }
3615  /* Be careful not to allocate space for element area constraints that */
3616  /* will never be assigned any value (other than the default -1.0). */
3617  if (!b->refine && !b->poly) {
3618  b->vararea = 0;
3619  }
3620  /* Be careful not to add an extra attribute to each element unless the */
3621  /* input supports it (PSLG in, but not refining a preexisting mesh). */
3622  if (b->refine || !b->poly) {
3623  b->regionattrib = 0;
3624  }
3625  /* Regular/weighted triangulations are incompatible with PSLGs */
3626  /* and meshing. */
3627  if (b->weighted && (b->poly || b->quality)) {
3628  b->weighted = 0;
3629  if (!b->quiet) {
3630  printf("Warning: weighted triangulations (-w, -W) are incompatible\n");
3631  printf(" with PSLGs (-p) and meshing (-q, -a, -u). Weights ignored.\n"
3632  );
3633  }
3634  }
3635  if (b->jettison && b->nonodewritten && !b->quiet) {
3636  printf("Warning: -j and -N switches are somewhat incompatible.\n");
3637  printf(" If any vertices are jettisoned, you will need the output\n");
3638  printf(" .node file to reconstruct the new node indices.");
3639  }
3640 
3641 #ifndef TRILIBRARY
3642  strcpy(b->inpolyfilename, b->innodefilename);
3643  strcpy(b->inelefilename, b->innodefilename);
3644  strcpy(b->areafilename, b->innodefilename);
3645  increment = 0;
3646  strcpy(workstring, b->innodefilename);
3647  j = 1;
3648  while (workstring[j] != '\0') {
3649  if ((workstring[j] == '.') && (workstring[j + 1] != '\0')) {
3650  increment = j + 1;
3651  }
3652  j++;
3653  }
3654  meshnumber = 0;
3655  if (increment > 0) {
3656  j = increment;
3657  do {
3658  if ((workstring[j] >= '0') && (workstring[j] <= '9')) {
3659  meshnumber = meshnumber * 10 + (int) (workstring[j] - '0');
3660  } else {
3661  increment = 0;
3662  }
3663  j++;
3664  } while (workstring[j] != '\0');
3665  }
3666  if (b->noiterationnum) {
3667  strcpy(b->outnodefilename, b->innodefilename);
3668  strcpy(b->outelefilename, b->innodefilename);
3669  strcpy(b->edgefilename, b->innodefilename);
3670  strcpy(b->vnodefilename, b->innodefilename);
3671  strcpy(b->vedgefilename, b->innodefilename);
3672  strcpy(b->neighborfilename, b->innodefilename);
3673  strcpy(b->offfilename, b->innodefilename);
3674  strcat(b->outnodefilename, ".node");
3675  strcat(b->outelefilename, ".ele");
3676  strcat(b->edgefilename, ".edge");
3677  strcat(b->vnodefilename, ".v.node");
3678  strcat(b->vedgefilename, ".v.edge");
3679  strcat(b->neighborfilename, ".neigh");
3680  strcat(b->offfilename, ".off");
3681  } else if (increment == 0) {
3682  strcpy(b->outnodefilename, b->innodefilename);
3683  strcpy(b->outpolyfilename, b->innodefilename);
3684  strcpy(b->outelefilename, b->innodefilename);
3685  strcpy(b->edgefilename, b->innodefilename);
3686  strcpy(b->vnodefilename, b->innodefilename);
3687  strcpy(b->vedgefilename, b->innodefilename);
3688  strcpy(b->neighborfilename, b->innodefilename);
3689  strcpy(b->offfilename, b->innodefilename);
3690  strcat(b->outnodefilename, ".1.node");
3691  strcat(b->outpolyfilename, ".1.poly");
3692  strcat(b->outelefilename, ".1.ele");
3693  strcat(b->edgefilename, ".1.edge");
3694  strcat(b->vnodefilename, ".1.v.node");
3695  strcat(b->vedgefilename, ".1.v.edge");
3696  strcat(b->neighborfilename, ".1.neigh");
3697  strcat(b->offfilename, ".1.off");
3698  } else {
3699  workstring[increment] = '%';
3700  workstring[increment + 1] = 'd';
3701  workstring[increment + 2] = '\0';
3702  sprintf(b->outnodefilename, workstring, meshnumber + 1);
3703  strcpy(b->outpolyfilename, b->outnodefilename);
3704  strcpy(b->outelefilename, b->outnodefilename);
3705  strcpy(b->edgefilename, b->outnodefilename);
3706  strcpy(b->vnodefilename, b->outnodefilename);
3707  strcpy(b->vedgefilename, b->outnodefilename);
3708  strcpy(b->neighborfilename, b->outnodefilename);
3709  strcpy(b->offfilename, b->outnodefilename);
3710  strcat(b->outnodefilename, ".node");
3711  strcat(b->outpolyfilename, ".poly");
3712  strcat(b->outelefilename, ".ele");
3713  strcat(b->edgefilename, ".edge");
3714  strcat(b->vnodefilename, ".v.node");
3715  strcat(b->vedgefilename, ".v.edge");
3716  strcat(b->neighborfilename, ".neigh");
3717  strcat(b->offfilename, ".off");
3718  }
3719  strcat(b->innodefilename, ".node");
3720  strcat(b->inpolyfilename, ".poly");
3721  strcat(b->inelefilename, ".ele");
3722  strcat(b->areafilename, ".area");
3723 #endif /* not TRILIBRARY */
3724 }
3725 
3728 /********* User interaction routines begin here *********/
3729 
3730 /********* Debugging routines begin here *********/
3734 /*****************************************************************************/
3735 /* */
3736 /* printtriangle() Print out the details of an oriented triangle. */
3737 /* */
3738 /* I originally wrote this procedure to simplify debugging; it can be */
3739 /* called directly from the debugger, and presents information about an */
3740 /* oriented triangle in digestible form. It's also used when the */
3741 /* highest level of verbosity (`-VVV') is specified. */
3742 /* */
3743 /*****************************************************************************/
3744 
3745 #ifdef ANSI_DECLARATORS
3746 void printtriangle(struct mesh *m, struct behavior *b, struct otri *t)
3747 #else /* not ANSI_DECLARATORS */
3748 void printtriangle(m, b, t)
3749 struct mesh *m;
3750 struct behavior *b;
3751 struct otri *t;
3752 #endif /* not ANSI_DECLARATORS */
3753 
3754 {
3755  struct otri printtri;
3756  struct osub printsh;
3757  vertex printvertex;
3758 
3759  printf("triangle x%lx with orientation %d:\n", (unsigned long) t->tri,
3760  t->orient);
3761  decode(t->tri[0], printtri);
3762  if (printtri.tri == m->dummytri) {
3763  printf(" [0] = Outer space\n");
3764  } else {
3765  printf(" [0] = x%lx %d\n", (unsigned long) printtri.tri,
3766  printtri.orient);
3767  }
3768  decode(t->tri[1], printtri);
3769  if (printtri.tri == m->dummytri) {
3770  printf(" [1] = Outer space\n");
3771  } else {
3772  printf(" [1] = x%lx %d\n", (unsigned long) printtri.tri,
3773  printtri.orient);
3774  }
3775  decode(t->tri[2], printtri);
3776  if (printtri.tri == m->dummytri) {
3777  printf(" [2] = Outer space\n");
3778  } else {
3779  printf(" [2] = x%lx %d\n", (unsigned long) printtri.tri,
3780  printtri.orient);
3781  }
3782 
3783  org(*t, printvertex);
3784  if (printvertex == (vertex) NULL)
3785  printf(" Origin[%d] = NULL\n", (t->orient + 1) % 3 + 3);
3786  else
3787  printf(" Origin[%d] = x%lx (%.12g, %.12g)\n",
3788  (t->orient + 1) % 3 + 3, (unsigned long) printvertex,
3789  printvertex[0], printvertex[1]);
3790  dest(*t, printvertex);
3791  if (printvertex == (vertex) NULL)
3792  printf(" Dest [%d] = NULL\n", (t->orient + 2) % 3 + 3);
3793  else
3794  printf(" Dest [%d] = x%lx (%.12g, %.12g)\n",
3795  (t->orient + 2) % 3 + 3, (unsigned long) printvertex,
3796  printvertex[0], printvertex[1]);
3797  apex(*t, printvertex);
3798  if (printvertex == (vertex) NULL)
3799  printf(" Apex [%d] = NULL\n", t->orient + 3);
3800  else
3801  printf(" Apex [%d] = x%lx (%.12g, %.12g)\n",
3802  t->orient + 3, (unsigned long) printvertex,
3803  printvertex[0], printvertex[1]);
3804 
3805  if (b->usesegments) {
3806  sdecode(t->tri[6], printsh);
3807  if (printsh.ss != m->dummysub) {
3808  printf(" [6] = x%lx %d\n", (unsigned long) printsh.ss,
3809  printsh.ssorient);
3810  }
3811  sdecode(t->tri[7], printsh);
3812  if (printsh.ss != m->dummysub) {
3813  printf(" [7] = x%lx %d\n", (unsigned long) printsh.ss,
3814  printsh.ssorient);
3815  }
3816  sdecode(t->tri[8], printsh);
3817  if (printsh.ss != m->dummysub) {
3818  printf(" [8] = x%lx %d\n", (unsigned long) printsh.ss,
3819  printsh.ssorient);
3820  }
3821  }
3822 
3823  if (b->vararea) {
3824  printf(" Area constraint: %.4g\n", areabound(*t));
3825  }
3826 }
3827 
3828 /*****************************************************************************/
3829 /* */
3830 /* printsubseg() Print out the details of an oriented subsegment. */
3831 /* */
3832 /* I originally wrote this procedure to simplify debugging; it can be */
3833 /* called directly from the debugger, and presents information about an */
3834 /* oriented subsegment in digestible form. It's also used when the highest */
3835 /* level of verbosity (`-VVV') is specified. */
3836 /* */
3837 /*****************************************************************************/
3838 
3839 #ifdef ANSI_DECLARATORS
3840 void printsubseg(struct mesh *m, struct behavior *b, struct osub *s)
3841 #else /* not ANSI_DECLARATORS */
3842 void printsubseg(m, b, s)
3843 struct mesh *m;
3844 struct behavior *b;
3845 struct osub *s;
3846 #endif /* not ANSI_DECLARATORS */
3847 
3848 {
3849  struct osub printsh;
3850  struct otri printtri;
3851  vertex printvertex;
3852 
3853  printf("subsegment x%lx with orientation %d and mark %d:\n",
3854  (unsigned long) s->ss, s->ssorient, mark(*s));
3855  sdecode(s->ss[0], printsh);
3856  if (printsh.ss == m->dummysub) {
3857  printf(" [0] = No subsegment\n");
3858  } else {
3859  printf(" [0] = x%lx %d\n", (unsigned long) printsh.ss,
3860  printsh.ssorient);
3861  }
3862  sdecode(s->ss[1], printsh);
3863  if (printsh.ss == m->dummysub) {
3864  printf(" [1] = No subsegment\n");
3865  } else {
3866  printf(" [1] = x%lx %d\n", (unsigned long) printsh.ss,
3867  printsh.ssorient);
3868  }
3869 
3870  sorg(*s, printvertex);
3871  if (printvertex == (vertex) NULL)
3872  printf(" Origin[%d] = NULL\n", 2 + s->ssorient);
3873  else
3874  printf(" Origin[%d] = x%lx (%.12g, %.12g)\n",
3875  2 + s->ssorient, (unsigned long) printvertex,
3876  printvertex[0], printvertex[1]);
3877  sdest(*s, printvertex);
3878  if (printvertex == (vertex) NULL)
3879  printf(" Dest [%d] = NULL\n", 3 - s->ssorient);
3880  else
3881  printf(" Dest [%d] = x%lx (%.12g, %.12g)\n",
3882  3 - s->ssorient, (unsigned long) printvertex,
3883  printvertex[0], printvertex[1]);
3884 
3885  decode(s->ss[6], printtri);
3886  if (printtri.tri == m->dummytri) {
3887  printf(" [6] = Outer space\n");
3888  } else {
3889  printf(" [6] = x%lx %d\n", (unsigned long) printtri.tri,
3890  printtri.orient);
3891  }
3892  decode(s->ss[7], printtri);
3893  if (printtri.tri == m->dummytri) {
3894  printf(" [7] = Outer space\n");
3895  } else {
3896  printf(" [7] = x%lx %d\n", (unsigned long) printtri.tri,
3897  printtri.orient);
3898  }
3899 
3900  segorg(*s, printvertex);
3901  if (printvertex == (vertex) NULL)
3902  printf(" Segment origin[%d] = NULL\n", 4 + s->ssorient);
3903  else
3904  printf(" Segment origin[%d] = x%lx (%.12g, %.12g)\n",
3905  4 + s->ssorient, (unsigned long) printvertex,
3906  printvertex[0], printvertex[1]);
3907  segdest(*s, printvertex);
3908  if (printvertex == (vertex) NULL)
3909  printf(" Segment dest [%d] = NULL\n", 5 - s->ssorient);
3910  else
3911  printf(" Segment dest [%d] = x%lx (%.12g, %.12g)\n",
3912  5 - s->ssorient, (unsigned long) printvertex,
3913  printvertex[0], printvertex[1]);
3914 }
3915 
3918 /********* Debugging routines end here *********/
3919 
3920 /********* Memory management routines begin here *********/
3924 /*****************************************************************************/
3925 /* */
3926 /* poolzero() Set all of a pool's fields to zero. */
3927 /* */
3928 /* This procedure should never be called on a pool that has any memory */
3929 /* allocated to it, as that memory would leak. */
3930 /* */
3931 /*****************************************************************************/
3932 
3933 #ifdef ANSI_DECLARATORS
3934 void poolzero(struct memorypool* pool)
3935 #else /* not ANSI_DECLARATORS */
3936 void poolzero(pool)
3937 struct memorypool* pool;
3938 #endif /* not ANSI_DECLARATORS */
3939 
3940 {
3941  pool->firstblock = (VOID **) NULL;
3942  pool->nowblock = (VOID **) NULL;
3943  pool->nextitem = (VOID *) NULL;
3944  pool->deaditemstack = (VOID *) NULL;
3945  pool->pathblock = (VOID **) NULL;
3946  pool->pathitem = (VOID *) NULL;
3947  pool->alignbytes = 0;
3948  pool->itembytes = 0;
3949  pool->itemsperblock = 0;
3950  pool->itemsfirstblock = 0;
3951  pool->items = 0;
3952  pool->maxitems = 0;
3953  pool->unallocateditems = 0;
3954  pool->pathitemsleft = 0;
3955 }
3956 
3957 /*****************************************************************************/
3958 /* */
3959 /* poolrestart() Deallocate all items in a pool. */
3960 /* */
3961 /* The pool is returned to its starting state, except that no memory is */
3962 /* freed to the operating system. Rather, the previously allocated blocks */
3963 /* are ready to be reused. */
3964 /* */
3965 /*****************************************************************************/
3966 
3967 #ifdef ANSI_DECLARATORS
3968 void poolrestart(struct memorypool* pool)
3969 #else /* not ANSI_DECLARATORS */
3970 void poolrestart(pool)
3971 struct memorypool* pool;
3972 #endif /* not ANSI_DECLARATORS */
3973 
3974 {
3975  unsigned long alignptr;
3976 
3977  pool->items = 0;
3978  pool->maxitems = 0;
3979 
3980  /* Set the currently active block. */
3981  pool->nowblock = pool->firstblock;
3982  /* Find the first item in the pool. Increment by the size of (VOID *). */
3983  alignptr = (unsigned long) (pool->nowblock + 1);
3984  /* Align the item on an `alignbytes'-byte boundary. */
3985  pool->nextitem = (VOID *)
3986  (alignptr + (unsigned long) pool->alignbytes -
3987  (alignptr % (unsigned long) pool->alignbytes));
3988  /* There are lots of unallocated items left in this block. */
3989  pool->unallocateditems = pool->itemsfirstblock;
3990  /* The stack of deallocated items is empty. */
3991  pool->deaditemstack = (VOID *) NULL;
3992 }
3993 
3994 /*****************************************************************************/
3995 /* */
3996 /* poolinit() Initialize a pool of memory for allocation of items. */
3997 /* */
3998 /* This routine initializes the machinery for allocating items. A `pool' */
3999 /* is created whose records have size at least `bytecount'. Items will be */
4000 /* allocated in `itemcount'-item blocks. Each item is assumed to be a */
4001 /* collection of words, and either pointers or floating-point values are */
4002 /* assumed to be the "primary" word type. (The "primary" word type is used */
4003 /* to determine alignment of items.) If `alignment' isn't zero, all items */
4004 /* will be `alignment'-byte aligned in memory. `alignment' must be either */
4005 /* a multiple or a factor of the primary word size; powers of two are safe. */
4006 /* `alignment' is normally used to create a few unused bits at the bottom */
4007 /* of each item's pointer, in which information may be stored. */
4008 /* */
4009 /* Don't change this routine unless you understand it. */
4010 /* */
4011 /*****************************************************************************/
4012 
4013 #ifdef ANSI_DECLARATORS
4014 void poolinit(struct memorypool* pool, int bytecount, int itemcount,
4015  int firstitemcount, unsigned alignment)
4016 #else /* not ANSI_DECLARATORS */
4017 void poolinit(pool, bytecount, itemcount, firstitemcount, alignment)
4018 struct memorypool* pool;
4019 int bytecount;
4020 int itemcount;
4021 int firstitemcount;
4022 unsigned alignment;
4023 #endif /* not ANSI_DECLARATORS */
4024 
4025 {
4026  /* Find the proper alignment, which must be at least as large as: */
4027  /* - The parameter `alignment'. */
4028  /* - sizeof(VOID *), so the stack of dead items can be maintained */
4029  /* without unaligned accesses. */
4030  if (alignment > sizeof(VOID *)) {
4031  pool->alignbytes = alignment;
4032  } else {
4033  pool->alignbytes = sizeof(VOID *);
4034  }
4035  pool->itembytes = ((bytecount - 1) / pool->alignbytes + 1) *
4036  pool->alignbytes;
4037  pool->itemsperblock = itemcount;
4038  if (firstitemcount == 0) {
4039  pool->itemsfirstblock = itemcount;
4040  } else {
4041  pool->itemsfirstblock = firstitemcount;
4042  }
4043 
4044  /* Allocate a block of items. Space for `itemsfirstblock' items and one */
4045  /* pointer (to point to the next block) are allocated, as well as space */
4046  /* to ensure alignment of the items. */
4047  pool->firstblock = (VOID **)
4048  trimalloc(pool->itemsfirstblock * pool->itembytes + (int) sizeof(VOID *) +
4049  pool->alignbytes);
4050  /* Set the next block pointer to NULL. */
4051  *(pool->firstblock) = (VOID *) NULL;
4052  poolrestart(pool);
4053 }
4054 
4055 /*****************************************************************************/
4056 /* */
4057 /* pooldeinit() Free to the operating system all memory taken by a pool. */
4058 /* */
4059 /*****************************************************************************/
4060 
4061 #ifdef ANSI_DECLARATORS
4062 void pooldeinit(struct memorypool* pool)
4063 #else /* not ANSI_DECLARATORS */
4064 void pooldeinit(pool)
4065 struct memorypool* pool;
4066 #endif /* not ANSI_DECLARATORS */
4067 
4068 {
4069  while (pool->firstblock != (VOID **) NULL) {
4070  pool->nowblock = (VOID **) *(pool->firstblock);
4071  trifree((VOID *) pool->firstblock);
4072  pool->firstblock = pool->nowblock;
4073  }
4074 }
4075 
4076 /*****************************************************************************/
4077 /* */
4078 /* poolalloc() Allocate space for an item. */
4079 /* */
4080 /*****************************************************************************/
4081 
4082 #ifdef ANSI_DECLARATORS
4083 VOID* poolalloc(struct memorypool* pool)
4084 #else /* not ANSI_DECLARATORS */
4085 VOID* poolalloc(pool)
4086 struct memorypool* pool;
4087 #endif /* not ANSI_DECLARATORS */
4088 
4089 {
4090  VOID *newitem;
4091  VOID **newblock;
4092  unsigned long alignptr;
4093 
4094  /* First check the linked list of dead items. If the list is not */
4095  /* empty, allocate an item from the list rather than a fresh one. */
4096  if (pool->deaditemstack != (VOID *) NULL) {
4097  newitem = pool->deaditemstack; /* Take first item in list. */
4098  pool->deaditemstack = * (VOID **) pool->deaditemstack;
4099  } else {
4100  /* Check if there are any free items left in the current block. */
4101  if (pool->unallocateditems == 0) {
4102  /* Check if another block must be allocated. */
4103  if (*(pool->nowblock) == (VOID *) NULL) {
4104  /* Allocate a new block of items, pointed to by the previous block. */
4105  newblock = (VOID **) trimalloc(pool->itemsperblock * pool->itembytes +
4106  (int) sizeof(VOID *) +
4107  pool->alignbytes);
4108  *(pool->nowblock) = (VOID *) newblock;
4109  /* The next block pointer is NULL. */
4110  *newblock = (VOID *) NULL;
4111  }
4112 
4113  /* Move to the new block. */
4114  pool->nowblock = (VOID **) *(pool->nowblock);
4115  /* Find the first item in the block. */
4116  /* Increment by the size of (VOID *). */
4117  alignptr = (unsigned long) (pool->nowblock + 1);
4118  /* Align the item on an `alignbytes'-byte boundary. */
4119  pool->nextitem = (VOID *)
4120  (alignptr + (unsigned long) pool->alignbytes -
4121  (alignptr % (unsigned long) pool->alignbytes));
4122  /* There are lots of unallocated items left in this block. */
4123  pool->unallocateditems = pool->itemsperblock;
4124  }
4125 
4126  /* Allocate a new item. */
4127  newitem = pool->nextitem;
4128  /* Advance `nextitem' pointer to next free item in block. */
4129  pool->nextitem = (VOID *) ((char *) pool->nextitem + pool->itembytes);
4130  pool->unallocateditems--;
4131  pool->maxitems++;
4132  }
4133  pool->items++;
4134  return newitem;
4135 }
4136 
4137 /*****************************************************************************/
4138 /* */
4139 /* pooldealloc() Deallocate space for an item. */
4140 /* */
4141 /* The deallocated space is stored in a queue for later reuse. */
4142 /* */
4143 /*****************************************************************************/
4144 
4145 #ifdef ANSI_DECLARATORS
4146 void pooldealloc(struct memorypool* pool, VOID *dyingitem)
4147 #else /* not ANSI_DECLARATORS */
4148 void pooldealloc(pool, dyingitem)
4149 struct memorypool* pool;
4150 VOID *dyingitem;
4151 #endif /* not ANSI_DECLARATORS */
4152 
4153 {
4154  /* Push freshly killed item onto stack. */
4155  *((VOID **) dyingitem) = pool->deaditemstack;
4156  pool->deaditemstack = dyingitem;
4157  pool->items--;
4158 }
4159 
4160 /*****************************************************************************/
4161 /* */
4162 /* traversalinit() Prepare to traverse the entire list of items. */
4163 /* */
4164 /* This routine is used in conjunction with traverse(). */
4165 /* */
4166 /*****************************************************************************/
4167 
4168 #ifdef ANSI_DECLARATORS
4169 void traversalinit(struct memorypool* pool)
4170 #else /* not ANSI_DECLARATORS */
4171 void traversalinit(pool)
4172 struct memorypool* pool;
4173 #endif /* not ANSI_DECLARATORS */
4174 
4175 {
4176  unsigned long alignptr;
4177 
4178  /* Begin the traversal in the first block. */
4179  pool->pathblock = pool->firstblock;
4180  /* Find the first item in the block. Increment by the size of (VOID *). */
4181  alignptr = (unsigned long) (pool->pathblock + 1);
4182  /* Align with item on an `alignbytes'-byte boundary. */
4183  pool->pathitem = (VOID *)
4184  (alignptr + (unsigned long) pool->alignbytes -
4185  (alignptr % (unsigned long) pool->alignbytes));
4186  /* Set the number of items left in the current block. */
4187  pool->pathitemsleft = pool->itemsfirstblock;
4188 }
4189 
4190 /*****************************************************************************/
4191 /* */
4192 /* traverse() Find the next item in the list. */
4193 /* */
4194 /* This routine is used in conjunction with traversalinit(). Be forewarned */
4195 /* that this routine successively returns all items in the list, including */
4196 /* deallocated ones on the deaditemqueue. It's up to you to figure out */
4197 /* which ones are actually dead. Why? I don't want to allocate extra */
4198 /* space just to demarcate dead items. It can usually be done more */
4199 /* space-efficiently by a routine that knows something about the structure */
4200 /* of the item. */
4201 /* */
4202 /*****************************************************************************/
4203 
4204 #ifdef ANSI_DECLARATORS
4205 VOID *traverse(struct memorypool* pool)
4206 #else /* not ANSI_DECLARATORS */
4207 VOID *traverse(pool)
4208 struct memorypool* pool;
4209 #endif /* not ANSI_DECLARATORS */
4210 
4211 {
4212  VOID *newitem;
4213  unsigned long alignptr;
4214 
4215  /* Stop upon exhausting the list of items. */
4216  if (pool->pathitem == pool->nextitem) {
4217  return (VOID *) NULL;
4218  }
4219 
4220  /* Check whether any untraversed items remain in the current block. */
4221  if (pool->pathitemsleft == 0) {
4222  /* Find the next block. */
4223  pool->pathblock = (VOID **) *(pool->pathblock);
4224  /* Find the first item in the block. Increment by the size of (VOID *). */
4225  alignptr = (unsigned long) (pool->pathblock + 1);
4226  /* Align with item on an `alignbytes'-byte boundary. */
4227  pool->pathitem = (VOID *)
4228  (alignptr + (unsigned long) pool->alignbytes -
4229  (alignptr % (unsigned long) pool->alignbytes));
4230  /* Set the number of items left in the current block. */
4231  pool->pathitemsleft = pool->itemsperblock;
4232  }
4233 
4234  newitem = pool->pathitem;
4235  /* Find the next item in the block. */
4236  pool->pathitem = (VOID *) ((char *) pool->pathitem + pool->itembytes);
4237  pool->pathitemsleft--;
4238  return newitem;
4239 }
4240 
4241 /*****************************************************************************/
4242 /* */
4243 /* dummyinit() Initialize the triangle that fills "outer space" and the */
4244 /* omnipresent subsegment. */
4245 /* */
4246 /* The triangle that fills "outer space," called `dummytri', is pointed to */
4247 /* by every triangle and subsegment on a boundary (be it outer or inner) of */
4248 /* the triangulation. Also, `dummytri' points to one of the triangles on */
4249 /* the convex hull (until the holes and concavities are carved), making it */
4250 /* possible to find a starting triangle for point location. */
4251 /* */
4252 /* The omnipresent subsegment, `dummysub', is pointed to by every triangle */
4253 /* or subsegment that doesn't have a full complement of real subsegments */
4254 /* to point to. */
4255 /* */
4256 /* `dummytri' and `dummysub' are generally required to fulfill only a few */
4257 /* invariants: their vertices must remain NULL and `dummytri' must always */
4258 /* be bonded (at offset zero) to some triangle on the convex hull of the */
4259 /* mesh, via a boundary edge. Otherwise, the connections of `dummytri' and */
4260 /* `dummysub' may change willy-nilly. This makes it possible to avoid */
4261 /* writing a good deal of special-case code (in the edge flip, for example) */
4262 /* for dealing with the boundary of the mesh, places where no subsegment is */
4263 /* present, and so forth. Other entities are frequently bonded to */
4264 /* `dummytri' and `dummysub' as if they were real mesh entities, with no */
4265 /* harm done. */
4266 /* */
4267 /*****************************************************************************/
4268 
4269 #ifdef ANSI_DECLARATORS
4270 void dummyinit(struct mesh *m, struct behavior *b, int trianglebytes,
4271  int subsegbytes)
4272 #else /* not ANSI_DECLARATORS */
4273 void dummyinit(m, b, trianglebytes, subsegbytes)
4274 struct mesh *m;
4275 struct behavior *b;
4276 int trianglebytes;
4277 int subsegbytes;
4278 #endif /* not ANSI_DECLARATORS */
4279 
4280 {
4281  unsigned long alignptr;
4282 
4283  /* Set up `dummytri', the `triangle' that occupies "outer space." */
4284  m->dummytribase = (triangle *) trimalloc(trianglebytes +
4285  m->triangles.alignbytes);
4286  /* Align `dummytri' on a `triangles.alignbytes'-byte boundary. */
4287  alignptr = (unsigned long) m->dummytribase;
4288  m->dummytri = (triangle *)
4289  (alignptr + (unsigned long) m->triangles.alignbytes -
4290  (alignptr % (unsigned long) m->triangles.alignbytes));
4291  /* Initialize the three adjoining triangles to be "outer space." These */
4292  /* will eventually be changed by various bonding operations, but their */
4293  /* values don't really matter, as long as they can legally be */
4294  /* dereferenced. */
4295  m->dummytri[0] = (triangle) m->dummytri;
4296  m->dummytri[1] = (triangle) m->dummytri;
4297  m->dummytri[2] = (triangle) m->dummytri;
4298  /* Three NULL vertices. */
4299  m->dummytri[3] = (triangle) NULL;
4300  m->dummytri[4] = (triangle) NULL;
4301  m->dummytri[5] = (triangle) NULL;
4302 
4303  if (b->usesegments) {
4304  /* Set up `dummysub', the omnipresent subsegment pointed to by any */
4305  /* triangle side or subsegment end that isn't attached to a real */
4306  /* subsegment. */
4307  m->dummysubbase = (subseg *) trimalloc(subsegbytes +
4308  m->subsegs.alignbytes);
4309  /* Align `dummysub' on a `subsegs.alignbytes'-byte boundary. */
4310  alignptr = (unsigned long) m->dummysubbase;
4311  m->dummysub = (subseg *)
4312  (alignptr + (unsigned long) m->subsegs.alignbytes -
4313  (alignptr % (unsigned long) m->subsegs.alignbytes));
4314  /* Initialize the two adjoining subsegments to be the omnipresent */
4315  /* subsegment. These will eventually be changed by various bonding */
4316  /* operations, but their values don't really matter, as long as they */
4317  /* can legally be dereferenced. */
4318  m->dummysub[0] = (subseg) m->dummysub;
4319  m->dummysub[1] = (subseg) m->dummysub;
4320  /* Four NULL vertices. */
4321  m->dummysub[2] = (subseg) NULL;
4322  m->dummysub[3] = (subseg) NULL;
4323  m->dummysub[4] = (subseg) NULL;
4324  m->dummysub[5] = (subseg) NULL;
4325  /* Initialize the two adjoining triangles to be "outer space." */
4326  m->dummysub[6] = (subseg) m->dummytri;
4327  m->dummysub[7] = (subseg) m->dummytri;
4328  /* Set the boundary marker to zero. */
4329  * (int *) (m->dummysub + 8) = 0;
4330 
4331  /* Initialize the three adjoining subsegments of `dummytri' to be */
4332  /* the omnipresent subsegment. */
4333  m->dummytri[6] = (triangle) m->dummysub;
4334  m->dummytri[7] = (triangle) m->dummysub;
4335  m->dummytri[8] = (triangle) m->dummysub;
4336  }
4337 }
4338 
4339 /*****************************************************************************/
4340 /* */
4341 /* initializevertexpool() Calculate the size of the vertex data structure */
4342 /* and initialize its memory pool. */
4343 /* */
4344 /* This routine also computes the `vertexmarkindex' and `vertex2triindex' */
4345 /* indices used to find values within each vertex. */
4346 /* */
4347 /*****************************************************************************/
4348 
4349 #ifdef ANSI_DECLARATORS
4350 void initializevertexpool(struct mesh *m, struct behavior *b)
4351 #else /* not ANSI_DECLARATORS */
4352 void initializevertexpool(m, b)
4353 struct mesh *m;
4354 struct behavior *b;
4355 #endif /* not ANSI_DECLARATORS */
4356 
4357 {
4358  int vertexsize;
4359 
4360  /* The index within each vertex at which the boundary marker is found, */
4361  /* followed by the vertex type. Ensure the vertex marker is aligned to */
4362  /* a sizeof(int)-byte address. */
4363  m->vertexmarkindex = ((m->mesh_dim + m->nextras) * sizeof(REAL) +
4364  sizeof(int) - 1) /
4365  sizeof(int);
4366  vertexsize = (m->vertexmarkindex + 2) * sizeof(int);
4367  if (b->poly) {
4368  /* The index within each vertex at which a triangle pointer is found. */
4369  /* Ensure the pointer is aligned to a sizeof(triangle)-byte address. */
4370  m->vertex2triindex = (vertexsize + sizeof(triangle) - 1) /
4371  sizeof(triangle);
4372  vertexsize = (m->vertex2triindex + 1) * sizeof(triangle);
4373  }
4374 
4375  /* Initialize the pool of vertices. */
4376  poolinit(&m->vertices, vertexsize, VERTEXPERBLOCK,
4377  m->invertices > VERTEXPERBLOCK ? m->invertices : VERTEXPERBLOCK,
4378  sizeof(REAL));
4379 }
4380 
4381 /*****************************************************************************/
4382 /* */
4383 /* initializetrisubpools() Calculate the sizes of the triangle and */
4384 /* subsegment data structures and initialize */
4385 /* their memory pools. */
4386 /* */
4387 /* This routine also computes the `highorderindex', `elemattribindex', and */
4388 /* `areaboundindex' indices used to find values within each triangle. */
4389 /* */
4390 /*****************************************************************************/
4391 
4392 #ifdef ANSI_DECLARATORS
4393 void initializetrisubpools(struct mesh *m, struct behavior *b)
4394 #else /* not ANSI_DECLARATORS */
4395 void initializetrisubpools(m, b)
4396 struct mesh *m;
4397 struct behavior *b;
4398 #endif /* not ANSI_DECLARATORS */
4399 
4400 {
4401  unsigned trisize;
4402 
4403  /* The index within each triangle at which the extra nodes (above three) */
4404  /* associated with high order elements are found. There are three */
4405  /* pointers to other triangles, three pointers to corners, and possibly */
4406  /* three pointers to subsegments before the extra nodes. */
4407  m->highorderindex = 6 + (b->usesegments * 3);
4408  /* The number of bytes occupied by a triangle. */
4409  trisize = ((b->order + 1) * (b->order + 2) / 2 + (m->highorderindex - 3)) *
4410  sizeof(triangle);
4411  /* The index within each triangle at which its attributes are found, */
4412  /* where the index is measured in REALs. */
4413  m->elemattribindex = (trisize + sizeof(REAL) - 1) / sizeof(REAL);
4414  /* The index within each triangle at which the maximum area constraint */
4415  /* is found, where the index is measured in REALs. Note that if the */
4416  /* `regionattrib' flag is set, an additional attribute will be added. */
4417  m->areaboundindex = m->elemattribindex + m->eextras + b->regionattrib;
4418  /* If triangle attributes or an area bound are needed, increase the number */
4419  /* of bytes occupied by a triangle. */
4420  if (b->vararea) {
4421  trisize = (m->areaboundindex + 1) * sizeof(REAL);
4422  } else if (m->eextras + b->regionattrib > 0) {
4423  trisize = m->areaboundindex * sizeof(REAL);
4424  }
4425  /* If a Voronoi diagram or triangle neighbor graph is requested, make */
4426  /* sure there's room to store an integer index in each triangle. This */
4427  /* integer index can occupy the same space as the subsegment pointers */
4428  /* or attributes or area constraint or extra nodes. */
4429  if ((b->voronoi || b->neighbors) &&
4430  (trisize < 6 * sizeof(triangle) + sizeof(int))) {
4431  trisize = 6 * sizeof(triangle) + sizeof(int);
4432  }
4433 
4434  /* Having determined the memory size of a triangle, initialize the pool. */
4435  poolinit(&m->triangles, trisize, TRIPERBLOCK,
4436  (2 * m->invertices - 2) > TRIPERBLOCK ? (2 * m->invertices - 2) :
4437  TRIPERBLOCK, 4);
4438 
4439  if (b->usesegments) {
4440  /* Initialize the pool of subsegments. Take into account all eight */
4441  /* pointers and one boundary marker. */
4442  poolinit(&m->subsegs, 8 * sizeof(triangle) + sizeof(int),
4443  SUBSEGPERBLOCK, SUBSEGPERBLOCK, 4);
4444 
4445  /* Initialize the "outer space" triangle and omnipresent subsegment. */
4446  dummyinit(m, b, m->triangles.itembytes, m->subsegs.itembytes);
4447  } else {
4448  /* Initialize the "outer space" triangle. */
4449  dummyinit(m, b, m->triangles.itembytes, 0);
4450  }
4451 }
4452 
4453 /*****************************************************************************/
4454 /* */
4455 /* triangledealloc() Deallocate space for a triangle, marking it dead. */
4456 /* */
4457 /*****************************************************************************/
4458 
4459 #ifdef ANSI_DECLARATORS
4460 void triangledealloc(struct mesh *m, triangle *dyingtriangle)
4461 #else /* not ANSI_DECLARATORS */
4462 void triangledealloc(m, dyingtriangle)
4463 struct mesh *m;
4464 triangle *dyingtriangle;
4465 #endif /* not ANSI_DECLARATORS */
4466 
4467 {
4468  /* Mark the triangle as dead. This makes it possible to detect dead */
4469  /* triangles when traversing the list of all triangles. */
4470  killtri(dyingtriangle);
4471  pooldealloc(&m->triangles, (VOID *) dyingtriangle);
4472 }
4473 
4474 /*****************************************************************************/
4475 /* */
4476 /* triangletraverse() Traverse the triangles, skipping dead ones. */
4477 /* */
4478 /*****************************************************************************/
4479 
4480 #ifdef ANSI_DECLARATORS
4481 triangle *triangletraverse(struct mesh *m)
4482 #else /* not ANSI_DECLARATORS */
4483 triangle *triangletraverse(m)
4484 struct mesh *m;
4485 #endif /* not ANSI_DECLARATORS */
4486 
4487 {
4488  triangle *newtriangle;
4489 
4490  do {
4491  newtriangle = (triangle *) traverse(&m->triangles);
4492  if (newtriangle == (triangle *) NULL) {
4493  return (triangle *) NULL;
4494  }
4495  } while (deadtri(newtriangle)); /* Skip dead ones. */
4496  return newtriangle;
4497 }
4498 
4499 /*****************************************************************************/
4500 /* */
4501 /* subsegdealloc() Deallocate space for a subsegment, marking it dead. */
4502 /* */
4503 /*****************************************************************************/
4504 
4505 #ifdef ANSI_DECLARATORS
4506 void subsegdealloc(struct mesh *m, subseg *dyingsubseg)
4507 #else /* not ANSI_DECLARATORS */
4508 void subsegdealloc(m, dyingsubseg)
4509 struct mesh *m;
4510 subseg *dyingsubseg;
4511 #endif /* not ANSI_DECLARATORS */
4512 
4513 {
4514  /* Mark the subsegment as dead. This makes it possible to detect dead */
4515  /* subsegments when traversing the list of all subsegments. */
4516  killsubseg(dyingsubseg);
4517  pooldealloc(&m->subsegs, (VOID *) dyingsubseg);
4518 }
4519 
4520 /*****************************************************************************/
4521 /* */
4522 /* subsegtraverse() Traverse the subsegments, skipping dead ones. */
4523 /* */
4524 /*****************************************************************************/
4525 
4526 #ifdef ANSI_DECLARATORS
4527 subseg *subsegtraverse(struct mesh *m)
4528 #else /* not ANSI_DECLARATORS */
4529 subseg *subsegtraverse(m)
4530 struct mesh *m;
4531 #endif /* not ANSI_DECLARATORS */
4532 
4533 {
4534  subseg *newsubseg;
4535 
4536  do {
4537  newsubseg = (subseg *) traverse(&m->subsegs);
4538  if (newsubseg == (subseg *) NULL) {
4539  return (subseg *) NULL;
4540  }
4541  } while (deadsubseg(newsubseg)); /* Skip dead ones. */
4542  return newsubseg;
4543 }
4544 
4545 /*****************************************************************************/
4546 /* */
4547 /* vertexdealloc() Deallocate space for a vertex, marking it dead. */
4548 /* */
4549 /*****************************************************************************/
4550 
4551 #ifdef ANSI_DECLARATORS
4552 void vertexdealloc(struct mesh *m, vertex dyingvertex)
4553 #else /* not ANSI_DECLARATORS */
4554 void vertexdealloc(m, dyingvertex)
4555 struct mesh *m;
4556 vertex dyingvertex;
4557 #endif /* not ANSI_DECLARATORS */
4558 
4559 {
4560  /* Mark the vertex as dead. This makes it possible to detect dead */
4561  /* vertices when traversing the list of all vertices. */
4562  setvertextype(dyingvertex, DEADVERTEX);
4563  pooldealloc(&m->vertices, (VOID *) dyingvertex);
4564 }
4565 
4566 /*****************************************************************************/
4567 /* */
4568 /* vertextraverse() Traverse the vertices, skipping dead ones. */
4569 /* */
4570 /*****************************************************************************/
4571 
4572 #ifdef ANSI_DECLARATORS
4573 vertex vertextraverse(struct mesh *m)
4574 #else /* not ANSI_DECLARATORS */
4575 vertex vertextraverse(m)
4576 struct mesh *m;
4577 #endif /* not ANSI_DECLARATORS */
4578 
4579 {
4580  vertex newvertex;
4581 
4582  do {
4583  newvertex = (vertex) traverse(&m->vertices);
4584  if (newvertex == (vertex) NULL) {
4585  return (vertex) NULL;
4586  }
4587  } while (vertextype(newvertex) == DEADVERTEX); /* Skip dead ones. */
4588  return newvertex;
4589 }
4590 
4591 /*****************************************************************************/
4592 /* */
4593 /* badsubsegdealloc() Deallocate space for a bad subsegment, marking it */
4594 /* dead. */
4595 /* */
4596 /*****************************************************************************/
4597 
4598 #ifndef CDT_ONLY
4599 
4600 #ifdef ANSI_DECLARATORS
4601 void badsubsegdealloc(struct mesh *m, struct badsubseg *dyingseg)
4602 #else /* not ANSI_DECLARATORS */
4603 void badsubsegdealloc(m, dyingseg)
4604 struct mesh *m;
4605 struct badsubseg *dyingseg;
4606 #endif /* not ANSI_DECLARATORS */
4607 
4608 {
4609  /* Set subsegment's origin to NULL. This makes it possible to detect dead */
4610  /* badsubsegs when traversing the list of all badsubsegs . */
4611  dyingseg->subsegorg = (vertex) NULL;
4612  pooldealloc(&m->badsubsegs, (VOID *) dyingseg);
4613 }
4614 
4615 #endif /* not CDT_ONLY */
4616 
4617 /*****************************************************************************/
4618 /* */
4619 /* badsubsegtraverse() Traverse the bad subsegments, skipping dead ones. */
4620 /* */
4621 /*****************************************************************************/
4622 
4623 #ifndef CDT_ONLY
4624 
4625 #ifdef ANSI_DECLARATORS
4626 struct badsubseg *badsubsegtraverse(struct mesh *m)
4627 #else /* not ANSI_DECLARATORS */
4628 struct badsubseg *badsubsegtraverse(m)
4629 struct mesh *m;
4630 #endif /* not ANSI_DECLARATORS */
4631 
4632 {
4633  struct badsubseg *newseg;
4634 
4635  do {
4636  newseg = (struct badsubseg *) traverse(&m->badsubsegs);
4637  if (newseg == (struct badsubseg *) NULL) {
4638  return (struct badsubseg *) NULL;
4639  }
4640  } while (newseg->subsegorg == (vertex) NULL); /* Skip dead ones. */
4641  return newseg;
4642 }
4643 
4644 #endif /* not CDT_ONLY */
4645 
4646 /*****************************************************************************/
4647 /* */
4648 /* getvertex() Get a specific vertex, by number, from the list. */
4649 /* */
4650 /* The first vertex is number 'firstnumber'. */
4651 /* */
4652 /* Note that this takes O(n) time (with a small constant, if VERTEXPERBLOCK */
4653 /* is large). I don't care to take the trouble to make it work in constant */
4654 /* time. */
4655 /* */
4656 /*****************************************************************************/
4657 
4658 #ifdef ANSI_DECLARATORS
4659 vertex getvertex(struct mesh *m, struct behavior *b, int number)
4660 #else /* not ANSI_DECLARATORS */
4661 vertex getvertex(m, b, number)
4662 struct mesh *m;
4663 struct behavior *b;
4664 int number;
4665 #endif /* not ANSI_DECLARATORS */
4666 
4667 {
4668  VOID **getblock;
4669  char *foundvertex;
4670  unsigned long alignptr;
4671  int current;
4672 
4673  getblock = m->vertices.firstblock;
4674  current = b->firstnumber;
4675 
4676  /* Find the right block. */
4677  if (current + m->vertices.itemsfirstblock <= number) {
4678  getblock = (VOID **) *getblock;
4679  current += m->vertices.itemsfirstblock;
4680  while (current + m->vertices.itemsperblock <= number) {
4681  getblock = (VOID **) *getblock;
4682  current += m->vertices.itemsperblock;
4683  }
4684  }
4685 
4686  /* Now find the right vertex. */
4687  alignptr = (unsigned long) (getblock + 1);
4688  foundvertex = (char *) (alignptr + (unsigned long) m->vertices.alignbytes -
4689  (alignptr % (unsigned long) m->vertices.alignbytes));
4690  return (vertex) (foundvertex + m->vertices.itembytes * (number - current));
4691 }
4692 
4693 /*****************************************************************************/
4694 /* */
4695 /* triangledeinit() Free all remaining allocated memory. */
4696 /* */
4697 /*****************************************************************************/
4698 
4699 #ifdef ANSI_DECLARATORS
4700 void triangledeinit(struct mesh *m, struct behavior *b)
4701 #else /* not ANSI_DECLARATORS */
4702 void triangledeinit(m, b)
4703 struct mesh *m;
4704 struct behavior *b;
4705 #endif /* not ANSI_DECLARATORS */
4706 
4707 {
4708  pooldeinit(&m->triangles);
4709  trifree((VOID *) m->dummytribase);
4710  if (b->usesegments) {
4711  pooldeinit(&m->subsegs);
4712  trifree((VOID *) m->dummysubbase);
4713  }
4714  pooldeinit(&m->vertices);
4715 #ifndef CDT_ONLY
4716  if (b->quality) {
4717  pooldeinit(&m->badsubsegs);
4718  if ((b->minangle > 0.0) || b->vararea || b->fixedarea || b->usertest) {
4719  pooldeinit(&m->badtriangles);
4720  pooldeinit(&m->flipstackers);
4721  }
4722  }
4723 #endif /* not CDT_ONLY */
4724 }
4725 
4728 /********* Memory management routines end here *********/
4729 
4730 /********* Constructors begin here *********/
4734 /*****************************************************************************/
4735 /* */
4736 /* maketriangle() Create a new triangle with orientation zero. */
4737 /* */
4738 /*****************************************************************************/
4739 
4740 #ifdef ANSI_DECLARATORS
4741 void maketriangle(struct mesh *m, struct behavior *b, struct otri *newotri)
4742 #else /* not ANSI_DECLARATORS */
4743 void maketriangle(m, b, newotri)
4744 struct mesh *m;
4745 struct behavior *b;
4746 struct otri *newotri;
4747 #endif /* not ANSI_DECLARATORS */
4748 
4749 {
4750  int i;
4751 
4752  newotri->tri = (triangle *) poolalloc(&m->triangles);
4753  /* Initialize the three adjoining triangles to be "outer space". */
4754  newotri->tri[0] = (triangle) m->dummytri;
4755  newotri->tri[1] = (triangle) m->dummytri;
4756  newotri->tri[2] = (triangle) m->dummytri;
4757  /* Three NULL vertices. */
4758  newotri->tri[3] = (triangle) NULL;
4759  newotri->tri[4] = (triangle) NULL;
4760  newotri->tri[5] = (triangle) NULL;
4761  if (b->usesegments) {
4762  /* Initialize the three adjoining subsegments to be the omnipresent */
4763  /* subsegment. */
4764  newotri->tri[6] = (triangle) m->dummysub;
4765  newotri->tri[7] = (triangle) m->dummysub;
4766  newotri->tri[8] = (triangle) m->dummysub;
4767  }
4768  for (i = 0; i < m->eextras; i++) {
4769  setelemattribute(*newotri, i, 0.0);
4770  }
4771  if (b->vararea) {
4772  setareabound(*newotri, -1.0);
4773  }
4774 
4775  newotri->orient = 0;
4776 }
4777 
4778 /*****************************************************************************/
4779 /* */
4780 /* makesubseg() Create a new subsegment with orientation zero. */
4781 /* */
4782 /*****************************************************************************/
4783 
4784 #ifdef ANSI_DECLARATORS
4785 void makesubseg(struct mesh *m, struct osub *newsubseg)
4786 #else /* not ANSI_DECLARATORS */
4787 void makesubseg(m, newsubseg)
4788 struct mesh *m;
4789 struct osub *newsubseg;
4790 #endif /* not ANSI_DECLARATORS */
4791 
4792 {
4793  newsubseg->ss = (subseg *) poolalloc(&m->subsegs);
4794  /* Initialize the two adjoining subsegments to be the omnipresent */
4795  /* subsegment. */
4796  newsubseg->ss[0] = (subseg) m->dummysub;
4797  newsubseg->ss[1] = (subseg) m->dummysub;
4798  /* Four NULL vertices. */
4799  newsubseg->ss[2] = (subseg) NULL;
4800  newsubseg->ss[3] = (subseg) NULL;
4801  newsubseg->ss[4] = (subseg) NULL;
4802  newsubseg->ss[5] = (subseg) NULL;
4803  /* Initialize the two adjoining triangles to be "outer space." */
4804  newsubseg->ss[6] = (subseg) m->dummytri;
4805  newsubseg->ss[7] = (subseg) m->dummytri;
4806  /* Set the boundary marker to zero. */
4807  setmark(*newsubseg, 0);
4808 
4809  newsubseg->ssorient = 0;
4810 }
4811 
4814 /********* Constructors end here *********/
4815 
4816 /********* Geometric primitives begin here *********/
4820 /* The adaptive exact arithmetic geometric predicates implemented herein are */
4821 /* described in detail in my paper, "Adaptive Precision Floating-Point */
4822 /* Arithmetic and Fast Robust Geometric Predicates." See the header for a */
4823 /* full citation. */
4824 
4825 /* Which of the following two methods of finding the absolute values is */
4826 /* fastest is compiler-dependent. A few compilers can inline and optimize */
4827 /* the fabs() call; but most will incur the overhead of a function call, */
4828 /* which is disastrously slow. A faster way on IEEE machines might be to */
4829 /* mask the appropriate bit, but that's difficult to do in C without */
4830 /* forcing the value to be stored to memory (rather than be kept in the */
4831 /* register to which the optimizer assigned it). */
4832 
4833 #define Absolute(a) ((a) >= 0.0 ? (a) : -(a))
4834 /* #define Absolute(a) fabs(a) */
4835 
4836 /* Many of the operations are broken up into two pieces, a main part that */
4837 /* performs an approximate operation, and a "tail" that computes the */
4838 /* roundoff error of that operation. */
4839 /* */
4840 /* The operations Fast_Two_Sum(), Fast_Two_Diff(), Two_Sum(), Two_Diff(), */
4841 /* Split(), and Two_Product() are all implemented as described in the */
4842 /* reference. Each of these macros requires certain variables to be */
4843 /* defined in the calling routine. The variables `bvirt', `c', `abig', */
4844 /* `_i', `_j', `_k', `_l', `_m', and `_n' are declared `INEXACT' because */
4845 /* they store the result of an operation that may incur roundoff error. */
4846 /* The input parameter `x' (or the highest numbered `x_' parameter) must */
4847 /* also be declared `INEXACT'. */
4848 
4849 #define Fast_Two_Sum_Tail(a, b, x, y) \
4850  bvirt = x - a; \
4851  y = b - bvirt
4852 
4853 #define Fast_Two_Sum(a, b, x, y) \
4854  x = (REAL) (a + b); \
4855  Fast_Two_Sum_Tail(a, b, x, y)
4856 
4857 #define Two_Sum_Tail(a, b, x, y) \
4858  bvirt = (REAL) (x - a); \
4859  avirt = x - bvirt; \
4860  bround = b - bvirt; \
4861  around = a - avirt; \
4862  y = around + bround
4863 
4864 #define Two_Sum(a, b, x, y) \
4865  x = (REAL) (a + b); \
4866  Two_Sum_Tail(a, b, x, y)
4867 
4868 #define Two_Diff_Tail(a, b, x, y) \
4869  bvirt = (REAL) (a - x); \
4870  avirt = x + bvirt; \
4871  bround = bvirt - b; \
4872  around = a - avirt; \
4873  y = around + bround
4874 
4875 #define Two_Diff(a, b, x, y) \
4876  x = (REAL) (a - b); \
4877  Two_Diff_Tail(a, b, x, y)
4878 
4879 #define Split(a, ahi, alo) \
4880  c = (REAL) (splitter * a); \
4881  abig = (REAL) (c - a); \
4882  ahi = c - abig; \
4883  alo = a - ahi
4884 
4885 #define Two_Product_Tail(a, b, x, y) \
4886  Split(a, ahi, alo); \
4887  Split(b, bhi, blo); \
4888  err1 = x - (ahi * bhi); \
4889  err2 = err1 - (alo * bhi); \
4890  err3 = err2 - (ahi * blo); \
4891  y = (alo * blo) - err3
4892 
4893 #define Two_Product(a, b, x, y) \
4894  x = (REAL) (a * b); \
4895  Two_Product_Tail(a, b, x, y)
4896 
4897 /* Two_Product_Presplit() is Two_Product() where one of the inputs has */
4898 /* already been split. Avoids redundant splitting. */
4899 
4900 #define Two_Product_Presplit(a, b, bhi, blo, x, y) \
4901  x = (REAL) (a * b); \
4902  Split(a, ahi, alo); \
4903  err1 = x - (ahi * bhi); \
4904  err2 = err1 - (alo * bhi); \
4905  err3 = err2 - (ahi * blo); \
4906  y = (alo * blo) - err3
4907 
4908 /* Square() can be done more quickly than Two_Product(). */
4909 
4910 #define Square_Tail(a, x, y) \
4911  Split(a, ahi, alo); \
4912  err1 = x - (ahi * ahi); \
4913  err3 = err1 - ((ahi + ahi) * alo); \
4914  y = (alo * alo) - err3
4915 
4916 #define Square(a, x, y) \
4917  x = (REAL) (a * a); \
4918  Square_Tail(a, x, y)
4919 
4920 /* Macros for summing expansions of various fixed lengths. These are all */
4921 /* unrolled versions of Expansion_Sum(). */
4922 
4923 #define Two_One_Sum(a1, a0, b, x2, x1, x0) \
4924  Two_Sum(a0, b , _i, x0); \
4925  Two_Sum(a1, _i, x2, x1)
4926 
4927 #define Two_One_Diff(a1, a0, b, x2, x1, x0) \
4928  Two_Diff(a0, b , _i, x0); \
4929  Two_Sum( a1, _i, x2, x1)
4930 
4931 #define Two_Two_Sum(a1, a0, b1, b0, x3, x2, x1, x0) \
4932  Two_One_Sum(a1, a0, b0, _j, _0, x0); \
4933  Two_One_Sum(_j, _0, b1, x3, x2, x1)
4934 
4935 #define Two_Two_Diff(a1, a0, b1, b0, x3, x2, x1, x0) \
4936  Two_One_Diff(a1, a0, b0, _j, _0, x0); \
4937  Two_One_Diff(_j, _0, b1, x3, x2, x1)
4938 
4939 /* Macro for multiplying a two-component expansion by a single component. */
4940 
4941 #define Two_One_Product(a1, a0, b, x3, x2, x1, x0) \
4942  Split(b, bhi, blo); \
4943  Two_Product_Presplit(a0, b, bhi, blo, _i, x0); \
4944  Two_Product_Presplit(a1, b, bhi, blo, _j, _0); \
4945  Two_Sum(_i, _0, _k, x1); \
4946  Fast_Two_Sum(_j, _k, x3, x2)
4947 
4948 /*****************************************************************************/
4949 /* */
4950 /* exactinit() Initialize the variables used for exact arithmetic. */
4951 /* */
4952 /* `epsilon' is the largest power of two such that 1.0 + epsilon = 1.0 in */
4953 /* floating-point arithmetic. `epsilon' bounds the relative roundoff */
4954 /* error. It is used for floating-point error analysis. */
4955 /* */
4956 /* `splitter' is used to split floating-point numbers into two half- */
4957 /* length significands for exact multiplication. */
4958 /* */
4959 /* I imagine that a highly optimizing compiler might be too smart for its */
4960 /* own good, and somehow cause this routine to fail, if it pretends that */
4961 /* floating-point arithmetic is too much like real arithmetic. */
4962 /* */
4963 /* Don't change this routine unless you fully understand it. */
4964 /* */
4965 /*****************************************************************************/
4966 
4967 void exactinit()
4968 {
4969  REAL half;
4970  REAL check, lastcheck;
4971  int every_other;
4972 #ifdef LINUX
4973  int cword;
4974 #endif /* LINUX */
4975 
4976 #ifdef CPU86
4977 #ifdef SINGLE
4978  _control87(_PC_24, _MCW_PC); /* Set FPU control word for single precision. */
4979 #else /* not SINGLE */
4980  _control87(_PC_53, _MCW_PC); /* Set FPU control word for double precision. */
4981 #endif /* not SINGLE */
4982 #endif /* CPU86 */
4983 #ifdef LINUX
4984 #ifdef SINGLE
4985  /* cword = 4223; */
4986  cword = 4210; /* set FPU control word for single precision */
4987 #else /* not SINGLE */
4988  /* cword = 4735; */
4989  cword = 4722; /* set FPU control word for double precision */
4990 #endif /* not SINGLE */
4991  _FPU_SETCW(cword);
4992 #endif /* LINUX */
4993 
4994  every_other = 1;
4995  half = 0.5;
4996  epsilon = 1.0;
4997  splitter = 1.0;
4998  check = 1.0;
4999  /* Repeatedly divide `epsilon' by two until it is too small to add to */
5000  /* one without causing roundoff. (Also check if the sum is equal to */
5001  /* the previous sum, for machines that round up instead of using exact */
5002  /* rounding. Not that these routines will work on such machines.) */
5003  do {
5004  lastcheck = check;
5005  epsilon *= half;
5006  if (every_other) {
5007  splitter *= 2.0;
5008  }
5009  every_other = !every_other;
5010  check = 1.0 + epsilon;
5011  } while ((check != 1.0) && (check != lastcheck));
5012  splitter += 1.0;
5013  /* Error bounds for orientation and incircle tests. */
5014  resulterrbound = (3.0 + 8.0 * epsilon) * epsilon;
5015  ccwerrboundA = (3.0 + 16.0 * epsilon) * epsilon;
5016  ccwerrboundB = (2.0 + 12.0 * epsilon) * epsilon;
5017  ccwerrboundC = (9.0 + 64.0 * epsilon) * epsilon * epsilon;
5018  iccerrboundA = (10.0 + 96.0 * epsilon) * epsilon;
5019  iccerrboundB = (4.0 + 48.0 * epsilon) * epsilon;
5020  iccerrboundC = (44.0 + 576.0 * epsilon) * epsilon * epsilon;
5021  o3derrboundA = (7.0 + 56.0 * epsilon) * epsilon;
5022  o3derrboundB = (3.0 + 28.0 * epsilon) * epsilon;
5023  o3derrboundC = (26.0 + 288.0 * epsilon) * epsilon * epsilon;
5024 }
5025 
5026 /*****************************************************************************/
5027 /* */
5028 /* fast_expansion_sum_zeroelim() Sum two expansions, eliminating zero */
5029 /* components from the output expansion. */
5030 /* */
5031 /* Sets h = e + f. See my Robust Predicates paper for details. */
5032 /* */
5033 /* If round-to-even is used (as with IEEE 754), maintains the strongly */
5034 /* nonoverlapping property. (That is, if e is strongly nonoverlapping, h */
5035 /* will be also.) Does NOT maintain the nonoverlapping or nonadjacent */
5036 /* properties. */
5037 /* */
5038 /*****************************************************************************/
5039 
5040 #ifdef ANSI_DECLARATORS
5041 int fast_expansion_sum_zeroelim(int elen, REAL *e, int flen, REAL *f, REAL *h)
5042 #else /* not ANSI_DECLARATORS */
5043 int fast_expansion_sum_zeroelim(elen, e, flen, f, h) /* h cannot be e or f. */
5044 int elen;
5045 REAL *e;
5046 int flen;
5047 REAL *f;
5048 REAL *h;
5049 #endif /* not ANSI_DECLARATORS */
5050 
5051 {
5052  REAL Q;
5053  INEXACT REAL Qnew;
5054  INEXACT REAL hh;
5055  INEXACT REAL bvirt;
5056  REAL avirt, bround, around;
5057  int eindex, findex, hindex;
5058  REAL enow, fnow;
5059 
5060  enow = e[0];
5061  fnow = f[0];
5062  eindex = findex = 0;
5063  if ((fnow > enow) == (fnow > -enow)) {
5064  Q = enow;
5065  enow = e[++eindex];
5066  } else {
5067  Q = fnow;
5068  fnow = f[++findex];
5069  }
5070  hindex = 0;
5071  if ((eindex < elen) && (findex < flen)) {
5072  if ((fnow > enow) == (fnow > -enow)) {
5073  Fast_Two_Sum(enow, Q, Qnew, hh);
5074  enow = e[++eindex];
5075  } else {
5076  Fast_Two_Sum(fnow, Q, Qnew, hh);
5077  fnow = f[++findex];
5078  }
5079  Q = Qnew;
5080  if (hh != 0.0) {
5081  h[hindex++] = hh;
5082  }
5083  while ((eindex < elen) && (findex < flen)) {
5084  if ((fnow > enow) == (fnow > -enow)) {
5085  Two_Sum(Q, enow, Qnew, hh);
5086  enow = e[++eindex];
5087  } else {
5088  Two_Sum(Q, fnow, Qnew, hh);
5089  fnow = f[++findex];
5090  }
5091  Q = Qnew;
5092  if (hh != 0.0) {
5093  h[hindex++] = hh;
5094  }
5095  }
5096  }
5097  while (eindex < elen) {
5098  Two_Sum(Q, enow, Qnew, hh);
5099  enow = e[++eindex];
5100  Q = Qnew;
5101  if (hh != 0.0) {
5102  h[hindex++] = hh;
5103  }
5104  }
5105  while (findex < flen) {
5106  Two_Sum(Q, fnow, Qnew, hh);
5107  fnow = f[++findex];
5108  Q = Qnew;
5109  if (hh != 0.0) {
5110  h[hindex++] = hh;
5111  }
5112  }
5113  if ((Q != 0.0) || (hindex == 0)) {
5114  h[hindex++] = Q;
5115  }
5116  return hindex;
5117 }
5118 
5119 /*****************************************************************************/
5120 /* */
5121 /* scale_expansion_zeroelim() Multiply an expansion by a scalar, */
5122 /* eliminating zero components from the */
5123 /* output expansion. */
5124 /* */
5125 /* Sets h = be. See my Robust Predicates paper for details. */
5126 /* */
5127 /* Maintains the nonoverlapping property. If round-to-even is used (as */
5128 /* with IEEE 754), maintains the strongly nonoverlapping and nonadjacent */
5129 /* properties as well. (That is, if e has one of these properties, so */
5130 /* will h.) */
5131 /* */
5132 /*****************************************************************************/
5133 
5134 #ifdef ANSI_DECLARATORS
5135 int scale_expansion_zeroelim(int elen, REAL *e, REAL b, REAL *h)
5136 #else /* not ANSI_DECLARATORS */
5137 int scale_expansion_zeroelim(elen, e, b, h) /* e and h cannot be the same. */
5138 int elen;
5139 REAL *e;
5140 REAL b;
5141 REAL *h;
5142 #endif /* not ANSI_DECLARATORS */
5143 
5144 {
5145  INEXACT REAL Q, sum;
5146  REAL hh;
5147  INEXACT REAL product1;
5148  REAL product0;
5149  int eindex, hindex;
5150  REAL enow;
5151  INEXACT REAL bvirt;
5152  REAL avirt, bround, around;
5153  INEXACT REAL c;
5154  INEXACT REAL abig;
5155  REAL ahi, alo, bhi, blo;
5156  REAL err1, err2, err3;
5157 
5158  Split(b, bhi, blo);
5159  Two_Product_Presplit(e[0], b, bhi, blo, Q, hh);
5160  hindex = 0;
5161  if (hh != 0) {
5162  h[hindex++] = hh;
5163  }
5164  for (eindex = 1; eindex < elen; eindex++) {
5165  enow = e[eindex];
5166  Two_Product_Presplit(enow, b, bhi, blo, product1, product0);
5167  Two_Sum(Q, product0, sum, hh);
5168  if (hh != 0) {
5169  h[hindex++] = hh;
5170  }
5171  Fast_Two_Sum(product1, sum, Q, hh);
5172  if (hh != 0) {
5173  h[hindex++] = hh;
5174  }
5175  }
5176  if ((Q != 0.0) || (hindex == 0)) {
5177  h[hindex++] = Q;
5178  }
5179  return hindex;
5180 }
5181 
5182 /*****************************************************************************/
5183 /* */
5184 /* estimate() Produce a one-word estimate of an expansion's value. */
5185 /* */
5186 /* See my Robust Predicates paper for details. */
5187 /* */
5188 /*****************************************************************************/
5189 
5190 #ifdef ANSI_DECLARATORS
5191 REAL estimate(int elen, REAL *e)
5192 #else /* not ANSI_DECLARATORS */
5193 REAL estimate(elen, e)
5194 int elen;
5195 REAL *e;
5196 #endif /* not ANSI_DECLARATORS */
5197 
5198 {
5199  REAL Q;
5200  int eindex;
5201 
5202  Q = e[0];
5203  for (eindex = 1; eindex < elen; eindex++) {
5204  Q += e[eindex];
5205  }
5206  return Q;
5207 }
5208 
5209 /*****************************************************************************/
5210 /* */
5211 /* counterclockwise() Return a positive value if the points pa, pb, and */
5212 /* pc occur in counterclockwise order; a negative */
5213 /* value if they occur in clockwise order; and zero */
5214 /* if they are collinear. The result is also a rough */
5215 /* approximation of twice the signed area of the */
5216 /* triangle defined by the three points. */
5217 /* */
5218 /* Uses exact arithmetic if necessary to ensure a correct answer. The */
5219 /* result returned is the determinant of a matrix. This determinant is */
5220 /* computed adaptively, in the sense that exact arithmetic is used only to */
5221 /* the degree it is needed to ensure that the returned value has the */
5222 /* correct sign. Hence, this function is usually quite fast, but will run */
5223 /* more slowly when the input points are collinear or nearly so. */
5224 /* */
5225 /* See my Robust Predicates paper for details. */
5226 /* */
5227 /*****************************************************************************/
5228 
5229 #ifdef ANSI_DECLARATORS
5230 REAL counterclockwiseadapt(vertex pa, vertex pb, vertex pc, REAL detsum)
5231 #else /* not ANSI_DECLARATORS */
5232 REAL counterclockwiseadapt(pa, pb, pc, detsum)
5233 vertex pa;
5234 vertex pb;
5235 vertex pc;
5236 REAL detsum;
5237 #endif /* not ANSI_DECLARATORS */
5238 
5239 {
5240  INEXACT REAL acx, acy, bcx, bcy;
5241  REAL acxtail, acytail, bcxtail, bcytail;
5242  INEXACT REAL detleft, detright;
5243  REAL detlefttail, detrighttail;
5244  REAL det, errbound;
5245  REAL B[4], C1[8], C2[12], D[16];
5246  INEXACT REAL B3;
5247  int C1length, C2length, Dlength;
5248  REAL u[4];
5249  INEXACT REAL u3;
5250  INEXACT REAL s1, t1;
5251  REAL s0, t0;
5252 
5253  INEXACT REAL bvirt;
5254  REAL avirt, bround, around;
5255  INEXACT REAL c;
5256  INEXACT REAL abig;
5257  REAL ahi, alo, bhi, blo;
5258  REAL err1, err2, err3;
5259  INEXACT REAL _i, _j;
5260  REAL _0;
5261 
5262  acx = (REAL) (pa[0] - pc[0]);
5263  bcx = (REAL) (pb[0] - pc[0]);
5264  acy = (REAL) (pa[1] - pc[1]);
5265  bcy = (REAL) (pb[1] - pc[1]);
5266 
5267  Two_Product(acx, bcy, detleft, detlefttail);
5268  Two_Product(acy, bcx, detright, detrighttail);
5269 
5270  Two_Two_Diff(detleft, detlefttail, detright, detrighttail,
5271  B3, B[2], B[1], B[0]);
5272  B[3] = B3;
5273 
5274  det = estimate(4, B);
5275  errbound = ccwerrboundB * detsum;
5276  if ((det >= errbound) || (-det >= errbound)) {
5277  return det;
5278  }
5279 
5280  Two_Diff_Tail(pa[0], pc[0], acx, acxtail);
5281  Two_Diff_Tail(pb[0], pc[0], bcx, bcxtail);
5282  Two_Diff_Tail(pa[1], pc[1], acy, acytail);
5283  Two_Diff_Tail(pb[1], pc[1], bcy, bcytail);
5284 
5285  if ((acxtail == 0.0) && (acytail == 0.0)
5286  && (bcxtail == 0.0) && (bcytail == 0.0)) {
5287  return det;
5288  }
5289 
5290  errbound = ccwerrboundC * detsum + resulterrbound * Absolute(det);
5291  det += (acx * bcytail + bcy * acxtail)
5292  - (acy * bcxtail + bcx * acytail);
5293  if ((det >= errbound) || (-det >= errbound)) {
5294  return det;
5295  }
5296 
5297  Two_Product(acxtail, bcy, s1, s0);
5298  Two_Product(acytail, bcx, t1, t0);
5299  Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
5300  u[3] = u3;
5301  C1length = fast_expansion_sum_zeroelim(4, B, 4, u, C1);
5302 
5303  Two_Product(acx, bcytail, s1, s0);
5304  Two_Product(acy, bcxtail, t1, t0);
5305  Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
5306  u[3] = u3;
5307  C2length = fast_expansion_sum_zeroelim(C1length, C1, 4, u, C2);
5308 
5309  Two_Product(acxtail, bcytail, s1, s0);
5310  Two_Product(acytail, bcxtail, t1, t0);
5311  Two_Two_Diff(s1, s0, t1, t0, u3, u[2], u[1], u[0]);
5312  u[3] = u3;
5313  Dlength = fast_expansion_sum_zeroelim(C2length, C2, 4, u, D);
5314 
5315  return(D[Dlength - 1]);
5316 }
5317 
5318 #ifdef ANSI_DECLARATORS
5319 REAL counterclockwise(struct mesh *m, struct behavior *b,
5320  vertex pa, vertex pb, vertex pc)
5321 #else /* not ANSI_DECLARATORS */
5322 REAL counterclockwise(m, b, pa, pb, pc)
5323 struct mesh *m;
5324 struct behavior *b;
5325 vertex pa;
5326 vertex pb;
5327 vertex pc;
5328 #endif /* not ANSI_DECLARATORS */
5329 
5330 {
5331  REAL detleft, detright, det;
5332  REAL detsum, errbound;
5333 
5334  m->counterclockcount++;
5335 
5336  detleft = (pa[0] - pc[0]) * (pb[1] - pc[1]);
5337  detright = (pa[1] - pc[1]) * (pb[0] - pc[0]);
5338  det = detleft - detright;
5339 
5340  if (b->noexact) {
5341  return det;
5342  }
5343 
5344  if (detleft > 0.0) {
5345  if (detright <= 0.0) {
5346  return det;
5347  } else {
5348  detsum = detleft + detright;
5349  }
5350  } else if (detleft < 0.0) {
5351  if (detright >= 0.0) {
5352  return det;
5353  } else {
5354  detsum = -detleft - detright;
5355  }
5356  } else {
5357  return det;
5358  }
5359 
5360  errbound = ccwerrboundA * detsum;
5361  if ((det >= errbound) || (-det >= errbound)) {
5362  return det;
5363  }
5364 
5365  return counterclockwiseadapt(pa, pb, pc, detsum);
5366 }
5367 
5368 /*****************************************************************************/
5369 /* */
5370 /* incircle() Return a positive value if the point pd lies inside the */
5371 /* circle passing through pa, pb, and pc; a negative value if */
5372 /* it lies outside; and zero if the four points are cocircular.*/
5373 /* The points pa, pb, and pc must be in counterclockwise */
5374 /* order, or the sign of the result will be reversed. */
5375 /* */
5376 /* Uses exact arithmetic if necessary to ensure a correct answer. The */
5377 /* result returned is the determinant of a matrix. This determinant is */
5378 /* computed adaptively, in the sense that exact arithmetic is used only to */
5379 /* the degree it is needed to ensure that the returned value has the */
5380 /* correct sign. Hence, this function is usually quite fast, but will run */
5381 /* more slowly when the input points are cocircular or nearly so. */
5382 /* */
5383 /* See my Robust Predicates paper for details. */
5384 /* */
5385 /*****************************************************************************/
5386 
5387 #ifdef ANSI_DECLARATORS
5388 REAL incircleadapt(vertex pa, vertex pb, vertex pc, vertex pd, REAL permanent)
5389 #else /* not ANSI_DECLARATORS */
5390 REAL incircleadapt(pa, pb, pc, pd, permanent)
5391 vertex pa;
5392 vertex pb;
5393 vertex pc;
5394 vertex pd;
5395 REAL permanent;
5396 #endif /* not ANSI_DECLARATORS */
5397 
5398 {
5399  INEXACT REAL adx, bdx, cdx, ady, bdy, cdy;
5400  REAL det, errbound;
5401 
5402  INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1;
5403  REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0;
5404  REAL bc[4], ca[4], ab[4];
5405  INEXACT REAL bc3, ca3, ab3;
5406  REAL axbc[8], axxbc[16], aybc[8], ayybc[16], adet[32];
5407  int axbclen, axxbclen, aybclen, ayybclen, alen;
5408  REAL bxca[8], bxxca[16], byca[8], byyca[16], bdet[32];
5409  int bxcalen, bxxcalen, bycalen, byycalen, blen;
5410  REAL cxab[8], cxxab[16], cyab[8], cyyab[16], cdet[32];
5411  int cxablen, cxxablen, cyablen, cyyablen, clen;
5412  REAL abdet[64];
5413  int ablen;
5414  REAL fin1[1152], fin2[1152];
5415  REAL *finnow, *finother, *finswap;
5416  int finlength;
5417 
5418  REAL adxtail, bdxtail, cdxtail, adytail, bdytail, cdytail;
5419  INEXACT REAL adxadx1, adyady1, bdxbdx1, bdybdy1, cdxcdx1, cdycdy1;
5420  REAL adxadx0, adyady0, bdxbdx0, bdybdy0, cdxcdx0, cdycdy0;
5421  REAL aa[4], bb[4], cc[4];
5422  INEXACT REAL aa3, bb3, cc3;
5423  INEXACT REAL ti1, tj1;
5424  REAL ti0, tj0;
5425  REAL u[4], v[4];
5426  INEXACT REAL u3, v3;
5427  REAL temp8[8], temp16a[16], temp16b[16], temp16c[16];
5428  REAL temp32a[32], temp32b[32], temp48[48], temp64[64];
5429  int temp8len, temp16alen, temp16blen, temp16clen;
5430  int temp32alen, temp32blen, temp48len, temp64len;
5431  REAL axtbb[8], axtcc[8], aytbb[8], aytcc[8];
5432  int axtbblen, axtcclen, aytbblen, aytcclen;
5433  REAL bxtaa[8], bxtcc[8], bytaa[8], bytcc[8];
5434  int bxtaalen, bxtcclen, bytaalen, bytcclen;
5435  REAL cxtaa[8], cxtbb[8], cytaa[8], cytbb[8];
5436  int cxtaalen, cxtbblen, cytaalen, cytbblen;
5437  REAL axtbc[8], aytbc[8], bxtca[8], bytca[8], cxtab[8], cytab[8];
5438  int axtbclen=0, aytbclen=0, bxtcalen=0, bytcalen=0, cxtablen=0, cytablen=0;
5439  REAL axtbct[16], aytbct[16], bxtcat[16], bytcat[16], cxtabt[16], cytabt[16];
5440  int axtbctlen, aytbctlen, bxtcatlen, bytcatlen, cxtabtlen, cytabtlen;
5441  REAL axtbctt[8], aytbctt[8], bxtcatt[8];
5442  REAL bytcatt[8], cxtabtt[8], cytabtt[8];
5443  int axtbcttlen, aytbcttlen, bxtcattlen, bytcattlen, cxtabttlen, cytabttlen;
5444  REAL abt[8], bct[8], cat[8];
5445  int abtlen, bctlen, catlen;
5446  REAL abtt[4], bctt[4], catt[4];
5447  int abttlen, bcttlen, cattlen;
5448  INEXACT REAL abtt3, bctt3, catt3;
5449  REAL negate;
5450 
5451  INEXACT REAL bvirt;
5452  REAL avirt, bround, around;
5453  INEXACT REAL c;
5454  INEXACT REAL abig;
5455  REAL ahi, alo, bhi, blo;
5456  REAL err1, err2, err3;
5457  INEXACT REAL _i, _j;
5458  REAL _0;
5459 
5460  adx = (REAL) (pa[0] - pd[0]);
5461  bdx = (REAL) (pb[0] - pd[0]);
5462  cdx = (REAL) (pc[0] - pd[0]);
5463  ady = (REAL) (pa[1] - pd[1]);
5464  bdy = (REAL) (pb[1] - pd[1]);
5465  cdy = (REAL) (pc[1] - pd[1]);
5466 
5467  Two_Product(bdx, cdy, bdxcdy1, bdxcdy0);
5468  Two_Product(cdx, bdy, cdxbdy1, cdxbdy0);
5469  Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]);
5470  bc[3] = bc3;
5471  axbclen = scale_expansion_zeroelim(4, bc, adx, axbc);
5472  axxbclen = scale_expansion_zeroelim(axbclen, axbc, adx, axxbc);
5473  aybclen = scale_expansion_zeroelim(4, bc, ady, aybc);
5474  ayybclen = scale_expansion_zeroelim(aybclen, aybc, ady, ayybc);
5475  alen = fast_expansion_sum_zeroelim(axxbclen, axxbc, ayybclen, ayybc, adet);
5476 
5477  Two_Product(cdx, ady, cdxady1, cdxady0);
5478  Two_Product(adx, cdy, adxcdy1, adxcdy0);
5479  Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]);
5480  ca[3] = ca3;
5481  bxcalen = scale_expansion_zeroelim(4, ca, bdx, bxca);
5482  bxxcalen = scale_expansion_zeroelim(bxcalen, bxca, bdx, bxxca);
5483  bycalen = scale_expansion_zeroelim(4, ca, bdy, byca);
5484  byycalen = scale_expansion_zeroelim(bycalen, byca, bdy, byyca);
5485  blen = fast_expansion_sum_zeroelim(bxxcalen, bxxca, byycalen, byyca, bdet);
5486 
5487  Two_Product(adx, bdy, adxbdy1, adxbdy0);
5488  Two_Product(bdx, ady, bdxady1, bdxady0);
5489  Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]);
5490  ab[3] = ab3;
5491  cxablen = scale_expansion_zeroelim(4, ab, cdx, cxab);
5492  cxxablen = scale_expansion_zeroelim(cxablen, cxab, cdx, cxxab);
5493  cyablen = scale_expansion_zeroelim(4, ab, cdy, cyab);
5494  cyyablen = scale_expansion_zeroelim(cyablen, cyab, cdy, cyyab);
5495  clen = fast_expansion_sum_zeroelim(cxxablen, cxxab, cyyablen, cyyab, cdet);
5496 
5497  ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
5498  finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1);
5499 
5500  det = estimate(finlength, fin1);
5501  errbound = iccerrboundB * permanent;
5502  if ((det >= errbound) || (-det >= errbound)) {
5503  return det;
5504  }
5505 
5506  Two_Diff_Tail(pa[0], pd[0], adx, adxtail);
5507  Two_Diff_Tail(pa[1], pd[1], ady, adytail);
5508  Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail);
5509  Two_Diff_Tail(pb[1], pd[1], bdy, bdytail);
5510  Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail);
5511  Two_Diff_Tail(pc[1], pd[1], cdy, cdytail);
5512  if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0)
5513  && (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0)) {
5514  return det;
5515  }
5516 
5517  errbound = iccerrboundC * permanent + resulterrbound * Absolute(det);
5518  det += ((adx * adx + ady * ady) * ((bdx * cdytail + cdy * bdxtail)
5519  - (bdy * cdxtail + cdx * bdytail))
5520  + 2.0 * (adx * adxtail + ady * adytail) * (bdx * cdy - bdy * cdx))
5521  + ((bdx * bdx + bdy * bdy) * ((cdx * adytail + ady * cdxtail)
5522  - (cdy * adxtail + adx * cdytail))
5523  + 2.0 * (bdx * bdxtail + bdy * bdytail) * (cdx * ady - cdy * adx))
5524  + ((cdx * cdx + cdy * cdy) * ((adx * bdytail + bdy * adxtail)
5525  - (ady * bdxtail + bdx * adytail))
5526  + 2.0 * (cdx * cdxtail + cdy * cdytail) * (adx * bdy - ady * bdx));
5527  if ((det >= errbound) || (-det >= errbound)) {
5528  return det;
5529  }
5530 
5531  finnow = fin1;
5532  finother = fin2;
5533 
5534  if ((bdxtail != 0.0) || (bdytail != 0.0)
5535  || (cdxtail != 0.0) || (cdytail != 0.0)) {
5536  Square(adx, adxadx1, adxadx0);
5537  Square(ady, adyady1, adyady0);
5538  Two_Two_Sum(adxadx1, adxadx0, adyady1, adyady0, aa3, aa[2], aa[1], aa[0]);
5539  aa[3] = aa3;
5540  }
5541  if ((cdxtail != 0.0) || (cdytail != 0.0)
5542  || (adxtail != 0.0) || (adytail != 0.0)) {
5543  Square(bdx, bdxbdx1, bdxbdx0);
5544  Square(bdy, bdybdy1, bdybdy0);
5545  Two_Two_Sum(bdxbdx1, bdxbdx0, bdybdy1, bdybdy0, bb3, bb[2], bb[1], bb[0]);
5546  bb[3] = bb3;
5547  }
5548  if ((adxtail != 0.0) || (adytail != 0.0)
5549  || (bdxtail != 0.0) || (bdytail != 0.0)) {
5550  Square(cdx, cdxcdx1, cdxcdx0);
5551  Square(cdy, cdycdy1, cdycdy0);
5552  Two_Two_Sum(cdxcdx1, cdxcdx0, cdycdy1, cdycdy0, cc3, cc[2], cc[1], cc[0]);
5553  cc[3] = cc3;
5554  }
5555 
5556  if (adxtail != 0.0) {
5557  axtbclen = scale_expansion_zeroelim(4, bc, adxtail, axtbc);
5558  temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, 2.0 * adx,
5559  temp16a);
5560 
5561  axtcclen = scale_expansion_zeroelim(4, cc, adxtail, axtcc);
5562  temp16blen = scale_expansion_zeroelim(axtcclen, axtcc, bdy, temp16b);
5563 
5564  axtbblen = scale_expansion_zeroelim(4, bb, adxtail, axtbb);
5565  temp16clen = scale_expansion_zeroelim(axtbblen, axtbb, -cdy, temp16c);
5566 
5567  temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5568  temp16blen, temp16b, temp32a);
5569  temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
5570  temp32alen, temp32a, temp48);
5571  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5572  temp48, finother);
5573  finswap = finnow; finnow = finother; finother = finswap;
5574  }
5575  if (adytail != 0.0) {
5576  aytbclen = scale_expansion_zeroelim(4, bc, adytail, aytbc);
5577  temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, 2.0 * ady,
5578  temp16a);
5579 
5580  aytbblen = scale_expansion_zeroelim(4, bb, adytail, aytbb);
5581  temp16blen = scale_expansion_zeroelim(aytbblen, aytbb, cdx, temp16b);
5582 
5583  aytcclen = scale_expansion_zeroelim(4, cc, adytail, aytcc);
5584  temp16clen = scale_expansion_zeroelim(aytcclen, aytcc, -bdx, temp16c);
5585 
5586  temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5587  temp16blen, temp16b, temp32a);
5588  temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
5589  temp32alen, temp32a, temp48);
5590  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5591  temp48, finother);
5592  finswap = finnow; finnow = finother; finother = finswap;
5593  }
5594  if (bdxtail != 0.0) {
5595  bxtcalen = scale_expansion_zeroelim(4, ca, bdxtail, bxtca);
5596  temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, 2.0 * bdx,
5597  temp16a);
5598 
5599  bxtaalen = scale_expansion_zeroelim(4, aa, bdxtail, bxtaa);
5600  temp16blen = scale_expansion_zeroelim(bxtaalen, bxtaa, cdy, temp16b);
5601 
5602  bxtcclen = scale_expansion_zeroelim(4, cc, bdxtail, bxtcc);
5603  temp16clen = scale_expansion_zeroelim(bxtcclen, bxtcc, -ady, temp16c);
5604 
5605  temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5606  temp16blen, temp16b, temp32a);
5607  temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
5608  temp32alen, temp32a, temp48);
5609  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5610  temp48, finother);
5611  finswap = finnow; finnow = finother; finother = finswap;
5612  }
5613  if (bdytail != 0.0) {
5614  bytcalen = scale_expansion_zeroelim(4, ca, bdytail, bytca);
5615  temp16alen = scale_expansion_zeroelim(bytcalen, bytca, 2.0 * bdy,
5616  temp16a);
5617 
5618  bytcclen = scale_expansion_zeroelim(4, cc, bdytail, bytcc);
5619  temp16blen = scale_expansion_zeroelim(bytcclen, bytcc, adx, temp16b);
5620 
5621  bytaalen = scale_expansion_zeroelim(4, aa, bdytail, bytaa);
5622  temp16clen = scale_expansion_zeroelim(bytaalen, bytaa, -cdx, temp16c);
5623 
5624  temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5625  temp16blen, temp16b, temp32a);
5626  temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
5627  temp32alen, temp32a, temp48);
5628  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5629  temp48, finother);
5630  finswap = finnow; finnow = finother; finother = finswap;
5631  }
5632  if (cdxtail != 0.0) {
5633  cxtablen = scale_expansion_zeroelim(4, ab, cdxtail, cxtab);
5634  temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, 2.0 * cdx,
5635  temp16a);
5636 
5637  cxtbblen = scale_expansion_zeroelim(4, bb, cdxtail, cxtbb);
5638  temp16blen = scale_expansion_zeroelim(cxtbblen, cxtbb, ady, temp16b);
5639 
5640  cxtaalen = scale_expansion_zeroelim(4, aa, cdxtail, cxtaa);
5641  temp16clen = scale_expansion_zeroelim(cxtaalen, cxtaa, -bdy, temp16c);
5642 
5643  temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5644  temp16blen, temp16b, temp32a);
5645  temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
5646  temp32alen, temp32a, temp48);
5647  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5648  temp48, finother);
5649  finswap = finnow; finnow = finother; finother = finswap;
5650  }
5651  if (cdytail != 0.0) {
5652  cytablen = scale_expansion_zeroelim(4, ab, cdytail, cytab);
5653  temp16alen = scale_expansion_zeroelim(cytablen, cytab, 2.0 * cdy,
5654  temp16a);
5655 
5656  cytaalen = scale_expansion_zeroelim(4, aa, cdytail, cytaa);
5657  temp16blen = scale_expansion_zeroelim(cytaalen, cytaa, bdx, temp16b);
5658 
5659  cytbblen = scale_expansion_zeroelim(4, bb, cdytail, cytbb);
5660  temp16clen = scale_expansion_zeroelim(cytbblen, cytbb, -adx, temp16c);
5661 
5662  temp32alen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5663  temp16blen, temp16b, temp32a);
5664  temp48len = fast_expansion_sum_zeroelim(temp16clen, temp16c,
5665  temp32alen, temp32a, temp48);
5666  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5667  temp48, finother);
5668  finswap = finnow; finnow = finother; finother = finswap;
5669  }
5670 
5671  if ((adxtail != 0.0) || (adytail != 0.0)) {
5672  if ((bdxtail != 0.0) || (bdytail != 0.0)
5673  || (cdxtail != 0.0) || (cdytail != 0.0)) {
5674  Two_Product(bdxtail, cdy, ti1, ti0);
5675  Two_Product(bdx, cdytail, tj1, tj0);
5676  Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
5677  u[3] = u3;
5678  negate = -bdy;
5679  Two_Product(cdxtail, negate, ti1, ti0);
5680  negate = -bdytail;
5681  Two_Product(cdx, negate, tj1, tj0);
5682  Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
5683  v[3] = v3;
5684  bctlen = fast_expansion_sum_zeroelim(4, u, 4, v, bct);
5685 
5686  Two_Product(bdxtail, cdytail, ti1, ti0);
5687  Two_Product(cdxtail, bdytail, tj1, tj0);
5688  Two_Two_Diff(ti1, ti0, tj1, tj0, bctt3, bctt[2], bctt[1], bctt[0]);
5689  bctt[3] = bctt3;
5690  bcttlen = 4;
5691  } else {
5692  bct[0] = 0.0;
5693  bctlen = 1;
5694  bctt[0] = 0.0;
5695  bcttlen = 1;
5696  }
5697 
5698  if (adxtail != 0.0) {
5699  temp16alen = scale_expansion_zeroelim(axtbclen, axtbc, adxtail, temp16a);
5700  axtbctlen = scale_expansion_zeroelim(bctlen, bct, adxtail, axtbct);
5701  temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, 2.0 * adx,
5702  temp32a);
5703  temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5704  temp32alen, temp32a, temp48);
5705  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5706  temp48, finother);
5707  finswap = finnow; finnow = finother; finother = finswap;
5708  if (bdytail != 0.0) {
5709  temp8len = scale_expansion_zeroelim(4, cc, adxtail, temp8);
5710  temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail,
5711  temp16a);
5712  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
5713  temp16a, finother);
5714  finswap = finnow; finnow = finother; finother = finswap;
5715  }
5716  if (cdytail != 0.0) {
5717  temp8len = scale_expansion_zeroelim(4, bb, -adxtail, temp8);
5718  temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail,
5719  temp16a);
5720  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
5721  temp16a, finother);
5722  finswap = finnow; finnow = finother; finother = finswap;
5723  }
5724 
5725  temp32alen = scale_expansion_zeroelim(axtbctlen, axtbct, adxtail,
5726  temp32a);
5727  axtbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adxtail, axtbctt);
5728  temp16alen = scale_expansion_zeroelim(axtbcttlen, axtbctt, 2.0 * adx,
5729  temp16a);
5730  temp16blen = scale_expansion_zeroelim(axtbcttlen, axtbctt, adxtail,
5731  temp16b);
5732  temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5733  temp16blen, temp16b, temp32b);
5734  temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
5735  temp32blen, temp32b, temp64);
5736  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
5737  temp64, finother);
5738  finswap = finnow; finnow = finother; finother = finswap;
5739  }
5740  if (adytail != 0.0) {
5741  temp16alen = scale_expansion_zeroelim(aytbclen, aytbc, adytail, temp16a);
5742  aytbctlen = scale_expansion_zeroelim(bctlen, bct, adytail, aytbct);
5743  temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, 2.0 * ady,
5744  temp32a);
5745  temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5746  temp32alen, temp32a, temp48);
5747  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5748  temp48, finother);
5749  finswap = finnow; finnow = finother; finother = finswap;
5750 
5751 
5752  temp32alen = scale_expansion_zeroelim(aytbctlen, aytbct, adytail,
5753  temp32a);
5754  aytbcttlen = scale_expansion_zeroelim(bcttlen, bctt, adytail, aytbctt);
5755  temp16alen = scale_expansion_zeroelim(aytbcttlen, aytbctt, 2.0 * ady,
5756  temp16a);
5757  temp16blen = scale_expansion_zeroelim(aytbcttlen, aytbctt, adytail,
5758  temp16b);
5759  temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5760  temp16blen, temp16b, temp32b);
5761  temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
5762  temp32blen, temp32b, temp64);
5763  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
5764  temp64, finother);
5765  finswap = finnow; finnow = finother; finother = finswap;
5766  }
5767  }
5768  if ((bdxtail != 0.0) || (bdytail != 0.0)) {
5769  if ((cdxtail != 0.0) || (cdytail != 0.0)
5770  || (adxtail != 0.0) || (adytail != 0.0)) {
5771  Two_Product(cdxtail, ady, ti1, ti0);
5772  Two_Product(cdx, adytail, tj1, tj0);
5773  Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
5774  u[3] = u3;
5775  negate = -cdy;
5776  Two_Product(adxtail, negate, ti1, ti0);
5777  negate = -cdytail;
5778  Two_Product(adx, negate, tj1, tj0);
5779  Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
5780  v[3] = v3;
5781  catlen = fast_expansion_sum_zeroelim(4, u, 4, v, cat);
5782 
5783  Two_Product(cdxtail, adytail, ti1, ti0);
5784  Two_Product(adxtail, cdytail, tj1, tj0);
5785  Two_Two_Diff(ti1, ti0, tj1, tj0, catt3, catt[2], catt[1], catt[0]);
5786  catt[3] = catt3;
5787  cattlen = 4;
5788  } else {
5789  cat[0] = 0.0;
5790  catlen = 1;
5791  catt[0] = 0.0;
5792  cattlen = 1;
5793  }
5794 
5795  if (bdxtail != 0.0) {
5796  temp16alen = scale_expansion_zeroelim(bxtcalen, bxtca, bdxtail, temp16a);
5797  bxtcatlen = scale_expansion_zeroelim(catlen, cat, bdxtail, bxtcat);
5798  temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, 2.0 * bdx,
5799  temp32a);
5800  temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5801  temp32alen, temp32a, temp48);
5802  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5803  temp48, finother);
5804  finswap = finnow; finnow = finother; finother = finswap;
5805  if (cdytail != 0.0) {
5806  temp8len = scale_expansion_zeroelim(4, aa, bdxtail, temp8);
5807  temp16alen = scale_expansion_zeroelim(temp8len, temp8, cdytail,
5808  temp16a);
5809  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
5810  temp16a, finother);
5811  finswap = finnow; finnow = finother; finother = finswap;
5812  }
5813  if (adytail != 0.0) {
5814  temp8len = scale_expansion_zeroelim(4, cc, -bdxtail, temp8);
5815  temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail,
5816  temp16a);
5817  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
5818  temp16a, finother);
5819  finswap = finnow; finnow = finother; finother = finswap;
5820  }
5821 
5822  temp32alen = scale_expansion_zeroelim(bxtcatlen, bxtcat, bdxtail,
5823  temp32a);
5824  bxtcattlen = scale_expansion_zeroelim(cattlen, catt, bdxtail, bxtcatt);
5825  temp16alen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, 2.0 * bdx,
5826  temp16a);
5827  temp16blen = scale_expansion_zeroelim(bxtcattlen, bxtcatt, bdxtail,
5828  temp16b);
5829  temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5830  temp16blen, temp16b, temp32b);
5831  temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
5832  temp32blen, temp32b, temp64);
5833  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
5834  temp64, finother);
5835  finswap = finnow; finnow = finother; finother = finswap;
5836  }
5837  if (bdytail != 0.0) {
5838  temp16alen = scale_expansion_zeroelim(bytcalen, bytca, bdytail, temp16a);
5839  bytcatlen = scale_expansion_zeroelim(catlen, cat, bdytail, bytcat);
5840  temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, 2.0 * bdy,
5841  temp32a);
5842  temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5843  temp32alen, temp32a, temp48);
5844  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5845  temp48, finother);
5846  finswap = finnow; finnow = finother; finother = finswap;
5847 
5848 
5849  temp32alen = scale_expansion_zeroelim(bytcatlen, bytcat, bdytail,
5850  temp32a);
5851  bytcattlen = scale_expansion_zeroelim(cattlen, catt, bdytail, bytcatt);
5852  temp16alen = scale_expansion_zeroelim(bytcattlen, bytcatt, 2.0 * bdy,
5853  temp16a);
5854  temp16blen = scale_expansion_zeroelim(bytcattlen, bytcatt, bdytail,
5855  temp16b);
5856  temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5857  temp16blen, temp16b, temp32b);
5858  temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
5859  temp32blen, temp32b, temp64);
5860  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
5861  temp64, finother);
5862  finswap = finnow; finnow = finother; finother = finswap;
5863  }
5864  }
5865  if ((cdxtail != 0.0) || (cdytail != 0.0)) {
5866  if ((adxtail != 0.0) || (adytail != 0.0)
5867  || (bdxtail != 0.0) || (bdytail != 0.0)) {
5868  Two_Product(adxtail, bdy, ti1, ti0);
5869  Two_Product(adx, bdytail, tj1, tj0);
5870  Two_Two_Sum(ti1, ti0, tj1, tj0, u3, u[2], u[1], u[0]);
5871  u[3] = u3;
5872  negate = -ady;
5873  Two_Product(bdxtail, negate, ti1, ti0);
5874  negate = -adytail;
5875  Two_Product(bdx, negate, tj1, tj0);
5876  Two_Two_Sum(ti1, ti0, tj1, tj0, v3, v[2], v[1], v[0]);
5877  v[3] = v3;
5878  abtlen = fast_expansion_sum_zeroelim(4, u, 4, v, abt);
5879 
5880  Two_Product(adxtail, bdytail, ti1, ti0);
5881  Two_Product(bdxtail, adytail, tj1, tj0);
5882  Two_Two_Diff(ti1, ti0, tj1, tj0, abtt3, abtt[2], abtt[1], abtt[0]);
5883  abtt[3] = abtt3;
5884  abttlen = 4;
5885  } else {
5886  abt[0] = 0.0;
5887  abtlen = 1;
5888  abtt[0] = 0.0;
5889  abttlen = 1;
5890  }
5891 
5892  if (cdxtail != 0.0) {
5893  temp16alen = scale_expansion_zeroelim(cxtablen, cxtab, cdxtail, temp16a);
5894  cxtabtlen = scale_expansion_zeroelim(abtlen, abt, cdxtail, cxtabt);
5895  temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, 2.0 * cdx,
5896  temp32a);
5897  temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5898  temp32alen, temp32a, temp48);
5899  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5900  temp48, finother);
5901  finswap = finnow; finnow = finother; finother = finswap;
5902  if (adytail != 0.0) {
5903  temp8len = scale_expansion_zeroelim(4, bb, cdxtail, temp8);
5904  temp16alen = scale_expansion_zeroelim(temp8len, temp8, adytail,
5905  temp16a);
5906  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
5907  temp16a, finother);
5908  finswap = finnow; finnow = finother; finother = finswap;
5909  }
5910  if (bdytail != 0.0) {
5911  temp8len = scale_expansion_zeroelim(4, aa, -cdxtail, temp8);
5912  temp16alen = scale_expansion_zeroelim(temp8len, temp8, bdytail,
5913  temp16a);
5914  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp16alen,
5915  temp16a, finother);
5916  finswap = finnow; finnow = finother; finother = finswap;
5917  }
5918 
5919  temp32alen = scale_expansion_zeroelim(cxtabtlen, cxtabt, cdxtail,
5920  temp32a);
5921  cxtabttlen = scale_expansion_zeroelim(abttlen, abtt, cdxtail, cxtabtt);
5922  temp16alen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, 2.0 * cdx,
5923  temp16a);
5924  temp16blen = scale_expansion_zeroelim(cxtabttlen, cxtabtt, cdxtail,
5925  temp16b);
5926  temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5927  temp16blen, temp16b, temp32b);
5928  temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
5929  temp32blen, temp32b, temp64);
5930  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
5931  temp64, finother);
5932  finswap = finnow; finnow = finother; finother = finswap;
5933  }
5934  if (cdytail != 0.0) {
5935  temp16alen = scale_expansion_zeroelim(cytablen, cytab, cdytail, temp16a);
5936  cytabtlen = scale_expansion_zeroelim(abtlen, abt, cdytail, cytabt);
5937  temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, 2.0 * cdy,
5938  temp32a);
5939  temp48len = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5940  temp32alen, temp32a, temp48);
5941  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp48len,
5942  temp48, finother);
5943  finswap = finnow; finnow = finother; finother = finswap;
5944 
5945 
5946  temp32alen = scale_expansion_zeroelim(cytabtlen, cytabt, cdytail,
5947  temp32a);
5948  cytabttlen = scale_expansion_zeroelim(abttlen, abtt, cdytail, cytabtt);
5949  temp16alen = scale_expansion_zeroelim(cytabttlen, cytabtt, 2.0 * cdy,
5950  temp16a);
5951  temp16blen = scale_expansion_zeroelim(cytabttlen, cytabtt, cdytail,
5952  temp16b);
5953  temp32blen = fast_expansion_sum_zeroelim(temp16alen, temp16a,
5954  temp16blen, temp16b, temp32b);
5955  temp64len = fast_expansion_sum_zeroelim(temp32alen, temp32a,
5956  temp32blen, temp32b, temp64);
5957  finlength = fast_expansion_sum_zeroelim(finlength, finnow, temp64len,
5958  temp64, finother);
5959  finswap = finnow; finnow = finother; finother = finswap;
5960  }
5961  }
5962 
5963  return finnow[finlength - 1];
5964 }
5965 
5966 #ifdef ANSI_DECLARATORS
5967 REAL incircle(struct mesh *m, struct behavior *b,
5968  vertex pa, vertex pb, vertex pc, vertex pd)
5969 #else /* not ANSI_DECLARATORS */
5970 REAL incircle(m, b, pa, pb, pc, pd)
5971 struct mesh *m;
5972 struct behavior *b;
5973 vertex pa;
5974 vertex pb;
5975 vertex pc;
5976 vertex pd;
5977 #endif /* not ANSI_DECLARATORS */
5978 
5979 {
5980  REAL adx, bdx, cdx, ady, bdy, cdy;
5981  REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
5982  REAL alift, blift, clift;
5983  REAL det;
5984  REAL permanent, errbound;
5985 
5986  m->incirclecount++;
5987 
5988  adx = pa[0] - pd[0];
5989  bdx = pb[0] - pd[0];
5990  cdx = pc[0] - pd[0];
5991  ady = pa[1] - pd[1];
5992  bdy = pb[1] - pd[1];
5993  cdy = pc[1] - pd[1];
5994 
5995  bdxcdy = bdx * cdy;
5996  cdxbdy = cdx * bdy;
5997  alift = adx * adx + ady * ady;
5998 
5999  cdxady = cdx * ady;
6000  adxcdy = adx * cdy;
6001  blift = bdx * bdx + bdy * bdy;
6002 
6003  adxbdy = adx * bdy;
6004  bdxady = bdx * ady;
6005  clift = cdx * cdx + cdy * cdy;
6006 
6007  det = alift * (bdxcdy - cdxbdy)
6008  + blift * (cdxady - adxcdy)
6009  + clift * (adxbdy - bdxady);
6010 
6011  if (b->noexact) {
6012  return det;
6013  }
6014 
6015  permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * alift
6016  + (Absolute(cdxady) + Absolute(adxcdy)) * blift
6017  + (Absolute(adxbdy) + Absolute(bdxady)) * clift;
6018  errbound = iccerrboundA * permanent;
6019  if ((det > errbound) || (-det > errbound)) {
6020  return det;
6021  }
6022 
6023  return incircleadapt(pa, pb, pc, pd, permanent);
6024 }
6025 
6026 /*****************************************************************************/
6027 /* */
6028 /* orient3d() Return a positive value if the point pd lies below the */
6029 /* plane passing through pa, pb, and pc; "below" is defined so */
6030 /* that pa, pb, and pc appear in counterclockwise order when */
6031 /* viewed from above the plane. Returns a negative value if */
6032 /* pd lies above the plane. Returns zero if the points are */
6033 /* coplanar. The result is also a rough approximation of six */
6034 /* times the signed volume of the tetrahedron defined by the */
6035 /* four points. */
6036 /* */
6037 /* Uses exact arithmetic if necessary to ensure a correct answer. The */
6038 /* result returned is the determinant of a matrix. This determinant is */
6039 /* computed adaptively, in the sense that exact arithmetic is used only to */
6040 /* the degree it is needed to ensure that the returned value has the */
6041 /* correct sign. Hence, this function is usually quite fast, but will run */
6042 /* more slowly when the input points are coplanar or nearly so. */
6043 /* */
6044 /* See my Robust Predicates paper for details. */
6045 /* */
6046 /*****************************************************************************/
6047 
6048 #ifdef ANSI_DECLARATORS
6049 REAL orient3dadapt(vertex pa, vertex pb, vertex pc, vertex pd,
6050  REAL aheight, REAL bheight, REAL cheight, REAL dheight,
6051  REAL permanent)
6052 #else /* not ANSI_DECLARATORS */
6053 REAL orient3dadapt(pa, pb, pc, pd,
6054  aheight, bheight, cheight, dheight, permanent)
6055 vertex pa;
6056 vertex pb;
6057 vertex pc;
6058 vertex pd;
6059 REAL aheight;
6060 REAL bheight;
6061 REAL cheight;
6062 REAL dheight;
6063 REAL permanent;
6064 #endif /* not ANSI_DECLARATORS */
6065 
6066 {
6067  INEXACT REAL adx, bdx, cdx, ady, bdy, cdy, adheight, bdheight, cdheight;
6068  REAL det, errbound;
6069 
6070  INEXACT REAL bdxcdy1, cdxbdy1, cdxady1, adxcdy1, adxbdy1, bdxady1;
6071  REAL bdxcdy0, cdxbdy0, cdxady0, adxcdy0, adxbdy0, bdxady0;
6072  REAL bc[4], ca[4], ab[4];
6073  INEXACT REAL bc3, ca3, ab3;
6074  REAL adet[8], bdet[8], cdet[8];
6075  int alen, blen, clen;
6076  REAL abdet[16];
6077  int ablen;
6078  REAL *finnow, *finother, *finswap;
6079  REAL fin1[192], fin2[192];
6080  int finlength;
6081 
6082  REAL adxtail, bdxtail, cdxtail;
6083  REAL adytail, bdytail, cdytail;
6084  REAL adheighttail, bdheighttail, cdheighttail;
6085  INEXACT REAL at_blarge, at_clarge;
6086  INEXACT REAL bt_clarge, bt_alarge;
6087  INEXACT REAL ct_alarge, ct_blarge;
6088  REAL at_b[4], at_c[4], bt_c[4], bt_a[4], ct_a[4], ct_b[4];
6089  int at_blen, at_clen, bt_clen, bt_alen, ct_alen, ct_blen;
6090  INEXACT REAL bdxt_cdy1, cdxt_bdy1, cdxt_ady1;
6091  INEXACT REAL adxt_cdy1, adxt_bdy1, bdxt_ady1;
6092  REAL bdxt_cdy0, cdxt_bdy0, cdxt_ady0;
6093  REAL adxt_cdy0, adxt_bdy0, bdxt_ady0;
6094  INEXACT REAL bdyt_cdx1, cdyt_bdx1, cdyt_adx1;
6095  INEXACT REAL adyt_cdx1, adyt_bdx1, bdyt_adx1;
6096  REAL bdyt_cdx0, cdyt_bdx0, cdyt_adx0;
6097  REAL adyt_cdx0, adyt_bdx0, bdyt_adx0;
6098  REAL bct[8], cat[8], abt[8];
6099  int bctlen, catlen, abtlen;
6100  INEXACT REAL bdxt_cdyt1, cdxt_bdyt1, cdxt_adyt1;
6101  INEXACT REAL adxt_cdyt1, adxt_bdyt1, bdxt_adyt1;
6102  REAL bdxt_cdyt0, cdxt_bdyt0, cdxt_adyt0;
6103  REAL adxt_cdyt0, adxt_bdyt0, bdxt_adyt0;
6104  REAL u[4], v[12], w[16];
6105  INEXACT REAL u3;
6106  int vlength, wlength;
6107  REAL negate;
6108 
6109  INEXACT REAL bvirt;
6110  REAL avirt, bround, around;
6111  INEXACT REAL c;
6112  INEXACT REAL abig;
6113  REAL ahi, alo, bhi, blo;
6114  REAL err1, err2, err3;
6115  INEXACT REAL _i, _j, _k;
6116  REAL _0;
6117 
6118  adx = (REAL) (pa[0] - pd[0]);
6119  bdx = (REAL) (pb[0] - pd[0]);
6120  cdx = (REAL) (pc[0] - pd[0]);
6121  ady = (REAL) (pa[1] - pd[1]);
6122  bdy = (REAL) (pb[1] - pd[1]);
6123  cdy = (REAL) (pc[1] - pd[1]);
6124  adheight = (REAL) (aheight - dheight);
6125  bdheight = (REAL) (bheight - dheight);
6126  cdheight = (REAL) (cheight - dheight);
6127 
6128  Two_Product(bdx, cdy, bdxcdy1, bdxcdy0);
6129  Two_Product(cdx, bdy, cdxbdy1, cdxbdy0);
6130  Two_Two_Diff(bdxcdy1, bdxcdy0, cdxbdy1, cdxbdy0, bc3, bc[2], bc[1], bc[0]);
6131  bc[3] = bc3;
6132  alen = scale_expansion_zeroelim(4, bc, adheight, adet);
6133 
6134  Two_Product(cdx, ady, cdxady1, cdxady0);
6135  Two_Product(adx, cdy, adxcdy1, adxcdy0);
6136  Two_Two_Diff(cdxady1, cdxady0, adxcdy1, adxcdy0, ca3, ca[2], ca[1], ca[0]);
6137  ca[3] = ca3;
6138  blen = scale_expansion_zeroelim(4, ca, bdheight, bdet);
6139 
6140  Two_Product(adx, bdy, adxbdy1, adxbdy0);
6141  Two_Product(bdx, ady, bdxady1, bdxady0);
6142  Two_Two_Diff(adxbdy1, adxbdy0, bdxady1, bdxady0, ab3, ab[2], ab[1], ab[0]);
6143  ab[3] = ab3;
6144  clen = scale_expansion_zeroelim(4, ab, cdheight, cdet);
6145 
6146  ablen = fast_expansion_sum_zeroelim(alen, adet, blen, bdet, abdet);
6147  finlength = fast_expansion_sum_zeroelim(ablen, abdet, clen, cdet, fin1);
6148 
6149  det = estimate(finlength, fin1);
6150  errbound = o3derrboundB * permanent;
6151  if ((det >= errbound) || (-det >= errbound)) {
6152  return det;
6153  }
6154 
6155  Two_Diff_Tail(pa[0], pd[0], adx, adxtail);
6156  Two_Diff_Tail(pb[0], pd[0], bdx, bdxtail);
6157  Two_Diff_Tail(pc[0], pd[0], cdx, cdxtail);
6158  Two_Diff_Tail(pa[1], pd[1], ady, adytail);
6159  Two_Diff_Tail(pb[1], pd[1], bdy, bdytail);
6160  Two_Diff_Tail(pc[1], pd[1], cdy, cdytail);
6161  Two_Diff_Tail(aheight, dheight, adheight, adheighttail);
6162  Two_Diff_Tail(bheight, dheight, bdheight, bdheighttail);
6163  Two_Diff_Tail(cheight, dheight, cdheight, cdheighttail);
6164 
6165  if ((adxtail == 0.0) && (bdxtail == 0.0) && (cdxtail == 0.0) &&
6166  (adytail == 0.0) && (bdytail == 0.0) && (cdytail == 0.0) &&
6167  (adheighttail == 0.0) &&
6168  (bdheighttail == 0.0) &&
6169  (cdheighttail == 0.0)) {
6170  return det;
6171  }
6172 
6173  errbound = o3derrboundC * permanent + resulterrbound * Absolute(det);
6174  det += (adheight * ((bdx * cdytail + cdy * bdxtail) -
6175  (bdy * cdxtail + cdx * bdytail)) +
6176  adheighttail * (bdx * cdy - bdy * cdx)) +
6177  (bdheight * ((cdx * adytail + ady * cdxtail) -
6178  (cdy * adxtail + adx * cdytail)) +
6179  bdheighttail * (cdx * ady - cdy * adx)) +
6180  (cdheight * ((adx * bdytail + bdy * adxtail) -
6181  (ady * bdxtail + bdx * adytail)) +
6182  cdheighttail * (adx * bdy - ady * bdx));
6183  if ((det >= errbound) || (-det >= errbound)) {
6184  return det;
6185  }
6186 
6187  finnow = fin1;
6188  finother = fin2;
6189 
6190  if (adxtail == 0.0) {
6191  if (adytail == 0.0) {
6192  at_b[0] = 0.0;
6193  at_blen = 1;
6194  at_c[0] = 0.0;
6195  at_clen = 1;
6196  } else {
6197  negate = -adytail;
6198  Two_Product(negate, bdx, at_blarge, at_b[0]);
6199  at_b[1] = at_blarge;
6200  at_blen = 2;
6201  Two_Product(adytail, cdx, at_clarge, at_c[0]);
6202  at_c[1] = at_clarge;
6203  at_clen = 2;
6204  }
6205  } else {
6206  if (adytail == 0.0) {
6207  Two_Product(adxtail, bdy, at_blarge, at_b[0]);
6208  at_b[1] = at_blarge;
6209  at_blen = 2;
6210  negate = -adxtail;
6211  Two_Product(negate, cdy, at_clarge, at_c[0]);
6212  at_c[1] = at_clarge;
6213  at_clen = 2;
6214  } else {
6215  Two_Product(adxtail, bdy, adxt_bdy1, adxt_bdy0);
6216  Two_Product(adytail, bdx, adyt_bdx1, adyt_bdx0);
6217  Two_Two_Diff(adxt_bdy1, adxt_bdy0, adyt_bdx1, adyt_bdx0,
6218  at_blarge, at_b[2], at_b[1], at_b[0]);
6219  at_b[3] = at_blarge;
6220  at_blen = 4;
6221  Two_Product(adytail, cdx, adyt_cdx1, adyt_cdx0);
6222  Two_Product(adxtail, cdy, adxt_cdy1, adxt_cdy0);
6223  Two_Two_Diff(adyt_cdx1, adyt_cdx0, adxt_cdy1, adxt_cdy0,
6224  at_clarge, at_c[2], at_c[1], at_c[0]);
6225  at_c[3] = at_clarge;
6226  at_clen = 4;
6227  }
6228  }
6229  if (bdxtail == 0.0) {
6230  if (bdytail == 0.0) {
6231  bt_c[0] = 0.0;
6232  bt_clen = 1;
6233  bt_a[0] = 0.0;
6234  bt_alen = 1;
6235  } else {
6236  negate = -bdytail;
6237  Two_Product(negate, cdx, bt_clarge, bt_c[0]);
6238  bt_c[1] = bt_clarge;
6239  bt_clen = 2;
6240  Two_Product(bdytail, adx, bt_alarge, bt_a[0]);
6241  bt_a[1] = bt_alarge;
6242  bt_alen = 2;
6243  }
6244  } else {
6245  if (bdytail == 0.0) {
6246  Two_Product(bdxtail, cdy, bt_clarge, bt_c[0]);
6247  bt_c[1] = bt_clarge;
6248  bt_clen = 2;
6249  negate = -bdxtail;
6250  Two_Product(negate, ady, bt_alarge, bt_a[0]);
6251  bt_a[1] = bt_alarge;
6252  bt_alen = 2;
6253  } else {
6254  Two_Product(bdxtail, cdy, bdxt_cdy1, bdxt_cdy0);
6255  Two_Product(bdytail, cdx, bdyt_cdx1, bdyt_cdx0);
6256  Two_Two_Diff(bdxt_cdy1, bdxt_cdy0, bdyt_cdx1, bdyt_cdx0,
6257  bt_clarge, bt_c[2], bt_c[1], bt_c[0]);
6258  bt_c[3] = bt_clarge;
6259  bt_clen = 4;
6260  Two_Product(bdytail, adx, bdyt_adx1, bdyt_adx0);
6261  Two_Product(bdxtail, ady, bdxt_ady1, bdxt_ady0);
6262  Two_Two_Diff(bdyt_adx1, bdyt_adx0, bdxt_ady1, bdxt_ady0,
6263  bt_alarge, bt_a[2], bt_a[1], bt_a[0]);
6264  bt_a[3] = bt_alarge;
6265  bt_alen = 4;
6266  }
6267  }
6268  if (cdxtail == 0.0) {
6269  if (cdytail == 0.0) {
6270  ct_a[0] = 0.0;
6271  ct_alen = 1;
6272  ct_b[0] = 0.0;
6273  ct_blen = 1;
6274  } else {
6275  negate = -cdytail;
6276  Two_Product(negate, adx, ct_alarge, ct_a[0]);
6277  ct_a[1] = ct_alarge;
6278  ct_alen = 2;
6279  Two_Product(cdytail, bdx, ct_blarge, ct_b[0]);
6280  ct_b[1] = ct_blarge;
6281  ct_blen = 2;
6282  }
6283  } else {
6284  if (cdytail == 0.0) {
6285  Two_Product(cdxtail, ady, ct_alarge, ct_a[0]);
6286  ct_a[1] = ct_alarge;
6287  ct_alen = 2;
6288  negate = -cdxtail;
6289  Two_Product(negate, bdy, ct_blarge, ct_b[0]);
6290  ct_b[1] = ct_blarge;
6291  ct_blen = 2;
6292  } else {
6293  Two_Product(cdxtail, ady, cdxt_ady1, cdxt_ady0);
6294  Two_Product(cdytail, adx, cdyt_adx1, cdyt_adx0);
6295  Two_Two_Diff(cdxt_ady1, cdxt_ady0, cdyt_adx1, cdyt_adx0,
6296  ct_alarge, ct_a[2], ct_a[1], ct_a[0]);
6297  ct_a[3] = ct_alarge;
6298  ct_alen = 4;
6299  Two_Product(cdytail, bdx, cdyt_bdx1, cdyt_bdx0);
6300  Two_Product(cdxtail, bdy, cdxt_bdy1, cdxt_bdy0);
6301  Two_Two_Diff(cdyt_bdx1, cdyt_bdx0, cdxt_bdy1, cdxt_bdy0,
6302  ct_blarge, ct_b[2], ct_b[1], ct_b[0]);
6303  ct_b[3] = ct_blarge;
6304  ct_blen = 4;
6305  }
6306  }
6307 
6308  bctlen = fast_expansion_sum_zeroelim(bt_clen, bt_c, ct_blen, ct_b, bct);
6309  wlength = scale_expansion_zeroelim(bctlen, bct, adheight, w);
6310  finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
6311  finother);
6312  finswap = finnow; finnow = finother; finother = finswap;
6313 
6314  catlen = fast_expansion_sum_zeroelim(ct_alen, ct_a, at_clen, at_c, cat);
6315  wlength = scale_expansion_zeroelim(catlen, cat, bdheight, w);
6316  finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
6317  finother);
6318  finswap = finnow; finnow = finother; finother = finswap;
6319 
6320  abtlen = fast_expansion_sum_zeroelim(at_blen, at_b, bt_alen, bt_a, abt);
6321  wlength = scale_expansion_zeroelim(abtlen, abt, cdheight, w);
6322  finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
6323  finother);
6324  finswap = finnow; finnow = finother; finother = finswap;
6325 
6326  if (adheighttail != 0.0) {
6327  vlength = scale_expansion_zeroelim(4, bc, adheighttail, v);
6328  finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
6329  finother);
6330  finswap = finnow; finnow = finother; finother = finswap;
6331  }
6332  if (bdheighttail != 0.0) {
6333  vlength = scale_expansion_zeroelim(4, ca, bdheighttail, v);
6334  finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
6335  finother);
6336  finswap = finnow; finnow = finother; finother = finswap;
6337  }
6338  if (cdheighttail != 0.0) {
6339  vlength = scale_expansion_zeroelim(4, ab, cdheighttail, v);
6340  finlength = fast_expansion_sum_zeroelim(finlength, finnow, vlength, v,
6341  finother);
6342  finswap = finnow; finnow = finother; finother = finswap;
6343  }
6344 
6345  if (adxtail != 0.0) {
6346  if (bdytail != 0.0) {
6347  Two_Product(adxtail, bdytail, adxt_bdyt1, adxt_bdyt0);
6348  Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdheight, u3, u[2], u[1], u[0]);
6349  u[3] = u3;
6350  finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6351  finother);
6352  finswap = finnow; finnow = finother; finother = finswap;
6353  if (cdheighttail != 0.0) {
6354  Two_One_Product(adxt_bdyt1, adxt_bdyt0, cdheighttail,
6355  u3, u[2], u[1], u[0]);
6356  u[3] = u3;
6357  finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6358  finother);
6359  finswap = finnow; finnow = finother; finother = finswap;
6360  }
6361  }
6362  if (cdytail != 0.0) {
6363  negate = -adxtail;
6364  Two_Product(negate, cdytail, adxt_cdyt1, adxt_cdyt0);
6365  Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdheight, u3, u[2], u[1], u[0]);
6366  u[3] = u3;
6367  finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6368  finother);
6369  finswap = finnow; finnow = finother; finother = finswap;
6370  if (bdheighttail != 0.0) {
6371  Two_One_Product(adxt_cdyt1, adxt_cdyt0, bdheighttail,
6372  u3, u[2], u[1], u[0]);
6373  u[3] = u3;
6374  finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6375  finother);
6376  finswap = finnow; finnow = finother; finother = finswap;
6377  }
6378  }
6379  }
6380  if (bdxtail != 0.0) {
6381  if (cdytail != 0.0) {
6382  Two_Product(bdxtail, cdytail, bdxt_cdyt1, bdxt_cdyt0);
6383  Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adheight, u3, u[2], u[1], u[0]);
6384  u[3] = u3;
6385  finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6386  finother);
6387  finswap = finnow; finnow = finother; finother = finswap;
6388  if (adheighttail != 0.0) {
6389  Two_One_Product(bdxt_cdyt1, bdxt_cdyt0, adheighttail,
6390  u3, u[2], u[1], u[0]);
6391  u[3] = u3;
6392  finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6393  finother);
6394  finswap = finnow; finnow = finother; finother = finswap;
6395  }
6396  }
6397  if (adytail != 0.0) {
6398  negate = -bdxtail;
6399  Two_Product(negate, adytail, bdxt_adyt1, bdxt_adyt0);
6400  Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdheight, u3, u[2], u[1], u[0]);
6401  u[3] = u3;
6402  finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6403  finother);
6404  finswap = finnow; finnow = finother; finother = finswap;
6405  if (cdheighttail != 0.0) {
6406  Two_One_Product(bdxt_adyt1, bdxt_adyt0, cdheighttail,
6407  u3, u[2], u[1], u[0]);
6408  u[3] = u3;
6409  finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6410  finother);
6411  finswap = finnow; finnow = finother; finother = finswap;
6412  }
6413  }
6414  }
6415  if (cdxtail != 0.0) {
6416  if (adytail != 0.0) {
6417  Two_Product(cdxtail, adytail, cdxt_adyt1, cdxt_adyt0);
6418  Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdheight, u3, u[2], u[1], u[0]);
6419  u[3] = u3;
6420  finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6421  finother);
6422  finswap = finnow; finnow = finother; finother = finswap;
6423  if (bdheighttail != 0.0) {
6424  Two_One_Product(cdxt_adyt1, cdxt_adyt0, bdheighttail,
6425  u3, u[2], u[1], u[0]);
6426  u[3] = u3;
6427  finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6428  finother);
6429  finswap = finnow; finnow = finother; finother = finswap;
6430  }
6431  }
6432  if (bdytail != 0.0) {
6433  negate = -cdxtail;
6434  Two_Product(negate, bdytail, cdxt_bdyt1, cdxt_bdyt0);
6435  Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adheight, u3, u[2], u[1], u[0]);
6436  u[3] = u3;
6437  finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6438  finother);
6439  finswap = finnow; finnow = finother; finother = finswap;
6440  if (adheighttail != 0.0) {
6441  Two_One_Product(cdxt_bdyt1, cdxt_bdyt0, adheighttail,
6442  u3, u[2], u[1], u[0]);
6443  u[3] = u3;
6444  finlength = fast_expansion_sum_zeroelim(finlength, finnow, 4, u,
6445  finother);
6446  finswap = finnow; finnow = finother; finother = finswap;
6447  }
6448  }
6449  }
6450 
6451  if (adheighttail != 0.0) {
6452  wlength = scale_expansion_zeroelim(bctlen, bct, adheighttail, w);
6453  finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
6454  finother);
6455  finswap = finnow; finnow = finother; finother = finswap;
6456  }
6457  if (bdheighttail != 0.0) {
6458  wlength = scale_expansion_zeroelim(catlen, cat, bdheighttail, w);
6459  finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
6460  finother);
6461  finswap = finnow; finnow = finother; finother = finswap;
6462  }
6463  if (cdheighttail != 0.0) {
6464  wlength = scale_expansion_zeroelim(abtlen, abt, cdheighttail, w);
6465  finlength = fast_expansion_sum_zeroelim(finlength, finnow, wlength, w,
6466  finother);
6467  finswap = finnow; finnow = finother; finother = finswap;
6468  }
6469 
6470  return finnow[finlength - 1];
6471 }
6472 
6473 #ifdef ANSI_DECLARATORS
6474 REAL orient3d(struct mesh *m, struct behavior *b,
6475  vertex pa, vertex pb, vertex pc, vertex pd,
6476  REAL aheight, REAL bheight, REAL cheight, REAL dheight)
6477 #else /* not ANSI_DECLARATORS */
6478 REAL orient3d(m, b, pa, pb, pc, pd, aheight, bheight, cheight, dheight)
6479 struct mesh *m;
6480 struct behavior *b;
6481 vertex pa;
6482 vertex pb;
6483 vertex pc;
6484 vertex pd;
6485 REAL aheight;
6486 REAL bheight;
6487 REAL cheight;
6488 REAL dheight;
6489 #endif /* not ANSI_DECLARATORS */
6490 
6491 {
6492  REAL adx, bdx, cdx, ady, bdy, cdy, adheight, bdheight, cdheight;
6493  REAL bdxcdy, cdxbdy, cdxady, adxcdy, adxbdy, bdxady;
6494  REAL det;
6495  REAL permanent, errbound;
6496 
6497  m->orient3dcount++;
6498 
6499  adx = pa[0] - pd[0];
6500  bdx = pb[0] - pd[0];
6501  cdx = pc[0] - pd[0];
6502  ady = pa[1] - pd[1];
6503  bdy = pb[1] - pd[1];
6504  cdy = pc[1] - pd[1];
6505  adheight = aheight - dheight;
6506  bdheight = bheight - dheight;
6507  cdheight = cheight - dheight;
6508 
6509  bdxcdy = bdx * cdy;
6510  cdxbdy = cdx * bdy;
6511 
6512  cdxady = cdx * ady;
6513  adxcdy = adx * cdy;
6514 
6515  adxbdy = adx * bdy;
6516  bdxady = bdx * ady;
6517 
6518  det = adheight * (bdxcdy - cdxbdy)
6519  + bdheight * (cdxady - adxcdy)
6520  + cdheight * (adxbdy - bdxady);
6521 
6522  if (b->noexact) {
6523  return det;
6524  }
6525 
6526  permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * Absolute(adheight)
6527  + (Absolute(cdxady) + Absolute(adxcdy)) * Absolute(bdheight)
6528  + (Absolute(adxbdy) + Absolute(bdxady)) * Absolute(cdheight);
6529  errbound = o3derrboundA * permanent;
6530  if ((det > errbound) || (-det > errbound)) {
6531  return det;
6532  }
6533 
6534  return orient3dadapt(pa, pb, pc, pd, aheight, bheight, cheight, dheight,
6535  permanent);
6536 }
6537 
6538 /*****************************************************************************/
6539 /* */
6540 /* nonregular() Return a positive value if the point pd is incompatible */
6541 /* with the circle or plane passing through pa, pb, and pc */
6542 /* (meaning that pd is inside the circle or below the */
6543 /* plane); a negative value if it is compatible; and zero if */
6544 /* the four points are cocircular/coplanar. The points pa, */
6545 /* pb, and pc must be in counterclockwise order, or the sign */
6546 /* of the result will be reversed. */
6547 /* */
6548 /* If the -w switch is used, the points are lifted onto the parabolic */
6549 /* lifting map, then they are dropped according to their weights, then the */
6550 /* 3D orientation test is applied. If the -W switch is used, the points' */
6551 /* heights are already provided, so the 3D orientation test is applied */
6552 /* directly. If neither switch is used, the incircle test is applied. */
6553 /* */
6554 /*****************************************************************************/
6555 
6556 #ifdef ANSI_DECLARATORS
6557 REAL nonregular(struct mesh *m, struct behavior *b,
6558  vertex pa, vertex pb, vertex pc, vertex pd)
6559 #else /* not ANSI_DECLARATORS */
6560 REAL nonregular(m, b, pa, pb, pc, pd)
6561 struct mesh *m;
6562 struct behavior *b;
6563 vertex pa;
6564 vertex pb;
6565 vertex pc;
6566 vertex pd;
6567 #endif /* not ANSI_DECLARATORS */
6568 
6569 {
6570  if (b->weighted == 0) {
6571  return incircle(m, b, pa, pb, pc, pd);
6572  } else if (b->weighted == 1) {
6573  return orient3d(m, b, pa, pb, pc, pd,
6574  pa[0] * pa[0] + pa[1] * pa[1] - pa[2],
6575  pb[0] * pb[0] + pb[1] * pb[1] - pb[2],
6576  pc[0] * pc[0] + pc[1] * pc[1] - pc[2],
6577  pd[0] * pd[0] + pd[1] * pd[1] - pd[2]);
6578  } else {
6579  return orient3d(m, b, pa, pb, pc, pd, pa[2], pb[2], pc[2], pd[2]);
6580  }
6581 }
6582 
6583 /*****************************************************************************/
6584 /* */
6585 /* findcircumcenter() Find the circumcenter of a triangle. */
6586 /* */
6587 /* The result is returned both in terms of x-y coordinates and xi-eta */
6588 /* (barycentric) coordinates. The xi-eta coordinate system is defined in */
6589 /* terms of the triangle: the origin of the triangle is the origin of the */
6590 /* coordinate system; the destination of the triangle is one unit along the */
6591 /* xi axis; and the apex of the triangle is one unit along the eta axis. */
6592 /* This procedure also returns the square of the length of the triangle's */
6593 /* shortest edge. */
6594 /* */
6595 /*****************************************************************************/
6596 
6597 #ifdef ANSI_DECLARATORS
6598 void findcircumcenter(struct mesh *m, struct behavior *b,
6599  vertex torg, vertex tdest, vertex tapex,
6600  vertex circumcenter, REAL *xi, REAL *eta, int offcenter)
6601 #else /* not ANSI_DECLARATORS */
6602 void findcircumcenter(m, b, torg, tdest, tapex, circumcenter, xi, eta,
6603  offcenter)
6604 struct mesh *m;
6605 struct behavior *b;
6606 vertex torg;
6607 vertex tdest;
6608 vertex tapex;
6609 vertex circumcenter;
6610 REAL *xi;
6611 REAL *eta;
6612 int offcenter;
6613 #endif /* not ANSI_DECLARATORS */
6614 
6615 {
6616  REAL xdo, ydo, xao, yao;
6617  REAL dodist, aodist, dadist;
6618  REAL denominator;
6619  REAL dx, dy, dxoff, dyoff;
6620 
6621  m->circumcentercount++;
6622 
6623  /* Compute the circumcenter of the triangle. */
6624  xdo = tdest[0] - torg[0];
6625  ydo = tdest[1] - torg[1];
6626  xao = tapex[0] - torg[0];
6627  yao = tapex[1] - torg[1];
6628  dodist = xdo * xdo + ydo * ydo;
6629  aodist = xao * xao + yao * yao;
6630  dadist = (tdest[0] - tapex[0]) * (tdest[0] - tapex[0]) +
6631  (tdest[1] - tapex[1]) * (tdest[1] - tapex[1]);
6632  if (b->noexact) {
6633  denominator = 0.5 / (xdo * yao - xao * ydo);
6634  } else {
6635  /* Use the counterclockwise() routine to ensure a positive (and */
6636  /* reasonably accurate) result, avoiding any possibility of */
6637  /* division by zero. */
6638  denominator = 0.5 / counterclockwise(m, b, tdest, tapex, torg);
6639  /* Don't count the above as an orientation test. */
6640  m->counterclockcount--;
6641  }
6642  dx = (yao * dodist - ydo * aodist) * denominator;
6643  dy = (xdo * aodist - xao * dodist) * denominator;
6644 
6645  /* Find the (squared) length of the triangle's shortest edge. This */
6646  /* serves as a conservative estimate of the insertion radius of the */
6647  /* circumcenter's parent. The estimate is used to ensure that */
6648  /* the algorithm terminates even if very small angles appear in */
6649  /* the input PSLG. */
6650  if ((dodist < aodist) && (dodist < dadist)) {
6651  if (offcenter && (b->offconstant > 0.0)) {
6652  /* Find the position of the off-center, as described by Alper Ungor. */
6653  dxoff = 0.5 * xdo - b->offconstant * ydo;
6654  dyoff = 0.5 * ydo + b->offconstant * xdo;
6655  /* If the off-center is closer to the origin than the */
6656  /* circumcenter, use the off-center instead. */
6657  if (dxoff * dxoff + dyoff * dyoff < dx * dx + dy * dy) {
6658  dx = dxoff;
6659  dy = dyoff;
6660  }
6661  }
6662  } else if (aodist < dadist) {
6663  if (offcenter && (b->offconstant > 0.0)) {
6664  dxoff = 0.5 * xao + b->offconstant * yao;
6665  dyoff = 0.5 * yao - b->offconstant * xao;
6666  /* If the off-center is closer to the origin than the */
6667  /* circumcenter, use the off-center instead. */
6668  if (dxoff * dxoff + dyoff * dyoff < dx * dx + dy * dy) {
6669  dx = dxoff;
6670  dy = dyoff;
6671  }
6672  }
6673  } else {
6674  if (offcenter && (b->offconstant > 0.0)) {
6675  dxoff = 0.5 * (tapex[0] - tdest[0]) -
6676  b->offconstant * (tapex[1] - tdest[1]);
6677  dyoff = 0.5 * (tapex[1] - tdest[1]) +
6678  b->offconstant * (tapex[0] - tdest[0]);
6679  /* If the off-center is closer to the destination than the */
6680  /* circumcenter, use the off-center instead. */
6681  if (dxoff * dxoff + dyoff * dyoff <
6682  (dx - xdo) * (dx - xdo) + (dy - ydo) * (dy - ydo)) {
6683  dx = xdo + dxoff;
6684  dy = ydo + dyoff;
6685  }
6686  }
6687  }
6688 
6689  circumcenter[0] = torg[0] + dx;
6690  circumcenter[1] = torg[1] + dy;
6691 
6692  /* To interpolate vertex attributes for the new vertex inserted at */
6693  /* the circumcenter, define a coordinate system with a xi-axis, */
6694  /* directed from the triangle's origin to its destination, and */
6695  /* an eta-axis, directed from its origin to its apex. */
6696  /* Calculate the xi and eta coordinates of the circumcenter. */
6697  *xi = (yao * dx - xao * dy) * (2.0 * denominator);
6698  *eta = (xdo * dy - ydo * dx) * (2.0 * denominator);
6699 }
6700 
6703 /********* Geometric primitives end here *********/
6704 
6705 /*****************************************************************************/
6706 /* */
6707 /* triangleinit() Initialize some variables. */
6708 /* */
6709 /*****************************************************************************/
6710 
6711 #ifdef ANSI_DECLARATORS
6712 void triangleinit(struct mesh *m)
6713 #else /* not ANSI_DECLARATORS */
6714 void triangleinit(m)
6715 struct mesh *m;
6716 #endif /* not ANSI_DECLARATORS */
6717 
6718 {
6719  poolzero(&m->vertices);
6720  poolzero(&m->triangles);
6721  poolzero(&m->subsegs);
6722  poolzero(&m->viri);
6723  poolzero(&m->badsubsegs);
6724  poolzero(&m->badtriangles);
6725  poolzero(&m->flipstackers);
6726  poolzero(&m->splaynodes);
6727 
6728  m->recenttri.tri = (triangle *) NULL; /* No triangle has been visited yet. */
6729  m->undeads = 0; /* No eliminated input vertices yet. */
6730  m->samples = 1; /* Point location should take at least one sample. */
6731  m->checksegments = 0; /* There are no segments in the triangulation yet. */
6732  m->checkquality = 0; /* The quality triangulation stage has not begun. */
6733  m->incirclecount = m->counterclockcount = m->orient3dcount = 0;
6734  m->hyperbolacount = m->circletopcount = m->circumcentercount = 0;
6735  randomseed = 1;
6736 
6737  exactinit(); /* Initialize exact arithmetic constants. */
6738 }
6739 
6740 /*****************************************************************************/
6741 /* */
6742 /* randomnation() Generate a random number between 0 and `choices' - 1. */
6743 /* */
6744 /* This is a simple linear congruential random number generator. Hence, it */
6745 /* is a bad random number generator, but good enough for most randomized */
6746 /* geometric algorithms. */
6747 /* */
6748 /*****************************************************************************/
6749 
6750 #ifdef ANSI_DECLARATORS
6751 unsigned long randomnation(unsigned int choices)
6752 #else /* not ANSI_DECLARATORS */
6753 unsigned long randomnation(choices)
6754 unsigned int choices;
6755 #endif /* not ANSI_DECLARATORS */
6756 
6757 {
6758  randomseed = (randomseed * 1366l + 150889l) % 714025l;
6759  return randomseed / (714025l / choices + 1);
6760 }
6761 
6762 /********* Mesh quality testing routines begin here *********/
6766 /*****************************************************************************/
6767 /* */
6768 /* checkmesh() Test the mesh for topological consistency. */
6769 /* */
6770 /*****************************************************************************/
6771 
6772 #ifndef REDUCED
6773 
6774 #ifdef ANSI_DECLARATORS
6775 void checkmesh(struct mesh *m, struct behavior *b)
6776 #else /* not ANSI_DECLARATORS */
6777 void checkmesh(m, b)
6778 struct mesh *m;
6779 struct behavior *b;
6780 #endif /* not ANSI_DECLARATORS */
6781 
6782 {
6783  struct otri triangleloop;
6784  struct otri oppotri, oppooppotri;
6785  vertex triorg, tridest, triapex;
6786  vertex oppoorg, oppodest;
6787  int horrors;
6788  int saveexact;
6789  triangle ptr; /* Temporary variable used by sym(). */
6790 
6791  /* Temporarily turn on exact arithmetic if it's off. */
6792  saveexact = b->noexact;
6793  b->noexact = 0;
6794  if (!b->quiet) {
6795  printf(" Checking consistency of mesh...\n");
6796  }
6797  horrors = 0;
6798  /* Run through the list of triangles, checking each one. */
6799  traversalinit(&m->triangles);
6800  triangleloop.tri = triangletraverse(m);
6801  while (triangleloop.tri != (triangle *) NULL) {
6802  /* Check all three edges of the triangle. */
6803  for (triangleloop.orient = 0; triangleloop.orient < 3;
6804  triangleloop.orient++) {
6805  org(triangleloop, triorg);
6806  dest(triangleloop, tridest);
6807  if (triangleloop.orient == 0) { /* Only test for inversion once. */
6808  /* Test if the triangle is flat or inverted. */
6809  apex(triangleloop, triapex);
6810  if (counterclockwise(m, b, triorg, tridest, triapex) <= 0.0) {
6811  printf(" !! !! Inverted ");
6812  printtriangle(m, b, &triangleloop);
6813  horrors++;
6814  }
6815  }
6816  /* Find the neighboring triangle on this edge. */
6817  sym(triangleloop, oppotri);
6818  if (oppotri.tri != m->dummytri) {
6819  /* Check that the triangle's neighbor knows it's a neighbor. */
6820  sym(oppotri, oppooppotri);
6821  if ((triangleloop.tri != oppooppotri.tri)
6822  || (triangleloop.orient != oppooppotri.orient)) {
6823  printf(" !! !! Asymmetric triangle-triangle bond:\n");
6824  if (triangleloop.tri == oppooppotri.tri) {
6825  printf(" (Right triangle, wrong orientation)\n");
6826  }
6827  printf(" First ");
6828  printtriangle(m, b, &triangleloop);
6829  printf(" Second (nonreciprocating) ");
6830  printtriangle(m, b, &oppotri);
6831  horrors++;
6832  }
6833  /* Check that both triangles agree on the identities */
6834  /* of their shared vertices. */
6835  org(oppotri, oppoorg);
6836  dest(oppotri, oppodest);
6837  if ((triorg != oppodest) || (tridest != oppoorg)) {
6838  printf(" !! !! Mismatched edge coordinates between two triangles:\n"
6839  );
6840  printf(" First mismatched ");
6841  printtriangle(m, b, &triangleloop);
6842  printf(" Second mismatched ");
6843  printtriangle(m, b, &oppotri);
6844  horrors++;
6845  }
6846  }
6847  }
6848  triangleloop.tri = triangletraverse(m);
6849  }
6850  if (horrors == 0) {
6851  if (!b->quiet) {
6852  printf(" In my studied opinion, the mesh appears to be consistent.\n");
6853  }
6854  } else if (horrors == 1) {
6855  printf(" !! !! !! !! Precisely one festering wound discovered.\n");
6856  } else {
6857  printf(" !! !! !! !! %d abominations witnessed.\n", horrors);
6858  }
6859  /* Restore the status of exact arithmetic. */
6860  b->noexact = saveexact;
6861 }
6862 
6863 #endif /* not REDUCED */
6864 
6865 /*****************************************************************************/
6866 /* */
6867 /* checkdelaunay() Ensure that the mesh is (constrained) Delaunay. */
6868 /* */
6869 /*****************************************************************************/
6870 
6871 #ifndef REDUCED
6872 
6873 #ifdef ANSI_DECLARATORS
6874 void checkdelaunay(struct mesh *m, struct behavior *b)
6875 #else /* not ANSI_DECLARATORS */
6876 void checkdelaunay(m, b)
6877 struct mesh *m;
6878 struct behavior *b;
6879 #endif /* not ANSI_DECLARATORS */
6880 
6881 {
6882  struct otri triangleloop;
6883  struct otri oppotri;
6884  struct osub opposubseg;
6885  vertex triorg, tridest, triapex;
6886  vertex oppoapex;
6887  int shouldbedelaunay;
6888  int horrors;
6889  int saveexact;
6890  triangle ptr; /* Temporary variable used by sym(). */
6891  subseg sptr; /* Temporary variable used by tspivot(). */
6892 
6893  /* Temporarily turn on exact arithmetic if it's off. */
6894  saveexact = b->noexact;
6895  b->noexact = 0;
6896  if (!b->quiet) {
6897  printf(" Checking Delaunay property of mesh...\n");
6898  }
6899  horrors = 0;
6900  /* Run through the list of triangles, checking each one. */
6901  traversalinit(&m->triangles);
6902  triangleloop.tri = triangletraverse(m);
6903  while (triangleloop.tri != (triangle *) NULL) {
6904  /* Check all three edges of the triangle. */
6905  for (triangleloop.orient = 0; triangleloop.orient < 3;
6906  triangleloop.orient++) {
6907  org(triangleloop, triorg);
6908  dest(triangleloop, tridest);
6909  apex(triangleloop, triapex);
6910  sym(triangleloop, oppotri);
6911  apex(oppotri, oppoapex);
6912  /* Only test that the edge is locally Delaunay if there is an */
6913  /* adjoining triangle whose pointer is larger (to ensure that */
6914  /* each pair isn't tested twice). */
6915  shouldbedelaunay = (oppotri.tri != m->dummytri) &&
6916  !deadtri(oppotri.tri) && (triangleloop.tri < oppotri.tri) &&
6917  (triorg != m->infvertex1) && (triorg != m->infvertex2) &&
6918  (triorg != m->infvertex3) &&
6919  (tridest != m->infvertex1) && (tridest != m->infvertex2) &&
6920  (tridest != m->infvertex3) &&
6921  (triapex != m->infvertex1) && (triapex != m->infvertex2) &&
6922  (triapex != m->infvertex3) &&
6923  (oppoapex != m->infvertex1) && (oppoapex != m->infvertex2) &&
6924  (oppoapex != m->infvertex3);
6925  if (m->checksegments && shouldbedelaunay) {
6926  /* If a subsegment separates the triangles, then the edge is */
6927  /* constrained, so no local Delaunay test should be done. */
6928  tspivot(triangleloop, opposubseg);
6929  if (opposubseg.ss != m->dummysub){
6930  shouldbedelaunay = 0;
6931  }
6932  }
6933  if (shouldbedelaunay) {
6934  if (nonregular(m, b, triorg, tridest, triapex, oppoapex) > 0.0) {
6935  if (!b->weighted) {
6936  printf(" !! !! Non-Delaunay pair of triangles:\n");
6937  printf(" First non-Delaunay ");
6938  printtriangle(m, b, &triangleloop);
6939  printf(" Second non-Delaunay ");
6940  } else {
6941  printf(" !! !! Non-regular pair of triangles:\n");
6942  printf(" First non-regular ");
6943  printtriangle(m, b, &triangleloop);
6944  printf(" Second non-regular ");
6945  }
6946  printtriangle(m, b, &oppotri);
6947  horrors++;
6948  }
6949  }
6950  }
6951  triangleloop.tri = triangletraverse(m);
6952  }
6953  if (horrors == 0) {
6954  if (!b->quiet) {
6955  printf(
6956  " By virtue of my perceptive intelligence, I declare the mesh Delaunay.\n");
6957  }
6958  } else if (horrors == 1) {
6959  printf(
6960  " !! !! !! !! Precisely one terrifying transgression identified.\n");
6961  } else {
6962  printf(" !! !! !! !! %d obscenities viewed with horror.\n", horrors);
6963  }
6964  /* Restore the status of exact arithmetic. */
6965  b->noexact = saveexact;
6966 }
6967 
6968 #endif /* not REDUCED */
6969 
6970 /*****************************************************************************/
6971 /* */
6972 /* enqueuebadtriang() Add a bad triangle data structure to the end of a */
6973 /* queue. */
6974 /* */
6975 /* The queue is actually a set of 4096 queues. I use multiple queues to */
6976 /* give priority to smaller angles. I originally implemented a heap, but */
6977 /* the queues are faster by a larger margin than I'd suspected. */
6978 /* */
6979 /*****************************************************************************/
6980 
6981 #ifndef CDT_ONLY
6982 
6983 #ifdef ANSI_DECLARATORS
6984 void enqueuebadtriang(struct mesh *m, struct behavior *b,
6985  struct badtriang *badtri)
6986 #else /* not ANSI_DECLARATORS */
6987 void enqueuebadtriang(m, b, badtri)
6988 struct mesh *m;
6989 struct behavior *b;
6990 struct badtriang *badtri;
6991 #endif /* not ANSI_DECLARATORS */
6992 
6993 {
6994  REAL length, multiplier;
6995  int exponent, expincrement;
6996  int queuenumber;
6997  int posexponent;
6998  int i;
6999 
7000  if (b->verbose > 2) {
7001  printf(" Queueing bad triangle:\n");
7002  printf(" (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
7003  badtri->triangorg[0], badtri->triangorg[1],
7004  badtri->triangdest[0], badtri->triangdest[1],
7005  badtri->triangapex[0], badtri->triangapex[1]);
7006  }
7007 
7008  /* Determine the appropriate queue to put the bad triangle into. */
7009  /* Recall that the key is the square of its shortest edge length. */
7010  if (badtri->key >= 1.0) {
7011  length = badtri->key;
7012  posexponent = 1;
7013  } else {
7014  /* `badtri->key' is 2.0 to a negative exponent, so we'll record that */
7015  /* fact and use the reciprocal of `badtri->key', which is > 1.0. */
7016  length = 1.0 / badtri->key;
7017  posexponent = 0;
7018  }
7019  /* `length' is approximately 2.0 to what exponent? The following code */
7020  /* determines the answer in time logarithmic in the exponent. */
7021  exponent = 0;
7022  while (length > 2.0) {
7023  /* Find an approximation by repeated squaring of two. */
7024  expincrement = 1;
7025  multiplier = 0.5;
7026  while (length * multiplier * multiplier > 1.0) {
7027  expincrement *= 2;
7028  multiplier *= multiplier;
7029  }
7030  /* Reduce the value of `length', then iterate if necessary. */
7031  exponent += expincrement;
7032  length *= multiplier;
7033  }
7034  /* `length' is approximately squareroot(2.0) to what exponent? */
7035  exponent = 2 * exponent + (length > SQUAREROOTTWO);
7036  /* `exponent' is now in the range 0...2047 for IEEE double precision. */
7037  /* Choose a queue in the range 0...4095. The shortest edges have the */
7038  /* highest priority (queue 4095). */
7039  if (posexponent) {
7040  queuenumber = 2047 - exponent;
7041  } else {
7042  queuenumber = 2048 + exponent;
7043  }
7044 
7045  /* Are we inserting into an empty queue? */
7046  if (m->queuefront[queuenumber] == (struct badtriang *) NULL) {
7047  /* Yes, we are inserting into an empty queue. */
7048  /* Will this become the highest-priority queue? */
7049  if (queuenumber > m->firstnonemptyq) {
7050  /* Yes, this is the highest-priority queue. */
7051  m->nextnonemptyq[queuenumber] = m->firstnonemptyq;
7052  m->firstnonemptyq = queuenumber;
7053  } else {
7054  /* No, this is not the highest-priority queue. */
7055  /* Find the queue with next higher priority. */
7056  i = queuenumber + 1;
7057  while (m->queuefront[i] == (struct badtriang *) NULL) {
7058  i++;
7059  }
7060  /* Mark the newly nonempty queue as following a higher-priority queue. */
7061  m->nextnonemptyq[queuenumber] = m->nextnonemptyq[i];
7062  m->nextnonemptyq[i] = queuenumber;
7063  }
7064  /* Put the bad triangle at the beginning of the (empty) queue. */
7065  m->queuefront[queuenumber] = badtri;
7066  } else {
7067  /* Add the bad triangle to the end of an already nonempty queue. */
7068  m->queuetail[queuenumber]->nexttriang = badtri;
7069  }
7070  /* Maintain a pointer to the last triangle of the queue. */
7071  m->queuetail[queuenumber] = badtri;
7072  /* Newly enqueued bad triangle has no successor in the queue. */
7073  badtri->nexttriang = (struct badtriang *) NULL;
7074 }
7075 
7076 #endif /* not CDT_ONLY */
7077 
7078 /*****************************************************************************/
7079 /* */
7080 /* enqueuebadtri() Add a bad triangle to the end of a queue. */
7081 /* */
7082 /* Allocates a badtriang data structure for the triangle, then passes it to */
7083 /* enqueuebadtriang(). */
7084 /* */
7085 /*****************************************************************************/
7086 
7087 #ifndef CDT_ONLY
7088 
7089 #ifdef ANSI_DECLARATORS
7090 void enqueuebadtri(struct mesh *m, struct behavior *b, struct otri *enqtri,
7091  REAL minedge, vertex enqapex, vertex enqorg, vertex enqdest)
7092 #else /* not ANSI_DECLARATORS */
7093 void enqueuebadtri(m, b, enqtri, minedge, enqapex, enqorg, enqdest)
7094 struct mesh *m;
7095 struct behavior *b;
7096 struct otri *enqtri;
7097 REAL minedge;
7098 vertex enqapex;
7099 vertex enqorg;
7100 vertex enqdest;
7101 #endif /* not ANSI_DECLARATORS */
7102 
7103 {
7104  struct badtriang *newbad;
7105 
7106  /* Allocate space for the bad triangle. */
7107  newbad = (struct badtriang *) poolalloc(&m->badtriangles);
7108  newbad->poortri = encode(*enqtri);
7109  newbad->key = minedge;
7110  newbad->triangapex = enqapex;
7111  newbad->triangorg = enqorg;
7112  newbad->triangdest = enqdest;
7113  enqueuebadtriang(m, b, newbad);
7114 }
7115 
7116 #endif /* not CDT_ONLY */
7117 
7118 /*****************************************************************************/
7119 /* */
7120 /* dequeuebadtriang() Remove a triangle from the front of the queue. */
7121 /* */
7122 /*****************************************************************************/
7123 
7124 #ifndef CDT_ONLY
7125 
7126 #ifdef ANSI_DECLARATORS
7127 struct badtriang *dequeuebadtriang(struct mesh *m)
7128 #else /* not ANSI_DECLARATORS */
7129 struct badtriang *dequeuebadtriang(m)
7130 struct mesh *m;
7131 #endif /* not ANSI_DECLARATORS */
7132 
7133 {
7134  struct badtriang *result;
7135 
7136  /* If no queues are nonempty, return NULL. */
7137  if (m->firstnonemptyq < 0) {
7138  return (struct badtriang *) NULL;
7139  }
7140  /* Find the first triangle of the highest-priority queue. */
7141  result = m->queuefront[m->firstnonemptyq];
7142  /* Remove the triangle from the queue. */
7143  m->queuefront[m->firstnonemptyq] = result->nexttriang;
7144  /* If this queue is now empty, note the new highest-priority */
7145  /* nonempty queue. */
7146  if (result == m->queuetail[m->firstnonemptyq]) {
7147  m->firstnonemptyq = m->nextnonemptyq[m->firstnonemptyq];
7148  }
7149  return result;
7150 }
7151 
7152 #endif /* not CDT_ONLY */
7153 
7154 /*****************************************************************************/
7155 /* */
7156 /* checkseg4encroach() Check a subsegment to see if it is encroached; add */
7157 /* it to the list if it is. */
7158 /* */
7159 /* A subsegment is encroached if there is a vertex in its diametral lens. */
7160 /* For Ruppert's algorithm (-D switch), the "diametral lens" is the */
7161 /* diametral circle. For Chew's algorithm (default), the diametral lens is */
7162 /* just big enough to enclose two isosceles triangles whose bases are the */
7163 /* subsegment. Each of the two isosceles triangles has two angles equal */
7164 /* to `b->minangle'. */
7165 /* */
7166 /* Chew's algorithm does not require diametral lenses at all--but they save */
7167 /* time. Any vertex inside a subsegment's diametral lens implies that the */
7168 /* triangle adjoining the subsegment will be too skinny, so it's only a */
7169 /* matter of time before the encroaching vertex is deleted by Chew's */
7170 /* algorithm. It's faster to simply not insert the doomed vertex in the */
7171 /* first place, which is why I use diametral lenses with Chew's algorithm. */
7172 /* */
7173 /* Returns a nonzero value if the subsegment is encroached. */
7174 /* */
7175 /*****************************************************************************/
7176 
7177 #ifndef CDT_ONLY
7178 
7179 #ifdef ANSI_DECLARATORS
7180 int checkseg4encroach(struct mesh *m, struct behavior *b,
7181  struct osub *testsubseg)
7182 #else /* not ANSI_DECLARATORS */
7183 int checkseg4encroach(m, b, testsubseg)
7184 struct mesh *m;
7185 struct behavior *b;
7186 struct osub *testsubseg;
7187 #endif /* not ANSI_DECLARATORS */
7188 
7189 {
7190  struct otri neighbortri;
7191  struct osub testsym;
7192  struct badsubseg *encroachedseg;
7193  REAL dotproduct;
7194  int encroached;
7195  int sides;
7196  vertex eorg, edest, eapex;
7197  triangle ptr; /* Temporary variable used by stpivot(). */
7198 
7199  encroached = 0;
7200  sides = 0;
7201 
7202  sorg(*testsubseg, eorg);
7203  sdest(*testsubseg, edest);
7204  /* Check one neighbor of the subsegment. */
7205  stpivot(*testsubseg, neighbortri);
7206  /* Does the neighbor exist, or is this a boundary edge? */
7207  if (neighbortri.tri != m->dummytri) {
7208  sides++;
7209  /* Find a vertex opposite this subsegment. */
7210  apex(neighbortri, eapex);
7211  /* Check whether the apex is in the diametral lens of the subsegment */
7212  /* (the diametral circle if `conformdel' is set). A dot product */
7213  /* of two sides of the triangle is used to check whether the angle */
7214  /* at the apex is greater than (180 - 2 `minangle') degrees (for */
7215  /* lenses; 90 degrees for diametral circles). */
7216  dotproduct = (eorg[0] - eapex[0]) * (edest[0] - eapex[0]) +
7217  (eorg[1] - eapex[1]) * (edest[1] - eapex[1]);
7218  if (dotproduct < 0.0) {
7219  if (b->conformdel ||
7220  (dotproduct * dotproduct >=
7221  (2.0 * b->goodangle - 1.0) * (2.0 * b->goodangle - 1.0) *
7222  ((eorg[0] - eapex[0]) * (eorg[0] - eapex[0]) +
7223  (eorg[1] - eapex[1]) * (eorg[1] - eapex[1])) *
7224  ((edest[0] - eapex[0]) * (edest[0] - eapex[0]) +
7225  (edest[1] - eapex[1]) * (edest[1] - eapex[1])))) {
7226  encroached = 1;
7227  }
7228  }
7229  }
7230  /* Check the other neighbor of the subsegment. */
7231  ssym(*testsubseg, testsym);
7232  stpivot(testsym, neighbortri);
7233  /* Does the neighbor exist, or is this a boundary edge? */
7234  if (neighbortri.tri != m->dummytri) {
7235  sides++;
7236  /* Find the other vertex opposite this subsegment. */
7237  apex(neighbortri, eapex);
7238  /* Check whether the apex is in the diametral lens of the subsegment */
7239  /* (or the diametral circle, if `conformdel' is set). */
7240  dotproduct = (eorg[0] - eapex[0]) * (edest[0] - eapex[0]) +
7241  (eorg[1] - eapex[1]) * (edest[1] - eapex[1]);
7242  if (dotproduct < 0.0) {
7243  if (b->conformdel ||
7244  (dotproduct * dotproduct >=
7245  (2.0 * b->goodangle - 1.0) * (2.0 * b->goodangle - 1.0) *
7246  ((eorg[0] - eapex[0]) * (eorg[0] - eapex[0]) +
7247  (eorg[1] - eapex[1]) * (eorg[1] - eapex[1])) *
7248  ((edest[0] - eapex[0]) * (edest[0] - eapex[0]) +
7249  (edest[1] - eapex[1]) * (edest[1] - eapex[1])))) {
7250  encroached += 2;
7251  }
7252  }
7253  }
7254 
7255  if (encroached && (!b->nobisect || ((b->nobisect == 1) && (sides == 2)))) {
7256  if (b->verbose > 2) {
7257  printf(
7258  " Queueing encroached subsegment (%.12g, %.12g) (%.12g, %.12g).\n",
7259  eorg[0], eorg[1], edest[0], edest[1]);
7260  }
7261  /* Add the subsegment to the list of encroached subsegments. */
7262  /* Be sure to get the orientation right. */
7263  encroachedseg = (struct badsubseg *) poolalloc(&m->badsubsegs);
7264  if (encroached == 1) {
7265  encroachedseg->encsubseg = sencode(*testsubseg);
7266  encroachedseg->subsegorg = eorg;
7267  encroachedseg->subsegdest = edest;
7268  } else {
7269  encroachedseg->encsubseg = sencode(testsym);
7270  encroachedseg->subsegorg = edest;
7271  encroachedseg->subsegdest = eorg;
7272  }
7273  }
7274 
7275  return encroached;
7276 }
7277 
7278 #endif /* not CDT_ONLY */
7279 
7280 /*****************************************************************************/
7281 /* */
7282 /* testtriangle() Test a triangle for quality and size. */
7283 /* */
7284 /* Tests a triangle to see if it satisfies the minimum angle condition and */
7285 /* the maximum area condition. Triangles that aren't up to spec are added */
7286 /* to the bad triangle queue. */
7287 /* */
7288 /*****************************************************************************/
7289 
7290 #ifndef CDT_ONLY
7291 
7292 #ifdef ANSI_DECLARATORS
7293 void testtriangle(struct mesh *m, struct behavior *b, struct otri *testtri)
7294 #else /* not ANSI_DECLARATORS */
7295 void testtriangle(m, b, testtri)
7296 struct mesh *m;
7297 struct behavior *b;
7298 struct otri *testtri;
7299 #endif /* not ANSI_DECLARATORS */
7300 
7301 {
7302  struct otri tri1, tri2;
7303  struct osub testsub;
7304  vertex torg, tdest, tapex;
7305  vertex base1, base2;
7306  vertex org1, dest1, org2, dest2;
7307  vertex joinvertex;
7308  REAL dxod, dyod, dxda, dyda, dxao, dyao;
7309  REAL dxod2, dyod2, dxda2, dyda2, dxao2, dyao2;
7310  REAL apexlen, orglen, destlen, minedge;
7311  REAL angle;
7312  REAL area;
7313  REAL dist1, dist2;
7314  subseg sptr; /* Temporary variable used by tspivot(). */
7315  triangle ptr; /* Temporary variable used by oprev() and dnext(). */
7316 
7317  org(*testtri, torg);
7318  dest(*testtri, tdest);
7319  apex(*testtri, tapex);
7320  dxod = torg[0] - tdest[0];
7321  dyod = torg[1] - tdest[1];
7322  dxda = tdest[0] - tapex[0];
7323  dyda = tdest[1] - tapex[1];
7324  dxao = tapex[0] - torg[0];
7325  dyao = tapex[1] - torg[1];
7326  dxod2 = dxod * dxod;
7327  dyod2 = dyod * dyod;
7328  dxda2 = dxda * dxda;
7329  dyda2 = dyda * dyda;
7330  dxao2 = dxao * dxao;
7331  dyao2 = dyao * dyao;
7332  /* Find the lengths of the triangle's three edges. */
7333  apexlen = dxod2 + dyod2;
7334  orglen = dxda2 + dyda2;
7335  destlen = dxao2 + dyao2;
7336 
7337  if ((apexlen < orglen) && (apexlen < destlen)) {
7338  /* The edge opposite the apex is shortest. */
7339  minedge = apexlen;
7340  /* Find the square of the cosine of the angle at the apex. */
7341  angle = dxda * dxao + dyda * dyao;
7342  angle = angle * angle / (orglen * destlen);
7343  base1 = torg;
7344  base2 = tdest;
7345  otricopy(*testtri, tri1);
7346  } else if (orglen < destlen) {
7347  /* The edge opposite the origin is shortest. */
7348  minedge = orglen;
7349  /* Find the square of the cosine of the angle at the origin. */
7350  angle = dxod * dxao + dyod * dyao;
7351  angle = angle * angle / (apexlen * destlen);
7352  base1 = tdest;
7353  base2 = tapex;
7354  lnext(*testtri, tri1);
7355  } else {
7356  /* The edge opposite the destination is shortest. */
7357  minedge = destlen;
7358  /* Find the square of the cosine of the angle at the destination. */
7359  angle = dxod * dxda + dyod * dyda;
7360  angle = angle * angle / (apexlen * orglen);
7361  base1 = tapex;
7362  base2 = torg;
7363  lprev(*testtri, tri1);
7364  }
7365 
7366  if (b->vararea || b->fixedarea || b->usertest) {
7367  /* Check whether the area is larger than permitted. */
7368  area = 0.5 * (dxod * dyda - dyod * dxda);
7369  if (b->fixedarea && (area > b->maxarea)) {
7370  /* Add this triangle to the list of bad triangles. */
7371  enqueuebadtri(m, b, testtri, minedge, tapex, torg, tdest);
7372  return;
7373  }
7374 
7375  /* Nonpositive area constraints are treated as unconstrained. */
7376  if ((b->vararea) && (area > areabound(*testtri)) &&
7377  (areabound(*testtri) > 0.0)) {
7378  /* Add this triangle to the list of bad triangles. */
7379  enqueuebadtri(m, b, testtri, minedge, tapex, torg, tdest);
7380  return;
7381  }
7382 
7383  if (b->usertest) {
7384  /* Check whether the user thinks this triangle is too large. */
7385  if (triunsuitable(torg, tdest, tapex, area)) {
7386  enqueuebadtri(m, b, testtri, minedge, tapex, torg, tdest);
7387  return;
7388  }
7389  }
7390  }
7391 
7392  /* Check whether the angle is smaller than permitted. */
7393  if (angle > b->goodangle) {
7394  /* Use the rules of Miller, Pav, and Walkington to decide that certain */
7395  /* triangles should not be split, even if they have bad angles. */
7396  /* A skinny triangle is not split if its shortest edge subtends a */
7397  /* small input angle, and both endpoints of the edge lie on a */
7398  /* concentric circular shell. For convenience, I make a small */
7399  /* adjustment to that rule: I check if the endpoints of the edge */
7400  /* both lie in segment interiors, equidistant from the apex where */
7401  /* the two segments meet. */
7402  /* First, check if both points lie in segment interiors. */
7403  if ((vertextype(base1) == SEGMENTVERTEX) &&
7404  (vertextype(base2) == SEGMENTVERTEX)) {
7405  /* Check if both points lie in a common segment. If they do, the */
7406  /* skinny triangle is enqueued to be split as usual. */
7407  tspivot(tri1, testsub);
7408  if (testsub.ss == m->dummysub) {
7409  /* No common segment. Find a subsegment that contains `torg'. */
7410  otricopy(tri1, tri2);
7411  do {
7412  oprevself(tri1);
7413  tspivot(tri1, testsub);
7414  } while (testsub.ss == m->dummysub);
7415  /* Find the endpoints of the containing segment. */
7416  segorg(testsub, org1);
7417  segdest(testsub, dest1);
7418  /* Find a subsegment that contains `tdest'. */
7419  do {
7420  dnextself(tri2);
7421  tspivot(tri2, testsub);
7422  } while (testsub.ss == m->dummysub);
7423  /* Find the endpoints of the containing segment. */
7424  segorg(testsub, org2);
7425  segdest(testsub, dest2);
7426  /* Check if the two containing segments have an endpoint in common. */
7427  joinvertex = (vertex) NULL;
7428  if ((dest1[0] == org2[0]) && (dest1[1] == org2[1])) {
7429  joinvertex = dest1;
7430  } else if ((org1[0] == dest2[0]) && (org1[1] == dest2[1])) {
7431  joinvertex = org1;
7432  }
7433  if (joinvertex != (vertex) NULL) {
7434  /* Compute the distance from the common endpoint (of the two */
7435  /* segments) to each of the endpoints of the shortest edge. */
7436  dist1 = ((base1[0] - joinvertex[0]) * (base1[0] - joinvertex[0]) +
7437  (base1[1] - joinvertex[1]) * (base1[1] - joinvertex[1]));
7438  dist2 = ((base2[0] - joinvertex[0]) * (base2[0] - joinvertex[0]) +
7439  (base2[1] - joinvertex[1]) * (base2[1] - joinvertex[1]));
7440  /* If the two distances are equal, don't split the triangle. */
7441  if ((dist1 < 1.001 * dist2) && (dist1 > 0.999 * dist2)) {
7442  /* Return now to avoid enqueueing the bad triangle. */
7443  return;
7444  }
7445  }
7446  }
7447  }
7448 
7449  /* Add this triangle to the list of bad triangles. */
7450  enqueuebadtri(m, b, testtri, minedge, tapex, torg, tdest);
7451  }
7452 }
7453 
7454 #endif /* not CDT_ONLY */
7455 
7458 /********* Mesh quality testing routines end here *********/
7459 
7460 /********* Point location routines begin here *********/
7464 /*****************************************************************************/
7465 /* */
7466 /* makevertexmap() Construct a mapping from vertices to triangles to */
7467 /* improve the speed of point location for segment */
7468 /* insertion. */
7469 /* */
7470 /* Traverses all the triangles, and provides each corner of each triangle */
7471 /* with a pointer to that triangle. Of course, pointers will be */
7472 /* overwritten by other pointers because (almost) each vertex is a corner */
7473 /* of several triangles, but in the end every vertex will point to some */
7474 /* triangle that contains it. */
7475 /* */
7476 /*****************************************************************************/
7477 
7478 #ifdef ANSI_DECLARATORS
7479 void makevertexmap(struct mesh *m, struct behavior *b)
7480 #else /* not ANSI_DECLARATORS */
7481 void makevertexmap(m, b)
7482 struct mesh *m;
7483 struct behavior *b;
7484 #endif /* not ANSI_DECLARATORS */
7485 
7486 {
7487  struct otri triangleloop;
7488  vertex triorg;
7489 
7490  if (b->verbose) {
7491  printf(" Constructing mapping from vertices to triangles.\n");
7492  }
7493  traversalinit(&m->triangles);
7494  triangleloop.tri = triangletraverse(m);
7495  while (triangleloop.tri != (triangle *) NULL) {
7496  /* Check all three vertices of the triangle. */
7497  for (triangleloop.orient = 0; triangleloop.orient < 3;
7498  triangleloop.orient++) {
7499  org(triangleloop, triorg);
7500  setvertex2tri(triorg, encode(triangleloop));
7501  }
7502  triangleloop.tri = triangletraverse(m);
7503  }
7504 }
7505 
7506 /*****************************************************************************/
7507 /* */
7508 /* preciselocate() Find a triangle or edge containing a given point. */
7509 /* */
7510 /* Begins its search from `searchtri'. It is important that `searchtri' */
7511 /* be a handle with the property that `searchpoint' is strictly to the left */
7512 /* of the edge denoted by `searchtri', or is collinear with that edge and */
7513 /* does not intersect that edge. (In particular, `searchpoint' should not */
7514 /* be the origin or destination of that edge.) */
7515 /* */
7516 /* These conditions are imposed because preciselocate() is normally used in */
7517 /* one of two situations: */
7518 /* */
7519 /* (1) To try to find the location to insert a new point. Normally, we */
7520 /* know an edge that the point is strictly to the left of. In the */
7521 /* incremental Delaunay algorithm, that edge is a bounding box edge. */
7522 /* In Ruppert's Delaunay refinement algorithm for quality meshing, */
7523 /* that edge is the shortest edge of the triangle whose circumcenter */
7524 /* is being inserted. */
7525 /* */
7526 /* (2) To try to find an existing point. In this case, any edge on the */
7527 /* convex hull is a good starting edge. You must screen out the */
7528 /* possibility that the vertex sought is an endpoint of the starting */
7529 /* edge before you call preciselocate(). */
7530 /* */
7531 /* On completion, `searchtri' is a triangle that contains `searchpoint'. */
7532 /* */
7533 /* This implementation differs from that given by Guibas and Stolfi. It */
7534 /* walks from triangle to triangle, crossing an edge only if `searchpoint' */
7535 /* is on the other side of the line containing that edge. After entering */
7536 /* a triangle, there are two edges by which one can leave that triangle. */
7537 /* If both edges are valid (`searchpoint' is on the other side of both */
7538 /* edges), one of the two is chosen by drawing a line perpendicular to */
7539 /* the entry edge (whose endpoints are `forg' and `fdest') passing through */
7540 /* `fapex'. Depending on which side of this perpendicular `searchpoint' */
7541 /* falls on, an exit edge is chosen. */
7542 /* */
7543 /* This implementation is empirically faster than the Guibas and Stolfi */
7544 /* point location routine (which I originally used), which tends to spiral */
7545 /* in toward its target. */
7546 /* */
7547 /* Returns ONVERTEX if the point lies on an existing vertex. `searchtri' */
7548 /* is a handle whose origin is the existing vertex. */
7549 /* */
7550 /* Returns ONEDGE if the point lies on a mesh edge. `searchtri' is a */
7551 /* handle whose primary edge is the edge on which the point lies. */
7552 /* */
7553 /* Returns INTRIANGLE if the point lies strictly within a triangle. */
7554 /* `searchtri' is a handle on the triangle that contains the point. */
7555 /* */
7556 /* Returns OUTSIDE if the point lies outside the mesh. `searchtri' is a */
7557 /* handle whose primary edge the point is to the right of. This might */
7558 /* occur when the circumcenter of a triangle falls just slightly outside */
7559 /* the mesh due to floating-point roundoff error. It also occurs when */
7560 /* seeking a hole or region point that a foolish user has placed outside */
7561 /* the mesh. */
7562 /* */
7563 /* If `stopatsubsegment' is nonzero, the search will stop if it tries to */
7564 /* walk through a subsegment, and will return OUTSIDE. */
7565 /* */
7566 /* WARNING: This routine is designed for convex triangulations, and will */
7567 /* not generally work after the holes and concavities have been carved. */
7568 /* However, it can still be used to find the circumcenter of a triangle, as */
7569 /* long as the search is begun from the triangle in question. */
7570 /* */
7571 /*****************************************************************************/
7572 
7573 #ifdef ANSI_DECLARATORS
7574 enum locateresult preciselocate(struct mesh *m, struct behavior *b,
7575  vertex searchpoint, struct otri *searchtri,
7576  int stopatsubsegment)
7577 #else /* not ANSI_DECLARATORS */
7578 enum locateresult preciselocate(m, b, searchpoint, searchtri, stopatsubsegment)
7579 struct mesh *m;
7580 struct behavior *b;
7581 vertex searchpoint;
7582 struct otri *searchtri;
7583 int stopatsubsegment;
7584 #endif /* not ANSI_DECLARATORS */
7585 
7586 {
7587  struct otri backtracktri;
7588  struct osub checkedge;
7589  vertex forg, fdest, fapex;
7590  REAL orgorient, destorient;
7591  int moveleft;
7592  triangle ptr; /* Temporary variable used by sym(). */
7593  subseg sptr; /* Temporary variable used by tspivot(). */
7594 
7595  if (b->verbose > 2) {
7596  printf(" Searching for point (%.12g, %.12g).\n",
7597  searchpoint[0], searchpoint[1]);
7598  }
7599  /* Where are we? */
7600  org(*searchtri, forg);
7601  dest(*searchtri, fdest);
7602  apex(*searchtri, fapex);
7603  while (1) {
7604  if (b->verbose > 2) {
7605  printf(" At (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
7606  forg[0], forg[1], fdest[0], fdest[1], fapex[0], fapex[1]);
7607  }
7608  /* Check whether the apex is the point we seek. */
7609  if ((fapex[0] == searchpoint[0]) && (fapex[1] == searchpoint[1])) {
7610  lprevself(*searchtri);
7611  return ONVERTEX;
7612  }
7613  /* Does the point lie on the other side of the line defined by the */
7614  /* triangle edge opposite the triangle's destination? */
7615  destorient = counterclockwise(m, b, forg, fapex, searchpoint);
7616  /* Does the point lie on the other side of the line defined by the */
7617  /* triangle edge opposite the triangle's origin? */
7618  orgorient = counterclockwise(m, b, fapex, fdest, searchpoint);
7619  if (destorient > 0.0) {
7620  if (orgorient > 0.0) {
7621  /* Move left if the inner product of (fapex - searchpoint) and */
7622  /* (fdest - forg) is positive. This is equivalent to drawing */
7623  /* a line perpendicular to the line (forg, fdest) and passing */
7624  /* through `fapex', and determining which side of this line */
7625  /* `searchpoint' falls on. */
7626  moveleft = (fapex[0] - searchpoint[0]) * (fdest[0] - forg[0]) +
7627  (fapex[1] - searchpoint[1]) * (fdest[1] - forg[1]) > 0.0;
7628  } else {
7629  moveleft = 1;
7630  }
7631  } else {
7632  if (orgorient > 0.0) {
7633  moveleft = 0;
7634  } else {
7635  /* The point we seek must be on the boundary of or inside this */
7636  /* triangle. */
7637  if (destorient == 0.0) {
7638  lprevself(*searchtri);
7639  return ONEDGE;
7640  }
7641  if (orgorient == 0.0) {
7642  lnextself(*searchtri);
7643  return ONEDGE;
7644  }
7645  return INTRIANGLE;
7646  }
7647  }
7648 
7649  /* Move to another triangle. Leave a trace `backtracktri' in case */
7650  /* floating-point roundoff or some such bogey causes us to walk */
7651  /* off a boundary of the triangulation. */
7652  if (moveleft) {
7653  lprev(*searchtri, backtracktri);
7654  fdest = fapex;
7655  } else {
7656  lnext(*searchtri, backtracktri);
7657  forg = fapex;
7658  }
7659  sym(backtracktri, *searchtri);
7660 
7661  if (m->checksegments && stopatsubsegment) {
7662  /* Check for walking through a subsegment. */
7663  tspivot(backtracktri, checkedge);
7664  if (checkedge.ss != m->dummysub) {
7665  /* Go back to the last triangle. */
7666  otricopy(backtracktri, *searchtri);
7667  return OUTSIDE;
7668  }
7669  }
7670  /* Check for walking right out of the triangulation. */
7671  if (searchtri->tri == m->dummytri) {
7672  /* Go back to the last triangle. */
7673  otricopy(backtracktri, *searchtri);
7674  return OUTSIDE;
7675  }
7676 
7677  apex(*searchtri, fapex);
7678  }
7679 }
7680 
7681 /*****************************************************************************/
7682 /* */
7683 /* locate() Find a triangle or edge containing a given point. */
7684 /* */
7685 /* Searching begins from one of: the input `searchtri', a recently */
7686 /* encountered triangle `recenttri', or from a triangle chosen from a */
7687 /* random sample. The choice is made by determining which triangle's */
7688 /* origin is closest to the point we are searching for. Normally, */
7689 /* `searchtri' should be a handle on the convex hull of the triangulation. */
7690 /* */
7691 /* Details on the random sampling method can be found in the Mucke, Saias, */
7692 /* and Zhu paper cited in the header of this code. */
7693 /* */
7694 /* On completion, `searchtri' is a triangle that contains `searchpoint'. */
7695 /* */
7696 /* Returns ONVERTEX if the point lies on an existing vertex. `searchtri' */
7697 /* is a handle whose origin is the existing vertex. */
7698 /* */
7699 /* Returns ONEDGE if the point lies on a mesh edge. `searchtri' is a */
7700 /* handle whose primary edge is the edge on which the point lies. */
7701 /* */
7702 /* Returns INTRIANGLE if the point lies strictly within a triangle. */
7703 /* `searchtri' is a handle on the triangle that contains the point. */
7704 /* */
7705 /* Returns OUTSIDE if the point lies outside the mesh. `searchtri' is a */
7706 /* handle whose primary edge the point is to the right of. This might */
7707 /* occur when the circumcenter of a triangle falls just slightly outside */
7708 /* the mesh due to floating-point roundoff error. It also occurs when */
7709 /* seeking a hole or region point that a foolish user has placed outside */
7710 /* the mesh. */
7711 /* */
7712 /* WARNING: This routine is designed for convex triangulations, and will */
7713 /* not generally work after the holes and concavities have been carved. */
7714 /* */
7715 /*****************************************************************************/
7716 
7717 #ifdef ANSI_DECLARATORS
7718 enum locateresult locate(struct mesh *m, struct behavior *b,
7719  vertex searchpoint, struct otri *searchtri)
7720 #else /* not ANSI_DECLARATORS */
7721 enum locateresult locate(m, b, searchpoint, searchtri)
7722 struct mesh *m;
7723 struct behavior *b;
7724 vertex searchpoint;
7725 struct otri *searchtri;
7726 #endif /* not ANSI_DECLARATORS */
7727 
7728 {
7729  VOID **sampleblock;
7730  char *firsttri;
7731  struct otri sampletri;
7732  vertex torg, tdest;
7733  unsigned long alignptr;
7734  REAL searchdist, dist;
7735  REAL ahead;
7736  long samplesperblock, totalsamplesleft, samplesleft;
7737  long population, totalpopulation;
7738  triangle ptr; /* Temporary variable used by sym(). */
7739 
7740  if (b->verbose > 2) {
7741  printf(" Randomly sampling for a triangle near point (%.12g, %.12g).\n",
7742  searchpoint[0], searchpoint[1]);
7743  }
7744  /* Record the distance from the suggested starting triangle to the */
7745  /* point we seek. */
7746  org(*searchtri, torg);
7747  searchdist = (searchpoint[0] - torg[0]) * (searchpoint[0] - torg[0]) +
7748  (searchpoint[1] - torg[1]) * (searchpoint[1] - torg[1]);
7749  if (b->verbose > 2) {
7750  printf(" Boundary triangle has origin (%.12g, %.12g).\n",
7751  torg[0], torg[1]);
7752  }
7753 
7754  /* If a recently encountered triangle has been recorded and has not been */
7755  /* deallocated, test it as a good starting point. */
7756  if (m->recenttri.tri != (triangle *) NULL) {
7757  if (!deadtri(m->recenttri.tri)) {
7758  org(m->recenttri, torg);
7759  if ((torg[0] == searchpoint[0]) && (torg[1] == searchpoint[1])) {
7760  otricopy(m->recenttri, *searchtri);
7761  return ONVERTEX;
7762  }
7763  dist = (searchpoint[0] - torg[0]) * (searchpoint[0] - torg[0]) +
7764  (searchpoint[1] - torg[1]) * (searchpoint[1] - torg[1]);
7765  if (dist < searchdist) {
7766  otricopy(m->recenttri, *searchtri);
7767  searchdist = dist;
7768  if (b->verbose > 2) {
7769  printf(" Choosing recent triangle with origin (%.12g, %.12g).\n",
7770  torg[0], torg[1]);
7771  }
7772  }
7773  }
7774  }
7775 
7776  /* The number of random samples taken is proportional to the cube root of */
7777  /* the number of triangles in the mesh. The next bit of code assumes */
7778  /* that the number of triangles increases monotonically (or at least */
7779  /* doesn't decrease enough to matter). */
7780  while (SAMPLEFACTOR * m->samples * m->samples * m->samples <
7781  m->triangles.items) {
7782  m->samples++;
7783  }
7784 
7785  /* We'll draw ceiling(samples * TRIPERBLOCK / maxitems) random samples */
7786  /* from each block of triangles (except the first)--until we meet the */
7787  /* sample quota. The ceiling means that blocks at the end might be */
7788  /* neglected, but I don't care. */
7789  samplesperblock = (m->samples * TRIPERBLOCK - 1) / m->triangles.maxitems + 1;
7790  /* We'll draw ceiling(samples * itemsfirstblock / maxitems) random samples */
7791  /* from the first block of triangles. */
7792  samplesleft = (m->samples * m->triangles.itemsfirstblock - 1) /
7793  m->triangles.maxitems + 1;
7794  totalsamplesleft = m->samples;
7795  population = m->triangles.itemsfirstblock;
7796  totalpopulation = m->triangles.maxitems;
7797  sampleblock = m->triangles.firstblock;
7798  sampletri.orient = 0;
7799  while (totalsamplesleft > 0) {
7800  /* If we're in the last block, `population' needs to be corrected. */
7801  if (population > totalpopulation) {
7802  population = totalpopulation;
7803  }
7804  /* Find a pointer to the first triangle in the block. */
7805  alignptr = (unsigned long) (sampleblock + 1);
7806  firsttri = (char *) (alignptr +
7807  (unsigned long) m->triangles.alignbytes -
7808  (alignptr %
7809  (unsigned long) m->triangles.alignbytes));
7810 
7811  /* Choose `samplesleft' randomly sampled triangles in this block. */
7812  do {
7813  sampletri.tri = (triangle *) (firsttri +
7814  (randomnation((unsigned int) population) *
7815  m->triangles.itembytes));
7816  if (!deadtri(sampletri.tri)) {
7817  org(sampletri, torg);
7818  dist = (searchpoint[0] - torg[0]) * (searchpoint[0] - torg[0]) +
7819  (searchpoint[1] - torg[1]) * (searchpoint[1] - torg[1]);
7820  if (dist < searchdist) {
7821  otricopy(sampletri, *searchtri);
7822  searchdist = dist;
7823  if (b->verbose > 2) {
7824  printf(" Choosing triangle with origin (%.12g, %.12g).\n",
7825  torg[0], torg[1]);
7826  }
7827  }
7828  }
7829 
7830  samplesleft--;
7831  totalsamplesleft--;
7832  } while ((samplesleft > 0) && (totalsamplesleft > 0));
7833 
7834  if (totalsamplesleft > 0) {
7835  sampleblock = (VOID **) *sampleblock;
7836  samplesleft = samplesperblock;
7837  totalpopulation -= population;
7838  population = TRIPERBLOCK;
7839  }
7840  }
7841 
7842  /* Where are we? */
7843  org(*searchtri, torg);
7844  dest(*searchtri, tdest);
7845  /* Check the starting triangle's vertices. */
7846  if ((torg[0] == searchpoint[0]) && (torg[1] == searchpoint[1])) {
7847  return ONVERTEX;
7848  }
7849  if ((tdest[0] == searchpoint[0]) && (tdest[1] == searchpoint[1])) {
7850  lnextself(*searchtri);
7851  return ONVERTEX;
7852  }
7853  /* Orient `searchtri' to fit the preconditions of calling preciselocate(). */
7854  ahead = counterclockwise(m, b, torg, tdest, searchpoint);
7855  if (ahead < 0.0) {
7856  /* Turn around so that `searchpoint' is to the left of the */
7857  /* edge specified by `searchtri'. */
7858  symself(*searchtri);
7859  } else if (ahead == 0.0) {
7860  /* Check if `searchpoint' is between `torg' and `tdest'. */
7861  if (((torg[0] < searchpoint[0]) == (searchpoint[0] < tdest[0])) &&
7862  ((torg[1] < searchpoint[1]) == (searchpoint[1] < tdest[1]))) {
7863  return ONEDGE;
7864  }
7865  }
7866  return preciselocate(m, b, searchpoint, searchtri, 0);
7867 }
7868 
7871 /********* Point location routines end here *********/
7872 
7873 /********* Mesh transformation routines begin here *********/
7877 /*****************************************************************************/
7878 /* */
7879 /* insertsubseg() Create a new subsegment and insert it between two */
7880 /* triangles. */
7881 /* */
7882 /* The new subsegment is inserted at the edge described by the handle */
7883 /* `tri'. Its vertices are properly initialized. The marker `subsegmark' */
7884 /* is applied to the subsegment and, if appropriate, its vertices. */
7885 /* */
7886 /*****************************************************************************/
7887 
7888 #ifdef ANSI_DECLARATORS
7889 void insertsubseg(struct mesh *m, struct behavior *b, struct otri *tri,
7890  int subsegmark)
7891 #else /* not ANSI_DECLARATORS */
7892 void insertsubseg(m, b, tri, subsegmark)
7893 struct mesh *m;
7894 struct behavior *b;
7895 struct otri *tri; /* Edge at which to insert the new subsegment. */
7896 int subsegmark; /* Marker for the new subsegment. */
7897 #endif /* not ANSI_DECLARATORS */
7898 
7899 {
7900  struct otri oppotri;
7901  struct osub newsubseg;
7902  vertex triorg, tridest;
7903  triangle ptr; /* Temporary variable used by sym(). */
7904  subseg sptr; /* Temporary variable used by tspivot(). */
7905 
7906  org(*tri, triorg);
7907  dest(*tri, tridest);
7908  /* Mark vertices if possible. */
7909  if (vertexmark(triorg) == 0) {
7910  setvertexmark(triorg, subsegmark);
7911  }
7912  if (vertexmark(tridest) == 0) {
7913  setvertexmark(tridest, subsegmark);
7914  }
7915  /* Check if there's already a subsegment here. */
7916  tspivot(*tri, newsubseg);
7917  if (newsubseg.ss == m->dummysub) {
7918  /* Make new subsegment and initialize its vertices. */
7919  makesubseg(m, &newsubseg);
7920  setsorg(newsubseg, tridest);
7921  setsdest(newsubseg, triorg);
7922  setsegorg(newsubseg, tridest);
7923  setsegdest(newsubseg, triorg);
7924  /* Bond new subsegment to the two triangles it is sandwiched between. */
7925  /* Note that the facing triangle `oppotri' might be equal to */
7926  /* `dummytri' (outer space), but the new subsegment is bonded to it */
7927  /* all the same. */
7928  tsbond(*tri, newsubseg);
7929  sym(*tri, oppotri);
7930  ssymself(newsubseg);
7931  tsbond(oppotri, newsubseg);
7932  setmark(newsubseg, subsegmark);
7933  if (b->verbose > 2) {
7934  printf(" Inserting new ");
7935  printsubseg(m, b, &newsubseg);
7936  }
7937  } else {
7938  if (mark(newsubseg) == 0) {
7939  setmark(newsubseg, subsegmark);
7940  }
7941  }
7942 }
7943 
7944 /*****************************************************************************/
7945 /* */
7946 /* Terminology */
7947 /* */
7948 /* A "local transformation" replaces a small set of triangles with another */
7949 /* set of triangles. This may or may not involve inserting or deleting a */
7950 /* vertex. */
7951 /* */
7952 /* The term "casing" is used to describe the set of triangles that are */
7953 /* attached to the triangles being transformed, but are not transformed */
7954 /* themselves. Think of the casing as a fixed hollow structure inside */
7955 /* which all the action happens. A "casing" is only defined relative to */
7956 /* a single transformation; each occurrence of a transformation will */
7957 /* involve a different casing. */
7958 /* */
7959 /*****************************************************************************/
7960 
7961 /*****************************************************************************/
7962 /* */
7963 /* flip() Transform two triangles to two different triangles by flipping */
7964 /* an edge counterclockwise within a quadrilateral. */
7965 /* */
7966 /* Imagine the original triangles, abc and bad, oriented so that the */
7967 /* shared edge ab lies in a horizontal plane, with the vertex b on the left */
7968 /* and the vertex a on the right. The vertex c lies below the edge, and */
7969 /* the vertex d lies above the edge. The `flipedge' handle holds the edge */
7970 /* ab of triangle abc, and is directed left, from vertex a to vertex b. */
7971 /* */
7972 /* The triangles abc and bad are deleted and replaced by the triangles cdb */
7973 /* and dca. The triangles that represent abc and bad are NOT deallocated; */
7974 /* they are reused for dca and cdb, respectively. Hence, any handles that */
7975 /* may have held the original triangles are still valid, although not */
7976 /* directed as they were before. */
7977 /* */
7978 /* Upon completion of this routine, the `flipedge' handle holds the edge */
7979 /* dc of triangle dca, and is directed down, from vertex d to vertex c. */
7980 /* (Hence, the two triangles have rotated counterclockwise.) */
7981 /* */
7982 /* WARNING: This transformation is geometrically valid only if the */
7983 /* quadrilateral adbc is convex. Furthermore, this transformation is */
7984 /* valid only if there is not a subsegment between the triangles abc and */
7985 /* bad. This routine does not check either of these preconditions, and */
7986 /* it is the responsibility of the calling routine to ensure that they are */
7987 /* met. If they are not, the streets shall be filled with wailing and */
7988 /* gnashing of teeth. */
7989 /* */
7990 /*****************************************************************************/
7991 
7992 #ifdef ANSI_DECLARATORS
7993 void flip(struct mesh *m, struct behavior *b, struct otri *flipedge)
7994 #else /* not ANSI_DECLARATORS */
7995 void flip(m, b, flipedge)
7996 struct mesh *m;
7997 struct behavior *b;
7998 struct otri *flipedge; /* Handle for the triangle abc. */
7999 #endif /* not ANSI_DECLARATORS */
8000 
8001 {
8002  struct otri botleft, botright;
8003  struct otri topleft, topright;
8004  struct otri top;
8005  struct otri botlcasing, botrcasing;
8006  struct otri toplcasing, toprcasing;
8007  struct osub botlsubseg, botrsubseg;
8008  struct osub toplsubseg, toprsubseg;
8009  vertex leftvertex, rightvertex, botvertex;
8010  vertex farvertex;
8011  triangle ptr; /* Temporary variable used by sym(). */
8012  subseg sptr; /* Temporary variable used by tspivot(). */
8013 
8014  /* Identify the vertices of the quadrilateral. */
8015  org(*flipedge, rightvertex);
8016  dest(*flipedge, leftvertex);
8017  apex(*flipedge, botvertex);
8018  sym(*flipedge, top);
8019 #ifdef SELF_CHECK
8020  if (top.tri == m->dummytri) {
8021  printf("Internal error in flip(): Attempt to flip on boundary.\n");
8022  lnextself(*flipedge);
8023  return;
8024  }
8025  if (m->checksegments) {
8026  tspivot(*flipedge, toplsubseg);
8027  if (toplsubseg.ss != m->dummysub) {
8028  printf("Internal error in flip(): Attempt to flip a segment.\n");
8029  lnextself(*flipedge);
8030  return;
8031  }
8032  }
8033 #endif /* SELF_CHECK */
8034  apex(top, farvertex);
8035 
8036  /* Identify the casing of the quadrilateral. */
8037  lprev(top, topleft);
8038  sym(topleft, toplcasing);
8039  lnext(top, topright);
8040  sym(topright, toprcasing);
8041  lnext(*flipedge, botleft);
8042  sym(botleft, botlcasing);
8043  lprev(*flipedge, botright);
8044  sym(botright, botrcasing);
8045  /* Rotate the quadrilateral one-quarter turn counterclockwise. */
8046  bond(topleft, botlcasing);
8047  bond(botleft, botrcasing);
8048  bond(botright, toprcasing);
8049  bond(topright, toplcasing);
8050 
8051  if (m->checksegments) {
8052  /* Check for subsegments and rebond them to the quadrilateral. */
8053  tspivot(topleft, toplsubseg);
8054  tspivot(botleft, botlsubseg);
8055  tspivot(botright, botrsubseg);
8056  tspivot(topright, toprsubseg);
8057  if (toplsubseg.ss == m->dummysub) {
8058  tsdissolve(topright);
8059  } else {
8060  tsbond(topright, toplsubseg);
8061  }
8062  if (botlsubseg.ss == m->dummysub) {
8063  tsdissolve(topleft);
8064  } else {
8065  tsbond(topleft, botlsubseg);
8066  }
8067  if (botrsubseg.ss == m->dummysub) {
8068  tsdissolve(botleft);
8069  } else {
8070  tsbond(botleft, botrsubseg);
8071  }
8072  if (toprsubseg.ss == m->dummysub) {
8073  tsdissolve(botright);
8074  } else {
8075  tsbond(botright, toprsubseg);
8076  }
8077  }
8078 
8079  /* New vertex assignments for the rotated quadrilateral. */
8080  setorg(*flipedge, farvertex);
8081  setdest(*flipedge, botvertex);
8082  setapex(*flipedge, rightvertex);
8083  setorg(top, botvertex);
8084  setdest(top, farvertex);
8085  setapex(top, leftvertex);
8086  if (b->verbose > 2) {
8087  printf(" Edge flip results in left ");
8088  printtriangle(m, b, &top);
8089  printf(" and right ");
8090  printtriangle(m, b, flipedge);
8091  }
8092 }
8093 
8094 /*****************************************************************************/
8095 /* */
8096 /* unflip() Transform two triangles to two different triangles by */
8097 /* flipping an edge clockwise within a quadrilateral. Reverses */
8098 /* the flip() operation so that the data structures representing */
8099 /* the triangles are back where they were before the flip(). */
8100 /* */
8101 /* Imagine the original triangles, abc and bad, oriented so that the */
8102 /* shared edge ab lies in a horizontal plane, with the vertex b on the left */
8103 /* and the vertex a on the right. The vertex c lies below the edge, and */
8104 /* the vertex d lies above the edge. The `flipedge' handle holds the edge */
8105 /* ab of triangle abc, and is directed left, from vertex a to vertex b. */
8106 /* */
8107 /* The triangles abc and bad are deleted and replaced by the triangles cdb */
8108 /* and dca. The triangles that represent abc and bad are NOT deallocated; */
8109 /* they are reused for cdb and dca, respectively. Hence, any handles that */
8110 /* may have held the original triangles are still valid, although not */
8111 /* directed as they were before. */
8112 /* */
8113 /* Upon completion of this routine, the `flipedge' handle holds the edge */
8114 /* cd of triangle cdb, and is directed up, from vertex c to vertex d. */
8115 /* (Hence, the two triangles have rotated clockwise.) */
8116 /* */
8117 /* WARNING: This transformation is geometrically valid only if the */
8118 /* quadrilateral adbc is convex. Furthermore, this transformation is */
8119 /* valid only if there is not a subsegment between the triangles abc and */
8120 /* bad. This routine does not check either of these preconditions, and */
8121 /* it is the responsibility of the calling routine to ensure that they are */
8122 /* met. If they are not, the streets shall be filled with wailing and */
8123 /* gnashing of teeth. */
8124 /* */
8125 /*****************************************************************************/
8126 
8127 #ifdef ANSI_DECLARATORS
8128 void unflip(struct mesh *m, struct behavior *b, struct otri *flipedge)
8129 #else /* not ANSI_DECLARATORS */
8130 void unflip(m, b, flipedge)
8131 struct mesh *m;
8132 struct behavior *b;
8133 struct otri *flipedge; /* Handle for the triangle abc. */
8134 #endif /* not ANSI_DECLARATORS */
8135 
8136 {
8137  struct otri botleft, botright;
8138  struct otri topleft, topright;
8139  struct otri top;
8140  struct otri botlcasing, botrcasing;
8141  struct otri toplcasing, toprcasing;
8142  struct osub botlsubseg, botrsubseg;
8143  struct osub toplsubseg, toprsubseg;
8144  vertex leftvertex, rightvertex, botvertex;
8145  vertex farvertex;
8146  triangle ptr; /* Temporary variable used by sym(). */
8147  subseg sptr; /* Temporary variable used by tspivot(). */
8148 
8149  /* Identify the vertices of the quadrilateral. */
8150  org(*flipedge, rightvertex);
8151  dest(*flipedge, leftvertex);
8152  apex(*flipedge, botvertex);
8153  sym(*flipedge, top);
8154 #ifdef SELF_CHECK
8155  if (top.tri == m->dummytri) {
8156  printf("Internal error in unflip(): Attempt to flip on boundary.\n");
8157  lnextself(*flipedge);
8158  return;
8159  }
8160  if (m->checksegments) {
8161  tspivot(*flipedge, toplsubseg);
8162  if (toplsubseg.ss != m->dummysub) {
8163  printf("Internal error in unflip(): Attempt to flip a subsegment.\n");
8164  lnextself(*flipedge);
8165  return;
8166  }
8167  }
8168 #endif /* SELF_CHECK */
8169  apex(top, farvertex);
8170 
8171  /* Identify the casing of the quadrilateral. */
8172  lprev(top, topleft);
8173  sym(topleft, toplcasing);
8174  lnext(top, topright);
8175  sym(topright, toprcasing);
8176  lnext(*flipedge, botleft);
8177  sym(botleft, botlcasing);
8178  lprev(*flipedge, botright);
8179  sym(botright, botrcasing);
8180  /* Rotate the quadrilateral one-quarter turn clockwise. */
8181  bond(topleft, toprcasing);
8182  bond(botleft, toplcasing);
8183  bond(botright, botlcasing);
8184  bond(topright, botrcasing);
8185 
8186  if (m->checksegments) {
8187  /* Check for subsegments and rebond them to the quadrilateral. */
8188  tspivot(topleft, toplsubseg);
8189  tspivot(botleft, botlsubseg);
8190  tspivot(botright, botrsubseg);
8191  tspivot(topright, toprsubseg);
8192  if (toplsubseg.ss == m->dummysub) {
8193  tsdissolve(botleft);
8194  } else {
8195  tsbond(botleft, toplsubseg);
8196  }
8197  if (botlsubseg.ss == m->dummysub) {
8198  tsdissolve(botright);
8199  } else {
8200  tsbond(botright, botlsubseg);
8201  }
8202  if (botrsubseg.ss == m->dummysub) {
8203  tsdissolve(topright);
8204  } else {
8205  tsbond(topright, botrsubseg);
8206  }
8207  if (toprsubseg.ss == m->dummysub) {
8208  tsdissolve(topleft);
8209  } else {
8210  tsbond(topleft, toprsubseg);
8211  }
8212  }
8213 
8214  /* New vertex assignments for the rotated quadrilateral. */
8215  setorg(*flipedge, botvertex);
8216  setdest(*flipedge, farvertex);
8217  setapex(*flipedge, leftvertex);
8218  setorg(top, farvertex);
8219  setdest(top, botvertex);
8220  setapex(top, rightvertex);
8221  if (b->verbose > 2) {
8222  printf(" Edge unflip results in left ");
8223  printtriangle(m, b, flipedge);
8224  printf(" and right ");
8225  printtriangle(m, b, &top);
8226  }
8227 }
8228 
8229 /*****************************************************************************/
8230 /* */
8231 /* insertvertex() Insert a vertex into a Delaunay triangulation, */
8232 /* performing flips as necessary to maintain the Delaunay */
8233 /* property. */
8234 /* */
8235 /* The point `insertvertex' is located. If `searchtri.tri' is not NULL, */
8236 /* the search for the containing triangle begins from `searchtri'. If */
8237 /* `searchtri.tri' is NULL, a full point location procedure is called. */
8238 /* If `insertvertex' is found inside a triangle, the triangle is split into */
8239 /* three; if `insertvertex' lies on an edge, the edge is split in two, */
8240 /* thereby splitting the two adjacent triangles into four. Edge flips are */
8241 /* used to restore the Delaunay property. If `insertvertex' lies on an */
8242 /* existing vertex, no action is taken, and the value DUPLICATEVERTEX is */
8243 /* returned. On return, `searchtri' is set to a handle whose origin is the */
8244 /* existing vertex. */
8245 /* */
8246 /* Normally, the parameter `splitseg' is set to NULL, implying that no */
8247 /* subsegment should be split. In this case, if `insertvertex' is found to */
8248 /* lie on a segment, no action is taken, and the value VIOLATINGVERTEX is */
8249 /* returned. On return, `searchtri' is set to a handle whose primary edge */
8250 /* is the violated subsegment. */
8251 /* */
8252 /* If the calling routine wishes to split a subsegment by inserting a */
8253 /* vertex in it, the parameter `splitseg' should be that subsegment. In */
8254 /* this case, `searchtri' MUST be the triangle handle reached by pivoting */
8255 /* from that subsegment; no point location is done. */
8256 /* */
8257 /* `segmentflaws' and `triflaws' are flags that indicate whether or not */
8258 /* there should be checks for the creation of encroached subsegments or bad */
8259 /* quality triangles. If a newly inserted vertex encroaches upon */
8260 /* subsegments, these subsegments are added to the list of subsegments to */
8261 /* be split if `segmentflaws' is set. If bad triangles are created, these */
8262 /* are added to the queue if `triflaws' is set. */
8263 /* */
8264 /* If a duplicate vertex or violated segment does not prevent the vertex */
8265 /* from being inserted, the return value will be ENCROACHINGVERTEX if the */
8266 /* vertex encroaches upon a subsegment (and checking is enabled), or */
8267 /* SUCCESSFULVERTEX otherwise. In either case, `searchtri' is set to a */
8268 /* handle whose origin is the newly inserted vertex. */
8269 /* */
8270 /* insertvertex() does not use flip() for reasons of speed; some */
8271 /* information can be reused from edge flip to edge flip, like the */
8272 /* locations of subsegments. */
8273 /* */
8274 /*****************************************************************************/
8275 
8276 #ifdef ANSI_DECLARATORS
8277 enum insertvertexresult insertvertex(struct mesh *m, struct behavior *b,
8278  vertex newvertex, struct otri *searchtri,
8279  struct osub *splitseg,
8280  int segmentflaws, int triflaws)
8281 #else /* not ANSI_DECLARATORS */
8282 enum insertvertexresult insertvertex(m, b, newvertex, searchtri, splitseg,
8283  segmentflaws, triflaws)
8284 struct mesh *m;
8285 struct behavior *b;
8286 vertex newvertex;
8287 struct otri *searchtri;
8288 struct osub *splitseg;
8289 int segmentflaws;
8290 int triflaws;
8291 #endif /* not ANSI_DECLARATORS */
8292 
8293 {
8294  struct otri horiz;
8295  struct otri top;
8296  struct otri botleft, botright;
8297  struct otri topleft, topright;
8298  struct otri newbotleft, newbotright;
8299  struct otri newtopright;
8300  struct otri botlcasing, botrcasing;
8301  struct otri toplcasing={NULL, 0}, toprcasing={NULL, 0};
8302  struct otri testtri;
8303  struct osub botlsubseg, botrsubseg;
8304  struct osub toplsubseg, toprsubseg;
8305  struct osub brokensubseg;
8306  struct osub checksubseg;
8307  struct osub rightsubseg;
8308  struct osub newsubseg;
8309  struct badsubseg *encroached;
8310  struct flipstacker *newflip;
8311  vertex first;
8312  vertex leftvertex, rightvertex, botvertex, topvertex, farvertex;
8313  vertex segmentorg, segmentdest;
8314  REAL attrib;
8315  REAL area;
8316  enum insertvertexresult success;
8317  enum locateresult intersect;
8318  int doflip;
8319  int mirrorflag;
8320  int enq;
8321  int i;
8322  triangle ptr; /* Temporary variable used by sym(). */
8323  subseg sptr; /* Temporary variable used by spivot() and tspivot(). */
8324 
8325  if (b->verbose > 1) {
8326  printf(" Inserting (%.12g, %.12g).\n", newvertex[0], newvertex[1]);
8327  }
8328 
8329  if (splitseg == (struct osub *) NULL) {
8330  /* Find the location of the vertex to be inserted. Check if a good */
8331  /* starting triangle has already been provided by the caller. */
8332  if (searchtri->tri == m->dummytri) {
8333  /* Find a boundary triangle. */
8334  horiz.tri = m->dummytri;
8335  horiz.orient = 0;
8336  symself(horiz);
8337  /* Search for a triangle containing `newvertex'. */
8338  intersect = locate(m, b, newvertex, &horiz);
8339  } else {
8340  /* Start searching from the triangle provided by the caller. */
8341  otricopy(*searchtri, horiz);
8342  intersect = preciselocate(m, b, newvertex, &horiz, 1);
8343  }
8344  } else {
8345  /* The calling routine provides the subsegment in which */
8346  /* the vertex is inserted. */
8347  otricopy(*searchtri, horiz);
8348  intersect = ONEDGE;
8349  }
8350 
8351  if (intersect == ONVERTEX) {
8352  /* There's already a vertex there. Return in `searchtri' a triangle */
8353  /* whose origin is the existing vertex. */
8354  otricopy(horiz, *searchtri);
8355  otricopy(horiz, m->recenttri);
8356  return DUPLICATEVERTEX;
8357  }
8358  if ((intersect == ONEDGE) || (intersect == OUTSIDE)) {
8359  /* The vertex falls on an edge or boundary. */
8360  if (m->checksegments && (splitseg == (struct osub *) NULL)) {
8361  /* Check whether the vertex falls on a subsegment. */
8362  tspivot(horiz, brokensubseg);
8363  if (brokensubseg.ss != m->dummysub) {
8364  /* The vertex falls on a subsegment, and hence will not be inserted. */
8365  if (segmentflaws) {
8366  enq = b->nobisect != 2;
8367  if (enq && (b->nobisect == 1)) {
8368  /* This subsegment may be split only if it is an */
8369  /* internal boundary. */
8370  sym(horiz, testtri);
8371  enq = testtri.tri != m->dummytri;
8372  }
8373  if (enq) {
8374  /* Add the subsegment to the list of encroached subsegments. */
8375  encroached = (struct badsubseg *) poolalloc(&m->badsubsegs);
8376  encroached->encsubseg = sencode(brokensubseg);
8377  sorg(brokensubseg, encroached->subsegorg);
8378  sdest(brokensubseg, encroached->subsegdest);
8379  if (b->verbose > 2) {
8380  printf(
8381  " Queueing encroached subsegment (%.12g, %.12g) (%.12g, %.12g).\n",
8382  encroached->subsegorg[0], encroached->subsegorg[1],
8383  encroached->subsegdest[0], encroached->subsegdest[1]);
8384  }
8385  }
8386  }
8387  /* Return a handle whose primary edge contains the vertex, */
8388  /* which has not been inserted. */
8389  otricopy(horiz, *searchtri);
8390  otricopy(horiz, m->recenttri);
8391  return VIOLATINGVERTEX;
8392  }
8393  }
8394 
8395  /* Insert the vertex on an edge, dividing one triangle into two (if */
8396  /* the edge lies on a boundary) or two triangles into four. */
8397  lprev(horiz, botright);
8398  sym(botright, botrcasing);
8399  sym(horiz, topright);
8400  /* Is there a second triangle? (Or does this edge lie on a boundary?) */
8401  mirrorflag = topright.tri != m->dummytri;
8402  if (mirrorflag) {
8403  lnextself(topright);
8404  sym(topright, toprcasing);
8405  maketriangle(m, b, &newtopright);
8406  } else {
8407  /* Splitting a boundary edge increases the number of boundary edges. */
8408  m->hullsize++;
8409  }
8410  maketriangle(m, b, &newbotright);
8411 
8412  /* Set the vertices of changed and new triangles. */
8413  org(horiz, rightvertex);
8414  dest(horiz, leftvertex);
8415  apex(horiz, botvertex);
8416  setorg(newbotright, botvertex);
8417  setdest(newbotright, rightvertex);
8418  setapex(newbotright, newvertex);
8419  setorg(horiz, newvertex);
8420  for (i = 0; i < m->eextras; i++) {
8421  /* Set the element attributes of a new triangle. */
8422  setelemattribute(newbotright, i, elemattribute(botright, i));
8423  }
8424  if (b->vararea) {
8425  /* Set the area constraint of a new triangle. */
8426  setareabound(newbotright, areabound(botright));
8427  }
8428  if (mirrorflag) {
8429  dest(topright, topvertex);
8430  setorg(newtopright, rightvertex);
8431  setdest(newtopright, topvertex);
8432  setapex(newtopright, newvertex);
8433  setorg(topright, newvertex);
8434  for (i = 0; i < m->eextras; i++) {
8435  /* Set the element attributes of another new triangle. */
8436  setelemattribute(newtopright, i, elemattribute(topright, i));
8437  }
8438  if (b->vararea) {
8439  /* Set the area constraint of another new triangle. */
8440  setareabound(newtopright, areabound(topright));
8441  }
8442  }
8443 
8444  /* There may be subsegments that need to be bonded */
8445  /* to the new triangle(s). */
8446  if (m->checksegments) {
8447  tspivot(botright, botrsubseg);
8448  if (botrsubseg.ss != m->dummysub) {
8449  tsdissolve(botright);
8450  tsbond(newbotright, botrsubseg);
8451  }
8452  if (mirrorflag) {
8453  tspivot(topright, toprsubseg);
8454  if (toprsubseg.ss != m->dummysub) {
8455  tsdissolve(topright);
8456  tsbond(newtopright, toprsubseg);
8457  }
8458  }
8459  }
8460 
8461  /* Bond the new triangle(s) to the surrounding triangles. */
8462  bond(newbotright, botrcasing);
8463  lprevself(newbotright);
8464  bond(newbotright, botright);
8465  lprevself(newbotright);
8466  if (mirrorflag) {
8467  bond(newtopright, toprcasing);
8468  lnextself(newtopright);
8469  bond(newtopright, topright);
8470  lnextself(newtopright);
8471  bond(newtopright, newbotright);
8472  }
8473 
8474  if (splitseg != (struct osub *) NULL) {
8475  /* Split the subsegment into two. */
8476  setsdest(*splitseg, newvertex);
8477  segorg(*splitseg, segmentorg);
8478  segdest(*splitseg, segmentdest);
8479  ssymself(*splitseg);
8480  spivot(*splitseg, rightsubseg);
8481  insertsubseg(m, b, &newbotright, mark(*splitseg));
8482  tspivot(newbotright, newsubseg);
8483  setsegorg(newsubseg, segmentorg);
8484  setsegdest(newsubseg, segmentdest);
8485  sbond(*splitseg, newsubseg);
8486  ssymself(newsubseg);
8487  sbond(newsubseg, rightsubseg);
8488  ssymself(*splitseg);
8489  /* Transfer the subsegment's boundary marker to the vertex */
8490  /* if required. */
8491  if (vertexmark(newvertex) == 0) {
8492  setvertexmark(newvertex, mark(*splitseg));
8493  }
8494  }
8495 
8496  if (m->checkquality) {
8497  poolrestart(&m->flipstackers);
8498  m->lastflip = (struct flipstacker *) poolalloc(&m->flipstackers);
8499  m->lastflip->flippedtri = encode(horiz);
8500  m->lastflip->prevflip = (struct flipstacker *) &insertvertex;
8501  }
8502 
8503 #ifdef SELF_CHECK
8504  if (counterclockwise(m, b, rightvertex, leftvertex, botvertex) < 0.0) {
8505  printf("Internal error in insertvertex():\n");
8506  printf(
8507  " Clockwise triangle prior to edge vertex insertion (bottom).\n");
8508  }
8509  if (mirrorflag) {
8510  if (counterclockwise(m, b, leftvertex, rightvertex, topvertex) < 0.0) {
8511  printf("Internal error in insertvertex():\n");
8512  printf(" Clockwise triangle prior to edge vertex insertion (top).\n");
8513  }
8514  if (counterclockwise(m, b, rightvertex, topvertex, newvertex) < 0.0) {
8515  printf("Internal error in insertvertex():\n");
8516  printf(
8517  " Clockwise triangle after edge vertex insertion (top right).\n");
8518  }
8519  if (counterclockwise(m, b, topvertex, leftvertex, newvertex) < 0.0) {
8520  printf("Internal error in insertvertex():\n");
8521  printf(
8522  " Clockwise triangle after edge vertex insertion (top left).\n");
8523  }
8524  }
8525  if (counterclockwise(m, b, leftvertex, botvertex, newvertex) < 0.0) {
8526  printf("Internal error in insertvertex():\n");
8527  printf(
8528  " Clockwise triangle after edge vertex insertion (bottom left).\n");
8529  }
8530  if (counterclockwise(m, b, botvertex, rightvertex, newvertex) < 0.0) {
8531  printf("Internal error in insertvertex():\n");
8532  printf(
8533  " Clockwise triangle after edge vertex insertion (bottom right).\n");
8534  }
8535 #endif /* SELF_CHECK */
8536  if (b->verbose > 2) {
8537  printf(" Updating bottom left ");
8538  printtriangle(m, b, &botright);
8539  if (mirrorflag) {
8540  printf(" Updating top left ");
8541  printtriangle(m, b, &topright);
8542  printf(" Creating top right ");
8543  printtriangle(m, b, &newtopright);
8544  }
8545  printf(" Creating bottom right ");
8546  printtriangle(m, b, &newbotright);
8547  }
8548 
8549  /* Position `horiz' on the first edge to check for */
8550  /* the Delaunay property. */
8551  lnextself(horiz);
8552  } else {
8553  /* Insert the vertex in a triangle, splitting it into three. */
8554  lnext(horiz, botleft);
8555  lprev(horiz, botright);
8556  sym(botleft, botlcasing);
8557  sym(botright, botrcasing);
8558  maketriangle(m, b, &newbotleft);
8559  maketriangle(m, b, &newbotright);
8560 
8561  /* Set the vertices of changed and new triangles. */
8562  org(horiz, rightvertex);
8563  dest(horiz, leftvertex);
8564  apex(horiz, botvertex);
8565  setorg(newbotleft, leftvertex);
8566  setdest(newbotleft, botvertex);
8567  setapex(newbotleft, newvertex);
8568  setorg(newbotright, botvertex);
8569  setdest(newbotright, rightvertex);
8570  setapex(newbotright, newvertex);
8571  setapex(horiz, newvertex);
8572  for (i = 0; i < m->eextras; i++) {
8573  /* Set the element attributes of the new triangles. */
8574  attrib = elemattribute(horiz, i);
8575  setelemattribute(newbotleft, i, attrib);
8576  setelemattribute(newbotright, i, attrib);
8577  }
8578  if (b->vararea) {
8579  /* Set the area constraint of the new triangles. */
8580  area = areabound(horiz);
8581  setareabound(newbotleft, area);
8582  setareabound(newbotright, area);
8583  }
8584 
8585  /* There may be subsegments that need to be bonded */
8586  /* to the new triangles. */
8587  if (m->checksegments) {
8588  tspivot(botleft, botlsubseg);
8589  if (botlsubseg.ss != m->dummysub) {
8590  tsdissolve(botleft);
8591  tsbond(newbotleft, botlsubseg);
8592  }
8593  tspivot(botright, botrsubseg);
8594  if (botrsubseg.ss != m->dummysub) {
8595  tsdissolve(botright);
8596  tsbond(newbotright, botrsubseg);
8597  }
8598  }
8599 
8600  /* Bond the new triangles to the surrounding triangles. */
8601  bond(newbotleft, botlcasing);
8602  bond(newbotright, botrcasing);
8603  lnextself(newbotleft);
8604  lprevself(newbotright);
8605  bond(newbotleft, newbotright);
8606  lnextself(newbotleft);
8607  bond(botleft, newbotleft);
8608  lprevself(newbotright);
8609  bond(botright, newbotright);
8610 
8611  if (m->checkquality) {
8612  poolrestart(&m->flipstackers);
8613  m->lastflip = (struct flipstacker *) poolalloc(&m->flipstackers);
8614  m->lastflip->flippedtri = encode(horiz);
8615  m->lastflip->prevflip = (struct flipstacker *) NULL;
8616  }
8617 
8618 #ifdef SELF_CHECK
8619  if (counterclockwise(m, b, rightvertex, leftvertex, botvertex) < 0.0) {
8620  printf("Internal error in insertvertex():\n");
8621  printf(" Clockwise triangle prior to vertex insertion.\n");
8622  }
8623  if (counterclockwise(m, b, rightvertex, leftvertex, newvertex) < 0.0) {
8624  printf("Internal error in insertvertex():\n");
8625  printf(" Clockwise triangle after vertex insertion (top).\n");
8626  }
8627  if (counterclockwise(m, b, leftvertex, botvertex, newvertex) < 0.0) {
8628  printf("Internal error in insertvertex():\n");
8629  printf(" Clockwise triangle after vertex insertion (left).\n");
8630  }
8631  if (counterclockwise(m, b, botvertex, rightvertex, newvertex) < 0.0) {
8632  printf("Internal error in insertvertex():\n");
8633  printf(" Clockwise triangle after vertex insertion (right).\n");
8634  }
8635 #endif /* SELF_CHECK */
8636  if (b->verbose > 2) {
8637  printf(" Updating top ");
8638  printtriangle(m, b, &horiz);
8639  printf(" Creating left ");
8640  printtriangle(m, b, &newbotleft);
8641  printf(" Creating right ");
8642  printtriangle(m, b, &newbotright);
8643  }
8644  }
8645 
8646  /* The insertion is successful by default, unless an encroached */
8647  /* subsegment is found. */
8648  success = SUCCESSFULVERTEX;
8649  /* Circle around the newly inserted vertex, checking each edge opposite */
8650  /* it for the Delaunay property. Non-Delaunay edges are flipped. */
8651  /* `horiz' is always the edge being checked. `first' marks where to */
8652  /* stop circling. */
8653  org(horiz, first);
8654  rightvertex = first;
8655  dest(horiz, leftvertex);
8656  /* Circle until finished. */
8657  while (1) {
8658  /* By default, the edge will be flipped. */
8659  doflip = 1;
8660 
8661  if (m->checksegments) {
8662  /* Check for a subsegment, which cannot be flipped. */
8663  tspivot(horiz, checksubseg);
8664  if (checksubseg.ss != m->dummysub) {
8665  /* The edge is a subsegment and cannot be flipped. */
8666  doflip = 0;
8667 #ifndef CDT_ONLY
8668  if (segmentflaws) {
8669  /* Does the new vertex encroach upon this subsegment? */
8670  if (checkseg4encroach(m, b, &checksubseg)) {
8671  success = ENCROACHINGVERTEX;
8672  }
8673  }
8674 #endif /* not CDT_ONLY */
8675  }
8676  }
8677 
8678  if (doflip) {
8679  /* Check if the edge is a boundary edge. */
8680  sym(horiz, top);
8681  if (top.tri == m->dummytri) {
8682  /* The edge is a boundary edge and cannot be flipped. */
8683  doflip = 0;
8684  } else {
8685  /* Find the vertex on the other side of the edge. */
8686  apex(top, farvertex);
8687  /* In the incremental Delaunay triangulation algorithm, any of */
8688  /* `leftvertex', `rightvertex', and `farvertex' could be vertices */
8689  /* of the triangular bounding box. These vertices must be */
8690  /* treated as if they are infinitely distant, even though their */
8691  /* "coordinates" are not. */
8692  if ((leftvertex == m->infvertex1) || (leftvertex == m->infvertex2) ||
8693  (leftvertex == m->infvertex3)) {
8694  /* `leftvertex' is infinitely distant. Check the convexity of */
8695  /* the boundary of the triangulation. 'farvertex' might be */
8696  /* infinite as well, but trust me, this same condition should */
8697  /* be applied. */
8698  doflip = counterclockwise(m, b, newvertex, rightvertex, farvertex)
8699  > 0.0;
8700  } else if ((rightvertex == m->infvertex1) ||
8701  (rightvertex == m->infvertex2) ||
8702  (rightvertex == m->infvertex3)) {
8703  /* `rightvertex' is infinitely distant. Check the convexity of */
8704  /* the boundary of the triangulation. 'farvertex' might be */
8705  /* infinite as well, but trust me, this same condition should */
8706  /* be applied. */
8707  doflip = counterclockwise(m, b, farvertex, leftvertex, newvertex)
8708  > 0.0;
8709  } else if ((farvertex == m->infvertex1) ||
8710  (farvertex == m->infvertex2) ||
8711  (farvertex == m->infvertex3)) {
8712  /* `farvertex' is infinitely distant and cannot be inside */
8713  /* the circumcircle of the triangle `horiz'. */
8714  doflip = 0;
8715  } else {
8716  /* Test whether the edge is locally Delaunay. */
8717  doflip = incircle(m, b, leftvertex, newvertex, rightvertex,
8718  farvertex) > 0.0;
8719  }
8720  if (doflip) {
8721  /* We made it! Flip the edge `horiz' by rotating its containing */
8722  /* quadrilateral (the two triangles adjacent to `horiz'). */
8723  /* Identify the casing of the quadrilateral. */
8724  lprev(top, topleft);
8725  sym(topleft, toplcasing);
8726  lnext(top, topright);
8727  sym(topright, toprcasing);
8728  lnext(horiz, botleft);
8729  sym(botleft, botlcasing);
8730  lprev(horiz, botright);
8731  sym(botright, botrcasing);
8732  /* Rotate the quadrilateral one-quarter turn counterclockwise. */
8733  bond(topleft, botlcasing);
8734  bond(botleft, botrcasing);
8735  bond(botright, toprcasing);
8736  bond(topright, toplcasing);
8737  if (m->checksegments) {
8738  /* Check for subsegments and rebond them to the quadrilateral. */
8739  tspivot(topleft, toplsubseg);
8740  tspivot(botleft, botlsubseg);
8741  tspivot(botright, botrsubseg);
8742  tspivot(topright, toprsubseg);
8743  if (toplsubseg.ss == m->dummysub) {
8744  tsdissolve(topright);
8745  } else {
8746  tsbond(topright, toplsubseg);
8747  }
8748  if (botlsubseg.ss == m->dummysub) {
8749  tsdissolve(topleft);
8750  } else {
8751  tsbond(topleft, botlsubseg);
8752  }
8753  if (botrsubseg.ss == m->dummysub) {
8754  tsdissolve(botleft);
8755  } else {
8756  tsbond(botleft, botrsubseg);
8757  }
8758  if (toprsubseg.ss == m->dummysub) {
8759  tsdissolve(botright);
8760  } else {
8761  tsbond(botright, toprsubseg);
8762  }
8763  }
8764  /* New vertex assignments for the rotated quadrilateral. */
8765  setorg(horiz, farvertex);
8766  setdest(horiz, newvertex);
8767  setapex(horiz, rightvertex);
8768  setorg(top, newvertex);
8769  setdest(top, farvertex);
8770  setapex(top, leftvertex);
8771  for (i = 0; i < m->eextras; i++) {
8772  /* Take the average of the two triangles' attributes. */
8773  attrib = 0.5 * (elemattribute(top, i) + elemattribute(horiz, i));
8774  setelemattribute(top, i, attrib);
8775  setelemattribute(horiz, i, attrib);
8776  }
8777  if (b->vararea) {
8778  if ((areabound(top) <= 0.0) || (areabound(horiz) <= 0.0)) {
8779  area = -1.0;
8780  } else {
8781  /* Take the average of the two triangles' area constraints. */
8782  /* This prevents small area constraints from migrating a */
8783  /* long, long way from their original location due to flips. */
8784  area = 0.5 * (areabound(top) + areabound(horiz));
8785  }
8786  setareabound(top, area);
8787  setareabound(horiz, area);
8788  }
8789 
8790  if (m->checkquality) {
8791  newflip = (struct flipstacker *) poolalloc(&m->flipstackers);
8792  newflip->flippedtri = encode(horiz);
8793  newflip->prevflip = m->lastflip;
8794  m->lastflip = newflip;
8795  }
8796 
8797 #ifdef SELF_CHECK
8798  if (newvertex != (vertex) NULL) {
8799  if (counterclockwise(m, b, leftvertex, newvertex, rightvertex) <
8800  0.0) {
8801  printf("Internal error in insertvertex():\n");
8802  printf(" Clockwise triangle prior to edge flip (bottom).\n");
8803  }
8804  /* The following test has been removed because constrainededge() */
8805  /* sometimes generates inverted triangles that insertvertex() */
8806  /* removes. */
8807 /*
8808  if (counterclockwise(m, b, rightvertex, farvertex, leftvertex) <
8809  0.0) {
8810  printf("Internal error in insertvertex():\n");
8811  printf(" Clockwise triangle prior to edge flip (top).\n");
8812  }
8813 */
8814  if (counterclockwise(m, b, farvertex, leftvertex, newvertex) <
8815  0.0) {
8816  printf("Internal error in insertvertex():\n");
8817  printf(" Clockwise triangle after edge flip (left).\n");
8818  }
8819  if (counterclockwise(m, b, newvertex, rightvertex, farvertex) <
8820  0.0) {
8821  printf("Internal error in insertvertex():\n");
8822  printf(" Clockwise triangle after edge flip (right).\n");
8823  }
8824  }
8825 #endif /* SELF_CHECK */
8826  if (b->verbose > 2) {
8827  printf(" Edge flip results in left ");
8828  lnextself(topleft);
8829  printtriangle(m, b, &topleft);
8830  printf(" and right ");
8831  printtriangle(m, b, &horiz);
8832  }
8833  /* On the next iterations, consider the two edges that were */
8834  /* exposed (this is, are now visible to the newly inserted */
8835  /* vertex) by the edge flip. */
8836  lprevself(horiz);
8837  leftvertex = farvertex;
8838  }
8839  }
8840  }
8841  if (!doflip) {
8842  /* The handle `horiz' is accepted as locally Delaunay. */
8843 #ifndef CDT_ONLY
8844  if (triflaws) {
8845  /* Check the triangle `horiz' for quality. */
8846  testtriangle(m, b, &horiz);
8847  }
8848 #endif /* not CDT_ONLY */
8849  /* Look for the next edge around the newly inserted vertex. */
8850  lnextself(horiz);
8851  sym(horiz, testtri);
8852  /* Check for finishing a complete revolution about the new vertex, or */
8853  /* falling outside of the triangulation. The latter will happen */
8854  /* when a vertex is inserted at a boundary. */
8855  if ((leftvertex == first) || (testtri.tri == m->dummytri)) {
8856  /* We're done. Return a triangle whose origin is the new vertex. */
8857  lnext(horiz, *searchtri);
8858  lnext(horiz, m->recenttri);
8859  return success;
8860  }
8861  /* Finish finding the next edge around the newly inserted vertex. */
8862  lnext(testtri, horiz);
8863  rightvertex = leftvertex;
8864  dest(horiz, leftvertex);
8865  }
8866  }
8867 }
8868 
8869 /*****************************************************************************/
8870 /* */
8871 /* triangulatepolygon() Find the Delaunay triangulation of a polygon that */
8872 /* has a certain "nice" shape. This includes the */
8873 /* polygons that result from deletion of a vertex or */
8874 /* insertion of a segment. */
8875 /* */
8876 /* This is a conceptually difficult routine. The starting assumption is */
8877 /* that we have a polygon with n sides. n - 1 of these sides are currently */
8878 /* represented as edges in the mesh. One side, called the "base", need not */
8879 /* be. */
8880 /* */
8881 /* Inside the polygon is a structure I call a "fan", consisting of n - 1 */
8882 /* triangles that share a common origin. For each of these triangles, the */
8883 /* edge opposite the origin is one of the sides of the polygon. The */
8884 /* primary edge of each triangle is the edge directed from the origin to */
8885 /* the destination; note that this is not the same edge that is a side of */
8886 /* the polygon. `firstedge' is the primary edge of the first triangle. */
8887 /* From there, the triangles follow in counterclockwise order about the */
8888 /* polygon, until `lastedge', the primary edge of the last triangle. */
8889 /* `firstedge' and `lastedge' are probably connected to other triangles */
8890 /* beyond the extremes of the fan, but their identity is not important, as */
8891 /* long as the fan remains connected to them. */
8892 /* */
8893 /* Imagine the polygon oriented so that its base is at the bottom. This */
8894 /* puts `firstedge' on the far right, and `lastedge' on the far left. */
8895 /* The right vertex of the base is the destination of `firstedge', and the */
8896 /* left vertex of the base is the apex of `lastedge'. */
8897 /* */
8898 /* The challenge now is to find the right sequence of edge flips to */
8899 /* transform the fan into a Delaunay triangulation of the polygon. Each */
8900 /* edge flip effectively removes one triangle from the fan, committing it */
8901 /* to the polygon. The resulting polygon has one fewer edge. If `doflip' */
8902 /* is set, the final flip will be performed, resulting in a fan of one */
8903 /* (useless?) triangle. If `doflip' is not set, the final flip is not */
8904 /* performed, resulting in a fan of two triangles, and an unfinished */
8905 /* triangular polygon that is not yet filled out with a single triangle. */
8906 /* On completion of the routine, `lastedge' is the last remaining triangle, */
8907 /* or the leftmost of the last two. */
8908 /* */
8909 /* Although the flips are performed in the order described above, the */
8910 /* decisions about what flips to perform are made in precisely the reverse */
8911 /* order. The recursive triangulatepolygon() procedure makes a decision, */
8912 /* uses up to two recursive calls to triangulate the "subproblems" */
8913 /* (polygons with fewer edges), and then performs an edge flip. */
8914 /* */
8915 /* The "decision" it makes is which vertex of the polygon should be */
8916 /* connected to the base. This decision is made by testing every possible */
8917 /* vertex. Once the best vertex is found, the two edges that connect this */
8918 /* vertex to the base become the bases for two smaller polygons. These */
8919 /* are triangulated recursively. Unfortunately, this approach can take */
8920 /* O(n^2) time not only in the worst case, but in many common cases. It's */
8921 /* rarely a big deal for vertex deletion, where n is rarely larger than */
8922 /* ten, but it could be a big deal for segment insertion, especially if */
8923 /* there's a lot of long segments that each cut many triangles. I ought to */
8924 /* code a faster algorithm some day. */
8925 /* */
8926 /* The `edgecount' parameter is the number of sides of the polygon, */
8927 /* including its base. `triflaws' is a flag that determines whether the */
8928 /* new triangles should be tested for quality, and enqueued if they are */
8929 /* bad. */
8930 /* */
8931 /*****************************************************************************/
8932 
8933 #ifdef ANSI_DECLARATORS
8934 void triangulatepolygon(struct mesh *m, struct behavior *b,
8935  struct otri *firstedge, struct otri *lastedge,
8936  int edgecount, int doflip, int triflaws)
8937 #else /* not ANSI_DECLARATORS */
8938 void triangulatepolygon(m, b, firstedge, lastedge, edgecount, doflip, triflaws)
8939 struct mesh *m;
8940 struct behavior *b;
8941 struct otri *firstedge;
8942 struct otri *lastedge;
8943 int edgecount;
8944 int doflip;
8945 int triflaws;
8946 #endif /* not ANSI_DECLARATORS */
8947 
8948 {
8949  struct otri testtri;
8950  struct otri besttri;
8951  struct otri tempedge;
8952  vertex leftbasevertex, rightbasevertex;
8953  vertex testvertex;
8954  vertex bestvertex;
8955  int bestnumber;
8956  int i;
8957  triangle ptr; /* Temporary variable used by sym(), onext(), and oprev(). */
8958 
8959  /* Identify the base vertices. */
8960  apex(*lastedge, leftbasevertex);
8961  dest(*firstedge, rightbasevertex);
8962  if (b->verbose > 2) {
8963  printf(" Triangulating interior polygon at edge\n");
8964  printf(" (%.12g, %.12g) (%.12g, %.12g)\n", leftbasevertex[0],
8965  leftbasevertex[1], rightbasevertex[0], rightbasevertex[1]);
8966  }
8967  /* Find the best vertex to connect the base to. */
8968  onext(*firstedge, besttri);
8969  dest(besttri, bestvertex);
8970  otricopy(besttri, testtri);
8971  bestnumber = 1;
8972  for (i = 2; i <= edgecount - 2; i++) {
8973  onextself(testtri);
8974  dest(testtri, testvertex);
8975  /* Is this a better vertex? */
8976  if (incircle(m, b, leftbasevertex, rightbasevertex, bestvertex,
8977  testvertex) > 0.0) {
8978  otricopy(testtri, besttri);
8979  bestvertex = testvertex;
8980  bestnumber = i;
8981  }
8982  }
8983  if (b->verbose > 2) {
8984  printf(" Connecting edge to (%.12g, %.12g)\n", bestvertex[0],
8985  bestvertex[1]);
8986  }
8987  if (bestnumber > 1) {
8988  /* Recursively triangulate the smaller polygon on the right. */
8989  oprev(besttri, tempedge);
8990  triangulatepolygon(m, b, firstedge, &tempedge, bestnumber + 1, 1,
8991  triflaws);
8992  }
8993  if (bestnumber < edgecount - 2) {
8994  /* Recursively triangulate the smaller polygon on the left. */
8995  sym(besttri, tempedge);
8996  triangulatepolygon(m, b, &besttri, lastedge, edgecount - bestnumber, 1,
8997  triflaws);
8998  /* Find `besttri' again; it may have been lost to edge flips. */
8999  sym(tempedge, besttri);
9000  }
9001  if (doflip) {
9002  /* Do one final edge flip. */
9003  flip(m, b, &besttri);
9004 #ifndef CDT_ONLY
9005  if (triflaws) {
9006  /* Check the quality of the newly committed triangle. */
9007  sym(besttri, testtri);
9008  testtriangle(m, b, &testtri);
9009  }
9010 #endif /* not CDT_ONLY */
9011  }
9012  /* Return the base triangle. */
9013  otricopy(besttri, *lastedge);
9014 }
9015 
9016 /*****************************************************************************/
9017 /* */
9018 /* deletevertex() Delete a vertex from a Delaunay triangulation, ensuring */
9019 /* that the triangulation remains Delaunay. */
9020 /* */
9021 /* The origin of `deltri' is deleted. The union of the triangles adjacent */
9022 /* to this vertex is a polygon, for which the Delaunay triangulation is */
9023 /* found. Two triangles are removed from the mesh. */
9024 /* */
9025 /* Only interior vertices that do not lie on segments or boundaries may be */
9026 /* deleted. */
9027 /* */
9028 /*****************************************************************************/
9029 
9030 #ifndef CDT_ONLY
9031 
9032 #ifdef ANSI_DECLARATORS
9033 void deletevertex(struct mesh *m, struct behavior *b, struct otri *deltri)
9034 #else /* not ANSI_DECLARATORS */
9035 void deletevertex(m, b, deltri)
9036 struct mesh *m;
9037 struct behavior *b;
9038 struct otri *deltri;
9039 #endif /* not ANSI_DECLARATORS */
9040 
9041 {
9042  struct otri countingtri;
9043  struct otri firstedge, lastedge;
9044  struct otri deltriright;
9045  struct otri lefttri, righttri;
9046  struct otri leftcasing, rightcasing;
9047  struct osub leftsubseg, rightsubseg;
9048  vertex delvertex;
9049  vertex neworg;
9050  int edgecount;
9051  triangle ptr; /* Temporary variable used by sym(), onext(), and oprev(). */
9052  subseg sptr; /* Temporary variable used by tspivot(). */
9053 
9054  org(*deltri, delvertex);
9055  if (b->verbose > 1) {
9056  printf(" Deleting (%.12g, %.12g).\n", delvertex[0], delvertex[1]);
9057  }
9058  vertexdealloc(m, delvertex);
9059 
9060  /* Count the degree of the vertex being deleted. */
9061  onext(*deltri, countingtri);
9062  edgecount = 1;
9063  while (!otriequal(*deltri, countingtri)) {
9064 #ifdef SELF_CHECK
9065  if (countingtri.tri == m->dummytri) {
9066  printf("Internal error in deletevertex():\n");
9067  printf(" Attempt to delete boundary vertex.\n");
9068  internalerror();
9069  }
9070 #endif /* SELF_CHECK */
9071  edgecount++;
9072  onextself(countingtri);
9073  }
9074 
9075 #ifdef SELF_CHECK
9076  if (edgecount < 3) {
9077  printf("Internal error in deletevertex():\n Vertex has degree %d.\n",
9078  edgecount);
9079  internalerror();
9080  }
9081 #endif /* SELF_CHECK */
9082  if (edgecount > 3) {
9083  /* Triangulate the polygon defined by the union of all triangles */
9084  /* adjacent to the vertex being deleted. Check the quality of */
9085  /* the resulting triangles. */
9086  onext(*deltri, firstedge);
9087  oprev(*deltri, lastedge);
9088  triangulatepolygon(m, b, &firstedge, &lastedge, edgecount, 0,
9089  !b->nobisect);
9090  }
9091  /* Splice out two triangles. */
9092  lprev(*deltri, deltriright);
9093  dnext(*deltri, lefttri);
9094  sym(lefttri, leftcasing);
9095  oprev(deltriright, righttri);
9096  sym(righttri, rightcasing);
9097  bond(*deltri, leftcasing);
9098  bond(deltriright, rightcasing);
9099  tspivot(lefttri, leftsubseg);
9100  if (leftsubseg.ss != m->dummysub) {
9101  tsbond(*deltri, leftsubseg);
9102  }
9103  tspivot(righttri, rightsubseg);
9104  if (rightsubseg.ss != m->dummysub) {
9105  tsbond(deltriright, rightsubseg);
9106  }
9107 
9108  /* Set the new origin of `deltri' and check its quality. */
9109  org(lefttri, neworg);
9110  setorg(*deltri, neworg);
9111  if (!b->nobisect) {
9112  testtriangle(m, b, deltri);
9113  }
9114 
9115  /* Delete the two spliced-out triangles. */
9116  triangledealloc(m, lefttri.tri);
9117  triangledealloc(m, righttri.tri);
9118 }
9119 
9120 #endif /* not CDT_ONLY */
9121 
9122 /*****************************************************************************/
9123 /* */
9124 /* undovertex() Undo the most recent vertex insertion. */
9125 /* */
9126 /* Walks through the list of transformations (flips and a vertex insertion) */
9127 /* in the reverse of the order in which they were done, and undoes them. */
9128 /* The inserted vertex is removed from the triangulation and deallocated. */
9129 /* Two triangles (possibly just one) are also deallocated. */
9130 /* */
9131 /*****************************************************************************/
9132 
9133 #ifndef CDT_ONLY
9134 
9135 #ifdef ANSI_DECLARATORS
9136 void undovertex(struct mesh *m, struct behavior *b)
9137 #else /* not ANSI_DECLARATORS */
9138 void undovertex(m, b)
9139 struct mesh *m;
9140 struct behavior *b;
9141 #endif /* not ANSI_DECLARATORS */
9142 
9143 {
9144  struct otri fliptri;
9145  struct otri botleft, botright, topright;
9146  struct otri botlcasing, botrcasing, toprcasing;
9147  struct otri gluetri;
9148  struct osub botlsubseg, botrsubseg, toprsubseg;
9149  vertex botvertex, rightvertex;
9150  triangle ptr; /* Temporary variable used by sym(). */
9151  subseg sptr; /* Temporary variable used by tspivot(). */
9152 
9153  /* Walk through the list of transformations (flips and a vertex insertion) */
9154  /* in the reverse of the order in which they were done, and undo them. */
9155  while (m->lastflip != (struct flipstacker *) NULL) {
9156  /* Find a triangle involved in the last unreversed transformation. */
9157  decode(m->lastflip->flippedtri, fliptri);
9158 
9159  /* We are reversing one of three transformations: a trisection of one */
9160  /* triangle into three (by inserting a vertex in the triangle), a */
9161  /* bisection of two triangles into four (by inserting a vertex in an */
9162  /* edge), or an edge flip. */
9163  if (m->lastflip->prevflip == (struct flipstacker *) NULL) {
9164  /* Restore a triangle that was split into three triangles, */
9165  /* so it is again one triangle. */
9166  dprev(fliptri, botleft);
9167  lnextself(botleft);
9168  onext(fliptri, botright);
9169  lprevself(botright);
9170  sym(botleft, botlcasing);
9171  sym(botright, botrcasing);
9172  dest(botleft, botvertex);
9173 
9174  setapex(fliptri, botvertex);
9175  lnextself(fliptri);
9176  bond(fliptri, botlcasing);
9177  tspivot(botleft, botlsubseg);
9178  tsbond(fliptri, botlsubseg);
9179  lnextself(fliptri);
9180  bond(fliptri, botrcasing);
9181  tspivot(botright, botrsubseg);
9182  tsbond(fliptri, botrsubseg);
9183 
9184  /* Delete the two spliced-out triangles. */
9185  triangledealloc(m, botleft.tri);
9186  triangledealloc(m, botright.tri);
9187  } else if (m->lastflip->prevflip == (struct flipstacker *) &insertvertex) {
9188  /* Restore two triangles that were split into four triangles, */
9189  /* so they are again two triangles. */
9190  lprev(fliptri, gluetri);
9191  sym(gluetri, botright);
9192  lnextself(botright);
9193  sym(botright, botrcasing);
9194  dest(botright, rightvertex);
9195 
9196  setorg(fliptri, rightvertex);
9197  bond(gluetri, botrcasing);
9198  tspivot(botright, botrsubseg);
9199  tsbond(gluetri, botrsubseg);
9200 
9201  /* Delete the spliced-out triangle. */
9202  triangledealloc(m, botright.tri);
9203 
9204  sym(fliptri, gluetri);
9205  if (gluetri.tri != m->dummytri) {
9206  lnextself(gluetri);
9207  dnext(gluetri, topright);
9208  sym(topright, toprcasing);
9209 
9210  setorg(gluetri, rightvertex);
9211  bond(gluetri, toprcasing);
9212  tspivot(topright, toprsubseg);
9213  tsbond(gluetri, toprsubseg);
9214 
9215  /* Delete the spliced-out triangle. */
9216  triangledealloc(m, topright.tri);
9217  }
9218 
9219  /* This is the end of the list, sneakily encoded. */
9220  m->lastflip->prevflip = (struct flipstacker *) NULL;
9221  } else {
9222  /* Undo an edge flip. */
9223  unflip(m, b, &fliptri);
9224  }
9225 
9226  /* Go on and process the next transformation. */
9227  m->lastflip = m->lastflip->prevflip;
9228  }
9229 }
9230 
9231 #endif /* not CDT_ONLY */
9232 
9235 /********* Mesh transformation routines end here *********/
9236 
9237 /********* Divide-and-conquer Delaunay triangulation begins here *********/
9241 /*****************************************************************************/
9242 /* */
9243 /* The divide-and-conquer bounding box */
9244 /* */
9245 /* I originally implemented the divide-and-conquer and incremental Delaunay */
9246 /* triangulations using the edge-based data structure presented by Guibas */
9247 /* and Stolfi. Switching to a triangle-based data structure doubled the */
9248 /* speed. However, I had to think of a few extra tricks to maintain the */
9249 /* elegance of the original algorithms. */
9250 /* */
9251 /* The "bounding box" used by my variant of the divide-and-conquer */
9252 /* algorithm uses one triangle for each edge of the convex hull of the */
9253 /* triangulation. These bounding triangles all share a common apical */
9254 /* vertex, which is represented by NULL and which represents nothing. */
9255 /* The bounding triangles are linked in a circular fan about this NULL */
9256 /* vertex, and the edges on the convex hull of the triangulation appear */
9257 /* opposite the NULL vertex. You might find it easiest to imagine that */
9258 /* the NULL vertex is a point in 3D space behind the center of the */
9259 /* triangulation, and that the bounding triangles form a sort of cone. */
9260 /* */
9261 /* This bounding box makes it easy to represent degenerate cases. For */
9262 /* instance, the triangulation of two vertices is a single edge. This edge */
9263 /* is represented by two bounding box triangles, one on each "side" of the */
9264 /* edge. These triangles are also linked together in a fan about the NULL */
9265 /* vertex. */
9266 /* */
9267 /* The bounding box also makes it easy to traverse the convex hull, as the */
9268 /* divide-and-conquer algorithm needs to do. */
9269 /* */
9270 /*****************************************************************************/
9271 
9272 /*****************************************************************************/
9273 /* */
9274 /* vertexsort() Sort an array of vertices by x-coordinate, using the */
9275 /* y-coordinate as a secondary key. */
9276 /* */
9277 /* Uses quicksort. Randomized O(n log n) time. No, I did not make any of */
9278 /* the usual quicksort mistakes. */
9279 /* */
9280 /*****************************************************************************/
9281 
9282 #ifdef ANSI_DECLARATORS
9283 void vertexsort(vertex *sortarray, int arraysize)
9284 #else /* not ANSI_DECLARATORS */
9285 void vertexsort(sortarray, arraysize)
9286 vertex *sortarray;
9287 int arraysize;
9288 #endif /* not ANSI_DECLARATORS */
9289 
9290 {
9291  int left, right;
9292  int pivot;
9293  REAL pivotx, pivoty;
9294  vertex temp;
9295 
9296  if (arraysize == 2) {
9297  /* Recursive base case. */
9298  if ((sortarray[0][0] > sortarray[1][0]) ||
9299  ((sortarray[0][0] == sortarray[1][0]) &&
9300  (sortarray[0][1] > sortarray[1][1]))) {
9301  temp = sortarray[1];
9302  sortarray[1] = sortarray[0];
9303  sortarray[0] = temp;
9304  }
9305  return;
9306  }
9307  /* Choose a random pivot to split the array. */
9308  pivot = (int) randomnation((unsigned int) arraysize);
9309  pivotx = sortarray[pivot][0];
9310  pivoty = sortarray[pivot][1];
9311  /* Split the array. */
9312  left = -1;
9313  right = arraysize;
9314  while (left < right) {
9315  /* Search for a vertex whose x-coordinate is too large for the left. */
9316  do {
9317  left++;
9318  } while ((left <= right) && ((sortarray[left][0] < pivotx) ||
9319  ((sortarray[left][0] == pivotx) &&
9320  (sortarray[left][1] < pivoty))));
9321  /* Search for a vertex whose x-coordinate is too small for the right. */
9322  do {
9323  right--;
9324  } while ((left <= right) && ((sortarray[right][0] > pivotx) ||
9325  ((sortarray[right][0] == pivotx) &&
9326  (sortarray[right][1] > pivoty))));
9327  if (left < right) {
9328  /* Swap the left and right vertices. */
9329  temp = sortarray[left];
9330  sortarray[left] = sortarray[right];
9331  sortarray[right] = temp;
9332  }
9333  }
9334  if (left > 1) {
9335  /* Recursively sort the left subset. */
9336  vertexsort(sortarray, left);
9337  }
9338  if (right < arraysize - 2) {
9339  /* Recursively sort the right subset. */
9340  vertexsort(&sortarray[right + 1], arraysize - right - 1);
9341  }
9342 }
9343 
9344 /*****************************************************************************/
9345 /* */
9346 /* vertexmedian() An order statistic algorithm, almost. Shuffles an */
9347 /* array of vertices so that the first `median' vertices */
9348 /* occur lexicographically before the remaining vertices. */
9349 /* */
9350 /* Uses the x-coordinate as the primary key if axis == 0; the y-coordinate */
9351 /* if axis == 1. Very similar to the vertexsort() procedure, but runs in */
9352 /* randomized linear time. */
9353 /* */
9354 /*****************************************************************************/
9355 
9356 #ifdef ANSI_DECLARATORS
9357 void vertexmedian(vertex *sortarray, int arraysize, int median, int axis)
9358 #else /* not ANSI_DECLARATORS */
9359 void vertexmedian(sortarray, arraysize, median, axis)
9360 vertex *sortarray;
9361 int arraysize;
9362 int median;
9363 int axis;
9364 #endif /* not ANSI_DECLARATORS */
9365 
9366 {
9367  int left, right;
9368  int pivot;
9369  REAL pivot1, pivot2;
9370  vertex temp;
9371 
9372  if (arraysize == 2) {
9373  /* Recursive base case. */
9374  if ((sortarray[0][axis] > sortarray[1][axis]) ||
9375  ((sortarray[0][axis] == sortarray[1][axis]) &&
9376  (sortarray[0][1 - axis] > sortarray[1][1 - axis]))) {
9377  temp = sortarray[1];
9378  sortarray[1] = sortarray[0];
9379  sortarray[0] = temp;
9380  }
9381  return;
9382  }
9383  /* Choose a random pivot to split the array. */
9384  pivot = (int) randomnation((unsigned int) arraysize);
9385  pivot1 = sortarray[pivot][axis];
9386  pivot2 = sortarray[pivot][1 - axis];
9387  /* Split the array. */
9388  left = -1;
9389  right = arraysize;
9390  while (left < right) {
9391  /* Search for a vertex whose x-coordinate is too large for the left. */
9392  do {
9393  left++;
9394  } while ((left <= right) && ((sortarray[left][axis] < pivot1) ||
9395  ((sortarray[left][axis] == pivot1) &&
9396  (sortarray[left][1 - axis] < pivot2))));
9397  /* Search for a vertex whose x-coordinate is too small for the right. */
9398  do {
9399  right--;
9400  } while ((left <= right) && ((sortarray[right][axis] > pivot1) ||
9401  ((sortarray[right][axis] == pivot1) &&
9402  (sortarray[right][1 - axis] > pivot2))));
9403  if (left < right) {
9404  /* Swap the left and right vertices. */
9405  temp = sortarray[left];
9406  sortarray[left] = sortarray[right];
9407  sortarray[right] = temp;
9408  }
9409  }
9410  /* Unlike in vertexsort(), at most one of the following */
9411  /* conditionals is true. */
9412  if (left > median) {
9413  /* Recursively shuffle the left subset. */
9414  vertexmedian(sortarray, left, median, axis);
9415  }
9416  if (right < median - 1) {
9417  /* Recursively shuffle the right subset. */
9418  vertexmedian(&sortarray[right + 1], arraysize - right - 1,
9419  median - right - 1, axis);
9420  }
9421 }
9422 
9423 /*****************************************************************************/
9424 /* */
9425 /* alternateaxes() Sorts the vertices as appropriate for the divide-and- */
9426 /* conquer algorithm with alternating cuts. */
9427 /* */
9428 /* Partitions by x-coordinate if axis == 0; by y-coordinate if axis == 1. */
9429 /* For the base case, subsets containing only two or three vertices are */
9430 /* always sorted by x-coordinate. */
9431 /* */
9432 /*****************************************************************************/
9433 
9434 #ifdef ANSI_DECLARATORS
9435 void alternateaxes(vertex *sortarray, int arraysize, int axis)
9436 #else /* not ANSI_DECLARATORS */
9437 void alternateaxes(sortarray, arraysize, axis)
9438 vertex *sortarray;
9439 int arraysize;
9440 int axis;
9441 #endif /* not ANSI_DECLARATORS */
9442 
9443 {
9444  int divider;
9445 
9446  divider = arraysize >> 1;
9447  if (arraysize <= 3) {
9448  /* Recursive base case: subsets of two or three vertices will be */
9449  /* handled specially, and should always be sorted by x-coordinate. */
9450  axis = 0;
9451  }
9452  /* Partition with a horizontal or vertical cut. */
9453  vertexmedian(sortarray, arraysize, divider, axis);
9454  /* Recursively partition the subsets with a cross cut. */
9455  if (arraysize - divider >= 2) {
9456  if (divider >= 2) {
9457  alternateaxes(sortarray, divider, 1 - axis);
9458  }
9459  alternateaxes(&sortarray[divider], arraysize - divider, 1 - axis);
9460  }
9461 }
9462 
9463 /*****************************************************************************/
9464 /* */
9465 /* mergehulls() Merge two adjacent Delaunay triangulations into a */
9466 /* single Delaunay triangulation. */
9467 /* */
9468 /* This is similar to the algorithm given by Guibas and Stolfi, but uses */
9469 /* a triangle-based, rather than edge-based, data structure. */
9470 /* */
9471 /* The algorithm walks up the gap between the two triangulations, knitting */
9472 /* them together. As they are merged, some of their bounding triangles */
9473 /* are converted into real triangles of the triangulation. The procedure */
9474 /* pulls each hull's bounding triangles apart, then knits them together */
9475 /* like the teeth of two gears. The Delaunay property determines, at each */
9476 /* step, whether the next "tooth" is a bounding triangle of the left hull */
9477 /* or the right. When a bounding triangle becomes real, its apex is */
9478 /* changed from NULL to a real vertex. */
9479 /* */
9480 /* Only two new triangles need to be allocated. These become new bounding */
9481 /* triangles at the top and bottom of the seam. They are used to connect */
9482 /* the remaining bounding triangles (those that have not been converted */
9483 /* into real triangles) into a single fan. */
9484 /* */
9485 /* On entry, `farleft' and `innerleft' are bounding triangles of the left */
9486 /* triangulation. The origin of `farleft' is the leftmost vertex, and */
9487 /* the destination of `innerleft' is the rightmost vertex of the */
9488 /* triangulation. Similarly, `innerright' and `farright' are bounding */
9489 /* triangles of the right triangulation. The origin of `innerright' and */
9490 /* destination of `farright' are the leftmost and rightmost vertices. */
9491 /* */
9492 /* On completion, the origin of `farleft' is the leftmost vertex of the */
9493 /* merged triangulation, and the destination of `farright' is the rightmost */
9494 /* vertex. */
9495 /* */
9496 /*****************************************************************************/
9497 
9498 #ifdef ANSI_DECLARATORS
9499 void mergehulls(struct mesh *m, struct behavior *b, struct otri *farleft,
9500  struct otri *innerleft, struct otri *innerright,
9501  struct otri *farright, int axis)
9502 #else /* not ANSI_DECLARATORS */
9503 void mergehulls(m, b, farleft, innerleft, innerright, farright, axis)
9504 struct mesh *m;
9505 struct behavior *b;
9506 struct otri *farleft;
9507 struct otri *innerleft;
9508 struct otri *innerright;
9509 struct otri *farright;
9510 int axis;
9511 #endif /* not ANSI_DECLARATORS */
9512 
9513 {
9514  struct otri leftcand, rightcand;
9515  struct otri baseedge;
9516  struct otri nextedge;
9517  struct otri sidecasing, topcasing, outercasing;
9518  struct otri checkedge;
9519  vertex innerleftdest;
9520  vertex innerrightorg;
9521  vertex innerleftapex, innerrightapex;
9522  vertex farleftpt, farrightpt;
9523  vertex farleftapex, farrightapex;
9524  vertex lowerleft, lowerright;
9525  vertex upperleft, upperright;
9526  vertex nextapex;
9527  vertex checkvertex;
9528  int changemade;
9529  int badedge;
9530  int leftfinished, rightfinished;
9531  triangle ptr; /* Temporary variable used by sym(). */
9532 
9533  dest(*innerleft, innerleftdest);
9534  apex(*innerleft, innerleftapex);
9535  org(*innerright, innerrightorg);
9536  apex(*innerright, innerrightapex);
9537  /* Special treatment for horizontal cuts. */
9538  if (b->dwyer && (axis == 1)) {
9539  org(*farleft, farleftpt);
9540  apex(*farleft, farleftapex);
9541  dest(*farright, farrightpt);
9542  apex(*farright, farrightapex);
9543  /* The pointers to the extremal vertices are shifted to point to the */
9544  /* topmost and bottommost vertex of each hull, rather than the */
9545  /* leftmost and rightmost vertices. */
9546  while (farleftapex[1] < farleftpt[1]) {
9547  lnextself(*farleft);
9548  symself(*farleft);
9549  farleftpt = farleftapex;
9550  apex(*farleft, farleftapex);
9551  }
9552  sym(*innerleft, checkedge);
9553  apex(checkedge, checkvertex);
9554  while (checkvertex[1] > innerleftdest[1]) {
9555  lnext(checkedge, *innerleft);
9556  innerleftapex = innerleftdest;
9557  innerleftdest = checkvertex;
9558  sym(*innerleft, checkedge);
9559  apex(checkedge, checkvertex);
9560  }
9561  while (innerrightapex[1] < innerrightorg[1]) {
9562  lnextself(*innerright);
9563  symself(*innerright);
9564  innerrightorg = innerrightapex;
9565  apex(*innerright, innerrightapex);
9566  }
9567  sym(*farright, checkedge);
9568  apex(checkedge, checkvertex);
9569  while (checkvertex[1] > farrightpt[1]) {
9570  lnext(checkedge, *farright);
9571  farrightapex = farrightpt;
9572  farrightpt = checkvertex;
9573  sym(*farright, checkedge);
9574  apex(checkedge, checkvertex);
9575  }
9576  }
9577  /* Find a line tangent to and below both hulls. */
9578  do {
9579  changemade = 0;
9580  /* Make innerleftdest the "bottommost" vertex of the left hull. */
9581  if (counterclockwise(m, b, innerleftdest, innerleftapex, innerrightorg) >
9582  0.0) {
9583  lprevself(*innerleft);
9584  symself(*innerleft);
9585  innerleftdest = innerleftapex;
9586  apex(*innerleft, innerleftapex);
9587  changemade = 1;
9588  }
9589  /* Make innerrightorg the "bottommost" vertex of the right hull. */
9590  if (counterclockwise(m, b, innerrightapex, innerrightorg, innerleftdest) >
9591  0.0) {
9592  lnextself(*innerright);
9593  symself(*innerright);
9594  innerrightorg = innerrightapex;
9595  apex(*innerright, innerrightapex);
9596  changemade = 1;
9597  }
9598  } while (changemade);
9599  /* Find the two candidates to be the next "gear tooth." */
9600  sym(*innerleft, leftcand);
9601  sym(*innerright, rightcand);
9602  /* Create the bottom new bounding triangle. */
9603  maketriangle(m, b, &baseedge);
9604  /* Connect it to the bounding boxes of the left and right triangulations. */
9605  bond(baseedge, *innerleft);
9606  lnextself(baseedge);
9607  bond(baseedge, *innerright);
9608  lnextself(baseedge);
9609  setorg(baseedge, innerrightorg);
9610  setdest(baseedge, innerleftdest);
9611  /* Apex is intentionally left NULL. */
9612  if (b->verbose > 2) {
9613  printf(" Creating base bounding ");
9614  printtriangle(m, b, &baseedge);
9615  }
9616  /* Fix the extreme triangles if necessary. */
9617  org(*farleft, farleftpt);
9618  if (innerleftdest == farleftpt) {
9619  lnext(baseedge, *farleft);
9620  }
9621  dest(*farright, farrightpt);
9622  if (innerrightorg == farrightpt) {
9623  lprev(baseedge, *farright);
9624  }
9625  /* The vertices of the current knitting edge. */
9626  lowerleft = innerleftdest;
9627  lowerright = innerrightorg;
9628  /* The candidate vertices for knitting. */
9629  apex(leftcand, upperleft);
9630  apex(rightcand, upperright);
9631  /* Walk up the gap between the two triangulations, knitting them together. */
9632  while (1) {
9633  /* Have we reached the top? (This isn't quite the right question, */
9634  /* because even though the left triangulation might seem finished now, */
9635  /* moving up on the right triangulation might reveal a new vertex of */
9636  /* the left triangulation. And vice-versa.) */
9637  leftfinished = counterclockwise(m, b, upperleft, lowerleft, lowerright) <=
9638  0.0;
9639  rightfinished = counterclockwise(m, b, upperright, lowerleft, lowerright)
9640  <= 0.0;
9641  if (leftfinished && rightfinished) {
9642  /* Create the top new bounding triangle. */
9643  maketriangle(m, b, &nextedge);
9644  setorg(nextedge, lowerleft);
9645  setdest(nextedge, lowerright);
9646  /* Apex is intentionally left NULL. */
9647  /* Connect it to the bounding boxes of the two triangulations. */
9648  bond(nextedge, baseedge);
9649  lnextself(nextedge);
9650  bond(nextedge, rightcand);
9651  lnextself(nextedge);
9652  bond(nextedge, leftcand);
9653  if (b->verbose > 2) {
9654  printf(" Creating top bounding ");
9655  printtriangle(m, b, &nextedge);
9656  }
9657  /* Special treatment for horizontal cuts. */
9658  if (b->dwyer && (axis == 1)) {
9659  org(*farleft, farleftpt);
9660  apex(*farleft, farleftapex);
9661  dest(*farright, farrightpt);
9662  apex(*farright, farrightapex);
9663  sym(*farleft, checkedge);
9664  apex(checkedge, checkvertex);
9665  /* The pointers to the extremal vertices are restored to the */
9666  /* leftmost and rightmost vertices (rather than topmost and */
9667  /* bottommost). */
9668  while (checkvertex[0] < farleftpt[0]) {
9669  lprev(checkedge, *farleft);
9670  farleftapex = farleftpt;
9671  farleftpt = checkvertex;
9672  sym(*farleft, checkedge);
9673  apex(checkedge, checkvertex);
9674  }
9675  while (farrightapex[0] > farrightpt[0]) {
9676  lprevself(*farright);
9677  symself(*farright);
9678  farrightpt = farrightapex;
9679  apex(*farright, farrightapex);
9680  }
9681  }
9682  return;
9683  }
9684  /* Consider eliminating edges from the left triangulation. */
9685  if (!leftfinished) {
9686  /* What vertex would be exposed if an edge were deleted? */
9687  lprev(leftcand, nextedge);
9688  symself(nextedge);
9689  apex(nextedge, nextapex);
9690  /* If nextapex is NULL, then no vertex would be exposed; the */
9691  /* triangulation would have been eaten right through. */
9692  if (nextapex != (vertex) NULL) {
9693  /* Check whether the edge is Delaunay. */
9694  badedge = incircle(m, b, lowerleft, lowerright, upperleft, nextapex) >
9695  0.0;
9696  while (badedge) {
9697  /* Eliminate the edge with an edge flip. As a result, the */
9698  /* left triangulation will have one more boundary triangle. */
9699  lnextself(nextedge);
9700  sym(nextedge, topcasing);
9701  lnextself(nextedge);
9702  sym(nextedge, sidecasing);
9703  bond(nextedge, topcasing);
9704  bond(leftcand, sidecasing);
9705  lnextself(leftcand);
9706  sym(leftcand, outercasing);
9707  lprevself(nextedge);
9708  bond(nextedge, outercasing);
9709  /* Correct the vertices to reflect the edge flip. */
9710  setorg(leftcand, lowerleft);
9711  setdest(leftcand, NULL);
9712  setapex(leftcand, nextapex);
9713  setorg(nextedge, NULL);
9714  setdest(nextedge, upperleft);
9715  setapex(nextedge, nextapex);
9716  /* Consider the newly exposed vertex. */
9717  upperleft = nextapex;
9718  /* What vertex would be exposed if another edge were deleted? */
9719  otricopy(sidecasing, nextedge);
9720  apex(nextedge, nextapex);
9721  if (nextapex != (vertex) NULL) {
9722  /* Check whether the edge is Delaunay. */
9723  badedge = incircle(m, b, lowerleft, lowerright, upperleft,
9724  nextapex) > 0.0;
9725  } else {
9726  /* Avoid eating right through the triangulation. */
9727  badedge = 0;
9728  }
9729  }
9730  }
9731  }
9732  /* Consider eliminating edges from the right triangulation. */
9733  if (!rightfinished) {
9734  /* What vertex would be exposed if an edge were deleted? */
9735  lnext(rightcand, nextedge);
9736  symself(nextedge);
9737  apex(nextedge, nextapex);
9738  /* If nextapex is NULL, then no vertex would be exposed; the */
9739  /* triangulation would have been eaten right through. */
9740  if (nextapex != (vertex) NULL) {
9741  /* Check whether the edge is Delaunay. */
9742  badedge = incircle(m, b, lowerleft, lowerright, upperright, nextapex) >
9743  0.0;
9744  while (badedge) {
9745  /* Eliminate the edge with an edge flip. As a result, the */
9746  /* right triangulation will have one more boundary triangle. */
9747  lprevself(nextedge);
9748  sym(nextedge, topcasing);
9749  lprevself(nextedge);
9750  sym(nextedge, sidecasing);
9751  bond(nextedge, topcasing);
9752  bond(rightcand, sidecasing);
9753  lprevself(rightcand);
9754  sym(rightcand, outercasing);
9755  lnextself(nextedge);
9756  bond(nextedge, outercasing);
9757  /* Correct the vertices to reflect the edge flip. */
9758  setorg(rightcand, NULL);
9759  setdest(rightcand, lowerright);
9760  setapex(rightcand, nextapex);
9761  setorg(nextedge, upperright);
9762  setdest(nextedge, NULL);
9763  setapex(nextedge, nextapex);
9764  /* Consider the newly exposed vertex. */
9765  upperright = nextapex;
9766  /* What vertex would be exposed if another edge were deleted? */
9767  otricopy(sidecasing, nextedge);
9768  apex(nextedge, nextapex);
9769  if (nextapex != (vertex) NULL) {
9770  /* Check whether the edge is Delaunay. */
9771  badedge = incircle(m, b, lowerleft, lowerright, upperright,
9772  nextapex) > 0.0;
9773  } else {
9774  /* Avoid eating right through the triangulation. */
9775  badedge = 0;
9776  }
9777  }
9778  }
9779  }
9780  if (leftfinished || (!rightfinished &&
9781  (incircle(m, b, upperleft, lowerleft, lowerright, upperright) >
9782  0.0))) {
9783  /* Knit the triangulations, adding an edge from `lowerleft' */
9784  /* to `upperright'. */
9785  bond(baseedge, rightcand);
9786  lprev(rightcand, baseedge);
9787  setdest(baseedge, lowerleft);
9788  lowerright = upperright;
9789  sym(baseedge, rightcand);
9790  apex(rightcand, upperright);
9791  } else {
9792  /* Knit the triangulations, adding an edge from `upperleft' */
9793  /* to `lowerright'. */
9794  bond(baseedge, leftcand);
9795  lnext(leftcand, baseedge);
9796  setorg(baseedge, lowerright);
9797  lowerleft = upperleft;
9798  sym(baseedge, leftcand);
9799  apex(leftcand, upperleft);
9800  }
9801  if (b->verbose > 2) {
9802  printf(" Connecting ");
9803  printtriangle(m, b, &baseedge);
9804  }
9805  }
9806 }
9807 
9808 /*****************************************************************************/
9809 /* */
9810 /* divconqrecurse() Recursively form a Delaunay triangulation by the */
9811 /* divide-and-conquer method. */
9812 /* */
9813 /* Recursively breaks down the problem into smaller pieces, which are */
9814 /* knitted together by mergehulls(). The base cases (problems of two or */
9815 /* three vertices) are handled specially here. */
9816 /* */
9817 /* On completion, `farleft' and `farright' are bounding triangles such that */
9818 /* the origin of `farleft' is the leftmost vertex (breaking ties by */
9819 /* choosing the highest leftmost vertex), and the destination of */
9820 /* `farright' is the rightmost vertex (breaking ties by choosing the */
9821 /* lowest rightmost vertex). */
9822 /* */
9823 /*****************************************************************************/
9824 
9825 #ifdef ANSI_DECLARATORS
9826 void divconqrecurse(struct mesh *m, struct behavior *b, vertex *sortarray,
9827  int vertices, int axis,
9828  struct otri *farleft, struct otri *farright)
9829 #else /* not ANSI_DECLARATORS */
9830 void divconqrecurse(m, b, sortarray, vertices, axis, farleft, farright)
9831 struct mesh *m;
9832 struct behavior *b;
9833 vertex *sortarray;
9834 int vertices;
9835 int axis;
9836 struct otri *farleft;
9837 struct otri *farright;
9838 #endif /* not ANSI_DECLARATORS */
9839 
9840 {
9841  struct otri midtri, tri1, tri2, tri3;
9842  struct otri innerleft, innerright;
9843  REAL area;
9844  int divider;
9845 
9846  if (b->verbose > 2) {
9847  printf(" Triangulating %d vertices.\n", vertices);
9848  }
9849  if (vertices == 2) {
9850  /* The triangulation of two vertices is an edge. An edge is */
9851  /* represented by two bounding triangles. */
9852  maketriangle(m, b, farleft);
9853  setorg(*farleft, sortarray[0]);
9854  setdest(*farleft, sortarray[1]);
9855  /* The apex is intentionally left NULL. */
9856  maketriangle(m, b, farright);
9857  setorg(*farright, sortarray[1]);
9858  setdest(*farright, sortarray[0]);
9859  /* The apex is intentionally left NULL. */
9860  bond(*farleft, *farright);
9861  lprevself(*farleft);
9862  lnextself(*farright);
9863  bond(*farleft, *farright);
9864  lprevself(*farleft);
9865  lnextself(*farright);
9866  bond(*farleft, *farright);
9867  if (b->verbose > 2) {
9868  printf(" Creating ");
9869  printtriangle(m, b, farleft);
9870  printf(" Creating ");
9871  printtriangle(m, b, farright);
9872  }
9873  /* Ensure that the origin of `farleft' is sortarray[0]. */
9874  lprev(*farright, *farleft);
9875  return;
9876  } else if (vertices == 3) {
9877  /* The triangulation of three vertices is either a triangle (with */
9878  /* three bounding triangles) or two edges (with four bounding */
9879  /* triangles). In either case, four triangles are created. */
9880  maketriangle(m, b, &midtri);
9881  maketriangle(m, b, &tri1);
9882  maketriangle(m, b, &tri2);
9883  maketriangle(m, b, &tri3);
9884  area = counterclockwise(m, b, sortarray[0], sortarray[1], sortarray[2]);
9885  if (area == 0.0) {
9886  /* Three collinear vertices; the triangulation is two edges. */
9887  setorg(midtri, sortarray[0]);
9888  setdest(midtri, sortarray[1]);
9889  setorg(tri1, sortarray[1]);
9890  setdest(tri1, sortarray[0]);
9891  setorg(tri2, sortarray[2]);
9892  setdest(tri2, sortarray[1]);
9893  setorg(tri3, sortarray[1]);
9894  setdest(tri3, sortarray[2]);
9895  /* All apices are intentionally left NULL. */
9896  bond(midtri, tri1);
9897  bond(tri2, tri3);
9898  lnextself(midtri);
9899  lprevself(tri1);
9900  lnextself(tri2);
9901  lprevself(tri3);
9902  bond(midtri, tri3);
9903  bond(tri1, tri2);
9904  lnextself(midtri);
9905  lprevself(tri1);
9906  lnextself(tri2);
9907  lprevself(tri3);
9908  bond(midtri, tri1);
9909  bond(tri2, tri3);
9910  /* Ensure that the origin of `farleft' is sortarray[0]. */
9911  otricopy(tri1, *farleft);
9912  /* Ensure that the destination of `farright' is sortarray[2]. */
9913  otricopy(tri2, *farright);
9914  } else {
9915  /* The three vertices are not collinear; the triangulation is one */
9916  /* triangle, namely `midtri'. */
9917  setorg(midtri, sortarray[0]);
9918  setdest(tri1, sortarray[0]);
9919  setorg(tri3, sortarray[0]);
9920  /* Apices of tri1, tri2, and tri3 are left NULL. */
9921  if (area > 0.0) {
9922  /* The vertices are in counterclockwise order. */
9923  setdest(midtri, sortarray[1]);
9924  setorg(tri1, sortarray[1]);
9925  setdest(tri2, sortarray[1]);
9926  setapex(midtri, sortarray[2]);
9927  setorg(tri2, sortarray[2]);
9928  setdest(tri3, sortarray[2]);
9929  } else {
9930  /* The vertices are in clockwise order. */
9931  setdest(midtri, sortarray[2]);
9932  setorg(tri1, sortarray[2]);
9933  setdest(tri2, sortarray[2]);
9934  setapex(midtri, sortarray[1]);
9935  setorg(tri2, sortarray[1]);
9936  setdest(tri3, sortarray[1]);
9937  }
9938  /* The topology does not depend on how the vertices are ordered. */
9939  bond(midtri, tri1);
9940  lnextself(midtri);
9941  bond(midtri, tri2);
9942  lnextself(midtri);
9943  bond(midtri, tri3);
9944  lprevself(tri1);
9945  lnextself(tri2);
9946  bond(tri1, tri2);
9947  lprevself(tri1);
9948  lprevself(tri3);
9949  bond(tri1, tri3);
9950  lnextself(tri2);
9951  lprevself(tri3);
9952  bond(tri2, tri3);
9953  /* Ensure that the origin of `farleft' is sortarray[0]. */
9954  otricopy(tri1, *farleft);
9955  /* Ensure that the destination of `farright' is sortarray[2]. */
9956  if (area > 0.0) {
9957  otricopy(tri2, *farright);
9958  } else {
9959  lnext(*farleft, *farright);
9960  }
9961  }
9962  if (b->verbose > 2) {
9963  printf(" Creating ");
9964  printtriangle(m, b, &midtri);
9965  printf(" Creating ");
9966  printtriangle(m, b, &tri1);
9967  printf(" Creating ");
9968  printtriangle(m, b, &tri2);
9969  printf(" Creating ");
9970  printtriangle(m, b, &tri3);
9971  }
9972  return;
9973  } else {
9974  /* Split the vertices in half. */
9975  divider = vertices >> 1;
9976  /* Recursively triangulate each half. */
9977  divconqrecurse(m, b, sortarray, divider, 1 - axis, farleft, &innerleft);
9978  divconqrecurse(m, b, &sortarray[divider], vertices - divider, 1 - axis,
9979  &innerright, farright);
9980  if (b->verbose > 1) {
9981  printf(" Joining triangulations with %d and %d vertices.\n", divider,
9982  vertices - divider);
9983  }
9984  /* Merge the two triangulations into one. */
9985  mergehulls(m, b, farleft, &innerleft, &innerright, farright, axis);
9986  }
9987 }
9988 
9989 #ifdef ANSI_DECLARATORS
9990 long removeghosts(struct mesh *m, struct behavior *b, struct otri *startghost)
9991 #else /* not ANSI_DECLARATORS */
9992 long removeghosts(m, b, startghost)
9993 struct mesh *m;
9994 struct behavior *b;
9995 struct otri *startghost;
9996 #endif /* not ANSI_DECLARATORS */
9997 
9998 {
9999  struct otri searchedge;
10000  struct otri dissolveedge;
10001  struct otri deadtriangle;
10002  vertex markorg;
10003  long hullsize;
10004  triangle ptr; /* Temporary variable used by sym(). */
10005 
10006  if (b->verbose) {
10007  printf(" Removing ghost triangles.\n");
10008  }
10009  /* Find an edge on the convex hull to start point location from. */
10010  lprev(*startghost, searchedge);
10011  symself(searchedge);
10012  m->dummytri[0] = encode(searchedge);
10013  /* Remove the bounding box and count the convex hull edges. */
10014  otricopy(*startghost, dissolveedge);
10015  hullsize = 0;
10016  do {
10017  hullsize++;
10018  lnext(dissolveedge, deadtriangle);
10019  lprevself(dissolveedge);
10020  symself(dissolveedge);
10021  /* If no PSLG is involved, set the boundary markers of all the vertices */
10022  /* on the convex hull. If a PSLG is used, this step is done later. */
10023  if (!b->poly) {
10024  /* Watch out for the case where all the input vertices are collinear. */
10025  if (dissolveedge.tri != m->dummytri) {
10026  org(dissolveedge, markorg);
10027  if (vertexmark(markorg) == 0) {
10028  setvertexmark(markorg, 1);
10029  }
10030  }
10031  }
10032  /* Remove a bounding triangle from a convex hull triangle. */
10033  dissolve(dissolveedge);
10034  /* Find the next bounding triangle. */
10035  sym(deadtriangle, dissolveedge);
10036  /* Delete the bounding triangle. */
10037  triangledealloc(m, deadtriangle.tri);
10038  } while (!otriequal(dissolveedge, *startghost));
10039  return hullsize;
10040 }
10041 
10042 /*****************************************************************************/
10043 /* */
10044 /* divconqdelaunay() Form a Delaunay triangulation by the divide-and- */
10045 /* conquer method. */
10046 /* */
10047 /* Sorts the vertices, calls a recursive procedure to triangulate them, and */
10048 /* removes the bounding box, setting boundary markers as appropriate. */
10049 /* */
10050 /*****************************************************************************/
10051 
10052 #ifdef ANSI_DECLARATORS
10053 long divconqdelaunay(struct mesh *m, struct behavior *b)
10054 #else /* not ANSI_DECLARATORS */
10055 long divconqdelaunay(m, b)
10056 struct mesh *m;
10057 struct behavior *b;
10058 #endif /* not ANSI_DECLARATORS */
10059 
10060 {
10061  vertex *sortarray;
10062  struct otri hullleft, hullright;
10063  int divider;
10064  int i, j;
10065 
10066  if (b->verbose) {
10067  printf(" Sorting vertices.\n");
10068  }
10069 
10070  /* Allocate an array of pointers to vertices for sorting. */
10071  sortarray = (vertex *) trimalloc(m->invertices * (int) sizeof(vertex));
10072  traversalinit(&m->vertices);
10073  for (i = 0; i < m->invertices; i++) {
10074  sortarray[i] = vertextraverse(m);
10075  }
10076  /* Sort the vertices. */
10077  vertexsort(sortarray, m->invertices);
10078  /* Discard duplicate vertices, which can really mess up the algorithm. */
10079  i = 0;
10080  for (j = 1; j < m->invertices; j++) {
10081  if ((sortarray[i][0] == sortarray[j][0])
10082  && (sortarray[i][1] == sortarray[j][1])) {
10083  if (!b->quiet) {
10084  printf(
10085 "Warning: A duplicate vertex at (%.12g, %.12g) appeared and was ignored.\n",
10086  sortarray[j][0], sortarray[j][1]);
10087  }
10088  setvertextype(sortarray[j], UNDEADVERTEX);
10089  m->undeads++;
10090  } else {
10091  i++;
10092  sortarray[i] = sortarray[j];
10093  }
10094  }
10095  i++;
10096  if (b->dwyer) {
10097  /* Re-sort the array of vertices to accommodate alternating cuts. */
10098  divider = i >> 1;
10099  if (i - divider >= 2) {
10100  if (divider >= 2) {
10101  alternateaxes(sortarray, divider, 1);
10102  }
10103  alternateaxes(&sortarray[divider], i - divider, 1);
10104  }
10105  }
10106 
10107  if (b->verbose) {
10108  printf(" Forming triangulation.\n");
10109  }
10110 
10111  /* Form the Delaunay triangulation. */
10112  divconqrecurse(m, b, sortarray, i, 0, &hullleft, &hullright);
10113  trifree((VOID *) sortarray);
10114 
10115  return removeghosts(m, b, &hullleft);
10116 }
10117 
10120 /********* Divide-and-conquer Delaunay triangulation ends here *********/
10121 
10122 /********* Incremental Delaunay triangulation begins here *********/
10126 /*****************************************************************************/
10127 /* */
10128 /* boundingbox() Form an "infinite" bounding triangle to insert vertices */
10129 /* into. */
10130 /* */
10131 /* The vertices at "infinity" are assigned finite coordinates, which are */
10132 /* used by the point location routines, but (mostly) ignored by the */
10133 /* Delaunay edge flip routines. */
10134 /* */
10135 /*****************************************************************************/
10136 
10137 #ifndef REDUCED
10138 
10139 #ifdef ANSI_DECLARATORS
10140 void boundingbox(struct mesh *m, struct behavior *b)
10141 #else /* not ANSI_DECLARATORS */
10142 void boundingbox(m, b)
10143 struct mesh *m;
10144 struct behavior *b;
10145 #endif /* not ANSI_DECLARATORS */
10146 
10147 {
10148  struct otri inftri; /* Handle for the triangular bounding box. */
10149  REAL width;
10150 
10151  if (b->verbose) {
10152  printf(" Creating triangular bounding box.\n");
10153  }
10154  /* Find the width (or height, whichever is larger) of the triangulation. */
10155  width = m->xmax - m->xmin;
10156  if (m->ymax - m->ymin > width) {
10157  width = m->ymax - m->ymin;
10158  }
10159  if (width == 0.0) {
10160  width = 1.0;
10161  }
10162  /* Create the vertices of the bounding box. */
10163  m->infvertex1 = (vertex) trimalloc(m->vertices.itembytes);
10164  m->infvertex2 = (vertex) trimalloc(m->vertices.itembytes);
10165  m->infvertex3 = (vertex) trimalloc(m->vertices.itembytes);
10166  m->infvertex1[0] = m->xmin - 50.0 * width;
10167  m->infvertex1[1] = m->ymin - 40.0 * width;
10168  m->infvertex2[0] = m->xmax + 50.0 * width;
10169  m->infvertex2[1] = m->ymin - 40.0 * width;
10170  m->infvertex3[0] = 0.5 * (m->xmin + m->xmax);
10171  m->infvertex3[1] = m->ymax + 60.0 * width;
10172 
10173  /* Create the bounding box. */
10174  maketriangle(m, b, &inftri);
10175  setorg(inftri, m->infvertex1);
10176  setdest(inftri, m->infvertex2);
10177  setapex(inftri, m->infvertex3);
10178  /* Link dummytri to the bounding box so we can always find an */
10179  /* edge to begin searching (point location) from. */
10180  m->dummytri[0] = (triangle) inftri.tri;
10181  if (b->verbose > 2) {
10182  printf(" Creating ");
10183  printtriangle(m, b, &inftri);
10184  }
10185 }
10186 
10187 #endif /* not REDUCED */
10188 
10189 /*****************************************************************************/
10190 /* */
10191 /* removebox() Remove the "infinite" bounding triangle, setting boundary */
10192 /* markers as appropriate. */
10193 /* */
10194 /* The triangular bounding box has three boundary triangles (one for each */
10195 /* side of the bounding box), and a bunch of triangles fanning out from */
10196 /* the three bounding box vertices (one triangle for each edge of the */
10197 /* convex hull of the inner mesh). This routine removes these triangles. */
10198 /* */
10199 /* Returns the number of edges on the convex hull of the triangulation. */
10200 /* */
10201 /*****************************************************************************/
10202 
10203 #ifndef REDUCED
10204 
10205 #ifdef ANSI_DECLARATORS
10206 long removebox(struct mesh *m, struct behavior *b)
10207 #else /* not ANSI_DECLARATORS */
10208 long removebox(m, b)
10209 struct mesh *m;
10210 struct behavior *b;
10211 #endif /* not ANSI_DECLARATORS */
10212 
10213 {
10214  struct otri deadtriangle;
10215  struct otri searchedge;
10216  struct otri checkedge;
10217  struct otri nextedge, finaledge, dissolveedge;
10218  vertex markorg;
10219  long hullsize;
10220  triangle ptr; /* Temporary variable used by sym(). */
10221 
10222  if (b->verbose) {
10223  printf(" Removing triangular bounding box.\n");
10224  }
10225  /* Find a boundary triangle. */
10226  nextedge.tri = m->dummytri;
10227  nextedge.orient = 0;
10228  symself(nextedge);
10229  /* Mark a place to stop. */
10230  lprev(nextedge, finaledge);
10231  lnextself(nextedge);
10232  symself(nextedge);
10233  /* Find a triangle (on the boundary of the vertex set) that isn't */
10234  /* a bounding box triangle. */
10235  lprev(nextedge, searchedge);
10236  symself(searchedge);
10237  /* Check whether nextedge is another boundary triangle */
10238  /* adjacent to the first one. */
10239  lnext(nextedge, checkedge);
10240  symself(checkedge);
10241  if (checkedge.tri == m->dummytri) {
10242  /* Go on to the next triangle. There are only three boundary */
10243  /* triangles, and this next triangle cannot be the third one, */
10244  /* so it's safe to stop here. */
10245  lprevself(searchedge);
10246  symself(searchedge);
10247  }
10248  /* Find a new boundary edge to search from, as the current search */
10249  /* edge lies on a bounding box triangle and will be deleted. */
10250  m->dummytri[0] = encode(searchedge);
10251  hullsize = -2l;
10252  while (!otriequal(nextedge, finaledge)) {
10253  hullsize++;
10254  lprev(nextedge, dissolveedge);
10255  symself(dissolveedge);
10256  /* If not using a PSLG, the vertices should be marked now. */
10257  /* (If using a PSLG, markhull() will do the job.) */
10258  if (!b->poly) {
10259  /* Be careful! One must check for the case where all the input */
10260  /* vertices are collinear, and thus all the triangles are part of */
10261  /* the bounding box. Otherwise, the setvertexmark() call below */
10262  /* will cause a bad pointer reference. */
10263  if (dissolveedge.tri != m->dummytri) {
10264  org(dissolveedge, markorg);
10265  if (vertexmark(markorg) == 0) {
10266  setvertexmark(markorg, 1);
10267  }
10268  }
10269  }
10270  /* Disconnect the bounding box triangle from the mesh triangle. */
10271  dissolve(dissolveedge);
10272  lnext(nextedge, deadtriangle);
10273  sym(deadtriangle, nextedge);
10274  /* Get rid of the bounding box triangle. */
10275  triangledealloc(m, deadtriangle.tri);
10276  /* Do we need to turn the corner? */
10277  if (nextedge.tri == m->dummytri) {
10278  /* Turn the corner. */
10279  otricopy(dissolveedge, nextedge);
10280  }
10281  }
10282  triangledealloc(m, finaledge.tri);
10283 
10284  trifree((VOID *) m->infvertex1); /* Deallocate the bounding box vertices. */
10285  trifree((VOID *) m->infvertex2);
10286  trifree((VOID *) m->infvertex3);
10287 
10288  return hullsize;
10289 }
10290 
10291 #endif /* not REDUCED */
10292 
10293 /*****************************************************************************/
10294 /* */
10295 /* incrementaldelaunay() Form a Delaunay triangulation by incrementally */
10296 /* inserting vertices. */
10297 /* */
10298 /* Returns the number of edges on the convex hull of the triangulation. */
10299 /* */
10300 /*****************************************************************************/
10301 
10302 #ifndef REDUCED
10303 
10304 #ifdef ANSI_DECLARATORS
10305 long incrementaldelaunay(struct mesh *m, struct behavior *b)
10306 #else /* not ANSI_DECLARATORS */
10307 long incrementaldelaunay(m, b)
10308 struct mesh *m;
10309 struct behavior *b;
10310 #endif /* not ANSI_DECLARATORS */
10311 
10312 {
10313  struct otri starttri;
10314  vertex vertexloop;
10315 
10316  /* Create a triangular bounding box. */
10317  boundingbox(m, b);
10318  if (b->verbose) {
10319  printf(" Incrementally inserting vertices.\n");
10320  }
10321  traversalinit(&m->vertices);
10322  vertexloop = vertextraverse(m);
10323  while (vertexloop != (vertex) NULL) {
10324  starttri.tri = m->dummytri;
10325  if (insertvertex(m, b, vertexloop, &starttri, (struct osub *) NULL, 0, 0)
10326  == DUPLICATEVERTEX) {
10327  if (!b->quiet) {
10328  printf(
10329 "Warning: A duplicate vertex at (%.12g, %.12g) appeared and was ignored.\n",
10330  vertexloop[0], vertexloop[1]);
10331  }
10332  setvertextype(vertexloop, UNDEADVERTEX);
10333  m->undeads++;
10334  }
10335  vertexloop = vertextraverse(m);
10336  }
10337  /* Remove the bounding box. */
10338  return removebox(m, b);
10339 }
10340 
10341 #endif /* not REDUCED */
10342 
10345 /********* Incremental Delaunay triangulation ends here *********/
10346 
10347 /********* Sweepline Delaunay triangulation begins here *********/
10351 #ifndef REDUCED
10352 
10353 #ifdef ANSI_DECLARATORS
10354 void eventheapinsert(struct event **heap, int heapsize, struct event *newevent)
10355 #else /* not ANSI_DECLARATORS */
10356 void eventheapinsert(heap, heapsize, newevent)
10357 struct event **heap;
10358 int heapsize;
10359 struct event *newevent;
10360 #endif /* not ANSI_DECLARATORS */
10361 
10362 {
10363  REAL eventx, eventy;
10364  int eventnum;
10365  int parent;
10366  int notdone;
10367 
10368  eventx = newevent->xkey;
10369  eventy = newevent->ykey;
10370  eventnum = heapsize;
10371  notdone = eventnum > 0;
10372  while (notdone) {
10373  parent = (eventnum - 1) >> 1;
10374  if ((heap[parent]->ykey < eventy) ||
10375  ((heap[parent]->ykey == eventy)
10376  && (heap[parent]->xkey <= eventx))) {
10377  notdone = 0;
10378  } else {
10379  heap[eventnum] = heap[parent];
10380  heap[eventnum]->heapposition = eventnum;
10381 
10382  eventnum = parent;
10383  notdone = eventnum > 0;
10384  }
10385  }
10386  heap[eventnum] = newevent;
10387  newevent->heapposition = eventnum;
10388 }
10389 
10390 #endif /* not REDUCED */
10391 
10392 #ifndef REDUCED
10393 
10394 #ifdef ANSI_DECLARATORS
10395 void eventheapify(struct event **heap, int heapsize, int eventnum)
10396 #else /* not ANSI_DECLARATORS */
10397 void eventheapify(heap, heapsize, eventnum)
10398 struct event **heap;
10399 int heapsize;
10400 int eventnum;
10401 #endif /* not ANSI_DECLARATORS */
10402 
10403 {
10404  struct event *thisevent;
10405  REAL eventx, eventy;
10406  int leftchild, rightchild;
10407  int smallest;
10408  int notdone;
10409 
10410  thisevent = heap[eventnum];
10411  eventx = thisevent->xkey;
10412  eventy = thisevent->ykey;
10413  leftchild = 2 * eventnum + 1;
10414  notdone = leftchild < heapsize;
10415  while (notdone) {
10416  if ((heap[leftchild]->ykey < eventy) ||
10417  ((heap[leftchild]->ykey == eventy)
10418  && (heap[leftchild]->xkey < eventx))) {
10419  smallest = leftchild;
10420  } else {
10421  smallest = eventnum;
10422  }
10423  rightchild = leftchild + 1;
10424  if (rightchild < heapsize) {
10425  if ((heap[rightchild]->ykey < heap[smallest]->ykey) ||
10426  ((heap[rightchild]->ykey == heap[smallest]->ykey)
10427  && (heap[rightchild]->xkey < heap[smallest]->xkey))) {
10428  smallest = rightchild;
10429  }
10430  }
10431  if (smallest == eventnum) {
10432  notdone = 0;
10433  } else {
10434  heap[eventnum] = heap[smallest];
10435  heap[eventnum]->heapposition = eventnum;
10436  heap[smallest] = thisevent;
10437  thisevent->heapposition = smallest;
10438 
10439  eventnum = smallest;
10440  leftchild = 2 * eventnum + 1;
10441  notdone = leftchild < heapsize;
10442  }
10443  }
10444 }
10445 
10446 #endif /* not REDUCED */
10447 
10448 #ifndef REDUCED
10449 
10450 #ifdef ANSI_DECLARATORS
10451 void eventheapdelete(struct event **heap, int heapsize, int eventnum)
10452 #else /* not ANSI_DECLARATORS */
10453 void eventheapdelete(heap, heapsize, eventnum)
10454 struct event **heap;
10455 int heapsize;
10456 int eventnum;
10457 #endif /* not ANSI_DECLARATORS */
10458 
10459 {
10460  struct event *moveevent;
10461  REAL eventx, eventy;
10462  int parent;
10463  int notdone;
10464 
10465  moveevent = heap[heapsize - 1];
10466  if (eventnum > 0) {
10467  eventx = moveevent->xkey;
10468  eventy = moveevent->ykey;
10469  do {
10470  parent = (eventnum - 1) >> 1;
10471  if ((heap[parent]->ykey < eventy) ||
10472  ((heap[parent]->ykey == eventy)
10473  && (heap[parent]->xkey <= eventx))) {
10474  notdone = 0;
10475  } else {
10476  heap[eventnum] = heap[parent];
10477  heap[eventnum]->heapposition = eventnum;
10478 
10479  eventnum = parent;
10480  notdone = eventnum > 0;
10481  }
10482  } while (notdone);
10483  }
10484  heap[eventnum] = moveevent;
10485  moveevent->heapposition = eventnum;
10486  eventheapify(heap, heapsize - 1, eventnum);
10487 }
10488 
10489 #endif /* not REDUCED */
10490 
10491 #ifndef REDUCED
10492 
10493 #ifdef ANSI_DECLARATORS
10494 void createeventheap(struct mesh *m, struct event ***eventheap,
10495  struct event **events, struct event **freeevents)
10496 #else /* not ANSI_DECLARATORS */
10497 void createeventheap(m, eventheap, events, freeevents)
10498 struct mesh *m;
10499 struct event ***eventheap;
10500 struct event **events;
10501 struct event **freeevents;
10502 #endif /* not ANSI_DECLARATORS */
10503 
10504 {
10505  vertex thisvertex;
10506  int maxevents;
10507  int i;
10508 
10509  maxevents = (3 * m->invertices) / 2;
10510  *eventheap = (struct event **) trimalloc(maxevents *
10511  (int) sizeof(struct event *));
10512  *events = (struct event *) trimalloc(maxevents * (int) sizeof(struct event));
10513  traversalinit(&m->vertices);
10514  for (i = 0; i < m->invertices; i++) {
10515  thisvertex = vertextraverse(m);
10516  (*events)[i].eventptr = (VOID *) thisvertex;
10517  (*events)[i].xkey = thisvertex[0];
10518  (*events)[i].ykey = thisvertex[1];
10519  eventheapinsert(*eventheap, i, *events + i);
10520  }
10521  *freeevents = (struct event *) NULL;
10522  for (i = maxevents - 1; i >= m->invertices; i--) {
10523  (*events)[i].eventptr = (VOID *) *freeevents;
10524  *freeevents = *events + i;
10525  }
10526 }
10527 
10528 #endif /* not REDUCED */
10529 
10530 #ifndef REDUCED
10531 
10532 #ifdef ANSI_DECLARATORS
10533 int rightofhyperbola(struct mesh *m, struct otri *fronttri, vertex newsite)
10534 #else /* not ANSI_DECLARATORS */
10535 int rightofhyperbola(m, fronttri, newsite)
10536 struct mesh *m;
10537 struct otri *fronttri;
10538 vertex newsite;
10539 #endif /* not ANSI_DECLARATORS */
10540 
10541 {
10542  vertex leftvertex, rightvertex;
10543  REAL dxa, dya, dxb, dyb;
10544 
10545  m->hyperbolacount++;
10546 
10547  dest(*fronttri, leftvertex);
10548  apex(*fronttri, rightvertex);
10549  if ((leftvertex[1] < rightvertex[1]) ||
10550  ((leftvertex[1] == rightvertex[1]) &&
10551  (leftvertex[0] < rightvertex[0]))) {
10552  if (newsite[0] >= rightvertex[0]) {
10553  return 1;
10554  }
10555  } else {
10556  if (newsite[0] <= leftvertex[0]) {
10557  return 0;
10558  }
10559  }
10560  dxa = leftvertex[0] - newsite[0];
10561  dya = leftvertex[1] - newsite[1];
10562  dxb = rightvertex[0] - newsite[0];
10563  dyb = rightvertex[1] - newsite[1];
10564  return dya * (dxb * dxb + dyb * dyb) > dyb * (dxa * dxa + dya * dya);
10565 }
10566 
10567 #endif /* not REDUCED */
10568 
10569 #ifndef REDUCED
10570 
10571 #ifdef ANSI_DECLARATORS
10572 REAL circletop(struct mesh *m, vertex pa, vertex pb, vertex pc, REAL ccwabc)
10573 #else /* not ANSI_DECLARATORS */
10574 REAL circletop(m, pa, pb, pc, ccwabc)
10575 struct mesh *m;
10576 vertex pa;
10577 vertex pb;
10578 vertex pc;
10579 REAL ccwabc;
10580 #endif /* not ANSI_DECLARATORS */
10581 
10582 {
10583  REAL xac, yac, xbc, ybc, xab, yab;
10584  REAL aclen2, bclen2, ablen2;
10585 
10586  m->circletopcount++;
10587 
10588  xac = pa[0] - pc[0];
10589  yac = pa[1] - pc[1];
10590  xbc = pb[0] - pc[0];
10591  ybc = pb[1] - pc[1];
10592  xab = pa[0] - pb[0];
10593  yab = pa[1] - pb[1];
10594  aclen2 = xac * xac + yac * yac;
10595  bclen2 = xbc * xbc + ybc * ybc;
10596  ablen2 = xab * xab + yab * yab;
10597  return pc[1] + (xac * bclen2 - xbc * aclen2 + sqrt(aclen2 * bclen2 * ablen2))
10598  / (2.0 * ccwabc);
10599 }
10600 
10601 #endif /* not REDUCED */
10602 
10603 #ifndef REDUCED
10604 
10605 #ifdef ANSI_DECLARATORS
10606 void check4deadevent(struct otri *checktri, struct event **freeevents,
10607  struct event **eventheap, int *heapsize)
10608 #else /* not ANSI_DECLARATORS */
10609 void check4deadevent(checktri, freeevents, eventheap, heapsize)
10610 struct otri *checktri;
10611 struct event **freeevents;
10612 struct event **eventheap;
10613 int *heapsize;
10614 #endif /* not ANSI_DECLARATORS */
10615 
10616 {
10617  struct event *deadevent;
10618  vertex eventvertex;
10619  int eventnum;
10620 
10621  org(*checktri, eventvertex);
10622  if (eventvertex != (vertex) NULL) {
10623  deadevent = (struct event *) eventvertex;
10624  eventnum = deadevent->heapposition;
10625  deadevent->eventptr = (VOID *) *freeevents;
10626  *freeevents = deadevent;
10627  eventheapdelete(eventheap, *heapsize, eventnum);
10628  (*heapsize)--;
10629  setorg(*checktri, NULL);
10630  }
10631 }
10632 
10633 #endif /* not REDUCED */
10634 
10635 #ifndef REDUCED
10636 
10637 #ifdef ANSI_DECLARATORS
10638 struct splaynode *splay(struct mesh *m, struct splaynode *splaytree,
10639  vertex searchpoint, struct otri *searchtri)
10640 #else /* not ANSI_DECLARATORS */
10641 struct splaynode *splay(m, splaytree, searchpoint, searchtri)
10642 struct mesh *m;
10643 struct splaynode *splaytree;
10644 vertex searchpoint;
10645 struct otri *searchtri;
10646 #endif /* not ANSI_DECLARATORS */
10647 
10648 {
10649  struct splaynode *child, *grandchild;
10650  struct splaynode *lefttree, *righttree;
10651  struct splaynode *leftright;
10652  vertex checkvertex;
10653  int rightofroot, rightofchild;
10654 
10655  if (splaytree == (struct splaynode *) NULL) {
10656  return (struct splaynode *) NULL;
10657  }
10658  dest(splaytree->keyedge, checkvertex);
10659  if (checkvertex == splaytree->keydest) {
10660  rightofroot = rightofhyperbola(m, &splaytree->keyedge, searchpoint);
10661  if (rightofroot) {
10662  otricopy(splaytree->keyedge, *searchtri);
10663  child = splaytree->rchild;
10664  } else {
10665  child = splaytree->lchild;
10666  }
10667  if (child == (struct splaynode *) NULL) {
10668  return splaytree;
10669  }
10670  dest(child->keyedge, checkvertex);
10671  if (checkvertex != child->keydest) {
10672  child = splay(m, child, searchpoint, searchtri);
10673  if (child == (struct splaynode *) NULL) {
10674  if (rightofroot) {
10675  splaytree->rchild = (struct splaynode *) NULL;
10676  } else {
10677  splaytree->lchild = (struct splaynode *) NULL;
10678  }
10679  return splaytree;
10680  }
10681  }
10682  rightofchild = rightofhyperbola(m, &child->keyedge, searchpoint);
10683  if (rightofchild) {
10684  otricopy(child->keyedge, *searchtri);
10685  grandchild = splay(m, child->rchild, searchpoint, searchtri);
10686  child->rchild = grandchild;
10687  } else {
10688  grandchild = splay(m, child->lchild, searchpoint, searchtri);
10689  child->lchild = grandchild;
10690  }
10691  if (grandchild == (struct splaynode *) NULL) {
10692  if (rightofroot) {
10693  splaytree->rchild = child->lchild;
10694  child->lchild = splaytree;
10695  } else {
10696  splaytree->lchild = child->rchild;
10697  child->rchild = splaytree;
10698  }
10699  return child;
10700  }
10701  if (rightofchild) {
10702  if (rightofroot) {
10703  splaytree->rchild = child->lchild;
10704  child->lchild = splaytree;
10705  } else {
10706  splaytree->lchild = grandchild->rchild;
10707  grandchild->rchild = splaytree;
10708  }
10709  child->rchild = grandchild->lchild;
10710  grandchild->lchild = child;
10711  } else {
10712  if (rightofroot) {
10713  splaytree->rchild = grandchild->lchild;
10714  grandchild->lchild = splaytree;
10715  } else {
10716  splaytree->lchild = child->rchild;
10717  child->rchild = splaytree;
10718  }
10719  child->lchild = grandchild->rchild;
10720  grandchild->rchild = child;
10721  }
10722  return grandchild;
10723  } else {
10724  lefttree = splay(m, splaytree->lchild, searchpoint, searchtri);
10725  righttree = splay(m, splaytree->rchild, searchpoint, searchtri);
10726 
10727  pooldealloc(&m->splaynodes, (VOID *) splaytree);
10728  if (lefttree == (struct splaynode *) NULL) {
10729  return righttree;
10730  } else if (righttree == (struct splaynode *) NULL) {
10731  return lefttree;
10732  } else if (lefttree->rchild == (struct splaynode *) NULL) {
10733  lefttree->rchild = righttree->lchild;
10734  righttree->lchild = lefttree;
10735  return righttree;
10736  } else if (righttree->lchild == (struct splaynode *) NULL) {
10737  righttree->lchild = lefttree->rchild;
10738  lefttree->rchild = righttree;
10739  return lefttree;
10740  } else {
10741 /* printf("Holy Toledo!!!\n"); */
10742  leftright = lefttree->rchild;
10743  while (leftright->rchild != (struct splaynode *) NULL) {
10744  leftright = leftright->rchild;
10745  }
10746  leftright->rchild = righttree;
10747  return lefttree;
10748  }
10749  }
10750 }
10751 
10752 #endif /* not REDUCED */
10753 
10754 #ifndef REDUCED
10755 
10756 #ifdef ANSI_DECLARATORS
10757 struct splaynode *splayinsert(struct mesh *m, struct splaynode *splayroot,
10758  struct otri *newkey, vertex searchpoint)
10759 #else /* not ANSI_DECLARATORS */
10760 struct splaynode *splayinsert(m, splayroot, newkey, searchpoint)
10761 struct mesh *m;
10762 struct splaynode *splayroot;
10763 struct otri *newkey;
10764 vertex searchpoint;
10765 #endif /* not ANSI_DECLARATORS */
10766 
10767 {
10768  struct splaynode *newsplaynode;
10769 
10770  newsplaynode = (struct splaynode *) poolalloc(&m->splaynodes);
10771  otricopy(*newkey, newsplaynode->keyedge);
10772  dest(*newkey, newsplaynode->keydest);
10773  if (splayroot == (struct splaynode *) NULL) {
10774  newsplaynode->lchild = (struct splaynode *) NULL;
10775  newsplaynode->rchild = (struct splaynode *) NULL;
10776  } else if (rightofhyperbola(m, &splayroot->keyedge, searchpoint)) {
10777  newsplaynode->lchild = splayroot;
10778  newsplaynode->rchild = splayroot->rchild;
10779  splayroot->rchild = (struct splaynode *) NULL;
10780  } else {
10781  newsplaynode->lchild = splayroot->lchild;
10782  newsplaynode->rchild = splayroot;
10783  splayroot->lchild = (struct splaynode *) NULL;
10784  }
10785  return newsplaynode;
10786 }
10787 
10788 #endif /* not REDUCED */
10789 
10790 #ifndef REDUCED
10791 
10792 #ifdef ANSI_DECLARATORS
10793 struct splaynode *circletopinsert(struct mesh *m, struct behavior *b,
10794  struct splaynode *splayroot,
10795  struct otri *newkey,
10796  vertex pa, vertex pb, vertex pc, REAL topy)
10797 #else /* not ANSI_DECLARATORS */
10798 struct splaynode *circletopinsert(m, b, splayroot, newkey, pa, pb, pc, topy)
10799 struct mesh *m;
10800 struct behavior *b;
10801 struct splaynode *splayroot;
10802 struct otri *newkey;
10803 vertex pa;
10804 vertex pb;
10805 vertex pc;
10806 REAL topy;
10807 #endif /* not ANSI_DECLARATORS */
10808 
10809 {
10810  REAL ccwabc;
10811  REAL xac, yac, xbc, ybc;
10812  REAL aclen2, bclen2;
10813  REAL searchpoint[2];
10814  struct otri dummytri;
10815 
10816  ccwabc = counterclockwise(m, b, pa, pb, pc);
10817  xac = pa[0] - pc[0];
10818  yac = pa[1] - pc[1];
10819  xbc = pb[0] - pc[0];
10820  ybc = pb[1] - pc[1];
10821  aclen2 = xac * xac + yac * yac;
10822  bclen2 = xbc * xbc + ybc * ybc;
10823  searchpoint[0] = pc[0] - (yac * bclen2 - ybc * aclen2) / (2.0 * ccwabc);
10824  searchpoint[1] = topy;
10825  return splayinsert(m, splay(m, splayroot, (vertex) searchpoint, &dummytri),
10826  newkey, (vertex) searchpoint);
10827 }
10828 
10829 #endif /* not REDUCED */
10830 
10831 #ifndef REDUCED
10832 
10833 #ifdef ANSI_DECLARATORS
10834 struct splaynode *frontlocate(struct mesh *m, struct splaynode *splayroot,
10835  struct otri *bottommost, vertex searchvertex,
10836  struct otri *searchtri, int *farright)
10837 #else /* not ANSI_DECLARATORS */
10838 struct splaynode *frontlocate(m, splayroot, bottommost, searchvertex,
10839  searchtri, farright)
10840 struct mesh *m;
10841 struct splaynode *splayroot;
10842 struct otri *bottommost;
10843 vertex searchvertex;
10844 struct otri *searchtri;
10845 int *farright;
10846 #endif /* not ANSI_DECLARATORS */
10847 
10848 {
10849  int farrightflag;
10850  triangle ptr; /* Temporary variable used by onext(). */
10851 
10852  otricopy(*bottommost, *searchtri);
10853  splayroot = splay(m, splayroot, searchvertex, searchtri);
10854 
10855  farrightflag = 0;
10856  while (!farrightflag && rightofhyperbola(m, searchtri, searchvertex)) {
10857  onextself(*searchtri);
10858  farrightflag = otriequal(*searchtri, *bottommost);
10859  }
10860  *farright = farrightflag;
10861  return splayroot;
10862 }
10863 
10864 #endif /* not REDUCED */
10865 
10866 #ifndef REDUCED
10867 
10868 #ifdef ANSI_DECLARATORS
10869 long sweeplinedelaunay(struct mesh *m, struct behavior *b)
10870 #else /* not ANSI_DECLARATORS */
10871 long sweeplinedelaunay(m, b)
10872 struct mesh *m;
10873 struct behavior *b;
10874 #endif /* not ANSI_DECLARATORS */
10875 
10876 {
10877  struct event **eventheap;
10878  struct event *events;
10879  struct event *freeevents;
10880  struct event *nextevent;
10881  struct event *newevent;
10882  struct splaynode *splayroot;
10883  struct otri bottommost;
10884  struct otri searchtri;
10885  struct otri fliptri;
10886  struct otri lefttri, righttri, farlefttri, farrighttri;
10887  struct otri inserttri;
10888  vertex firstvertex, secondvertex;
10889  vertex nextvertex, lastvertex;
10890  vertex connectvertex;
10891  vertex leftvertex, midvertex, rightvertex;
10892  REAL lefttest, righttest;
10893  int heapsize;
10894  int check4events, farrightflag;
10895  triangle ptr; /* Temporary variable used by sym(), onext(), and oprev(). */
10896 
10897  poolinit(&m->splaynodes, sizeof(struct splaynode), SPLAYNODEPERBLOCK,
10898  SPLAYNODEPERBLOCK, 0);
10899  splayroot = (struct splaynode *) NULL;
10900 
10901  if (b->verbose) {
10902  printf(" Placing vertices in event heap.\n");
10903  }
10904  createeventheap(m, &eventheap, &events, &freeevents);
10905  heapsize = m->invertices;
10906 
10907  if (b->verbose) {
10908  printf(" Forming triangulation.\n");
10909  }
10910  maketriangle(m, b, &lefttri);
10911  maketriangle(m, b, &righttri);
10912  bond(lefttri, righttri);
10913  lnextself(lefttri);
10914  lprevself(righttri);
10915  bond(lefttri, righttri);
10916  lnextself(lefttri);
10917  lprevself(righttri);
10918  bond(lefttri, righttri);
10919  firstvertex = (vertex) eventheap[0]->eventptr;
10920  eventheap[0]->eventptr = (VOID *) freeevents;
10921  freeevents = eventheap[0];
10922  eventheapdelete(eventheap, heapsize, 0);
10923  heapsize--;
10924  do {
10925  if (heapsize == 0) {
10926  printf("Error: Input vertices are all identical.\n");
10927  triexit(1);
10928  }
10929  secondvertex = (vertex) eventheap[0]->eventptr;
10930  eventheap[0]->eventptr = (VOID *) freeevents;
10931  freeevents = eventheap[0];
10932  eventheapdelete(eventheap, heapsize, 0);
10933  heapsize--;
10934  if ((firstvertex[0] == secondvertex[0]) &&
10935  (firstvertex[1] == secondvertex[1])) {
10936  if (!b->quiet) {
10937  printf(
10938 "Warning: A duplicate vertex at (%.12g, %.12g) appeared and was ignored.\n",
10939  secondvertex[0], secondvertex[1]);
10940  }
10941  setvertextype(secondvertex, UNDEADVERTEX);
10942  m->undeads++;
10943  }
10944  } while ((firstvertex[0] == secondvertex[0]) &&
10945  (firstvertex[1] == secondvertex[1]));
10946  setorg(lefttri, firstvertex);
10947  setdest(lefttri, secondvertex);
10948  setorg(righttri, secondvertex);
10949  setdest(righttri, firstvertex);
10950  lprev(lefttri, bottommost);
10951  lastvertex = secondvertex;
10952  while (heapsize > 0) {
10953  nextevent = eventheap[0];
10954  eventheapdelete(eventheap, heapsize, 0);
10955  heapsize--;
10956  check4events = 1;
10957  if (nextevent->xkey < m->xmin) {
10958  decode(nextevent->eventptr, fliptri);
10959  oprev(fliptri, farlefttri);
10960  check4deadevent(&farlefttri, &freeevents, eventheap, &heapsize);
10961  onext(fliptri, farrighttri);
10962  check4deadevent(&farrighttri, &freeevents, eventheap, &heapsize);
10963 
10964  if (otriequal(farlefttri, bottommost)) {
10965  lprev(fliptri, bottommost);
10966  }
10967  flip(m, b, &fliptri);
10968  setapex(fliptri, NULL);
10969  lprev(fliptri, lefttri);
10970  lnext(fliptri, righttri);
10971  sym(lefttri, farlefttri);
10972 
10973  if (randomnation(SAMPLERATE) == 0) {
10974  symself(fliptri);
10975  dest(fliptri, leftvertex);
10976  apex(fliptri, midvertex);
10977  org(fliptri, rightvertex);
10978  splayroot = circletopinsert(m, b, splayroot, &lefttri, leftvertex,
10979  midvertex, rightvertex, nextevent->ykey);
10980  }
10981  } else {
10982  nextvertex = (vertex) nextevent->eventptr;
10983  if ((nextvertex[0] == lastvertex[0]) &&
10984  (nextvertex[1] == lastvertex[1])) {
10985  if (!b->quiet) {
10986  printf(
10987 "Warning: A duplicate vertex at (%.12g, %.12g) appeared and was ignored.\n",
10988  nextvertex[0], nextvertex[1]);
10989  }
10990  setvertextype(nextvertex, UNDEADVERTEX);
10991  m->undeads++;
10992  check4events = 0;
10993  } else {
10994  lastvertex = nextvertex;
10995 
10996  splayroot = frontlocate(m, splayroot, &bottommost, nextvertex,
10997  &searchtri, &farrightflag);
10998 /*
10999  otricopy(bottommost, searchtri);
11000  farrightflag = 0;
11001  while (!farrightflag && rightofhyperbola(m, &searchtri, nextvertex)) {
11002  onextself(searchtri);
11003  farrightflag = otriequal(searchtri, bottommost);
11004  }
11005 */
11006 
11007  check4deadevent(&searchtri, &freeevents, eventheap, &heapsize);
11008 
11009  otricopy(searchtri, farrighttri);
11010  sym(searchtri, farlefttri);
11011  maketriangle(m, b, &lefttri);
11012  maketriangle(m, b, &righttri);
11013  dest(farrighttri, connectvertex);
11014  setorg(lefttri, connectvertex);
11015  setdest(lefttri, nextvertex);
11016  setorg(righttri, nextvertex);
11017  setdest(righttri, connectvertex);
11018  bond(lefttri, righttri);
11019  lnextself(lefttri);
11020  lprevself(righttri);
11021  bond(lefttri, righttri);
11022  lnextself(lefttri);
11023  lprevself(righttri);
11024  bond(lefttri, farlefttri);
11025  bond(righttri, farrighttri);
11026  if (!farrightflag && otriequal(farrighttri, bottommost)) {
11027  otricopy(lefttri, bottommost);
11028  }
11029 
11030  if (randomnation(SAMPLERATE) == 0) {
11031  splayroot = splayinsert(m, splayroot, &lefttri, nextvertex);
11032  } else if (randomnation(SAMPLERATE) == 0) {
11033  lnext(righttri, inserttri);
11034  splayroot = splayinsert(m, splayroot, &inserttri, nextvertex);
11035  }
11036  }
11037  }
11038  nextevent->eventptr = (VOID *) freeevents;
11039  freeevents = nextevent;
11040 
11041  if (check4events) {
11042  apex(farlefttri, leftvertex);
11043  dest(lefttri, midvertex);
11044  apex(lefttri, rightvertex);
11045  lefttest = counterclockwise(m, b, leftvertex, midvertex, rightvertex);
11046  if (lefttest > 0.0) {
11047  newevent = freeevents;
11048  freeevents = (struct event *) freeevents->eventptr;
11049  newevent->xkey = m->xminextreme;
11050  newevent->ykey = circletop(m, leftvertex, midvertex, rightvertex,
11051  lefttest);
11052  newevent->eventptr = (VOID *) encode(lefttri);
11053  eventheapinsert(eventheap, heapsize, newevent);
11054  heapsize++;
11055  setorg(lefttri, newevent);
11056  }
11057  apex(righttri, leftvertex);
11058  org(righttri, midvertex);
11059  apex(farrighttri, rightvertex);
11060  righttest = counterclockwise(m, b, leftvertex, midvertex, rightvertex);
11061  if (righttest > 0.0) {
11062  newevent = freeevents;
11063  freeevents = (struct event *) freeevents->eventptr;
11064  newevent->xkey = m->xminextreme;
11065  newevent->ykey = circletop(m, leftvertex, midvertex, rightvertex,
11066  righttest);
11067  newevent->eventptr = (VOID *) encode(farrighttri);
11068  eventheapinsert(eventheap, heapsize, newevent);
11069  heapsize++;
11070  setorg(farrighttri, newevent);
11071  }
11072  }
11073  }
11074 
11075  pooldeinit(&m->splaynodes);
11076  lprevself(bottommost);
11077  return removeghosts(m, b, &bottommost);
11078 }
11079 
11080 #endif /* not REDUCED */
11081 
11084 /********* Sweepline Delaunay triangulation ends here *********/
11085 
11086 /********* General mesh construction routines begin here *********/
11090 /*****************************************************************************/
11091 /* */
11092 /* delaunay() Form a Delaunay triangulation. */
11093 /* */
11094 /*****************************************************************************/
11095 
11096 #ifdef ANSI_DECLARATORS
11097 long delaunay(struct mesh *m, struct behavior *b)
11098 #else /* not ANSI_DECLARATORS */
11099 long delaunay(m, b)
11100 struct mesh *m;
11101 struct behavior *b;
11102 #endif /* not ANSI_DECLARATORS */
11103 
11104 {
11105  long hulledges;
11106 
11107  m->eextras = 0;
11108  initializetrisubpools(m, b);
11109 
11110 #ifdef REDUCED
11111  if (!b->quiet) {
11112  printf(
11113  "Constructing Delaunay triangulation by divide-and-conquer method.\n");
11114  }
11115  hulledges = divconqdelaunay(m, b);
11116 #else /* not REDUCED */
11117  if (!b->quiet) {
11118  printf("Constructing Delaunay triangulation ");
11119  if (b->incremental) {
11120  printf("by incremental method.\n");
11121  } else if (b->sweepline) {
11122  printf("by sweepline method.\n");
11123  } else {
11124  printf("by divide-and-conquer method.\n");
11125  }
11126  }
11127  if (b->incremental) {
11128  hulledges = incrementaldelaunay(m, b);
11129  } else if (b->sweepline) {
11130  hulledges = sweeplinedelaunay(m, b);
11131  } else {
11132  hulledges = divconqdelaunay(m, b);
11133  }
11134 #endif /* not REDUCED */
11135 
11136  if (m->triangles.items == 0) {
11137  /* The input vertices were all collinear, so there are no triangles. */
11138  return 0l;
11139  } else {
11140  return hulledges;
11141  }
11142 }
11143 
11144 /*****************************************************************************/
11145 /* */
11146 /* reconstruct() Reconstruct a triangulation from its .ele (and possibly */
11147 /* .poly) file. Used when the -r switch is used. */
11148 /* */
11149 /* Reads an .ele file and reconstructs the original mesh. If the -p switch */
11150 /* is used, this procedure will also read a .poly file and reconstruct the */
11151 /* subsegments of the original mesh. If the -a switch is used, this */
11152 /* procedure will also read an .area file and set a maximum area constraint */
11153 /* on each triangle. */
11154 /* */
11155 /* Vertices that are not corners of triangles, such as nodes on edges of */
11156 /* subparametric elements, are discarded. */
11157 /* */
11158 /* This routine finds the adjacencies between triangles (and subsegments) */
11159 /* by forming one stack of triangles for each vertex. Each triangle is on */
11160 /* three different stacks simultaneously. Each triangle's subsegment */
11161 /* pointers are used to link the items in each stack. This memory-saving */
11162 /* feature makes the code harder to read. The most important thing to keep */
11163 /* in mind is that each triangle is removed from a stack precisely when */
11164 /* the corresponding pointer is adjusted to refer to a subsegment rather */
11165 /* than the next triangle of the stack. */
11166 /* */
11167 /*****************************************************************************/
11168 
11169 #ifndef CDT_ONLY
11170 
11171 #ifdef TRILIBRARY
11172 
11173 #ifdef ANSI_DECLARATORS
11174 int reconstruct(struct mesh *m, struct behavior *b, int *trianglelist,
11175  REAL *triangleattriblist, REAL *trianglearealist,
11176  int elements, int corners, int attribs,
11177  int *segmentlist,int *segmentmarkerlist, int numberofsegments)
11178 #else /* not ANSI_DECLARATORS */
11179 int reconstruct(m, b, trianglelist, triangleattriblist, trianglearealist,
11180  elements, corners, attribs, segmentlist, segmentmarkerlist,
11181  numberofsegments)
11182 struct mesh *m;
11183 struct behavior *b;
11184 int *trianglelist;
11185 REAL *triangleattriblist;
11186 REAL *trianglearealist;
11187 int elements;
11188 int corners;
11189 int attribs;
11190 int *segmentlist;
11191 int *segmentmarkerlist;
11192 int numberofsegments;
11193 #endif /* not ANSI_DECLARATORS */
11194 
11195 #else /* not TRILIBRARY */
11196 
11197 #ifdef ANSI_DECLARATORS
11198 long reconstruct(struct mesh *m, struct behavior *b, char *elefilename,
11199  char *areafilename, char* polyfilename, FILE* polyfile)
11200 #else /* not ANSI_DECLARATORS */
11201 long reconstruct(m, b, elefilename, areafilename, polyfilename, polyfile)
11202 struct mesh *m;
11203 struct behavior *b;
11204 char *elefilename;
11205 char *areafilename;
11206 char* polyfilename;
11207 FILE* polyfile;
11208 #endif /* not ANSI_DECLARATORS */
11209 
11210 #endif /* not TRILIBRARY */
11211 
11212 {
11213 #ifdef TRILIBRARY
11214  int vertexindex;
11215  int attribindex;
11216 #else /* not TRILIBRARY */
11217  FILE *elefile;
11218  FILE *areafile;
11219  char inputline[INPUTLINESIZE];
11220  char *stringptr;
11221  int areaelements;
11222 #endif /* not TRILIBRARY */
11223  struct otri triangleloop;
11224  struct otri triangleleft;
11225  struct otri checktri;
11226  struct otri checkleft;
11227  struct otri checkneighbor;
11228  struct osub subsegloop;
11229  triangle *vertexarray;
11230  triangle* prevlink;
11231  triangle nexttri;
11232  vertex tdest, tapex;
11233  vertex checkdest, checkapex;
11234  vertex shorg;
11235  vertex killvertex;
11236  vertex segmentorg, segmentdest;
11237  REAL area;
11238  int corner[3];
11239  int end[2];
11240  int killvertexindex;
11241  int incorners;
11242  int segmentmarkers;
11243  int boundmarker;
11244  int aroundvertex;
11245  long hullsize;
11246  int notfound;
11247  long elementnumber, segmentnumber;
11248  int i, j;
11249  triangle ptr; /* Temporary variable used by sym(). */
11250 
11251 #ifdef TRILIBRARY
11252  m->inelements = elements;
11253  incorners = corners;
11254  if (incorners < 3) {
11255  printf("Error: Triangles must have at least 3 vertices.\n");
11256  triexit(1);
11257  }
11258  m->eextras = attribs;
11259 #else /* not TRILIBRARY */
11260  /* Read the triangles from an .ele file. */
11261  if (!b->quiet) {
11262  printf("Opening %s.\n", elefilename);
11263  }
11264  elefile = fopen(elefilename, "r");
11265  if (elefile == (FILE *) NULL) {
11266  printf(" Error: Cannot access file %s.\n", elefilename);
11267  triexit(1);
11268  }
11269  /* Read number of triangles, number of vertices per triangle, and */
11270  /* number of triangle attributes from .ele file. */
11271  stringptr = readline(inputline, elefile, elefilename);
11272  m->inelements = (int) strtol(stringptr, &stringptr, 0);
11273  stringptr = findfield(stringptr);
11274  if (*stringptr == '\0') {
11275  incorners = 3;
11276  } else {
11277  incorners = (int) strtol(stringptr, &stringptr, 0);
11278  if (incorners < 3) {
11279  printf("Error: Triangles in %s must have at least 3 vertices.\n",
11280  elefilename);
11281  triexit(1);
11282  }
11283  }
11284  stringptr = findfield(stringptr);
11285  if (*stringptr == '\0') {
11286  m->eextras = 0;
11287  } else {
11288  m->eextras = (int) strtol(stringptr, &stringptr, 0);
11289  }
11290 #endif /* not TRILIBRARY */
11291 
11292  initializetrisubpools(m, b);
11293 
11294  /* Create the triangles. */
11295  for (elementnumber = 1; elementnumber <= m->inelements; elementnumber++) {
11296  maketriangle(m, b, &triangleloop);
11297  /* Mark the triangle as living. */
11298  triangleloop.tri[3] = (triangle) triangleloop.tri;
11299  }
11300 
11301  segmentmarkers = 0;
11302  if (b->poly) {
11303 #ifdef TRILIBRARY
11304  m->insegments = numberofsegments;
11305  segmentmarkers = segmentmarkerlist != (int *) NULL;
11306 #else /* not TRILIBRARY */
11307  /* Read number of segments and number of segment */
11308  /* boundary markers from .poly file. */
11309  stringptr = readline(inputline, polyfile, b->inpolyfilename);
11310  m->insegments = (int) strtol(stringptr, &stringptr, 0);
11311  stringptr = findfield(stringptr);
11312  if (*stringptr != '\0') {
11313  segmentmarkers = (int) strtol(stringptr, &stringptr, 0);
11314  }
11315 #endif /* not TRILIBRARY */
11316 
11317  /* Create the subsegments. */
11318  for (segmentnumber = 1; segmentnumber <= m->insegments; segmentnumber++) {
11319  makesubseg(m, &subsegloop);
11320  /* Mark the subsegment as living. */
11321  subsegloop.ss[2] = (subseg) subsegloop.ss;
11322  }
11323  }
11324 
11325 #ifdef TRILIBRARY
11326  vertexindex = 0;
11327  attribindex = 0;
11328 #else /* not TRILIBRARY */
11329  if (b->vararea) {
11330  /* Open an .area file, check for consistency with the .ele file. */
11331  if (!b->quiet) {
11332  printf("Opening %s.\n", areafilename);
11333  }
11334  areafile = fopen(areafilename, "r");
11335  if (areafile == (FILE *) NULL) {
11336  printf(" Error: Cannot access file %s.\n", areafilename);
11337  triexit(1);
11338  }
11339  stringptr = readline(inputline, areafile, areafilename);
11340  areaelements = (int) strtol(stringptr, &stringptr, 0);
11341  if (areaelements != m->inelements) {
11342  printf("Error: %s and %s disagree on number of triangles.\n",
11343  elefilename, areafilename);
11344  triexit(1);
11345  }
11346  }
11347 #endif /* not TRILIBRARY */
11348 
11349  if (!b->quiet) {
11350  printf("Reconstructing mesh.\n");
11351  }
11352  /* Allocate a temporary array that maps each vertex to some adjacent */
11353  /* triangle. I took care to allocate all the permanent memory for */
11354  /* triangles and subsegments first. */
11355  vertexarray = (triangle *) trimalloc(m->vertices.items *
11356  (int) sizeof(triangle));
11357  /* Each vertex is initially unrepresented. */
11358  for (i = 0; i < m->vertices.items; i++) {
11359  vertexarray[i] = (triangle) m->dummytri;
11360  }
11361 
11362  if (b->verbose) {
11363  printf(" Assembling triangles.\n");
11364  }
11365  /* Read the triangles from the .ele file, and link */
11366  /* together those that share an edge. */
11367  traversalinit(&m->triangles);
11368  triangleloop.tri = triangletraverse(m);
11369  elementnumber = b->firstnumber;
11370  while (triangleloop.tri != (triangle *) NULL) {
11371 #ifdef TRILIBRARY
11372  /* Copy the triangle's three corners. */
11373  for (j = 0; j < 3; j++) {
11374  corner[j] = trianglelist[vertexindex++];
11375  if ((corner[j] < b->firstnumber) ||
11376  (corner[j] >= b->firstnumber + m->invertices)) {
11377  printf("Error: Triangle %ld has an invalid vertex index.\n",
11378  elementnumber);
11379  triexit(1);
11380  }
11381  }
11382 #else /* not TRILIBRARY */
11383  /* Read triangle number and the triangle's three corners. */
11384  stringptr = readline(inputline, elefile, elefilename);
11385  for (j = 0; j < 3; j++) {
11386  stringptr = findfield(stringptr);
11387  if (*stringptr == '\0') {
11388  printf("Error: Triangle %ld is missing vertex %d in %s.\n",
11389  elementnumber, j + 1, elefilename);
11390  triexit(1);
11391  } else {
11392  corner[j] = (int) strtol(stringptr, &stringptr, 0);
11393  if ((corner[j] < b->firstnumber) ||
11394  (corner[j] >= b->firstnumber + m->invertices)) {
11395  printf("Error: Triangle %ld has an invalid vertex index.\n",
11396  elementnumber);
11397  triexit(1);
11398  }
11399  }
11400  }
11401 #endif /* not TRILIBRARY */
11402 
11403  /* Find out about (and throw away) extra nodes. */
11404  for (j = 3; j < incorners; j++) {
11405 #ifdef TRILIBRARY
11406  killvertexindex = trianglelist[vertexindex++];
11407 #else /* not TRILIBRARY */
11408  stringptr = findfield(stringptr);
11409  if (*stringptr != '\0') {
11410  killvertexindex = (int) strtol(stringptr, &stringptr, 0);
11411 #endif /* not TRILIBRARY */
11412  if ((killvertexindex >= b->firstnumber) &&
11413  (killvertexindex < b->firstnumber + m->invertices)) {
11414  /* Delete the non-corner vertex if it's not already deleted. */
11415  killvertex = getvertex(m, b, killvertexindex);
11416  if (vertextype(killvertex) != DEADVERTEX) {
11417  vertexdealloc(m, killvertex);
11418  }
11419  }
11420 #ifndef TRILIBRARY
11421  }
11422 #endif /* not TRILIBRARY */
11423  }
11424 
11425  /* Read the triangle's attributes. */
11426  for (j = 0; j < m->eextras; j++) {
11427 #ifdef TRILIBRARY
11428  setelemattribute(triangleloop, j, triangleattriblist[attribindex++]);
11429 #else /* not TRILIBRARY */
11430  stringptr = findfield(stringptr);
11431  if (*stringptr == '\0') {
11432  setelemattribute(triangleloop, j, 0);
11433  } else {
11434  setelemattribute(triangleloop, j,
11435  (REAL) strtod(stringptr, &stringptr));
11436  }
11437 #endif /* not TRILIBRARY */
11438  }
11439 
11440  if (b->vararea) {
11441 #ifdef TRILIBRARY
11442  area = trianglearealist[elementnumber - b->firstnumber];
11443 #else /* not TRILIBRARY */
11444  /* Read an area constraint from the .area file. */
11445  stringptr = readline(inputline, areafile, areafilename);
11446  stringptr = findfield(stringptr);
11447  if (*stringptr == '\0') {
11448  area = -1.0; /* No constraint on this triangle. */
11449  } else {
11450  area = (REAL) strtod(stringptr, &stringptr);
11451  }
11452 #endif /* not TRILIBRARY */
11453  setareabound(triangleloop, area);
11454  }
11455 
11456  /* Set the triangle's vertices. */
11457  triangleloop.orient = 0;
11458  setorg(triangleloop, getvertex(m, b, corner[0]));
11459  setdest(triangleloop, getvertex(m, b, corner[1]));
11460  setapex(triangleloop, getvertex(m, b, corner[2]));
11461  /* Try linking the triangle to others that share these vertices. */
11462  for (triangleloop.orient = 0; triangleloop.orient < 3;
11463  triangleloop.orient++) {
11464  /* Take the number for the origin of triangleloop. */
11465  aroundvertex = corner[triangleloop.orient];
11466  /* Look for other triangles having this vertex. */
11467  nexttri = vertexarray[aroundvertex - b->firstnumber];
11468  /* Link the current triangle to the next one in the stack. */
11469  triangleloop.tri[6 + triangleloop.orient] = nexttri;
11470  /* Push the current triangle onto the stack. */
11471  vertexarray[aroundvertex - b->firstnumber] = encode(triangleloop);
11472  decode(nexttri, checktri);
11473  if (checktri.tri != m->dummytri) {
11474  dest(triangleloop, tdest);
11475  apex(triangleloop, tapex);
11476  /* Look for other triangles that share an edge. */
11477  do {
11478  dest(checktri, checkdest);
11479  apex(checktri, checkapex);
11480  if (tapex == checkdest) {
11481  /* The two triangles share an edge; bond them together. */
11482  lprev(triangleloop, triangleleft);
11483  bond(triangleleft, checktri);
11484  }
11485  if (tdest == checkapex) {
11486  /* The two triangles share an edge; bond them together. */
11487  lprev(checktri, checkleft);
11488  bond(triangleloop, checkleft);
11489  }
11490  /* Find the next triangle in the stack. */
11491  nexttri = checktri.tri[6 + checktri.orient];
11492  decode(nexttri, checktri);
11493  } while (checktri.tri != m->dummytri);
11494  }
11495  }
11496  triangleloop.tri = triangletraverse(m);
11497  elementnumber++;
11498  }
11499 
11500 #ifdef TRILIBRARY
11501  vertexindex = 0;
11502 #else /* not TRILIBRARY */
11503  fclose(elefile);
11504  if (b->vararea) {
11505  fclose(areafile);
11506  }
11507 #endif /* not TRILIBRARY */
11508 
11509  hullsize = 0; /* Prepare to count the boundary edges. */
11510  if (b->poly) {
11511  if (b->verbose) {
11512  printf(" Marking segments in triangulation.\n");
11513  }
11514  /* Read the segments from the .poly file, and link them */
11515  /* to their neighboring triangles. */
11516  boundmarker = 0;
11517  traversalinit(&m->subsegs);
11518  subsegloop.ss = subsegtraverse(m);
11519  segmentnumber = b->firstnumber;
11520  while (subsegloop.ss != (subseg *) NULL) {
11521 #ifdef TRILIBRARY
11522  end[0] = segmentlist[vertexindex++];
11523  end[1] = segmentlist[vertexindex++];
11524  if (segmentmarkers) {
11525  boundmarker = segmentmarkerlist[segmentnumber - b->firstnumber];
11526  }
11527 #else /* not TRILIBRARY */
11528  /* Read the endpoints of each segment, and possibly a boundary marker. */
11529  stringptr = readline(inputline, polyfile, b->inpolyfilename);
11530  /* Skip the first (segment number) field. */
11531  stringptr = findfield(stringptr);
11532  if (*stringptr == '\0') {
11533  printf("Error: Segment %ld has no endpoints in %s.\n", segmentnumber,
11534  polyfilename);
11535  triexit(1);
11536  } else {
11537  end[0] = (int) strtol(stringptr, &stringptr, 0);
11538  }
11539  stringptr = findfield(stringptr);
11540  if (*stringptr == '\0') {
11541  printf("Error: Segment %ld is missing its second endpoint in %s.\n",
11542  segmentnumber, polyfilename);
11543  triexit(1);
11544  } else {
11545  end[1] = (int) strtol(stringptr, &stringptr, 0);
11546  }
11547  if (segmentmarkers) {
11548  stringptr = findfield(stringptr);
11549  if (*stringptr == '\0') {
11550  boundmarker = 0;
11551  } else {
11552  boundmarker = (int) strtol(stringptr, &stringptr, 0);
11553  }
11554  }
11555 #endif /* not TRILIBRARY */
11556  for (j = 0; j < 2; j++) {
11557  if ((end[j] < b->firstnumber) ||
11558  (end[j] >= b->firstnumber + m->invertices)) {
11559  printf("Error: Segment %ld has an invalid vertex index.\n",
11560  segmentnumber);
11561  triexit(1);
11562  }
11563  }
11564 
11565  /* set the subsegment's vertices. */
11566  subsegloop.ssorient = 0;
11567  segmentorg = getvertex(m, b, end[0]);
11568  segmentdest = getvertex(m, b, end[1]);
11569  setsorg(subsegloop, segmentorg);
11570  setsdest(subsegloop, segmentdest);
11571  setsegorg(subsegloop, segmentorg);
11572  setsegdest(subsegloop, segmentdest);
11573  setmark(subsegloop, boundmarker);
11574  /* Try linking the subsegment to triangles that share these vertices. */
11575  for (subsegloop.ssorient = 0; subsegloop.ssorient < 2;
11576  subsegloop.ssorient++) {
11577  /* Take the number for the destination of subsegloop. */
11578  aroundvertex = end[1 - subsegloop.ssorient];
11579  /* Look for triangles having this vertex. */
11580  prevlink = &vertexarray[aroundvertex - b->firstnumber];
11581  nexttri = vertexarray[aroundvertex - b->firstnumber];
11582  decode(nexttri, checktri);
11583  sorg(subsegloop, shorg);
11584  notfound = 1;
11585  /* Look for triangles having this edge. Note that I'm only */
11586  /* comparing each triangle's destination with the subsegment; */
11587  /* each triangle's apex is handled through a different vertex. */
11588  /* Because each triangle appears on three vertices' lists, each */
11589  /* occurrence of a triangle on a list can (and does) represent */
11590  /* an edge. In this way, most edges are represented twice, and */
11591  /* every triangle-subsegment bond is represented once. */
11592  while (notfound && (checktri.tri != m->dummytri)) {
11593  dest(checktri, checkdest);
11594  if (shorg == checkdest) {
11595  /* We have a match. Remove this triangle from the list. */
11596  * prevlink = checktri.tri[6 + checktri.orient];
11597  /* Bond the subsegment to the triangle. */
11598  tsbond(checktri, subsegloop);
11599  /* Check if this is a boundary edge. */
11600  sym(checktri, checkneighbor);
11601  if (checkneighbor.tri == m->dummytri) {
11602  /* The next line doesn't insert a subsegment (because there's */
11603  /* already one there), but it sets the boundary markers of */
11604  /* the existing subsegment and its vertices. */
11605  insertsubseg(m, b, &checktri, 1);
11606  hullsize++;
11607  }
11608  notfound = 0;
11609  }
11610  /* Find the next triangle in the stack. */
11611  prevlink = &checktri.tri[6 + checktri.orient];
11612  nexttri = checktri.tri[6 + checktri.orient];
11613  decode(nexttri, checktri);
11614  }
11615  }
11616  subsegloop.ss = subsegtraverse(m);
11617  segmentnumber++;
11618  }
11619  }
11620 
11621  /* Mark the remaining edges as not being attached to any subsegment. */
11622  /* Also, count the (yet uncounted) boundary edges. */
11623  for (i = 0; i < m->vertices.items; i++) {
11624  /* Search the stack of triangles adjacent to a vertex. */
11625  nexttri = vertexarray[i];
11626  decode(nexttri, checktri);
11627  while (checktri.tri != m->dummytri) {
11628  /* Find the next triangle in the stack before this */
11629  /* information gets overwritten. */
11630  nexttri = checktri.tri[6 + checktri.orient];
11631  /* No adjacent subsegment. (This overwrites the stack info.) */
11632  tsdissolve(checktri);
11633  sym(checktri, checkneighbor);
11634  if (checkneighbor.tri == m->dummytri) {
11635  insertsubseg(m, b, &checktri, 1);
11636  hullsize++;
11637  }
11638  decode(nexttri, checktri);
11639  }
11640  }
11641 
11642  trifree((VOID *) vertexarray);
11643  return hullsize;
11644 }
11645 
11646 #endif /* not CDT_ONLY */
11647 
11650 /********* General mesh construction routines end here *********/
11651 
11652 /********* Segment insertion begins here *********/
11656 /*****************************************************************************/
11657 /* */
11658 /* finddirection() Find the first triangle on the path from one point */
11659 /* to another. */
11660 /* */
11661 /* Finds the triangle that intersects a line segment drawn from the */
11662 /* origin of `searchtri' to the point `searchpoint', and returns the result */
11663 /* in `searchtri'. The origin of `searchtri' does not change, even though */
11664 /* the triangle returned may differ from the one passed in. This routine */
11665 /* is used to find the direction to move in to get from one point to */
11666 /* another. */
11667 /* */
11668 /* The return value notes whether the destination or apex of the found */
11669 /* triangle is collinear with the two points in question. */
11670 /* */
11671 /*****************************************************************************/
11672 
11673 #ifdef ANSI_DECLARATORS
11674 enum finddirectionresult finddirection(struct mesh *m, struct behavior *b,
11675  struct otri *searchtri,
11676  vertex searchpoint)
11677 #else /* not ANSI_DECLARATORS */
11678 enum finddirectionresult finddirection(m, b, searchtri, searchpoint)
11679 struct mesh *m;
11680 struct behavior *b;
11681 struct otri *searchtri;
11682 vertex searchpoint;
11683 #endif /* not ANSI_DECLARATORS */
11684 
11685 {
11686  struct otri checktri;
11687  vertex startvertex;
11688  vertex leftvertex, rightvertex;
11689  REAL leftccw, rightccw;
11690  int leftflag, rightflag;
11691  triangle ptr; /* Temporary variable used by onext() and oprev(). */
11692 
11693  org(*searchtri, startvertex);
11694  dest(*searchtri, rightvertex);
11695  apex(*searchtri, leftvertex);
11696  /* Is `searchpoint' to the left? */
11697  leftccw = counterclockwise(m, b, searchpoint, startvertex, leftvertex);
11698  leftflag = leftccw > 0.0;
11699  /* Is `searchpoint' to the right? */
11700  rightccw = counterclockwise(m, b, startvertex, searchpoint, rightvertex);
11701  rightflag = rightccw > 0.0;
11702  if (leftflag && rightflag) {
11703  /* `searchtri' faces directly away from `searchpoint'. We could go left */
11704  /* or right. Ask whether it's a triangle or a boundary on the left. */
11705  onext(*searchtri, checktri);
11706  if (checktri.tri == m->dummytri) {
11707  leftflag = 0;
11708  } else {
11709  rightflag = 0;
11710  }
11711  }
11712  while (leftflag) {
11713  /* Turn left until satisfied. */
11714  onextself(*searchtri);
11715  if (searchtri->tri == m->dummytri) {
11716  printf("Internal error in finddirection(): Unable to find a\n");
11717  printf(" triangle leading from (%.12g, %.12g) to", startvertex[0],
11718  startvertex[1]);
11719  printf(" (%.12g, %.12g).\n", searchpoint[0], searchpoint[1]);
11720  internalerror();
11721  }
11722  apex(*searchtri, leftvertex);
11723  rightccw = leftccw;
11724  leftccw = counterclockwise(m, b, searchpoint, startvertex, leftvertex);
11725  leftflag = leftccw > 0.0;
11726  }
11727  while (rightflag) {
11728  /* Turn right until satisfied. */
11729  oprevself(*searchtri);
11730  if (searchtri->tri == m->dummytri) {
11731  printf("Internal error in finddirection(): Unable to find a\n");
11732  printf(" triangle leading from (%.12g, %.12g) to", startvertex[0],
11733  startvertex[1]);
11734  printf(" (%.12g, %.12g).\n", searchpoint[0], searchpoint[1]);
11735  internalerror();
11736  }
11737  dest(*searchtri, rightvertex);
11738  leftccw = rightccw;
11739  rightccw = counterclockwise(m, b, startvertex, searchpoint, rightvertex);
11740  rightflag = rightccw > 0.0;
11741  }
11742  if (leftccw == 0.0) {
11743  return LEFTCOLLINEAR;
11744  } else if (rightccw == 0.0) {
11745  return RIGHTCOLLINEAR;
11746  } else {
11747  return WITHIN;
11748  }
11749 }
11750 
11751 /*****************************************************************************/
11752 /* */
11753 /* segmentintersection() Find the intersection of an existing segment */
11754 /* and a segment that is being inserted. Insert */
11755 /* a vertex at the intersection, splitting an */
11756 /* existing subsegment. */
11757 /* */
11758 /* The segment being inserted connects the apex of splittri to endpoint2. */
11759 /* splitsubseg is the subsegment being split, and MUST adjoin splittri. */
11760 /* Hence, endpoints of the subsegment being split are the origin and */
11761 /* destination of splittri. */
11762 /* */
11763 /* On completion, splittri is a handle having the newly inserted */
11764 /* intersection point as its origin, and endpoint1 as its destination. */
11765 /* */
11766 /*****************************************************************************/
11767 
11768 #ifdef ANSI_DECLARATORS
11769 void segmentintersection(struct mesh *m, struct behavior *b,
11770  struct otri *splittri, struct osub *splitsubseg,
11771  vertex endpoint2)
11772 #else /* not ANSI_DECLARATORS */
11773 void segmentintersection(m, b, splittri, splitsubseg, endpoint2)
11774 struct mesh *m;
11775 struct behavior *b;
11776 struct otri *splittri;
11777 struct osub *splitsubseg;
11778 vertex endpoint2;
11779 #endif /* not ANSI_DECLARATORS */
11780 
11781 {
11782  struct osub opposubseg;
11783  vertex endpoint1;
11784  vertex torg, tdest;
11785  vertex leftvertex, rightvertex;
11786  vertex newvertex;
11787  enum insertvertexresult success;
11788  //enum finddirectionresult collinear; // commented out to get gcc4.6 working
11789  REAL ex, ey;
11790  REAL tx, ty;
11791  REAL etx, ety;
11792  REAL split, denom;
11793  int i;
11794  triangle ptr; /* Temporary variable used by onext(). */
11795  subseg sptr; /* Temporary variable used by snext(). */
11796 
11797  /* Find the other three segment endpoints. */
11798  apex(*splittri, endpoint1);
11799  org(*splittri, torg);
11800  dest(*splittri, tdest);
11801  /* Segment intersection formulae; see the Antonio reference. */
11802  tx = tdest[0] - torg[0];
11803  ty = tdest[1] - torg[1];
11804  ex = endpoint2[0] - endpoint1[0];
11805  ey = endpoint2[1] - endpoint1[1];
11806  etx = torg[0] - endpoint2[0];
11807  ety = torg[1] - endpoint2[1];
11808  denom = ty * ex - tx * ey;
11809  if (denom == 0.0) {
11810  printf("Internal error in segmentintersection():");
11811  printf(" Attempt to find intersection of parallel segments.\n");
11812  internalerror();
11813  }
11814  split = (ey * etx - ex * ety) / denom;
11815  /* Create the new vertex. */
11816  newvertex = (vertex) poolalloc(&m->vertices);
11817  /* Interpolate its coordinate and attributes. */
11818  for (i = 0; i < 2 + m->nextras; i++) {
11819  newvertex[i] = torg[i] + split * (tdest[i] - torg[i]);
11820  }
11821  setvertexmark(newvertex, mark(*splitsubseg));
11822  setvertextype(newvertex, INPUTVERTEX);
11823  if (b->verbose > 1) {
11824  printf(
11825  " Splitting subsegment (%.12g, %.12g) (%.12g, %.12g) at (%.12g, %.12g).\n",
11826  torg[0], torg[1], tdest[0], tdest[1], newvertex[0], newvertex[1]);
11827  }
11828  /* Insert the intersection vertex. This should always succeed. */
11829  success = insertvertex(m, b, newvertex, splittri, splitsubseg, 0, 0);
11830  if (success != SUCCESSFULVERTEX) {
11831  printf("Internal error in segmentintersection():\n");
11832  printf(" Failure to split a segment.\n");
11833  internalerror();
11834  }
11835  /* Record a triangle whose origin is the new vertex. */
11836  setvertex2tri(newvertex, encode(*splittri));
11837  if (m->steinerleft > 0) {
11838  m->steinerleft--;
11839  }
11840 
11841  /* Divide the segment into two, and correct the segment endpoints. */
11842  ssymself(*splitsubseg);
11843  spivot(*splitsubseg, opposubseg);
11844  sdissolve(*splitsubseg);
11845  sdissolve(opposubseg);
11846  do {
11847  setsegorg(*splitsubseg, newvertex);
11848  snextself(*splitsubseg);
11849  } while (splitsubseg->ss != m->dummysub);
11850  do {
11851  setsegorg(opposubseg, newvertex);
11852  snextself(opposubseg);
11853  } while (opposubseg.ss != m->dummysub);
11854 
11855  /* Inserting the vertex may have caused edge flips. We wish to rediscover */
11856  /* the edge connecting endpoint1 to the new intersection vertex. */
11857  finddirection(m, b, splittri, endpoint1); // "collinear =" commented out to get gcc4.6 working
11858  dest(*splittri, rightvertex);
11859  apex(*splittri, leftvertex);
11860  if ((leftvertex[0] == endpoint1[0]) && (leftvertex[1] == endpoint1[1])) {
11861  onextself(*splittri);
11862  } else if ((rightvertex[0] != endpoint1[0]) ||
11863  (rightvertex[1] != endpoint1[1])) {
11864  printf("Internal error in segmentintersection():\n");
11865  printf(" Topological inconsistency after splitting a segment.\n");
11866  internalerror();
11867  }
11868  /* `splittri' should have destination endpoint1. */
11869 }
11870 
11871 /*****************************************************************************/
11872 /* */
11873 /* scoutsegment() Scout the first triangle on the path from one endpoint */
11874 /* to another, and check for completion (reaching the */
11875 /* second endpoint), a collinear vertex, or the */
11876 /* intersection of two segments. */
11877 /* */
11878 /* Returns one if the entire segment is successfully inserted, and zero if */
11879 /* the job must be finished by conformingedge() or constrainededge(). */
11880 /* */
11881 /* If the first triangle on the path has the second endpoint as its */
11882 /* destination or apex, a subsegment is inserted and the job is done. */
11883 /* */
11884 /* If the first triangle on the path has a destination or apex that lies on */
11885 /* the segment, a subsegment is inserted connecting the first endpoint to */
11886 /* the collinear vertex, and the search is continued from the collinear */
11887 /* vertex. */
11888 /* */
11889 /* If the first triangle on the path has a subsegment opposite its origin, */
11890 /* then there is a segment that intersects the segment being inserted. */
11891 /* Their intersection vertex is inserted, splitting the subsegment. */
11892 /* */
11893 /*****************************************************************************/
11894 
11895 #ifdef ANSI_DECLARATORS
11896 int scoutsegment(struct mesh *m, struct behavior *b, struct otri *searchtri,
11897  vertex endpoint2, int newmark)
11898 #else /* not ANSI_DECLARATORS */
11899 int scoutsegment(m, b, searchtri, endpoint2, newmark)
11900 struct mesh *m;
11901 struct behavior *b;
11902 struct otri *searchtri;
11903 vertex endpoint2;
11904 int newmark;
11905 #endif /* not ANSI_DECLARATORS */
11906 
11907 {
11908  struct otri crosstri;
11909  struct osub crosssubseg;
11910  vertex leftvertex, rightvertex;
11911  enum finddirectionresult collinear;
11912  subseg sptr; /* Temporary variable used by tspivot(). */
11913 
11914  collinear = finddirection(m, b, searchtri, endpoint2);
11915  dest(*searchtri, rightvertex);
11916  apex(*searchtri, leftvertex);
11917  if (((leftvertex[0] == endpoint2[0]) && (leftvertex[1] == endpoint2[1])) ||
11918  ((rightvertex[0] == endpoint2[0]) && (rightvertex[1] == endpoint2[1]))) {
11919  /* The segment is already an edge in the mesh. */
11920  if ((leftvertex[0] == endpoint2[0]) && (leftvertex[1] == endpoint2[1])) {
11921  lprevself(*searchtri);
11922  }
11923  /* Insert a subsegment, if there isn't already one there. */
11924  insertsubseg(m, b, searchtri, newmark);
11925  return 1;
11926  } else if (collinear == LEFTCOLLINEAR) {
11927  /* We've collided with a vertex between the segment's endpoints. */
11928  /* Make the collinear vertex be the triangle's origin. */
11929  lprevself(*searchtri);
11930  insertsubseg(m, b, searchtri, newmark);
11931  /* Insert the remainder of the segment. */
11932  return scoutsegment(m, b, searchtri, endpoint2, newmark);
11933  } else if (collinear == RIGHTCOLLINEAR) {
11934  /* We've collided with a vertex between the segment's endpoints. */
11935  insertsubseg(m, b, searchtri, newmark);
11936  /* Make the collinear vertex be the triangle's origin. */
11937  lnextself(*searchtri);
11938  /* Insert the remainder of the segment. */
11939  return scoutsegment(m, b, searchtri, endpoint2, newmark);
11940  } else {
11941  lnext(*searchtri, crosstri);
11942  tspivot(crosstri, crosssubseg);
11943  /* Check for a crossing segment. */
11944  if (crosssubseg.ss == m->dummysub) {
11945  return 0;
11946  } else {
11947  /* Insert a vertex at the intersection. */
11948  segmentintersection(m, b, &crosstri, &crosssubseg, endpoint2);
11949  otricopy(crosstri, *searchtri);
11950  insertsubseg(m, b, searchtri, newmark);
11951  /* Insert the remainder of the segment. */
11952  return scoutsegment(m, b, searchtri, endpoint2, newmark);
11953  }
11954  }
11955 }
11956 
11957 /*****************************************************************************/
11958 /* */
11959 /* conformingedge() Force a segment into a conforming Delaunay */
11960 /* triangulation by inserting a vertex at its midpoint, */
11961 /* and recursively forcing in the two half-segments if */
11962 /* necessary. */
11963 /* */
11964 /* Generates a sequence of subsegments connecting `endpoint1' to */
11965 /* `endpoint2'. `newmark' is the boundary marker of the segment, assigned */
11966 /* to each new splitting vertex and subsegment. */
11967 /* */
11968 /* Note that conformingedge() does not always maintain the conforming */
11969 /* Delaunay property. Once inserted, segments are locked into place; */
11970 /* vertices inserted later (to force other segments in) may render these */
11971 /* fixed segments non-Delaunay. The conforming Delaunay property will be */
11972 /* restored by enforcequality() by splitting encroached subsegments. */
11973 /* */
11974 /*****************************************************************************/
11975 
11976 #ifndef REDUCED
11977 #ifndef CDT_ONLY
11978 
11979 #ifdef ANSI_DECLARATORS
11980 void conformingedge(struct mesh *m, struct behavior *b,
11981  vertex endpoint1, vertex endpoint2, int newmark)
11982 #else /* not ANSI_DECLARATORS */
11983 void conformingedge(m, b, endpoint1, endpoint2, newmark)
11984 struct mesh *m;
11985 struct behavior *b;
11986 vertex endpoint1;
11987 vertex endpoint2;
11988 int newmark;
11989 #endif /* not ANSI_DECLARATORS */
11990 
11991 {
11992  struct otri searchtri1, searchtri2;
11993  struct osub brokensubseg;
11994  vertex newvertex;
11995  vertex midvertex1, midvertex2;
11996  enum insertvertexresult success;
11997  int i;
11998  subseg sptr; /* Temporary variable used by tspivot(). */
11999 
12000  if (b->verbose > 2) {
12001  printf("Forcing segment into triangulation by recursive splitting:\n");
12002  printf(" (%.12g, %.12g) (%.12g, %.12g)\n", endpoint1[0], endpoint1[1],
12003  endpoint2[0], endpoint2[1]);
12004  }
12005  /* Create a new vertex to insert in the middle of the segment. */
12006  newvertex = (vertex) poolalloc(&m->vertices);
12007  /* Interpolate coordinates and attributes. */
12008  for (i = 0; i < 2 + m->nextras; i++) {
12009  newvertex[i] = 0.5 * (endpoint1[i] + endpoint2[i]);
12010  }
12011  setvertexmark(newvertex, newmark);
12012  setvertextype(newvertex, SEGMENTVERTEX);
12013  /* No known triangle to search from. */
12014  searchtri1.tri = m->dummytri;
12015  /* Attempt to insert the new vertex. */
12016  success = insertvertex(m, b, newvertex, &searchtri1, (struct osub *) NULL,
12017  0, 0);
12018  if (success == DUPLICATEVERTEX) {
12019  if (b->verbose > 2) {
12020  printf(" Segment intersects existing vertex (%.12g, %.12g).\n",
12021  newvertex[0], newvertex[1]);
12022  }
12023  /* Use the vertex that's already there. */
12024  vertexdealloc(m, newvertex);
12025  org(searchtri1, newvertex);
12026  } else {
12027  if (success == VIOLATINGVERTEX) {
12028  if (b->verbose > 2) {
12029  printf(" Two segments intersect at (%.12g, %.12g).\n",
12030  newvertex[0], newvertex[1]);
12031  }
12032  /* By fluke, we've landed right on another segment. Split it. */
12033  tspivot(searchtri1, brokensubseg);
12034  success = insertvertex(m, b, newvertex, &searchtri1, &brokensubseg,
12035  0, 0);
12036  if (success != SUCCESSFULVERTEX) {
12037  printf("Internal error in conformingedge():\n");
12038  printf(" Failure to split a segment.\n");
12039  internalerror();
12040  }
12041  }
12042  /* The vertex has been inserted successfully. */
12043  if (m->steinerleft > 0) {
12044  m->steinerleft--;
12045  }
12046  }
12047  otricopy(searchtri1, searchtri2);
12048  /* `searchtri1' and `searchtri2' are fastened at their origins to */
12049  /* `newvertex', and will be directed toward `endpoint1' and `endpoint2' */
12050  /* respectively. First, we must get `searchtri2' out of the way so it */
12051  /* won't be invalidated during the insertion of the first half of the */
12052  /* segment. */
12053  finddirection(m, b, &searchtri2, endpoint2);
12054  if (!scoutsegment(m, b, &searchtri1, endpoint1, newmark)) {
12055  /* The origin of searchtri1 may have changed if a collision with an */
12056  /* intervening vertex on the segment occurred. */
12057  org(searchtri1, midvertex1);
12058  conformingedge(m, b, midvertex1, endpoint1, newmark);
12059  }
12060  if (!scoutsegment(m, b, &searchtri2, endpoint2, newmark)) {
12061  /* The origin of searchtri2 may have changed if a collision with an */
12062  /* intervening vertex on the segment occurred. */
12063  org(searchtri2, midvertex2);
12064  conformingedge(m, b, midvertex2, endpoint2, newmark);
12065  }
12066 }
12067 
12068 #endif /* not CDT_ONLY */
12069 #endif /* not REDUCED */
12070 
12071 /*****************************************************************************/
12072 /* */
12073 /* delaunayfixup() Enforce the Delaunay condition at an edge, fanning out */
12074 /* recursively from an existing vertex. Pay special */
12075 /* attention to stacking inverted triangles. */
12076 /* */
12077 /* This is a support routine for inserting segments into a constrained */
12078 /* Delaunay triangulation. */
12079 /* */
12080 /* The origin of fixuptri is treated as if it has just been inserted, and */
12081 /* the local Delaunay condition needs to be enforced. It is only enforced */
12082 /* in one sector, however, that being the angular range defined by */
12083 /* fixuptri. */
12084 /* */
12085 /* This routine also needs to make decisions regarding the "stacking" of */
12086 /* triangles. (Read the description of constrainededge() below before */
12087 /* reading on here, so you understand the algorithm.) If the position of */
12088 /* the new vertex (the origin of fixuptri) indicates that the vertex before */
12089 /* it on the polygon is a reflex vertex, then "stack" the triangle by */
12090 /* doing nothing. (fixuptri is an inverted triangle, which is how stacked */
12091 /* triangles are identified.) */
12092 /* */
12093 /* Otherwise, check whether the vertex before that was a reflex vertex. */
12094 /* If so, perform an edge flip, thereby eliminating an inverted triangle */
12095 /* (popping it off the stack). The edge flip may result in the creation */
12096 /* of a new inverted triangle, depending on whether or not the new vertex */
12097 /* is visible to the vertex three edges behind on the polygon. */
12098 /* */
12099 /* If neither of the two vertices behind the new vertex are reflex */
12100 /* vertices, fixuptri and fartri, the triangle opposite it, are not */
12101 /* inverted; hence, ensure that the edge between them is locally Delaunay. */
12102 /* */
12103 /* `leftside' indicates whether or not fixuptri is to the left of the */
12104 /* segment being inserted. (Imagine that the segment is pointing up from */
12105 /* endpoint1 to endpoint2.) */
12106 /* */
12107 /*****************************************************************************/
12108 
12109 #ifdef ANSI_DECLARATORS
12110 void delaunayfixup(struct mesh *m, struct behavior *b,
12111  struct otri *fixuptri, int leftside)
12112 #else /* not ANSI_DECLARATORS */
12113 void delaunayfixup(m, b, fixuptri, leftside)
12114 struct mesh *m;
12115 struct behavior *b;
12116 struct otri *fixuptri;
12117 int leftside;
12118 #endif /* not ANSI_DECLARATORS */
12119 
12120 {
12121  struct otri neartri;
12122  struct otri fartri;
12123  struct osub faredge;
12124  vertex nearvertex, leftvertex, rightvertex, farvertex;
12125  triangle ptr; /* Temporary variable used by sym(). */
12126  subseg sptr; /* Temporary variable used by tspivot(). */
12127 
12128  lnext(*fixuptri, neartri);
12129  sym(neartri, fartri);
12130  /* Check if the edge opposite the origin of fixuptri can be flipped. */
12131  if (fartri.tri == m->dummytri) {
12132  return;
12133  }
12134  tspivot(neartri, faredge);
12135  if (faredge.ss != m->dummysub) {
12136  return;
12137  }
12138  /* Find all the relevant vertices. */
12139  apex(neartri, nearvertex);
12140  org(neartri, leftvertex);
12141  dest(neartri, rightvertex);
12142  apex(fartri, farvertex);
12143  /* Check whether the previous polygon vertex is a reflex vertex. */
12144  if (leftside) {
12145  if (counterclockwise(m, b, nearvertex, leftvertex, farvertex) <= 0.0) {
12146  /* leftvertex is a reflex vertex too. Nothing can */
12147  /* be done until a convex section is found. */
12148  return;
12149  }
12150  } else {
12151  if (counterclockwise(m, b, farvertex, rightvertex, nearvertex) <= 0.0) {
12152  /* rightvertex is a reflex vertex too. Nothing can */
12153  /* be done until a convex section is found. */
12154  return;
12155  }
12156  }
12157  if (counterclockwise(m, b, rightvertex, leftvertex, farvertex) > 0.0) {
12158  /* fartri is not an inverted triangle, and farvertex is not a reflex */
12159  /* vertex. As there are no reflex vertices, fixuptri isn't an */
12160  /* inverted triangle, either. Hence, test the edge between the */
12161  /* triangles to ensure it is locally Delaunay. */
12162  if (incircle(m, b, leftvertex, farvertex, rightvertex, nearvertex) <=
12163  0.0) {
12164  return;
12165  }
12166  /* Not locally Delaunay; go on to an edge flip. */
12167  } /* else fartri is inverted; remove it from the stack by flipping. */
12168  flip(m, b, &neartri);
12169  lprevself(*fixuptri); /* Restore the origin of fixuptri after the flip. */
12170  /* Recursively process the two triangles that result from the flip. */
12171  delaunayfixup(m, b, fixuptri, leftside);
12172  delaunayfixup(m, b, &fartri, leftside);
12173 }
12174 
12175 /*****************************************************************************/
12176 /* */
12177 /* constrainededge() Force a segment into a constrained Delaunay */
12178 /* triangulation by deleting the triangles it */
12179 /* intersects, and triangulating the polygons that */
12180 /* form on each side of it. */
12181 /* */
12182 /* Generates a single subsegment connecting `endpoint1' to `endpoint2'. */
12183 /* The triangle `starttri' has `endpoint1' as its origin. `newmark' is the */
12184 /* boundary marker of the segment. */
12185 /* */
12186 /* To insert a segment, every triangle whose interior intersects the */
12187 /* segment is deleted. The union of these deleted triangles is a polygon */
12188 /* (which is not necessarily monotone, but is close enough), which is */
12189 /* divided into two polygons by the new segment. This routine's task is */
12190 /* to generate the Delaunay triangulation of these two polygons. */
12191 /* */
12192 /* You might think of this routine's behavior as a two-step process. The */
12193 /* first step is to walk from endpoint1 to endpoint2, flipping each edge */
12194 /* encountered. This step creates a fan of edges connected to endpoint1, */
12195 /* including the desired edge to endpoint2. The second step enforces the */
12196 /* Delaunay condition on each side of the segment in an incremental manner: */
12197 /* proceeding along the polygon from endpoint1 to endpoint2 (this is done */
12198 /* independently on each side of the segment), each vertex is "enforced" */
12199 /* as if it had just been inserted, but affecting only the previous */
12200 /* vertices. The result is the same as if the vertices had been inserted */
12201 /* in the order they appear on the polygon, so the result is Delaunay. */
12202 /* */
12203 /* In truth, constrainededge() interleaves these two steps. The procedure */
12204 /* walks from endpoint1 to endpoint2, and each time an edge is encountered */
12205 /* and flipped, the newly exposed vertex (at the far end of the flipped */
12206 /* edge) is "enforced" upon the previously flipped edges, usually affecting */
12207 /* only one side of the polygon (depending upon which side of the segment */
12208 /* the vertex falls on). */
12209 /* */
12210 /* The algorithm is complicated by the need to handle polygons that are not */
12211 /* convex. Although the polygon is not necessarily monotone, it can be */
12212 /* triangulated in a manner similar to the stack-based algorithms for */
12213 /* monotone polygons. For each reflex vertex (local concavity) of the */
12214 /* polygon, there will be an inverted triangle formed by one of the edge */
12215 /* flips. (An inverted triangle is one with negative area - that is, its */
12216 /* vertices are arranged in clockwise order - and is best thought of as a */
12217 /* wrinkle in the fabric of the mesh.) Each inverted triangle can be */
12218 /* thought of as a reflex vertex pushed on the stack, waiting to be fixed */
12219 /* later. */
12220 /* */
12221 /* A reflex vertex is popped from the stack when a vertex is inserted that */
12222 /* is visible to the reflex vertex. (However, if the vertex behind the */
12223 /* reflex vertex is not visible to the reflex vertex, a new inverted */
12224 /* triangle will take its place on the stack.) These details are handled */
12225 /* by the delaunayfixup() routine above. */
12226 /* */
12227 /*****************************************************************************/
12228 
12229 #ifdef ANSI_DECLARATORS
12230 void constrainededge(struct mesh *m, struct behavior *b,
12231  struct otri *starttri, vertex endpoint2, int newmark)
12232 #else /* not ANSI_DECLARATORS */
12233 void constrainededge(m, b, starttri, endpoint2, newmark)
12234 struct mesh *m;
12235 struct behavior *b;
12236 struct otri *starttri;
12237 vertex endpoint2;
12238 int newmark;
12239 #endif /* not ANSI_DECLARATORS */
12240 
12241 {
12242  struct otri fixuptri, fixuptri2;
12243  struct osub crosssubseg;
12244  vertex endpoint1;
12245  vertex farvertex;
12246  REAL area;
12247  int collision;
12248  int done;
12249  triangle ptr; /* Temporary variable used by sym() and oprev(). */
12250  subseg sptr; /* Temporary variable used by tspivot(). */
12251 
12252  org(*starttri, endpoint1);
12253  lnext(*starttri, fixuptri);
12254  flip(m, b, &fixuptri);
12255  /* `collision' indicates whether we have found a vertex directly */
12256  /* between endpoint1 and endpoint2. */
12257  collision = 0;
12258  done = 0;
12259  do {
12260  org(fixuptri, farvertex);
12261  /* `farvertex' is the extreme point of the polygon we are "digging" */
12262  /* to get from endpoint1 to endpoint2. */
12263  if ((farvertex[0] == endpoint2[0]) && (farvertex[1] == endpoint2[1])) {
12264  oprev(fixuptri, fixuptri2);
12265  /* Enforce the Delaunay condition around endpoint2. */
12266  delaunayfixup(m, b, &fixuptri, 0);
12267  delaunayfixup(m, b, &fixuptri2, 1);
12268  done = 1;
12269  } else {
12270  /* Check whether farvertex is to the left or right of the segment */
12271  /* being inserted, to decide which edge of fixuptri to dig */
12272  /* through next. */
12273  area = counterclockwise(m, b, endpoint1, endpoint2, farvertex);
12274  if (area == 0.0) {
12275  /* We've collided with a vertex between endpoint1 and endpoint2. */
12276  collision = 1;
12277  oprev(fixuptri, fixuptri2);
12278  /* Enforce the Delaunay condition around farvertex. */
12279  delaunayfixup(m, b, &fixuptri, 0);
12280  delaunayfixup(m, b, &fixuptri2, 1);
12281  done = 1;
12282  } else {
12283  if (area > 0.0) { /* farvertex is to the left of the segment. */
12284  oprev(fixuptri, fixuptri2);
12285  /* Enforce the Delaunay condition around farvertex, on the */
12286  /* left side of the segment only. */
12287  delaunayfixup(m, b, &fixuptri2, 1);
12288  /* Flip the edge that crosses the segment. After the edge is */
12289  /* flipped, one of its endpoints is the fan vertex, and the */
12290  /* destination of fixuptri is the fan vertex. */
12291  lprevself(fixuptri);
12292  } else { /* farvertex is to the right of the segment. */
12293  delaunayfixup(m, b, &fixuptri, 0);
12294  /* Flip the edge that crosses the segment. After the edge is */
12295  /* flipped, one of its endpoints is the fan vertex, and the */
12296  /* destination of fixuptri is the fan vertex. */
12297  oprevself(fixuptri);
12298  }
12299  /* Check for two intersecting segments. */
12300  tspivot(fixuptri, crosssubseg);
12301  if (crosssubseg.ss == m->dummysub) {
12302  flip(m, b, &fixuptri); /* May create inverted triangle at left. */
12303  } else {
12304  /* We've collided with a segment between endpoint1 and endpoint2. */
12305  collision = 1;
12306  /* Insert a vertex at the intersection. */
12307  segmentintersection(m, b, &fixuptri, &crosssubseg, endpoint2);
12308  done = 1;
12309  }
12310  }
12311  }
12312  } while (!done);
12313  /* Insert a subsegment to make the segment permanent. */
12314  insertsubseg(m, b, &fixuptri, newmark);
12315  /* If there was a collision with an interceding vertex, install another */
12316  /* segment connecting that vertex with endpoint2. */
12317  if (collision) {
12318  /* Insert the remainder of the segment. */
12319  if (!scoutsegment(m, b, &fixuptri, endpoint2, newmark)) {
12320  constrainededge(m, b, &fixuptri, endpoint2, newmark);
12321  }
12322  }
12323 }
12324 
12325 /*****************************************************************************/
12326 /* */
12327 /* insertsegment() Insert a PSLG segment into a triangulation. */
12328 /* */
12329 /*****************************************************************************/
12330 
12331 #ifdef ANSI_DECLARATORS
12332 void insertsegment(struct mesh *m, struct behavior *b,
12333  vertex endpoint1, vertex endpoint2, int newmark)
12334 #else /* not ANSI_DECLARATORS */
12335 void insertsegment(m, b, endpoint1, endpoint2, newmark)
12336 struct mesh *m;
12337 struct behavior *b;
12338 vertex endpoint1;
12339 vertex endpoint2;
12340 int newmark;
12341 #endif /* not ANSI_DECLARATORS */
12342 
12343 {
12344  struct otri searchtri1, searchtri2;
12345  triangle encodedtri;
12346  vertex checkvertex;
12347  triangle ptr; /* Temporary variable used by sym(). */
12348 
12349  if (b->verbose > 1) {
12350  printf(" Connecting (%.12g, %.12g) to (%.12g, %.12g).\n",
12351  endpoint1[0], endpoint1[1], endpoint2[0], endpoint2[1]);
12352  }
12353 
12354  /* Find a triangle whose origin is the segment's first endpoint. */
12355  checkvertex = (vertex) NULL;
12356  encodedtri = vertex2tri(endpoint1);
12357  if (encodedtri != (triangle) NULL) {
12358  decode(encodedtri, searchtri1);
12359  org(searchtri1, checkvertex);
12360  }
12361  if (checkvertex != endpoint1) {
12362  /* Find a boundary triangle to search from. */
12363  searchtri1.tri = m->dummytri;
12364  searchtri1.orient = 0;
12365  symself(searchtri1);
12366  /* Search for the segment's first endpoint by point location. */
12367  if (locate(m, b, endpoint1, &searchtri1) != ONVERTEX) {
12368  printf(
12369  "Internal error in insertsegment(): Unable to locate PSLG vertex\n");
12370  printf(" (%.12g, %.12g) in triangulation.\n",
12371  endpoint1[0], endpoint1[1]);
12372  internalerror();
12373  }
12374  }
12375  /* Remember this triangle to improve subsequent point location. */
12376  otricopy(searchtri1, m->recenttri);
12377  /* Scout the beginnings of a path from the first endpoint */
12378  /* toward the second. */
12379  if (scoutsegment(m, b, &searchtri1, endpoint2, newmark)) {
12380  /* The segment was easily inserted. */
12381  return;
12382  }
12383  /* The first endpoint may have changed if a collision with an intervening */
12384  /* vertex on the segment occurred. */
12385  org(searchtri1, endpoint1);
12386 
12387  /* Find a triangle whose origin is the segment's second endpoint. */
12388  checkvertex = (vertex) NULL;
12389  encodedtri = vertex2tri(endpoint2);
12390  if (encodedtri != (triangle) NULL) {
12391  decode(encodedtri, searchtri2);
12392  org(searchtri2, checkvertex);
12393  }
12394  if (checkvertex != endpoint2) {
12395  /* Find a boundary triangle to search from. */
12396  searchtri2.tri = m->dummytri;
12397  searchtri2.orient = 0;
12398  symself(searchtri2);
12399  /* Search for the segment's second endpoint by point location. */
12400  if (locate(m, b, endpoint2, &searchtri2) != ONVERTEX) {
12401  printf(
12402  "Internal error in insertsegment(): Unable to locate PSLG vertex\n");
12403  printf(" (%.12g, %.12g) in triangulation.\n",
12404  endpoint2[0], endpoint2[1]);
12405  internalerror();
12406  }
12407  }
12408  /* Remember this triangle to improve subsequent point location. */
12409  otricopy(searchtri2, m->recenttri);
12410  /* Scout the beginnings of a path from the second endpoint */
12411  /* toward the first. */
12412  if (scoutsegment(m, b, &searchtri2, endpoint1, newmark)) {
12413  /* The segment was easily inserted. */
12414  return;
12415  }
12416  /* The second endpoint may have changed if a collision with an intervening */
12417  /* vertex on the segment occurred. */
12418  org(searchtri2, endpoint2);
12419 
12420 #ifndef REDUCED
12421 #ifndef CDT_ONLY
12422  if (b->splitseg) {
12423  /* Insert vertices to force the segment into the triangulation. */
12424  conformingedge(m, b, endpoint1, endpoint2, newmark);
12425  } else {
12426 #endif /* not CDT_ONLY */
12427 #endif /* not REDUCED */
12428  /* Insert the segment directly into the triangulation. */
12429  constrainededge(m, b, &searchtri1, endpoint2, newmark);
12430 #ifndef REDUCED
12431 #ifndef CDT_ONLY
12432  }
12433 #endif /* not CDT_ONLY */
12434 #endif /* not REDUCED */
12435 }
12436 
12437 /*****************************************************************************/
12438 /* */
12439 /* markhull() Cover the convex hull of a triangulation with subsegments. */
12440 /* */
12441 /*****************************************************************************/
12442 
12443 #ifdef ANSI_DECLARATORS
12444 void markhull(struct mesh *m, struct behavior *b)
12445 #else /* not ANSI_DECLARATORS */
12446 void markhull(m, b)
12447 struct mesh *m;
12448 struct behavior *b;
12449 #endif /* not ANSI_DECLARATORS */
12450 
12451 {
12452  struct otri hulltri;
12453  struct otri nexttri;
12454  struct otri starttri;
12455  triangle ptr; /* Temporary variable used by sym() and oprev(). */
12456 
12457  /* Find a triangle handle on the hull. */
12458  hulltri.tri = m->dummytri;
12459  hulltri.orient = 0;
12460  symself(hulltri);
12461  /* Remember where we started so we know when to stop. */
12462  otricopy(hulltri, starttri);
12463  /* Go once counterclockwise around the convex hull. */
12464  do {
12465  /* Create a subsegment if there isn't already one here. */
12466  insertsubseg(m, b, &hulltri, 1);
12467  /* To find the next hull edge, go clockwise around the next vertex. */
12468  lnextself(hulltri);
12469  oprev(hulltri, nexttri);
12470  while (nexttri.tri != m->dummytri) {
12471  otricopy(nexttri, hulltri);
12472  oprev(hulltri, nexttri);
12473  }
12474  } while (!otriequal(hulltri, starttri));
12475 }
12476 
12477 /*****************************************************************************/
12478 /* */
12479 /* formskeleton() Create the segments of a triangulation, including PSLG */
12480 /* segments and edges on the convex hull. */
12481 /* */
12482 /* The PSLG segments are read from a .poly file. The return value is the */
12483 /* number of segments in the file. */
12484 /* */
12485 /*****************************************************************************/
12486 
12487 #ifdef TRILIBRARY
12488 
12489 #ifdef ANSI_DECLARATORS
12490 void formskeleton(struct mesh *m, struct behavior *b, int *segmentlist,
12491  int *segmentmarkerlist, int numberofsegments)
12492 #else /* not ANSI_DECLARATORS */
12493 void formskeleton(m, b, segmentlist, segmentmarkerlist, numberofsegments)
12494 struct mesh *m;
12495 struct behavior *b;
12496 int *segmentlist;
12497 int *segmentmarkerlist;
12498 int numberofsegments;
12499 #endif /* not ANSI_DECLARATORS */
12500 
12501 #else /* not TRILIBRARY */
12502 
12503 #ifdef ANSI_DECLARATORS
12504 void formskeleton(struct mesh *m, struct behavior *b,
12505  FILE* polyfile, char* polyfilename)
12506 #else /* not ANSI_DECLARATORS */
12507 void formskeleton(m, b, polyfile, polyfilename)
12508 struct mesh *m;
12509 struct behavior *b;
12510 FILE* polyfile;
12511 char* polyfilename;
12512 #endif /* not ANSI_DECLARATORS */
12513 
12514 #endif /* not TRILIBRARY */
12515 
12516 {
12517 #ifdef TRILIBRARY
12518  char polyfilename[6];
12519  int index;
12520 #else /* not TRILIBRARY */
12521  char inputline[INPUTLINESIZE];
12522  char *stringptr;
12523 #endif /* not TRILIBRARY */
12524  vertex endpoint1, endpoint2;
12525  int segmentmarkers;
12526  int end1, end2;
12527  int boundmarker;
12528  int i;
12529 
12530  if (b->poly) {
12531  if (!b->quiet) {
12532  printf("Recovering segments in Delaunay triangulation.\n");
12533  }
12534 #ifdef TRILIBRARY
12535  strcpy(polyfilename, "input");
12536  m->insegments = numberofsegments;
12537  segmentmarkers = segmentmarkerlist != (int *) NULL;
12538  index = 0;
12539 #else /* not TRILIBRARY */
12540  /* Read the segments from a .poly file. */
12541  /* Read number of segments and number of boundary markers. */
12542  stringptr = readline(inputline, polyfile, polyfilename);
12543  m->insegments = (int) strtol(stringptr, &stringptr, 0);
12544  stringptr = findfield(stringptr);
12545  if (*stringptr == '\0') {
12546  segmentmarkers = 0;
12547  } else {
12548  segmentmarkers = (int) strtol(stringptr, &stringptr, 0);
12549  }
12550 #endif /* not TRILIBRARY */
12551  /* If the input vertices are collinear, there is no triangulation, */
12552  /* so don't try to insert segments. */
12553  if (m->triangles.items == 0) {
12554  return;
12555  }
12556 
12557  /* If segments are to be inserted, compute a mapping */
12558  /* from vertices to triangles. */
12559  if (m->insegments > 0) {
12560  makevertexmap(m, b);
12561  if (b->verbose) {
12562  printf(" Recovering PSLG segments.\n");
12563  }
12564  }
12565 
12566  boundmarker = 0;
12567  /* Read and insert the segments. */
12568  for (i = 0; i < m->insegments; i++) {
12569 #ifdef TRILIBRARY
12570  end1 = segmentlist[index++];
12571  end2 = segmentlist[index++];
12572  if (segmentmarkers) {
12573  boundmarker = segmentmarkerlist[i];
12574  }
12575 #else /* not TRILIBRARY */
12576  stringptr = readline(inputline, polyfile, b->inpolyfilename);
12577  stringptr = findfield(stringptr);
12578  if (*stringptr == '\0') {
12579  printf("Error: Segment %d has no endpoints in %s.\n",
12580  b->firstnumber + i, polyfilename);
12581  triexit(1);
12582  } else {
12583  end1 = (int) strtol(stringptr, &stringptr, 0);
12584  }
12585  stringptr = findfield(stringptr);
12586  if (*stringptr == '\0') {
12587  printf("Error: Segment %d is missing its second endpoint in %s.\n",
12588  b->firstnumber + i, polyfilename);
12589  triexit(1);
12590  } else {
12591  end2 = (int) strtol(stringptr, &stringptr, 0);
12592  }
12593  if (segmentmarkers) {
12594  stringptr = findfield(stringptr);
12595  if (*stringptr == '\0') {
12596  boundmarker = 0;
12597  } else {
12598  boundmarker = (int) strtol(stringptr, &stringptr, 0);
12599  }
12600  }
12601 #endif /* not TRILIBRARY */
12602  if ((end1 < b->firstnumber) ||
12603  (end1 >= b->firstnumber + m->invertices)) {
12604  if (!b->quiet) {
12605  printf("Warning: Invalid first endpoint of segment %d in %s.\n",
12606  b->firstnumber + i, polyfilename);
12607  }
12608  } else if ((end2 < b->firstnumber) ||
12609  (end2 >= b->firstnumber + m->invertices)) {
12610  if (!b->quiet) {
12611  printf("Warning: Invalid second endpoint of segment %d in %s.\n",
12612  b->firstnumber + i, polyfilename);
12613  }
12614  } else {
12615  /* Find the vertices numbered `end1' and `end2'. */
12616  endpoint1 = getvertex(m, b, end1);
12617  endpoint2 = getvertex(m, b, end2);
12618  if ((endpoint1[0] == endpoint2[0]) && (endpoint1[1] == endpoint2[1])) {
12619  if (!b->quiet) {
12620  printf("Warning: Endpoints of segment %d are coincident in %s.\n",
12621  b->firstnumber + i, polyfilename);
12622  }
12623  } else {
12624  insertsegment(m, b, endpoint1, endpoint2, boundmarker);
12625  }
12626  }
12627  }
12628  } else {
12629  m->insegments = 0;
12630  }
12631  if (b->convex || !b->poly) {
12632  /* Enclose the convex hull with subsegments. */
12633  if (b->verbose) {
12634  printf(" Enclosing convex hull with segments.\n");
12635  }
12636  markhull(m, b);
12637  }
12638 }
12639 
12642 /********* Segment insertion ends here *********/
12643 
12644 /********* Carving out holes and concavities begins here *********/
12648 /*****************************************************************************/
12649 /* */
12650 /* infecthull() Virally infect all of the triangles of the convex hull */
12651 /* that are not protected by subsegments. Where there are */
12652 /* subsegments, set boundary markers as appropriate. */
12653 /* */
12654 /*****************************************************************************/
12655 
12656 #ifdef ANSI_DECLARATORS
12657 void infecthull(struct mesh *m, struct behavior *b)
12658 #else /* not ANSI_DECLARATORS */
12659 void infecthull(m, b)
12660 struct mesh *m;
12661 struct behavior *b;
12662 #endif /* not ANSI_DECLARATORS */
12663 
12664 {
12665  struct otri hulltri;
12666  struct otri nexttri;
12667  struct otri starttri;
12668  struct osub hullsubseg;
12669  triangle **deadtriangle;
12670  vertex horg, hdest;
12671  triangle ptr; /* Temporary variable used by sym(). */
12672  subseg sptr; /* Temporary variable used by tspivot(). */
12673 
12674  if (b->verbose) {
12675  printf(" Marking concavities (external triangles) for elimination.\n");
12676  }
12677  /* Find a triangle handle on the hull. */
12678  hulltri.tri = m->dummytri;
12679  hulltri.orient = 0;
12680  symself(hulltri);
12681  /* Remember where we started so we know when to stop. */
12682  otricopy(hulltri, starttri);
12683  /* Go once counterclockwise around the convex hull. */
12684  do {
12685  /* Ignore triangles that are already infected. */
12686  if (!infected(hulltri)) {
12687  /* Is the triangle protected by a subsegment? */
12688  tspivot(hulltri, hullsubseg);
12689  if (hullsubseg.ss == m->dummysub) {
12690  /* The triangle is not protected; infect it. */
12691  if (!infected(hulltri)) {
12692  infect(hulltri);
12693  deadtriangle = (triangle **) poolalloc(&m->viri);
12694  *deadtriangle = hulltri.tri;
12695  }
12696  } else {
12697  /* The triangle is protected; set boundary markers if appropriate. */
12698  if (mark(hullsubseg) == 0) {
12699  setmark(hullsubseg, 1);
12700  org(hulltri, horg);
12701  dest(hulltri, hdest);
12702  if (vertexmark(horg) == 0) {
12703  setvertexmark(horg, 1);
12704  }
12705  if (vertexmark(hdest) == 0) {
12706  setvertexmark(hdest, 1);
12707  }
12708  }
12709  }
12710  }
12711  /* To find the next hull edge, go clockwise around the next vertex. */
12712  lnextself(hulltri);
12713  oprev(hulltri, nexttri);
12714  while (nexttri.tri != m->dummytri) {
12715  otricopy(nexttri, hulltri);
12716  oprev(hulltri, nexttri);
12717  }
12718  } while (!otriequal(hulltri, starttri));
12719 }
12720 
12721 /*****************************************************************************/
12722 /* */
12723 /* plague() Spread the virus from all infected triangles to any neighbors */
12724 /* not protected by subsegments. Delete all infected triangles. */
12725 /* */
12726 /* This is the procedure that actually creates holes and concavities. */
12727 /* */
12728 /* This procedure operates in two phases. The first phase identifies all */
12729 /* the triangles that will die, and marks them as infected. They are */
12730 /* marked to ensure that each triangle is added to the virus pool only */
12731 /* once, so the procedure will terminate. */
12732 /* */
12733 /* The second phase actually eliminates the infected triangles. It also */
12734 /* eliminates orphaned vertices. */
12735 /* */
12736 /*****************************************************************************/
12737 
12738 #ifdef ANSI_DECLARATORS
12739 void plague(struct mesh *m, struct behavior *b)
12740 #else /* not ANSI_DECLARATORS */
12741 void plague(m, b)
12742 struct mesh *m;
12743 struct behavior *b;
12744 #endif /* not ANSI_DECLARATORS */
12745 
12746 {
12747  struct otri testtri;
12748  struct otri neighbor;
12749  triangle **virusloop;
12750  triangle **deadtriangle;
12751  struct osub neighborsubseg;
12752  vertex testvertex;
12753  vertex norg, ndest;
12754  vertex deadorg, deaddest, deadapex;
12755  int killorg;
12756  triangle ptr; /* Temporary variable used by sym() and onext(). */
12757  subseg sptr; /* Temporary variable used by tspivot(). */
12758 
12759  if (b->verbose) {
12760  printf(" Marking neighbors of marked triangles.\n");
12761  }
12762  /* Loop through all the infected triangles, spreading the virus to */
12763  /* their neighbors, then to their neighbors' neighbors. */
12764  traversalinit(&m->viri);
12765  virusloop = (triangle **) traverse(&m->viri);
12766  while (virusloop != (triangle **) NULL) {
12767  testtri.tri = *virusloop;
12768  /* A triangle is marked as infected by messing with one of its pointers */
12769  /* to subsegments, setting it to an illegal value. Hence, we have to */
12770  /* temporarily uninfect this triangle so that we can examine its */
12771  /* adjacent subsegments. */
12772  uninfect(testtri);
12773  if (b->verbose > 2) {
12774  /* Assign the triangle an orientation for convenience in */
12775  /* checking its vertices. */
12776  testtri.orient = 0;
12777  org(testtri, deadorg);
12778  dest(testtri, deaddest);
12779  apex(testtri, deadapex);
12780  printf(" Checking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
12781  deadorg[0], deadorg[1], deaddest[0], deaddest[1],
12782  deadapex[0], deadapex[1]);
12783  }
12784  /* Check each of the triangle's three neighbors. */
12785  for (testtri.orient = 0; testtri.orient < 3; testtri.orient++) {
12786  /* Find the neighbor. */
12787  sym(testtri, neighbor);
12788  /* Check for a subsegment between the triangle and its neighbor. */
12789  tspivot(testtri, neighborsubseg);
12790  /* Check if the neighbor is nonexistent or already infected. */
12791  if ((neighbor.tri == m->dummytri) || infected(neighbor)) {
12792  if (neighborsubseg.ss != m->dummysub) {
12793  /* There is a subsegment separating the triangle from its */
12794  /* neighbor, but both triangles are dying, so the subsegment */
12795  /* dies too. */
12796  subsegdealloc(m, neighborsubseg.ss);
12797  if (neighbor.tri != m->dummytri) {
12798  /* Make sure the subsegment doesn't get deallocated again */
12799  /* later when the infected neighbor is visited. */
12800  uninfect(neighbor);
12801  tsdissolve(neighbor);
12802  infect(neighbor);
12803  }
12804  }
12805  } else { /* The neighbor exists and is not infected. */
12806  if (neighborsubseg.ss == m->dummysub) {
12807  /* There is no subsegment protecting the neighbor, so */
12808  /* the neighbor becomes infected. */
12809  if (b->verbose > 2) {
12810  org(neighbor, deadorg);
12811  dest(neighbor, deaddest);
12812  apex(neighbor, deadapex);
12813  printf(
12814  " Marking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
12815  deadorg[0], deadorg[1], deaddest[0], deaddest[1],
12816  deadapex[0], deadapex[1]);
12817  }
12818  infect(neighbor);
12819  /* Ensure that the neighbor's neighbors will be infected. */
12820  deadtriangle = (triangle **) poolalloc(&m->viri);
12821  *deadtriangle = neighbor.tri;
12822  } else { /* The neighbor is protected by a subsegment. */
12823  /* Remove this triangle from the subsegment. */
12824  stdissolve(neighborsubseg);
12825  /* The subsegment becomes a boundary. Set markers accordingly. */
12826  if (mark(neighborsubseg) == 0) {
12827  setmark(neighborsubseg, 1);
12828  }
12829  org(neighbor, norg);
12830  dest(neighbor, ndest);
12831  if (vertexmark(norg) == 0) {
12832  setvertexmark(norg, 1);
12833  }
12834  if (vertexmark(ndest) == 0) {
12835  setvertexmark(ndest, 1);
12836  }
12837  }
12838  }
12839  }
12840  /* Remark the triangle as infected, so it doesn't get added to the */
12841  /* virus pool again. */
12842  infect(testtri);
12843  virusloop = (triangle **) traverse(&m->viri);
12844  }
12845 
12846  if (b->verbose) {
12847  printf(" Deleting marked triangles.\n");
12848  }
12849 
12850  traversalinit(&m->viri);
12851  virusloop = (triangle **) traverse(&m->viri);
12852  while (virusloop != (triangle **) NULL) {
12853  testtri.tri = *virusloop;
12854 
12855  /* Check each of the three corners of the triangle for elimination. */
12856  /* This is done by walking around each vertex, checking if it is */
12857  /* still connected to at least one live triangle. */
12858  for (testtri.orient = 0; testtri.orient < 3; testtri.orient++) {
12859  org(testtri, testvertex);
12860  /* Check if the vertex has already been tested. */
12861  if (testvertex != (vertex) NULL) {
12862  killorg = 1;
12863  /* Mark the corner of the triangle as having been tested. */
12864  setorg(testtri, NULL);
12865  /* Walk counterclockwise about the vertex. */
12866  onext(testtri, neighbor);
12867  /* Stop upon reaching a boundary or the starting triangle. */
12868  while ((neighbor.tri != m->dummytri) &&
12869  (!otriequal(neighbor, testtri))) {
12870  if (infected(neighbor)) {
12871  /* Mark the corner of this triangle as having been tested. */
12872  setorg(neighbor, NULL);
12873  } else {
12874  /* A live triangle. The vertex survives. */
12875  killorg = 0;
12876  }
12877  /* Walk counterclockwise about the vertex. */
12878  onextself(neighbor);
12879  }
12880  /* If we reached a boundary, we must walk clockwise as well. */
12881  if (neighbor.tri == m->dummytri) {
12882  /* Walk clockwise about the vertex. */
12883  oprev(testtri, neighbor);
12884  /* Stop upon reaching a boundary. */
12885  while (neighbor.tri != m->dummytri) {
12886  if (infected(neighbor)) {
12887  /* Mark the corner of this triangle as having been tested. */
12888  setorg(neighbor, NULL);
12889  } else {
12890  /* A live triangle. The vertex survives. */
12891  killorg = 0;
12892  }
12893  /* Walk clockwise about the vertex. */
12894  oprevself(neighbor);
12895  }
12896  }
12897  if (killorg) {
12898  if (b->verbose > 1) {
12899  printf(" Deleting vertex (%.12g, %.12g)\n",
12900  testvertex[0], testvertex[1]);
12901  }
12902  setvertextype(testvertex, UNDEADVERTEX);
12903  m->undeads++;
12904  }
12905  }
12906  }
12907 
12908  /* Record changes in the number of boundary edges, and disconnect */
12909  /* dead triangles from their neighbors. */
12910  for (testtri.orient = 0; testtri.orient < 3; testtri.orient++) {
12911  sym(testtri, neighbor);
12912  if (neighbor.tri == m->dummytri) {
12913  /* There is no neighboring triangle on this edge, so this edge */
12914  /* is a boundary edge. This triangle is being deleted, so this */
12915  /* boundary edge is deleted. */
12916  m->hullsize--;
12917  } else {
12918  /* Disconnect the triangle from its neighbor. */
12919  dissolve(neighbor);
12920  /* There is a neighboring triangle on this edge, so this edge */
12921  /* becomes a boundary edge when this triangle is deleted. */
12922  m->hullsize++;
12923  }
12924  }
12925  /* Return the dead triangle to the pool of triangles. */
12926  triangledealloc(m, testtri.tri);
12927  virusloop = (triangle **) traverse(&m->viri);
12928  }
12929  /* Empty the virus pool. */
12930  poolrestart(&m->viri);
12931 }
12932 
12933 /*****************************************************************************/
12934 /* */
12935 /* regionplague() Spread regional attributes and/or area constraints */
12936 /* (from a .poly file) throughout the mesh. */
12937 /* */
12938 /* This procedure operates in two phases. The first phase spreads an */
12939 /* attribute and/or an area constraint through a (segment-bounded) region. */
12940 /* The triangles are marked to ensure that each triangle is added to the */
12941 /* virus pool only once, so the procedure will terminate. */
12942 /* */
12943 /* The second phase uninfects all infected triangles, returning them to */
12944 /* normal. */
12945 /* */
12946 /*****************************************************************************/
12947 
12948 #ifdef ANSI_DECLARATORS
12949 void regionplague(struct mesh *m, struct behavior *b,
12950  REAL attribute, REAL area)
12951 #else /* not ANSI_DECLARATORS */
12952 void regionplague(m, b, attribute, area)
12953 struct mesh *m;
12954 struct behavior *b;
12955 REAL attribute;
12956 REAL area;
12957 #endif /* not ANSI_DECLARATORS */
12958 
12959 {
12960  struct otri testtri;
12961  struct otri neighbor;
12962  triangle **virusloop;
12963  triangle **regiontri;
12964  struct osub neighborsubseg;
12965  vertex regionorg, regiondest, regionapex;
12966  triangle ptr; /* Temporary variable used by sym() and onext(). */
12967  subseg sptr; /* Temporary variable used by tspivot(). */
12968 
12969  if (b->verbose > 1) {
12970  printf(" Marking neighbors of marked triangles.\n");
12971  }
12972  /* Loop through all the infected triangles, spreading the attribute */
12973  /* and/or area constraint to their neighbors, then to their neighbors' */
12974  /* neighbors. */
12975  traversalinit(&m->viri);
12976  virusloop = (triangle **) traverse(&m->viri);
12977  while (virusloop != (triangle **) NULL) {
12978  testtri.tri = *virusloop;
12979  /* A triangle is marked as infected by messing with one of its pointers */
12980  /* to subsegments, setting it to an illegal value. Hence, we have to */
12981  /* temporarily uninfect this triangle so that we can examine its */
12982  /* adjacent subsegments. */
12983  uninfect(testtri);
12984  if (b->regionattrib) {
12985  /* Set an attribute. */
12986  setelemattribute(testtri, m->eextras, attribute);
12987  }
12988  if (b->vararea) {
12989  /* Set an area constraint. */
12990  setareabound(testtri, area);
12991  }
12992  if (b->verbose > 2) {
12993  /* Assign the triangle an orientation for convenience in */
12994  /* checking its vertices. */
12995  testtri.orient = 0;
12996  org(testtri, regionorg);
12997  dest(testtri, regiondest);
12998  apex(testtri, regionapex);
12999  printf(" Checking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
13000  regionorg[0], regionorg[1], regiondest[0], regiondest[1],
13001  regionapex[0], regionapex[1]);
13002  }
13003  /* Check each of the triangle's three neighbors. */
13004  for (testtri.orient = 0; testtri.orient < 3; testtri.orient++) {
13005  /* Find the neighbor. */
13006  sym(testtri, neighbor);
13007  /* Check for a subsegment between the triangle and its neighbor. */
13008  tspivot(testtri, neighborsubseg);
13009  /* Make sure the neighbor exists, is not already infected, and */
13010  /* isn't protected by a subsegment. */
13011  if ((neighbor.tri != m->dummytri) && !infected(neighbor)
13012  && (neighborsubseg.ss == m->dummysub)) {
13013  if (b->verbose > 2) {
13014  org(neighbor, regionorg);
13015  dest(neighbor, regiondest);
13016  apex(neighbor, regionapex);
13017  printf(" Marking (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
13018  regionorg[0], regionorg[1], regiondest[0], regiondest[1],
13019  regionapex[0], regionapex[1]);
13020  }
13021  /* Infect the neighbor. */
13022  infect(neighbor);
13023  /* Ensure that the neighbor's neighbors will be infected. */
13024  regiontri = (triangle **) poolalloc(&m->viri);
13025  *regiontri = neighbor.tri;
13026  }
13027  }
13028  /* Remark the triangle as infected, so it doesn't get added to the */
13029  /* virus pool again. */
13030  infect(testtri);
13031  virusloop = (triangle **) traverse(&m->viri);
13032  }
13033 
13034  /* Uninfect all triangles. */
13035  if (b->verbose > 1) {
13036  printf(" Unmarking marked triangles.\n");
13037  }
13038  traversalinit(&m->viri);
13039  virusloop = (triangle **) traverse(&m->viri);
13040  while (virusloop != (triangle **) NULL) {
13041  testtri.tri = *virusloop;
13042  uninfect(testtri);
13043  virusloop = (triangle **) traverse(&m->viri);
13044  }
13045  /* Empty the virus pool. */
13046  poolrestart(&m->viri);
13047 }
13048 
13049 /*****************************************************************************/
13050 /* */
13051 /* carveholes() Find the holes and infect them. Find the area */
13052 /* constraints and infect them. Infect the convex hull. */
13053 /* Spread the infection and kill triangles. Spread the */
13054 /* area constraints. */
13055 /* */
13056 /* This routine mainly calls other routines to carry out all these */
13057 /* functions. */
13058 /* */
13059 /*****************************************************************************/
13060 
13061 #ifdef ANSI_DECLARATORS
13062 void carveholes(struct mesh *m, struct behavior *b, REAL *holelist, int holes,
13063  REAL *regionlist, int regions)
13064 #else /* not ANSI_DECLARATORS */
13065 void carveholes(m, b, holelist, holes, regionlist, regions)
13066 struct mesh *m;
13067 struct behavior *b;
13068 REAL *holelist;
13069 int holes;
13070 REAL *regionlist;
13071 int regions;
13072 #endif /* not ANSI_DECLARATORS */
13073 
13074 {
13075  struct otri searchtri;
13076  struct otri triangleloop;
13077  struct otri *regiontris;
13078  triangle **holetri;
13079  triangle **regiontri;
13080  vertex searchorg, searchdest;
13081  enum locateresult intersect;
13082  int i;
13083  triangle ptr; /* Temporary variable used by sym(). */
13084 
13085  if (!(b->quiet || (b->noholes && b->convex))) {
13086  printf("Removing unwanted triangles.\n");
13087  if (b->verbose && (holes > 0)) {
13088  printf(" Marking holes for elimination.\n");
13089  }
13090  }
13091 
13092  if (regions > 0) {
13093  /* Allocate storage for the triangles in which region points fall. */
13094  regiontris = (struct otri *) trimalloc(regions *
13095  (int) sizeof(struct otri));
13096  } else {
13097  regiontris = (struct otri *) NULL;
13098  }
13099 
13100  if (((holes > 0) && !b->noholes) || !b->convex || (regions > 0)) {
13101  /* Initialize a pool of viri to be used for holes, concavities, */
13102  /* regional attributes, and/or regional area constraints. */
13103  poolinit(&m->viri, sizeof(triangle *), VIRUSPERBLOCK, VIRUSPERBLOCK, 0);
13104  }
13105 
13106  if (!b->convex) {
13107  /* Mark as infected any unprotected triangles on the boundary. */
13108  /* This is one way by which concavities are created. */
13109  infecthull(m, b);
13110  }
13111 
13112  if ((holes > 0) && !b->noholes) {
13113  /* Infect each triangle in which a hole lies. */
13114  for (i = 0; i < 2 * holes; i += 2) {
13115  /* Ignore holes that aren't within the bounds of the mesh. */
13116  if ((holelist[i] >= m->xmin) && (holelist[i] <= m->xmax)
13117  && (holelist[i + 1] >= m->ymin) && (holelist[i + 1] <= m->ymax)) {
13118  /* Start searching from some triangle on the outer boundary. */
13119  searchtri.tri = m->dummytri;
13120  searchtri.orient = 0;
13121  symself(searchtri);
13122  /* Ensure that the hole is to the left of this boundary edge; */
13123  /* otherwise, locate() will falsely report that the hole */
13124  /* falls within the starting triangle. */
13125  org(searchtri, searchorg);
13126  dest(searchtri, searchdest);
13127  if (counterclockwise(m, b, searchorg, searchdest, &holelist[i]) >
13128  0.0) {
13129  /* Find a triangle that contains the hole. */
13130  intersect = locate(m, b, &holelist[i], &searchtri);
13131  if ((intersect != OUTSIDE) && (!infected(searchtri))) {
13132  /* Infect the triangle. This is done by marking the triangle */
13133  /* as infected and including the triangle in the virus pool. */
13134  infect(searchtri);
13135  holetri = (triangle **) poolalloc(&m->viri);
13136  *holetri = searchtri.tri;
13137  }
13138  }
13139  }
13140  }
13141  }
13142 
13143  /* Now, we have to find all the regions BEFORE we carve the holes, because */
13144  /* locate() won't work when the triangulation is no longer convex. */
13145  /* (Incidentally, this is the reason why regional attributes and area */
13146  /* constraints can't be used when refining a preexisting mesh, which */
13147  /* might not be convex; they can only be used with a freshly */
13148  /* triangulated PSLG.) */
13149  if (regions > 0) {
13150  /* Find the starting triangle for each region. */
13151  for (i = 0; i < regions; i++) {
13152  regiontris[i].tri = m->dummytri;
13153  /* Ignore region points that aren't within the bounds of the mesh. */
13154  if ((regionlist[4 * i] >= m->xmin) && (regionlist[4 * i] <= m->xmax) &&
13155  (regionlist[4 * i + 1] >= m->ymin) &&
13156  (regionlist[4 * i + 1] <= m->ymax)) {
13157  /* Start searching from some triangle on the outer boundary. */
13158  searchtri.tri = m->dummytri;
13159  searchtri.orient = 0;
13160  symself(searchtri);
13161  /* Ensure that the region point is to the left of this boundary */
13162  /* edge; otherwise, locate() will falsely report that the */
13163  /* region point falls within the starting triangle. */
13164  org(searchtri, searchorg);
13165  dest(searchtri, searchdest);
13166  if (counterclockwise(m, b, searchorg, searchdest, &regionlist[4 * i]) >
13167  0.0) {
13168  /* Find a triangle that contains the region point. */
13169  intersect = locate(m, b, &regionlist[4 * i], &searchtri);
13170  if ((intersect != OUTSIDE) && (!infected(searchtri))) {
13171  /* Record the triangle for processing after the */
13172  /* holes have been carved. */
13173  otricopy(searchtri, regiontris[i]);
13174  }
13175  }
13176  }
13177  }
13178  }
13179 
13180  if (m->viri.items > 0) {
13181  /* Carve the holes and concavities. */
13182  plague(m, b);
13183  }
13184  /* The virus pool should be empty now. */
13185 
13186  if (regions > 0) {
13187  if (!b->quiet) {
13188  if (b->regionattrib) {
13189  if (b->vararea) {
13190  printf("Spreading regional attributes and area constraints.\n");
13191  } else {
13192  printf("Spreading regional attributes.\n");
13193  }
13194  } else {
13195  printf("Spreading regional area constraints.\n");
13196  }
13197  }
13198  if (b->regionattrib && !b->refine) {
13199  /* Assign every triangle a regional attribute of zero. */
13200  traversalinit(&m->triangles);
13201  triangleloop.orient = 0;
13202  triangleloop.tri = triangletraverse(m);
13203  while (triangleloop.tri != (triangle *) NULL) {
13204  setelemattribute(triangleloop, m->eextras, 0.0);
13205  triangleloop.tri = triangletraverse(m);
13206  }
13207  }
13208  for (i = 0; i < regions; i++) {
13209  if (regiontris[i].tri != m->dummytri) {
13210  /* Make sure the triangle under consideration still exists. */
13211  /* It may have been eaten by the virus. */
13212  if (!deadtri(regiontris[i].tri)) {
13213  /* Put one triangle in the virus pool. */
13214  infect(regiontris[i]);
13215  regiontri = (triangle **) poolalloc(&m->viri);
13216  *regiontri = regiontris[i].tri;
13217  /* Apply one region's attribute and/or area constraint. */
13218  regionplague(m, b, regionlist[4 * i + 2], regionlist[4 * i + 3]);
13219  /* The virus pool should be empty now. */
13220  }
13221  }
13222  }
13223  if (b->regionattrib && !b->refine) {
13224  /* Note the fact that each triangle has an additional attribute. */
13225  m->eextras++;
13226  }
13227  }
13228 
13229  /* Free up memory. */
13230  if (((holes > 0) && !b->noholes) || !b->convex || (regions > 0)) {
13231  pooldeinit(&m->viri);
13232  }
13233  if (regions > 0) {
13234  trifree((VOID *) regiontris);
13235  }
13236 }
13237 
13240 /********* Carving out holes and concavities ends here *********/
13241 
13242 /********* Mesh quality maintenance begins here *********/
13246 /*****************************************************************************/
13247 /* */
13248 /* tallyencs() Traverse the entire list of subsegments, and check each */
13249 /* to see if it is encroached. If so, add it to the list. */
13250 /* */
13251 /*****************************************************************************/
13252 
13253 #ifndef CDT_ONLY
13254 
13255 #ifdef ANSI_DECLARATORS
13256 void tallyencs(struct mesh *m, struct behavior *b)
13257 #else /* not ANSI_DECLARATORS */
13258 void tallyencs(m, b)
13259 struct mesh *m;
13260 struct behavior *b;
13261 #endif /* not ANSI_DECLARATORS */
13262 
13263 {
13264  struct osub subsegloop;
13265  //int dummy;
13266 
13267  traversalinit(&m->subsegs);
13268  subsegloop.ssorient = 0;
13269  subsegloop.ss = subsegtraverse(m);
13270  while (subsegloop.ss != (subseg *) NULL) {
13271  /* If the segment is encroached, add it to the list. */
13272  // dummy = checkseg4encroach(m, b, &subsegloop); // "dummy =" commented out to get gcc 4.6 working
13273  checkseg4encroach(m, b, &subsegloop); // "dummy =" commented out to get gcc 4.6 working
13274  subsegloop.ss = subsegtraverse(m);
13275  }
13276 }
13277 
13278 #endif /* not CDT_ONLY */
13279 
13280 /*****************************************************************************/
13281 /* */
13282 /* precisionerror() Print an error message for precision problems. */
13283 /* */
13284 /*****************************************************************************/
13285 
13286 #ifndef CDT_ONLY
13287 
13288 void precisionerror()
13289 {
13290  printf("Try increasing the area criterion and/or reducing the minimum\n");
13291  printf(" allowable angle so that tiny triangles are not created.\n");
13292 #ifdef SINGLE
13293  printf("Alternatively, try recompiling me with double precision\n");
13294  printf(" arithmetic (by removing \"#define SINGLE\" from the\n");
13295  printf(" source file or \"-DSINGLE\" from the makefile).\n");
13296 #endif /* SINGLE */
13297 }
13298 
13299 #endif /* not CDT_ONLY */
13300 
13301 /*****************************************************************************/
13302 /* */
13303 /* splitencsegs() Split all the encroached subsegments. */
13304 /* */
13305 /* Each encroached subsegment is repaired by splitting it - inserting a */
13306 /* vertex at or near its midpoint. Newly inserted vertices may encroach */
13307 /* upon other subsegments; these are also repaired. */
13308 /* */
13309 /* `triflaws' is a flag that specifies whether one should take note of new */
13310 /* bad triangles that result from inserting vertices to repair encroached */
13311 /* subsegments. */
13312 /* */
13313 /*****************************************************************************/
13314 
13315 #ifndef CDT_ONLY
13316 
13317 #ifdef ANSI_DECLARATORS
13318 void splitencsegs(struct mesh *m, struct behavior *b, int triflaws)
13319 #else /* not ANSI_DECLARATORS */
13320 void splitencsegs(m, b, triflaws)
13321 struct mesh *m;
13322 struct behavior *b;
13323 int triflaws;
13324 #endif /* not ANSI_DECLARATORS */
13325 
13326 {
13327  struct otri enctri;
13328  struct otri testtri;
13329  struct osub testsh;
13330  struct osub currentenc;
13331  struct badsubseg *encloop;
13332  vertex eorg, edest, eapex;
13333  vertex newvertex;
13334  enum insertvertexresult success;
13335  REAL segmentlength, nearestpoweroftwo;
13336  REAL split;
13337  REAL multiplier, divisor;
13338  int acuteorg, acuteorg2, acutedest, acutedest2;
13339  //int dummy;
13340  int i;
13341  triangle ptr; /* Temporary variable used by stpivot(). */
13342  subseg sptr; /* Temporary variable used by snext(). */
13343 
13344  /* Note that steinerleft == -1 if an unlimited number */
13345  /* of Steiner points is allowed. */
13346  while ((m->badsubsegs.items > 0) && (m->steinerleft != 0)) {
13347  traversalinit(&m->badsubsegs);
13348  encloop = badsubsegtraverse(m);
13349  while ((encloop != (struct badsubseg *) NULL) && (m->steinerleft != 0)) {
13350  sdecode(encloop->encsubseg, currentenc);
13351  sorg(currentenc, eorg);
13352  sdest(currentenc, edest);
13353  /* Make sure that this segment is still the same segment it was */
13354  /* when it was determined to be encroached. If the segment was */
13355  /* enqueued multiple times (because several newly inserted */
13356  /* vertices encroached it), it may have already been split. */
13357  if (!deadsubseg(currentenc.ss) &&
13358  (eorg == encloop->subsegorg) && (edest == encloop->subsegdest)) {
13359  /* To decide where to split a segment, we need to know if the */
13360  /* segment shares an endpoint with an adjacent segment. */
13361  /* The concern is that, if we simply split every encroached */
13362  /* segment in its center, two adjacent segments with a small */
13363  /* angle between them might lead to an infinite loop; each */
13364  /* vertex added to split one segment will encroach upon the */
13365  /* other segment, which must then be split with a vertex that */
13366  /* will encroach upon the first segment, and so on forever. */
13367  /* To avoid this, imagine a set of concentric circles, whose */
13368  /* radii are powers of two, about each segment endpoint. */
13369  /* These concentric circles determine where the segment is */
13370  /* split. (If both endpoints are shared with adjacent */
13371  /* segments, split the segment in the middle, and apply the */
13372  /* concentric circles for later splittings.) */
13373 
13374  /* Is the origin shared with another segment? */
13375  stpivot(currentenc, enctri);
13376  lnext(enctri, testtri);
13377  tspivot(testtri, testsh);
13378  acuteorg = testsh.ss != m->dummysub;
13379  /* Is the destination shared with another segment? */
13380  lnextself(testtri);
13381  tspivot(testtri, testsh);
13382  acutedest = testsh.ss != m->dummysub;
13383 
13384  /* If we're using Chew's algorithm (rather than Ruppert's) */
13385  /* to define encroachment, delete free vertices from the */
13386  /* subsegment's diametral circle. */
13387  if (!b->conformdel && !acuteorg && !acutedest) {
13388  apex(enctri, eapex);
13389  while ((vertextype(eapex) == FREEVERTEX) &&
13390  ((eorg[0] - eapex[0]) * (edest[0] - eapex[0]) +
13391  (eorg[1] - eapex[1]) * (edest[1] - eapex[1]) < 0.0)) {
13392  deletevertex(m, b, &testtri);
13393  stpivot(currentenc, enctri);
13394  apex(enctri, eapex);
13395  lprev(enctri, testtri);
13396  }
13397  }
13398 
13399  /* Now, check the other side of the segment, if there's a triangle */
13400  /* there. */
13401  sym(enctri, testtri);
13402  if (testtri.tri != m->dummytri) {
13403  /* Is the destination shared with another segment? */
13404  lnextself(testtri);
13405  tspivot(testtri, testsh);
13406  acutedest2 = testsh.ss != m->dummysub;
13407  acutedest = acutedest || acutedest2;
13408  /* Is the origin shared with another segment? */
13409  lnextself(testtri);
13410  tspivot(testtri, testsh);
13411  acuteorg2 = testsh.ss != m->dummysub;
13412  acuteorg = acuteorg || acuteorg2;
13413 
13414  /* Delete free vertices from the subsegment's diametral circle. */
13415  if (!b->conformdel && !acuteorg2 && !acutedest2) {
13416  org(testtri, eapex);
13417  while ((vertextype(eapex) == FREEVERTEX) &&
13418  ((eorg[0] - eapex[0]) * (edest[0] - eapex[0]) +
13419  (eorg[1] - eapex[1]) * (edest[1] - eapex[1]) < 0.0)) {
13420  deletevertex(m, b, &testtri);
13421  sym(enctri, testtri);
13422  apex(testtri, eapex);
13423  lprevself(testtri);
13424  }
13425  }
13426  }
13427 
13428  /* Use the concentric circles if exactly one endpoint is shared */
13429  /* with another adjacent segment. */
13430  if (acuteorg || acutedest) {
13431  segmentlength = sqrt((edest[0] - eorg[0]) * (edest[0] - eorg[0]) +
13432  (edest[1] - eorg[1]) * (edest[1] - eorg[1]));
13433  /* Find the power of two that most evenly splits the segment. */
13434  /* The worst case is a 2:1 ratio between subsegment lengths. */
13435  nearestpoweroftwo = 1.0;
13436  while (segmentlength > 3.0 * nearestpoweroftwo) {
13437  nearestpoweroftwo *= 2.0;
13438  }
13439  while (segmentlength < 1.5 * nearestpoweroftwo) {
13440  nearestpoweroftwo *= 0.5;
13441  }
13442  /* Where do we split the segment? */
13443  split = nearestpoweroftwo / segmentlength;
13444  if (acutedest) {
13445  split = 1.0 - split;
13446  }
13447  } else {
13448  /* If we're not worried about adjacent segments, split */
13449  /* this segment in the middle. */
13450  split = 0.5;
13451  }
13452 
13453  /* Create the new vertex. */
13454  newvertex = (vertex) poolalloc(&m->vertices);
13455  /* Interpolate its coordinate and attributes. */
13456  for (i = 0; i < 2 + m->nextras; i++) {
13457  newvertex[i] = eorg[i] + split * (edest[i] - eorg[i]);
13458  }
13459 
13460  if (!b->noexact) {
13461  /* Roundoff in the above calculation may yield a `newvertex' */
13462  /* that is not precisely collinear with `eorg' and `edest'. */
13463  /* Improve collinearity by one step of iterative refinement. */
13464  multiplier = counterclockwise(m, b, eorg, edest, newvertex);
13465  divisor = ((eorg[0] - edest[0]) * (eorg[0] - edest[0]) +
13466  (eorg[1] - edest[1]) * (eorg[1] - edest[1]));
13467  if ((multiplier != 0.0) && (divisor != 0.0)) {
13468  multiplier = multiplier / divisor;
13469  /* Watch out for NANs. */
13470  if (multiplier == multiplier) {
13471  newvertex[0] += multiplier * (edest[1] - eorg[1]);
13472  newvertex[1] += multiplier * (eorg[0] - edest[0]);
13473  }
13474  }
13475  }
13476 
13477  setvertexmark(newvertex, mark(currentenc));
13478  setvertextype(newvertex, SEGMENTVERTEX);
13479  if (b->verbose > 1) {
13480  printf(
13481  " Splitting subsegment (%.12g, %.12g) (%.12g, %.12g) at (%.12g, %.12g).\n",
13482  eorg[0], eorg[1], edest[0], edest[1],
13483  newvertex[0], newvertex[1]);
13484  }
13485  /* Check whether the new vertex lies on an endpoint. */
13486  if (((newvertex[0] == eorg[0]) && (newvertex[1] == eorg[1])) ||
13487  ((newvertex[0] == edest[0]) && (newvertex[1] == edest[1]))) {
13488  printf("Error: Ran out of precision at (%.12g, %.12g).\n",
13489  newvertex[0], newvertex[1]);
13490  printf("I attempted to split a segment to a smaller size than\n");
13491  printf(" can be accommodated by the finite precision of\n");
13492  printf(" floating point arithmetic.\n");
13493  precisionerror();
13494  triexit(1);
13495  }
13496  /* Insert the splitting vertex. This should always succeed. */
13497  success = insertvertex(m, b, newvertex, &enctri, &currentenc,
13498  1, triflaws);
13499  if ((success != SUCCESSFULVERTEX) && (success != ENCROACHINGVERTEX)) {
13500  printf("Internal error in splitencsegs():\n");
13501  printf(" Failure to split a segment.\n");
13502  internalerror();
13503  }
13504  if (m->steinerleft > 0) {
13505  m->steinerleft--;
13506  }
13507  /* Check the two new subsegments to see if they're encroached. */
13508  //dummy = checkseg4encroach(m, b, &currentenc); // commented out to get gcc 4.6 working
13509  checkseg4encroach(m, b, &currentenc); // "dummy =" commented out to get gcc 4.6 working
13510  snextself(currentenc);
13511  //dummy = checkseg4encroach(m, b, &currentenc); // commented out to get gcc 4.6 working
13512  checkseg4encroach(m, b, &currentenc); // "dummy =" commented out to get gcc 4.6 working
13513  }
13514 
13515  badsubsegdealloc(m, encloop);
13516  encloop = badsubsegtraverse(m);
13517  }
13518  }
13519 }
13520 
13521 #endif /* not CDT_ONLY */
13522 
13523 /*****************************************************************************/
13524 /* */
13525 /* tallyfaces() Test every triangle in the mesh for quality measures. */
13526 /* */
13527 /*****************************************************************************/
13528 
13529 #ifndef CDT_ONLY
13530 
13531 #ifdef ANSI_DECLARATORS
13532 void tallyfaces(struct mesh *m, struct behavior *b)
13533 #else /* not ANSI_DECLARATORS */
13534 void tallyfaces(m, b)
13535 struct mesh *m;
13536 struct behavior *b;
13537 #endif /* not ANSI_DECLARATORS */
13538 
13539 {
13540  struct otri triangleloop;
13541 
13542  if (b->verbose) {
13543  printf(" Making a list of bad triangles.\n");
13544  }
13545  traversalinit(&m->triangles);
13546  triangleloop.orient = 0;
13547  triangleloop.tri = triangletraverse(m);
13548  while (triangleloop.tri != (triangle *) NULL) {
13549  /* If the triangle is bad, enqueue it. */
13550  testtriangle(m, b, &triangleloop);
13551  triangleloop.tri = triangletraverse(m);
13552  }
13553 }
13554 
13555 #endif /* not CDT_ONLY */
13556 
13557 /*****************************************************************************/
13558 /* */
13559 /* splittriangle() Inserts a vertex at the circumcenter of a triangle. */
13560 /* Deletes the newly inserted vertex if it encroaches */
13561 /* upon a segment. */
13562 /* */
13563 /*****************************************************************************/
13564 
13565 #ifndef CDT_ONLY
13566 
13567 #ifdef ANSI_DECLARATORS
13568 void splittriangle(struct mesh *m, struct behavior *b,
13569  struct badtriang *badtri)
13570 #else /* not ANSI_DECLARATORS */
13571 void splittriangle(m, b, badtri)
13572 struct mesh *m;
13573 struct behavior *b;
13574 struct badtriang *badtri;
13575 #endif /* not ANSI_DECLARATORS */
13576 
13577 {
13578  struct otri badotri;
13579  vertex borg, bdest, bapex;
13580  vertex newvertex;
13581  REAL xi, eta;
13582  enum insertvertexresult success;
13583  int errorflag;
13584  int i;
13585 
13586  decode(badtri->poortri, badotri);
13587  org(badotri, borg);
13588  dest(badotri, bdest);
13589  apex(badotri, bapex);
13590  /* Make sure that this triangle is still the same triangle it was */
13591  /* when it was tested and determined to be of bad quality. */
13592  /* Subsequent transformations may have made it a different triangle. */
13593  if (!deadtri(badotri.tri) && (borg == badtri->triangorg) &&
13594  (bdest == badtri->triangdest) && (bapex == badtri->triangapex)) {
13595  if (b->verbose > 1) {
13596  printf(" Splitting this triangle at its circumcenter:\n");
13597  printf(" (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n", borg[0],
13598  borg[1], bdest[0], bdest[1], bapex[0], bapex[1]);
13599  }
13600 
13601  errorflag = 0;
13602  /* Create a new vertex at the triangle's circumcenter. */
13603  newvertex = (vertex) poolalloc(&m->vertices);
13604  findcircumcenter(m, b, borg, bdest, bapex, newvertex, &xi, &eta, 1);
13605 
13606  /* Check whether the new vertex lies on a triangle vertex. */
13607  if (((newvertex[0] == borg[0]) && (newvertex[1] == borg[1])) ||
13608  ((newvertex[0] == bdest[0]) && (newvertex[1] == bdest[1])) ||
13609  ((newvertex[0] == bapex[0]) && (newvertex[1] == bapex[1]))) {
13610  if (!b->quiet) {
13611  printf(
13612  "Warning: New vertex (%.12g, %.12g) falls on existing vertex.\n",
13613  newvertex[0], newvertex[1]);
13614  errorflag = 1;
13615  }
13616  vertexdealloc(m, newvertex);
13617  } else {
13618  for (i = 2; i < 2 + m->nextras; i++) {
13619  /* Interpolate the vertex attributes at the circumcenter. */
13620  newvertex[i] = borg[i] + xi * (bdest[i] - borg[i])
13621  + eta * (bapex[i] - borg[i]);
13622  }
13623  /* The new vertex must be in the interior, and therefore is a */
13624  /* free vertex with a marker of zero. */
13625  setvertexmark(newvertex, 0);
13626  setvertextype(newvertex, FREEVERTEX);
13627 
13628  /* Ensure that the handle `badotri' does not represent the longest */
13629  /* edge of the triangle. This ensures that the circumcenter must */
13630  /* fall to the left of this edge, so point location will work. */
13631  /* (If the angle org-apex-dest exceeds 90 degrees, then the */
13632  /* circumcenter lies outside the org-dest edge, and eta is */
13633  /* negative. Roundoff error might prevent eta from being */
13634  /* negative when it should be, so I test eta against xi.) */
13635  if (eta < xi) {
13636  lprevself(badotri);
13637  }
13638 
13639  /* Insert the circumcenter, searching from the edge of the triangle, */
13640  /* and maintain the Delaunay property of the triangulation. */
13641  success = insertvertex(m, b, newvertex, &badotri, (struct osub *) NULL,
13642  1, 1);
13643  if (success == SUCCESSFULVERTEX) {
13644  if (m->steinerleft > 0) {
13645  m->steinerleft--;
13646  }
13647  } else if (success == ENCROACHINGVERTEX) {
13648  /* If the newly inserted vertex encroaches upon a subsegment, */
13649  /* delete the new vertex. */
13650  undovertex(m, b);
13651  if (b->verbose > 1) {
13652  printf(" Rejecting (%.12g, %.12g).\n", newvertex[0], newvertex[1]);
13653  }
13654  vertexdealloc(m, newvertex);
13655  } else if (success == VIOLATINGVERTEX) {
13656  /* Failed to insert the new vertex, but some subsegment was */
13657  /* marked as being encroached. */
13658  vertexdealloc(m, newvertex);
13659  } else { /* success == DUPLICATEVERTEX */
13660  /* Couldn't insert the new vertex because a vertex is already there. */
13661  if (!b->quiet) {
13662  printf(
13663  "Warning: New vertex (%.12g, %.12g) falls on existing vertex.\n",
13664  newvertex[0], newvertex[1]);
13665  errorflag = 1;
13666  }
13667  vertexdealloc(m, newvertex);
13668  }
13669  }
13670  if (errorflag) {
13671  if (b->verbose) {
13672  printf(" The new vertex is at the circumcenter of triangle\n");
13673  printf(" (%.12g, %.12g) (%.12g, %.12g) (%.12g, %.12g)\n",
13674  borg[0], borg[1], bdest[0], bdest[1], bapex[0], bapex[1]);
13675  }
13676  printf("This probably means that I am trying to refine triangles\n");
13677  printf(" to a smaller size than can be accommodated by the finite\n");
13678  printf(" precision of floating point arithmetic. (You can be\n");
13679  printf(" sure of this if I fail to terminate.)\n");
13680  precisionerror();
13681  }
13682  }
13683 }
13684 
13685 #endif /* not CDT_ONLY */
13686 
13687 /*****************************************************************************/
13688 /* */
13689 /* enforcequality() Remove all the encroached subsegments and bad */
13690 /* triangles from the triangulation. */
13691 /* */
13692 /*****************************************************************************/
13693 
13694 #ifndef CDT_ONLY
13695 
13696 #ifdef ANSI_DECLARATORS
13697 void enforcequality(struct mesh *m, struct behavior *b)
13698 #else /* not ANSI_DECLARATORS */
13699 void enforcequality(m, b)
13700 struct mesh *m;
13701 struct behavior *b;
13702 #endif /* not ANSI_DECLARATORS */
13703 
13704 {
13705  struct badtriang *badtri;
13706  int i;
13707 
13708  if (!b->quiet) {
13709  printf("Adding Steiner points to enforce quality.\n");
13710  }
13711  /* Initialize the pool of encroached subsegments. */
13712  poolinit(&m->badsubsegs, sizeof(struct badsubseg), BADSUBSEGPERBLOCK,
13713  BADSUBSEGPERBLOCK, 0);
13714  if (b->verbose) {
13715  printf(" Looking for encroached subsegments.\n");
13716  }
13717  /* Test all segments to see if they're encroached. */
13718  tallyencs(m, b);
13719  if (b->verbose && (m->badsubsegs.items > 0)) {
13720  printf(" Splitting encroached subsegments.\n");
13721  }
13722  /* Fix encroached subsegments without noting bad triangles. */
13723  splitencsegs(m, b, 0);
13724  /* At this point, if we haven't run out of Steiner points, the */
13725  /* triangulation should be (conforming) Delaunay. */
13726 
13727  /* Next, we worry about enforcing triangle quality. */
13728  if ((b->minangle > 0.0) || b->vararea || b->fixedarea || b->usertest) {
13729  /* Initialize the pool of bad triangles. */
13730  poolinit(&m->badtriangles, sizeof(struct badtriang), BADTRIPERBLOCK,
13731  BADTRIPERBLOCK, 0);
13732  /* Initialize the queues of bad triangles. */
13733  for (i = 0; i < 4096; i++) {
13734  m->queuefront[i] = (struct badtriang *) NULL;
13735  }
13736  m->firstnonemptyq = -1;
13737  /* Test all triangles to see if they're bad. */
13738  tallyfaces(m, b);
13739  /* Initialize the pool of recently flipped triangles. */
13740  poolinit(&m->flipstackers, sizeof(struct flipstacker), FLIPSTACKERPERBLOCK,
13741  FLIPSTACKERPERBLOCK, 0);
13742  m->checkquality = 1;
13743  if (b->verbose) {
13744  printf(" Splitting bad triangles.\n");
13745  }
13746  while ((m->badtriangles.items > 0) && (m->steinerleft != 0)) {
13747  /* Fix one bad triangle by inserting a vertex at its circumcenter. */
13748  badtri = dequeuebadtriang(m);
13749  splittriangle(m, b, badtri);
13750  if (m->badsubsegs.items > 0) {
13751  /* Put bad triangle back in queue for another try later. */
13752  enqueuebadtriang(m, b, badtri);
13753  /* Fix any encroached subsegments that resulted. */
13754  /* Record any new bad triangles that result. */
13755  splitencsegs(m, b, 1);
13756  } else {
13757  /* Return the bad triangle to the pool. */
13758  pooldealloc(&m->badtriangles, (VOID *) badtri);
13759  }
13760  }
13761  }
13762  /* At this point, if the "-D" switch was selected and we haven't run out */
13763  /* of Steiner points, the triangulation should be (conforming) Delaunay */
13764  /* and have no low-quality triangles. */
13765 
13766  /* Might we have run out of Steiner points too soon? */
13767  if (!b->quiet && b->conformdel && (m->badsubsegs.items > 0) &&
13768  (m->steinerleft == 0)) {
13769  printf("\nWarning: I ran out of Steiner points, but the mesh has\n");
13770  if (m->badsubsegs.items == 1) {
13771  printf(" one encroached subsegment, and therefore might not be truly\n"
13772  );
13773  } else {
13774  printf(" %ld encroached subsegments, and therefore might not be truly\n"
13775  , m->badsubsegs.items);
13776  }
13777  printf(" Delaunay. If the Delaunay property is important to you,\n");
13778  printf(" try increasing the number of Steiner points (controlled by\n");
13779  printf(" the -S switch) slightly and try again.\n\n");
13780  }
13781 }
13782 
13783 #endif /* not CDT_ONLY */
13784 
13787 /********* Mesh quality maintenance ends here *********/
13788 
13789 /*****************************************************************************/
13790 /* */
13791 /* highorder() Create extra nodes for quadratic subparametric elements. */
13792 /* */
13793 /*****************************************************************************/
13794 
13795 #ifdef ANSI_DECLARATORS
13796 void highorder(struct mesh *m, struct behavior *b)
13797 #else /* not ANSI_DECLARATORS */
13798 void highorder(m, b)
13799 struct mesh *m;
13800 struct behavior *b;
13801 #endif /* not ANSI_DECLARATORS */
13802 
13803 {
13804  struct otri triangleloop, trisym;
13805  struct osub checkmark;
13806  vertex newvertex;
13807  vertex torg, tdest;
13808  int i;
13809  triangle ptr; /* Temporary variable used by sym(). */
13810  subseg sptr; /* Temporary variable used by tspivot(). */
13811 
13812  if (!b->quiet) {
13813  printf("Adding vertices for second-order triangles.\n");
13814  }
13815  /* The following line ensures that dead items in the pool of nodes */
13816  /* cannot be allocated for the extra nodes associated with high */
13817  /* order elements. This ensures that the primary nodes (at the */
13818  /* corners of elements) will occur earlier in the output files, and */
13819  /* have lower indices, than the extra nodes. */
13820  m->vertices.deaditemstack = (VOID *) NULL;
13821 
13822  traversalinit(&m->triangles);
13823  triangleloop.tri = triangletraverse(m);
13824  /* To loop over the set of edges, loop over all triangles, and look at */
13825  /* the three edges of each triangle. If there isn't another triangle */
13826  /* adjacent to the edge, operate on the edge. If there is another */
13827  /* adjacent triangle, operate on the edge only if the current triangle */
13828  /* has a smaller pointer than its neighbor. This way, each edge is */
13829  /* considered only once. */
13830  while (triangleloop.tri != (triangle *) NULL) {
13831  for (triangleloop.orient = 0; triangleloop.orient < 3;
13832  triangleloop.orient++) {
13833  sym(triangleloop, trisym);
13834  if ((triangleloop.tri < trisym.tri) || (trisym.tri == m->dummytri)) {
13835  org(triangleloop, torg);
13836  dest(triangleloop, tdest);
13837  /* Create a new node in the middle of the edge. Interpolate */
13838  /* its attributes. */
13839  newvertex = (vertex) poolalloc(&m->vertices);
13840  for (i = 0; i < 2 + m->nextras; i++) {
13841  newvertex[i] = 0.5 * (torg[i] + tdest[i]);
13842  }
13843  /* Set the new node's marker to zero or one, depending on */
13844  /* whether it lies on a boundary. */
13845  setvertexmark(newvertex, trisym.tri == m->dummytri);
13846  setvertextype(newvertex,
13847  trisym.tri == m->dummytri ? FREEVERTEX : SEGMENTVERTEX);
13848  if (b->usesegments) {
13849  tspivot(triangleloop, checkmark);
13850  /* If this edge is a segment, transfer the marker to the new node. */
13851  if (checkmark.ss != m->dummysub) {
13852  setvertexmark(newvertex, mark(checkmark));
13853  setvertextype(newvertex, SEGMENTVERTEX);
13854  }
13855  }
13856  if (b->verbose > 1) {
13857  printf(" Creating (%.12g, %.12g).\n", newvertex[0], newvertex[1]);
13858  }
13859  /* Record the new node in the (one or two) adjacent elements. */
13860  triangleloop.tri[m->highorderindex + triangleloop.orient] =
13861  (triangle) newvertex;
13862  if (trisym.tri != m->dummytri) {
13863  trisym.tri[m->highorderindex + trisym.orient] = (triangle) newvertex;
13864  }
13865  }
13866  }
13867  triangleloop.tri = triangletraverse(m);
13868  }
13869 }
13870 
13871 /********* File I/O routines begin here *********/
13875 /*****************************************************************************/
13876 /* */
13877 /* readline() Read a nonempty line from a file. */
13878 /* */
13879 /* A line is considered "nonempty" if it contains something that looks like */
13880 /* a number. Comments (prefaced by `#') are ignored. */
13881 /* */
13882 /*****************************************************************************/
13883 
13884 #ifndef TRILIBRARY
13885 
13886 #ifdef ANSI_DECLARATORS
13887 char *readline(char *string, FILE *infile, char *infilename)
13888 #else /* not ANSI_DECLARATORS */
13889 char *readline(string, infile, infilename)
13890 char *string;
13891 FILE *infile;
13892 char *infilename;
13893 #endif /* not ANSI_DECLARATORS */
13894 
13895 {
13896  char *result;
13897 
13898  /* Search for something that looks like a number. */
13899  do {
13900  result = fgets(string, INPUTLINESIZE, infile);
13901  if (result == (char *) NULL) {
13902  printf(" Error: Unexpected end of file in %s.\n", infilename);
13903  triexit(1);
13904  }
13905  /* Skip anything that doesn't look like a number, a comment, */
13906  /* or the end of a line. */
13907  while ((*result != '\0') && (*result != '#')
13908  && (*result != '.') && (*result != '+') && (*result != '-')
13909  && ((*result < '0') || (*result > '9'))) {
13910  result++;
13911  }
13912  /* If it's a comment or end of line, read another line and try again. */
13913  } while ((*result == '#') || (*result == '\0'));
13914  return result;
13915 }
13916 
13917 #endif /* not TRILIBRARY */
13918 
13919 /*****************************************************************************/
13920 /* */
13921 /* findfield() Find the next field of a string. */
13922 /* */
13923 /* Jumps past the current field by searching for whitespace, then jumps */
13924 /* past the whitespace to find the next field. */
13925 /* */
13926 /*****************************************************************************/
13927 
13928 #ifndef TRILIBRARY
13929 
13930 #ifdef ANSI_DECLARATORS
13931 char *findfield(char *string)
13932 #else /* not ANSI_DECLARATORS */
13933 char *findfield(string)
13934 char *string;
13935 #endif /* not ANSI_DECLARATORS */
13936 
13937 {
13938  char *result;
13939 
13940  result = string;
13941  /* Skip the current field. Stop upon reaching whitespace. */
13942  while ((*result != '\0') && (*result != '#')
13943  && (*result != ' ') && (*result != '\t')) {
13944  result++;
13945  }
13946  /* Now skip the whitespace and anything else that doesn't look like a */
13947  /* number, a comment, or the end of a line. */
13948  while ((*result != '\0') && (*result != '#')
13949  && (*result != '.') && (*result != '+') && (*result != '-')
13950  && ((*result < '0') || (*result > '9'))) {
13951  result++;
13952  }
13953  /* Check for a comment (prefixed with `#'). */
13954  if (*result == '#') {
13955  *result = '\0';
13956  }
13957  return result;
13958 }
13959 
13960 #endif /* not TRILIBRARY */
13961 
13962 /*****************************************************************************/
13963 /* */
13964 /* readnodes() Read the vertices from a file, which may be a .node or */
13965 /* .poly file. */
13966 /* */
13967 /*****************************************************************************/
13968 
13969 #ifndef TRILIBRARY
13970 
13971 #ifdef ANSI_DECLARATORS
13972 void readnodes(struct mesh *m, struct behavior *b, char *nodefilename,
13973  char* polyfilename, FILE **polyfile)
13974 #else /* not ANSI_DECLARATORS */
13975 void readnodes(m, b, nodefilename, polyfilename, polyfile)
13976 struct mesh *m;
13977 struct behavior *b;
13978 char *nodefilename;
13979 char* polyfilename;
13980 FILE **polyfile;
13981 #endif /* not ANSI_DECLARATORS */
13982 
13983 {
13984  FILE *infile;
13985  vertex vertexloop;
13986  char inputline[INPUTLINESIZE];
13987  char *stringptr;
13988  char *infilename;
13989  REAL x, y;
13990  int firstnode;
13991  int nodemarkers;
13992  int currentmarker;
13993  int i, j;
13994 
13995  if (b->poly) {
13996  /* Read the vertices from a .poly file. */
13997  if (!b->quiet) {
13998  printf("Opening %s.\n", polyfilename);
13999  }
14000  * polyfile = fopen(polyfilename, "r");
14001  if (*polyfile == (FILE *) NULL) {
14002  printf(" Error: Cannot access file %s.\n", polyfilename);
14003  triexit(1);
14004  }
14005  /* Read number of vertices, number of dimensions, number of vertex */
14006  /* attributes, and number of boundary markers. */
14007  stringptr = readline(inputline,* polyfile, polyfilename);
14008  m->invertices = (int) strtol(stringptr, &stringptr, 0);
14009  stringptr = findfield(stringptr);
14010  if (*stringptr == '\0') {
14011  m->mesh_dim = 2;
14012  } else {
14013  m->mesh_dim = (int) strtol(stringptr, &stringptr, 0);
14014  }
14015  stringptr = findfield(stringptr);
14016  if (*stringptr == '\0') {
14017  m->nextras = 0;
14018  } else {
14019  m->nextras = (int) strtol(stringptr, &stringptr, 0);
14020  }
14021  stringptr = findfield(stringptr);
14022  if (*stringptr == '\0') {
14023  nodemarkers = 0;
14024  } else {
14025  nodemarkers = (int) strtol(stringptr, &stringptr, 0);
14026  }
14027  if (m->invertices > 0) {
14028  infile =* polyfile;
14029  infilename = polyfilename;
14030  m->readnodefile = 0;
14031  } else {
14032  /* If the .poly file claims there are zero vertices, that means that */
14033  /* the vertices should be read from a separate .node file. */
14034  m->readnodefile = 1;
14035  infilename = nodefilename;
14036  }
14037  } else {
14038  m->readnodefile = 1;
14039  infilename = nodefilename;
14040  * polyfile = (FILE *) NULL;
14041  }
14042 
14043  if (m->readnodefile) {
14044  /* Read the vertices from a .node file. */
14045  if (!b->quiet) {
14046  printf("Opening %s.\n", nodefilename);
14047  }
14048  infile = fopen(nodefilename, "r");
14049  if (infile == (FILE *) NULL) {
14050  printf(" Error: Cannot access file %s.\n", nodefilename);
14051  triexit(1);
14052  }
14053  /* Read number of vertices, number of dimensions, number of vertex */
14054  /* attributes, and number of boundary markers. */
14055  stringptr = readline(inputline, infile, nodefilename);
14056  m->invertices = (int) strtol(stringptr, &stringptr, 0);
14057  stringptr = findfield(stringptr);
14058  if (*stringptr == '\0') {
14059  m->mesh_dim = 2;
14060  } else {
14061  m->mesh_dim = (int) strtol(stringptr, &stringptr, 0);
14062  }
14063  stringptr = findfield(stringptr);
14064  if (*stringptr == '\0') {
14065  m->nextras = 0;
14066  } else {
14067  m->nextras = (int) strtol(stringptr, &stringptr, 0);
14068  }
14069  stringptr = findfield(stringptr);
14070  if (*stringptr == '\0') {
14071  nodemarkers = 0;
14072  } else {
14073  nodemarkers = (int) strtol(stringptr, &stringptr, 0);
14074  }
14075  }
14076 
14077  if (m->invertices < 3) {
14078  printf("Error: Input must have at least three input vertices.\n");
14079  triexit(1);
14080  }
14081  if (m->mesh_dim != 2) {
14082  printf("Error: Triangle only works with two-dimensional meshes.\n");
14083  triexit(1);
14084  }
14085  if (m->nextras == 0) {
14086  b->weighted = 0;
14087  }
14088 
14089  initializevertexpool(m, b);
14090 
14091  /* Read the vertices. */
14092  for (i = 0; i < m->invertices; i++) {
14093  vertexloop = (vertex) poolalloc(&m->vertices);
14094  stringptr = readline(inputline, infile, infilename);
14095  if (i == 0) {
14096  firstnode = (int) strtol(stringptr, &stringptr, 0);
14097  if ((firstnode == 0) || (firstnode == 1)) {
14098  b->firstnumber = firstnode;
14099  }
14100  }
14101  stringptr = findfield(stringptr);
14102  if (*stringptr == '\0') {
14103  printf("Error: Vertex %d has no x coordinate.\n", b->firstnumber + i);
14104  triexit(1);
14105  }
14106  x = (REAL) strtod(stringptr, &stringptr);
14107  stringptr = findfield(stringptr);
14108  if (*stringptr == '\0') {
14109  printf("Error: Vertex %d has no y coordinate.\n", b->firstnumber + i);
14110  triexit(1);
14111  }
14112  y = (REAL) strtod(stringptr, &stringptr);
14113  vertexloop[0] = x;
14114  vertexloop[1] = y;
14115  /* Read the vertex attributes. */
14116  for (j = 2; j < 2 + m->nextras; j++) {
14117  stringptr = findfield(stringptr);
14118  if (*stringptr == '\0') {
14119  vertexloop[j] = 0.0;
14120  } else {
14121  vertexloop[j] = (REAL) strtod(stringptr, &stringptr);
14122  }
14123  }
14124  if (nodemarkers) {
14125  /* Read a vertex marker. */
14126  stringptr = findfield(stringptr);
14127  if (*stringptr == '\0') {
14128  setvertexmark(vertexloop, 0);
14129  } else {
14130  currentmarker = (int) strtol(stringptr, &stringptr, 0);
14131  setvertexmark(vertexloop, currentmarker);
14132  }
14133  } else {
14134  /* If no markers are specified in the file, they default to zero. */
14135  setvertexmark(vertexloop, 0);
14136  }
14137  setvertextype(vertexloop, INPUTVERTEX);
14138  /* Determine the smallest and largest x and y coordinates. */
14139  if (i == 0) {
14140  m->xmin = m->xmax = x;
14141  m->ymin = m->ymax = y;
14142  } else {
14143  m->xmin = (x < m->xmin) ? x : m->xmin;
14144  m->xmax = (x > m->xmax) ? x : m->xmax;
14145  m->ymin = (y < m->ymin) ? y : m->ymin;
14146  m->ymax = (y > m->ymax) ? y : m->ymax;
14147  }
14148  }
14149  if (m->readnodefile) {
14150  fclose(infile);
14151  }
14152 
14153  /* Nonexistent x value used as a flag to mark circle events in sweepline */
14154  /* Delaunay algorithm. */
14155  m->xminextreme = 10 * m->xmin - 9 * m->xmax;
14156 }
14157 
14158 #endif /* not TRILIBRARY */
14159 
14160 /*****************************************************************************/
14161 /* */
14162 /* transfernodes() Read the vertices from memory. */
14163 /* */
14164 /*****************************************************************************/
14165 
14166 #ifdef TRILIBRARY
14167 
14168 #ifdef ANSI_DECLARATORS
14169 void transfernodes(struct mesh *m, struct behavior *b, REAL* pointlist,
14170  REAL* pointattriblist, int* pointmarkerlist,
14171  int numberofpoints, int numberofpointattribs)
14172 #else /* not ANSI_DECLARATORS */
14173 void transfernodes(m, b, pointlist, pointattriblist, pointmarkerlist,
14174  numberofpoints, numberofpointattribs)
14175 struct mesh *m;
14176 struct behavior *b;
14177 REAL* pointlist;
14178 REAL* pointattriblist;
14179 int* pointmarkerlist;
14180 int numberofpoints;
14181 int numberofpointattribs;
14182 #endif /* not ANSI_DECLARATORS */
14183 
14184 {
14185  vertex vertexloop;
14186  REAL x, y;
14187  int i, j;
14188  int coordindex;
14189  int attribindex;
14190 
14191  m->invertices = numberofpoints;
14192  m->mesh_dim = 2;
14193  m->nextras = numberofpointattribs;
14194  m->readnodefile = 0;
14195  if (m->invertices < 3) {
14196  printf("Error: Input must have at least three input vertices.\n");
14197  triexit(1);
14198  }
14199  if (m->nextras == 0) {
14200  b->weighted = 0;
14201  }
14202 
14203  initializevertexpool(m, b);
14204 
14205  /* Read the vertices. */
14206  coordindex = 0;
14207  attribindex = 0;
14208  for (i = 0; i < m->invertices; i++) {
14209  vertexloop = (vertex) poolalloc(&m->vertices);
14210  /* Read the vertex coordinates. */
14211  x = vertexloop[0] = pointlist[coordindex++];
14212  y = vertexloop[1] = pointlist[coordindex++];
14213  /* Read the vertex attributes. */
14214  for (j = 0; j < numberofpointattribs; j++) {
14215  vertexloop[2 + j] = pointattriblist[attribindex++];
14216  }
14217  if (pointmarkerlist != (int *) NULL) {
14218  /* Read a vertex marker. */
14219  setvertexmark(vertexloop, pointmarkerlist[i]);
14220  } else {
14221  /* If no markers are specified, they default to zero. */
14222  setvertexmark(vertexloop, 0);
14223  }
14224  setvertextype(vertexloop, INPUTVERTEX);
14225  /* Determine the smallest and largest x and y coordinates. */
14226  if (i == 0) {
14227  m->xmin = m->xmax = x;
14228  m->ymin = m->ymax = y;
14229  } else {
14230  m->xmin = (x < m->xmin) ? x : m->xmin;
14231  m->xmax = (x > m->xmax) ? x : m->xmax;
14232  m->ymin = (y < m->ymin) ? y : m->ymin;
14233  m->ymax = (y > m->ymax) ? y : m->ymax;
14234  }
14235  }
14236 
14237  /* Nonexistent x value used as a flag to mark circle events in sweepline */
14238  /* Delaunay algorithm. */
14239  m->xminextreme = 10 * m->xmin - 9 * m->xmax;
14240 }
14241 
14242 #endif /* TRILIBRARY */
14243 
14244 /*****************************************************************************/
14245 /* */
14246 /* readholes() Read the holes, and possibly regional attributes and area */
14247 /* constraints, from a .poly file. */
14248 /* */
14249 /*****************************************************************************/
14250 
14251 #ifndef TRILIBRARY
14252 
14253 #ifdef ANSI_DECLARATORS
14254 void readholes(struct mesh *m, struct behavior *b,
14255  FILE* polyfile, char* polyfilename, REAL **hlist, int *holes,
14256  REAL **rlist, int *regions)
14257 #else /* not ANSI_DECLARATORS */
14258 void readholes(m, b, polyfile, polyfilename, hlist, holes, rlist, regions)
14259 struct mesh *m;
14260 struct behavior *b;
14261 FILE* polyfile;
14262 char* polyfilename;
14263 REAL **hlist;
14264 int *holes;
14265 REAL **rlist;
14266 int *regions;
14267 #endif /* not ANSI_DECLARATORS */
14268 
14269 {
14270  REAL *holelist;
14271  REAL *regionlist;
14272  char inputline[INPUTLINESIZE];
14273  char *stringptr;
14274  int index;
14275  int i;
14276 
14277  /* Read the holes. */
14278  stringptr = readline(inputline, polyfile, polyfilename);
14279  *holes = (int) strtol(stringptr, &stringptr, 0);
14280  if (*holes > 0) {
14281  holelist = (REAL *) trimalloc(2 * *holes * (int) sizeof(REAL));
14282  *hlist = holelist;
14283  for (i = 0; i < 2 * *holes; i += 2) {
14284  stringptr = readline(inputline, polyfile, polyfilename);
14285  stringptr = findfield(stringptr);
14286  if (*stringptr == '\0') {
14287  printf("Error: Hole %d has no x coordinate.\n",
14288  b->firstnumber + (i >> 1));
14289  triexit(1);
14290  } else {
14291  holelist[i] = (REAL) strtod(stringptr, &stringptr);
14292  }
14293  stringptr = findfield(stringptr);
14294  if (*stringptr == '\0') {
14295  printf("Error: Hole %d has no y coordinate.\n",
14296  b->firstnumber + (i >> 1));
14297  triexit(1);
14298  } else {
14299  holelist[i + 1] = (REAL) strtod(stringptr, &stringptr);
14300  }
14301  }
14302  } else {
14303  *hlist = (REAL *) NULL;
14304  }
14305 
14306 #ifndef CDT_ONLY
14307  if ((b->regionattrib || b->vararea) && !b->refine) {
14308  /* Read the area constraints. */
14309  stringptr = readline(inputline, polyfile, polyfilename);
14310  *regions = (int) strtol(stringptr, &stringptr, 0);
14311  if (*regions > 0) {
14312  regionlist = (REAL *) trimalloc(4 * *regions * (int) sizeof(REAL));
14313  *rlist = regionlist;
14314  index = 0;
14315  for (i = 0; i < *regions; i++) {
14316  stringptr = readline(inputline, polyfile, polyfilename);
14317  stringptr = findfield(stringptr);
14318  if (*stringptr == '\0') {
14319  printf("Error: Region %d has no x coordinate.\n",
14320  b->firstnumber + i);
14321  triexit(1);
14322  } else {
14323  regionlist[index++] = (REAL) strtod(stringptr, &stringptr);
14324  }
14325  stringptr = findfield(stringptr);
14326  if (*stringptr == '\0') {
14327  printf("Error: Region %d has no y coordinate.\n",
14328  b->firstnumber + i);
14329  triexit(1);
14330  } else {
14331  regionlist[index++] = (REAL) strtod(stringptr, &stringptr);
14332  }
14333  stringptr = findfield(stringptr);
14334  if (*stringptr == '\0') {
14335  printf(
14336  "Error: Region %d has no region attribute or area constraint.\n",
14337  b->firstnumber + i);
14338  triexit(1);
14339  } else {
14340  regionlist[index++] = (REAL) strtod(stringptr, &stringptr);
14341  }
14342  stringptr = findfield(stringptr);
14343  if (*stringptr == '\0') {
14344  regionlist[index] = regionlist[index - 1];
14345  } else {
14346  regionlist[index] = (REAL) strtod(stringptr, &stringptr);
14347  }
14348  index++;
14349  }
14350  }
14351  } else {
14352  /* Set `*regions' to zero to avoid an accidental free() later. */
14353  *regions = 0;
14354  *rlist = (REAL *) NULL;
14355  }
14356 #endif /* not CDT_ONLY */
14357 
14358  fclose(polyfile);
14359 }
14360 
14361 #endif /* not TRILIBRARY */
14362 
14363 /*****************************************************************************/
14364 /* */
14365 /* finishfile() Write the command line to the output file so the user */
14366 /* can remember how the file was generated. Close the file. */
14367 /* */
14368 /*****************************************************************************/
14369 
14370 #ifndef TRILIBRARY
14371 
14372 #ifdef ANSI_DECLARATORS
14373 void finishfile(FILE *outfile, int argc, char **argv)
14374 #else /* not ANSI_DECLARATORS */
14375 void finishfile(outfile, argc, argv)
14376 FILE *outfile;
14377 int argc;
14378 char **argv;
14379 #endif /* not ANSI_DECLARATORS */
14380 
14381 {
14382  int i;
14383 
14384  fprintf(outfile, "# Generated by");
14385  for (i = 0; i < argc; i++) {
14386  fprintf(outfile, " ");
14387  fputs(argv[i], outfile);
14388  }
14389  fprintf(outfile, "\n");
14390  fclose(outfile);
14391 }
14392 
14393 #endif /* not TRILIBRARY */
14394 
14395 /*****************************************************************************/
14396 /* */
14397 /* writenodes() Number the vertices and write them to a .node file. */
14398 /* */
14399 /* To save memory, the vertex numbers are written over the boundary markers */
14400 /* after the vertices are written to a file. */
14401 /* */
14402 /*****************************************************************************/
14403 
14404 #ifdef TRILIBRARY
14405 
14406 #ifdef ANSI_DECLARATORS
14407 void writenodes(struct mesh *m, struct behavior *b, REAL **pointlist,
14408  REAL **pointattriblist, int **pointmarkerlist)
14409 #else /* not ANSI_DECLARATORS */
14410 void writenodes(m, b, pointlist, pointattriblist, pointmarkerlist)
14411 struct mesh *m;
14412 struct behavior *b;
14413 REAL **pointlist;
14414 REAL **pointattriblist;
14415 int **pointmarkerlist;
14416 #endif /* not ANSI_DECLARATORS */
14417 
14418 #else /* not TRILIBRARY */
14419 
14420 #ifdef ANSI_DECLARATORS
14421 void writenodes(struct mesh *m, struct behavior *b, char *nodefilename,
14422  int argc, char **argv)
14423 #else /* not ANSI_DECLARATORS */
14424 void writenodes(m, b, nodefilename, argc, argv)
14425 struct mesh *m;
14426 struct behavior *b;
14427 char *nodefilename;
14428 int argc;
14429 char **argv;
14430 #endif /* not ANSI_DECLARATORS */
14431 
14432 #endif /* not TRILIBRARY */
14433 
14434 {
14435 #ifdef TRILIBRARY
14436  REAL* plist;
14437  REAL* palist;
14438  int* pmlist;
14439  int coordindex;
14440  int attribindex;
14441 #else /* not TRILIBRARY */
14442  FILE *outfile;
14443 #endif /* not TRILIBRARY */
14444  vertex vertexloop;
14445  long outvertices;
14446  int vertexnumber;
14447  int i;
14448 
14449  if (b->jettison) {
14450  outvertices = m->vertices.items - m->undeads;
14451  } else {
14452  outvertices = m->vertices.items;
14453  }
14454 
14455 #ifdef TRILIBRARY
14456  if (!b->quiet) {
14457  printf("Writing vertices.\n");
14458  }
14459  /* Allocate memory for output vertices if necessary. */
14460  if (*pointlist == (REAL *) NULL) {
14461  * pointlist = (REAL *) trimalloc((int) (outvertices * 2 * sizeof(REAL)));
14462  }
14463  /* Allocate memory for output vertex attributes if necessary. */
14464  if ((m->nextras > 0) && (*pointattriblist == (REAL *) NULL)) {
14465  * pointattriblist = (REAL *) trimalloc((int) (outvertices * m->nextras *
14466  sizeof(REAL)));
14467  }
14468  /* Allocate memory for output vertex markers if necessary. */
14469  if (!b->nobound && (*pointmarkerlist == (int *) NULL)) {
14470  * pointmarkerlist = (int *) trimalloc((int) (outvertices * sizeof(int)));
14471  }
14472  plist =* pointlist;
14473  palist =* pointattriblist;
14474  pmlist =* pointmarkerlist;
14475  coordindex = 0;
14476  attribindex = 0;
14477 #else /* not TRILIBRARY */
14478  if (!b->quiet) {
14479  printf("Writing %s.\n", nodefilename);
14480  }
14481  outfile = fopen(nodefilename, "w");
14482  if (outfile == (FILE *) NULL) {
14483  printf(" Error: Cannot create file %s.\n", nodefilename);
14484  triexit(1);
14485  }
14486  /* Number of vertices, number of dimensions, number of vertex attributes, */
14487  /* and number of boundary markers (zero or one). */
14488  fprintf(outfile, "%ld %d %d %d\n", outvertices, m->mesh_dim,
14489  m->nextras, 1 - b->nobound);
14490 #endif /* not TRILIBRARY */
14491 
14492  traversalinit(&m->vertices);
14493  vertexnumber = b->firstnumber;
14494  vertexloop = vertextraverse(m);
14495  while (vertexloop != (vertex) NULL) {
14496  if (!b->jettison || (vertextype(vertexloop) != UNDEADVERTEX)) {
14497 #ifdef TRILIBRARY
14498  /* X and y coordinates. */
14499  plist[coordindex++] = vertexloop[0];
14500  plist[coordindex++] = vertexloop[1];
14501  /* Vertex attributes. */
14502  for (i = 0; i < m->nextras; i++) {
14503  palist[attribindex++] = vertexloop[2 + i];
14504  }
14505  if (!b->nobound) {
14506  /* Copy the boundary marker. */
14507  pmlist[vertexnumber - b->firstnumber] = vertexmark(vertexloop);
14508  }
14509 #else /* not TRILIBRARY */
14510  /* Vertex number, x and y coordinates. */
14511  fprintf(outfile, "%4d %.17g %.17g", vertexnumber, vertexloop[0],
14512  vertexloop[1]);
14513  for (i = 0; i < m->nextras; i++) {
14514  /* Write an attribute. */
14515  fprintf(outfile, " %.17g", vertexloop[i + 2]);
14516  }
14517  if (b->nobound) {
14518  fprintf(outfile, "\n");
14519  } else {
14520  /* Write the boundary marker. */
14521  fprintf(outfile, " %d\n", vertexmark(vertexloop));
14522  }
14523 #endif /* not TRILIBRARY */
14524 
14525  setvertexmark(vertexloop, vertexnumber);
14526  vertexnumber++;
14527  }
14528  vertexloop = vertextraverse(m);
14529  }
14530 
14531 #ifndef TRILIBRARY
14532  finishfile(outfile, argc, argv);
14533 #endif /* not TRILIBRARY */
14534 }
14535 
14536 /*****************************************************************************/
14537 /* */
14538 /* numbernodes() Number the vertices. */
14539 /* */
14540 /* Each vertex is assigned a marker equal to its number. */
14541 /* */
14542 /* Used when writenodes() is not called because no .node file is written. */
14543 /* */
14544 /*****************************************************************************/
14545 
14546 #ifdef ANSI_DECLARATORS
14547 void numbernodes(struct mesh *m, struct behavior *b)
14548 #else /* not ANSI_DECLARATORS */
14549 void numbernodes(m, b)
14550 struct mesh *m;
14551 struct behavior *b;
14552 #endif /* not ANSI_DECLARATORS */
14553 
14554 {
14555  vertex vertexloop;
14556  int vertexnumber;
14557 
14558  traversalinit(&m->vertices);
14559  vertexnumber = b->firstnumber;
14560  vertexloop = vertextraverse(m);
14561  while (vertexloop != (vertex) NULL) {
14562  setvertexmark(vertexloop, vertexnumber);
14563  if (!b->jettison || (vertextype(vertexloop) != UNDEADVERTEX)) {
14564  vertexnumber++;
14565  }
14566  vertexloop = vertextraverse(m);
14567  }
14568 }
14569 
14570 /*****************************************************************************/
14571 /* */
14572 /* writeelements() Write the triangles to an .ele file. */
14573 /* */
14574 /*****************************************************************************/
14575 
14576 #ifdef TRILIBRARY
14577 
14578 #ifdef ANSI_DECLARATORS
14579 void writeelements(struct mesh *m, struct behavior *b,
14580  int **trianglelist, REAL **triangleattriblist)
14581 #else /* not ANSI_DECLARATORS */
14582 void writeelements(m, b, trianglelist, triangleattriblist)
14583 struct mesh *m;
14584 struct behavior *b;
14585 int **trianglelist;
14586 REAL **triangleattriblist;
14587 #endif /* not ANSI_DECLARATORS */
14588 
14589 #else /* not TRILIBRARY */
14590 
14591 #ifdef ANSI_DECLARATORS
14592 void writeelements(struct mesh *m, struct behavior *b, char *elefilename,
14593  int argc, char **argv)
14594 #else /* not ANSI_DECLARATORS */
14595 void writeelements(m, b, elefilename, argc, argv)
14596 struct mesh *m;
14597 struct behavior *b;
14598 char *elefilename;
14599 int argc;
14600 char **argv;
14601 #endif /* not ANSI_DECLARATORS */
14602 
14603 #endif /* not TRILIBRARY */
14604 
14605 {
14606 #ifdef TRILIBRARY
14607  int *tlist;
14608  REAL *talist;
14609  int vertexindex;
14610  int attribindex;
14611 #else /* not TRILIBRARY */
14612  FILE *outfile;
14613 #endif /* not TRILIBRARY */
14614  struct otri triangleloop;
14615  vertex p1, p2, p3;
14616  vertex mid1, mid2, mid3;
14617  long elementnumber;
14618  int i;
14619 
14620 #ifdef TRILIBRARY
14621  if (!b->quiet) {
14622  printf("Writing triangles.\n");
14623  }
14624  /* Allocate memory for output triangles if necessary. */
14625  if (*trianglelist == (int *) NULL) {
14626  *trianglelist = (int *) trimalloc((int) (m->triangles.items *
14627  ((b->order + 1) * (b->order + 2) /
14628  2) * sizeof(int)));
14629  }
14630  /* Allocate memory for output triangle attributes if necessary. */
14631  if ((m->eextras > 0) && (*triangleattriblist == (REAL *) NULL)) {
14632  *triangleattriblist = (REAL *) trimalloc((int) (m->triangles.items *
14633  m->eextras *
14634  sizeof(REAL)));
14635  }
14636  tlist = *trianglelist;
14637  talist = *triangleattriblist;
14638  vertexindex = 0;
14639  attribindex = 0;
14640 #else /* not TRILIBRARY */
14641  if (!b->quiet) {
14642  printf("Writing %s.\n", elefilename);
14643  }
14644  outfile = fopen(elefilename, "w");
14645  if (outfile == (FILE *) NULL) {
14646  printf(" Error: Cannot create file %s.\n", elefilename);
14647  triexit(1);
14648  }
14649  /* Number of triangles, vertices per triangle, attributes per triangle. */
14650  fprintf(outfile, "%ld %d %d\n", m->triangles.items,
14651  (b->order + 1) * (b->order + 2) / 2, m->eextras);
14652 #endif /* not TRILIBRARY */
14653 
14654  traversalinit(&m->triangles);
14655  triangleloop.tri = triangletraverse(m);
14656  triangleloop.orient = 0;
14657  elementnumber = b->firstnumber;
14658  while (triangleloop.tri != (triangle *) NULL) {
14659  org(triangleloop, p1);
14660  dest(triangleloop, p2);
14661  apex(triangleloop, p3);
14662  if (b->order == 1) {
14663 #ifdef TRILIBRARY
14664  tlist[vertexindex++] = vertexmark(p1);
14665  tlist[vertexindex++] = vertexmark(p2);
14666  tlist[vertexindex++] = vertexmark(p3);
14667 #else /* not TRILIBRARY */
14668  /* Triangle number, indices for three vertices. */
14669  fprintf(outfile, "%4ld %4d %4d %4d", elementnumber,
14670  vertexmark(p1), vertexmark(p2), vertexmark(p3));
14671 #endif /* not TRILIBRARY */
14672  } else {
14673  mid1 = (vertex) triangleloop.tri[m->highorderindex + 1];
14674  mid2 = (vertex) triangleloop.tri[m->highorderindex + 2];
14675  mid3 = (vertex) triangleloop.tri[m->highorderindex];
14676 #ifdef TRILIBRARY
14677  tlist[vertexindex++] = vertexmark(p1);
14678  tlist[vertexindex++] = vertexmark(p2);
14679  tlist[vertexindex++] = vertexmark(p3);
14680  tlist[vertexindex++] = vertexmark(mid1);
14681  tlist[vertexindex++] = vertexmark(mid2);
14682  tlist[vertexindex++] = vertexmark(mid3);
14683 #else /* not TRILIBRARY */
14684  /* Triangle number, indices for six vertices. */
14685  fprintf(outfile, "%4ld %4d %4d %4d %4d %4d %4d", elementnumber,
14686  vertexmark(p1), vertexmark(p2), vertexmark(p3), vertexmark(mid1),
14687  vertexmark(mid2), vertexmark(mid3));
14688 #endif /* not TRILIBRARY */
14689  }
14690 
14691 #ifdef TRILIBRARY
14692  for (i = 0; i < m->eextras; i++) {
14693  talist[attribindex++] = elemattribute(triangleloop, i);
14694  }
14695 #else /* not TRILIBRARY */
14696  for (i = 0; i < m->eextras; i++) {
14697  fprintf(outfile, " %.17g", elemattribute(triangleloop, i));
14698  }
14699  fprintf(outfile, "\n");
14700 #endif /* not TRILIBRARY */
14701 
14702  triangleloop.tri = triangletraverse(m);
14703  elementnumber++;
14704  }
14705 
14706 #ifndef TRILIBRARY
14707  finishfile(outfile, argc, argv);
14708 #endif /* not TRILIBRARY */
14709 }
14710 
14711 /*****************************************************************************/
14712 /* */
14713 /* writepoly() Write the segments and holes to a .poly file. */
14714 /* */
14715 /*****************************************************************************/
14716 
14717 #ifdef TRILIBRARY
14718 
14719 #ifdef ANSI_DECLARATORS
14720 void writepoly(struct mesh *m, struct behavior *b,
14721  int **segmentlist, int **segmentmarkerlist)
14722 #else /* not ANSI_DECLARATORS */
14723 void writepoly(m, b, segmentlist, segmentmarkerlist)
14724 struct mesh *m;
14725 struct behavior *b;
14726 int **segmentlist;
14727 int **segmentmarkerlist;
14728 #endif /* not ANSI_DECLARATORS */
14729 
14730 #else /* not TRILIBRARY */
14731 
14732 #ifdef ANSI_DECLARATORS
14733 void writepoly(struct mesh *m, struct behavior *b, char* polyfilename,
14734  REAL *holelist, int holes, REAL *regionlist, int regions,
14735  int argc, char **argv)
14736 #else /* not ANSI_DECLARATORS */
14737 void writepoly(m, b, polyfilename, holelist, holes, regionlist, regions,
14738  argc, argv)
14739 struct mesh *m;
14740 struct behavior *b;
14741 char* polyfilename;
14742 REAL *holelist;
14743 int holes;
14744 REAL *regionlist;
14745 int regions;
14746 int argc;
14747 char **argv;
14748 #endif /* not ANSI_DECLARATORS */
14749 
14750 #endif /* not TRILIBRARY */
14751 
14752 {
14753 #ifdef TRILIBRARY
14754  int *slist;
14755  int *smlist;
14756  int index;
14757 #else /* not TRILIBRARY */
14758  FILE *outfile;
14759  long holenumber, regionnumber;
14760 #endif /* not TRILIBRARY */
14761  struct osub subsegloop;
14762  vertex endpoint1, endpoint2;
14763  long subsegnumber;
14764 
14765 #ifdef TRILIBRARY
14766  if (!b->quiet) {
14767  printf("Writing segments.\n");
14768  }
14769  /* Allocate memory for output segments if necessary. */
14770  if (*segmentlist == (int *) NULL) {
14771  *segmentlist = (int *) trimalloc((int) (m->subsegs.items * 2 *
14772  sizeof(int)));
14773  }
14774  /* Allocate memory for output segment markers if necessary. */
14775  if (!b->nobound && (*segmentmarkerlist == (int *) NULL)) {
14776  *segmentmarkerlist = (int *) trimalloc((int) (m->subsegs.items *
14777  sizeof(int)));
14778  }
14779  slist = *segmentlist;
14780  smlist = *segmentmarkerlist;
14781  index = 0;
14782 #else /* not TRILIBRARY */
14783  if (!b->quiet) {
14784  printf("Writing %s.\n", polyfilename);
14785  }
14786  outfile = fopen(polyfilename, "w");
14787  if (outfile == (FILE *) NULL) {
14788  printf(" Error: Cannot create file %s.\n", polyfilename);
14789  triexit(1);
14790  }
14791  /* The zero indicates that the vertices are in a separate .node file. */
14792  /* Followed by number of dimensions, number of vertex attributes, */
14793  /* and number of boundary markers (zero or one). */
14794  fprintf(outfile, "%d %d %d %d\n", 0, m->mesh_dim, m->nextras,
14795  1 - b->nobound);
14796  /* Number of segments, number of boundary markers (zero or one). */
14797  fprintf(outfile, "%ld %d\n", m->subsegs.items, 1 - b->nobound);
14798 #endif /* not TRILIBRARY */
14799 
14800  traversalinit(&m->subsegs);
14801  subsegloop.ss = subsegtraverse(m);
14802  subsegloop.ssorient = 0;
14803  subsegnumber = b->firstnumber;
14804  while (subsegloop.ss != (subseg *) NULL) {
14805  sorg(subsegloop, endpoint1);
14806  sdest(subsegloop, endpoint2);
14807 #ifdef TRILIBRARY
14808  /* Copy indices of the segment's two endpoints. */
14809  slist[index++] = vertexmark(endpoint1);
14810  slist[index++] = vertexmark(endpoint2);
14811  if (!b->nobound) {
14812  /* Copy the boundary marker. */
14813  smlist[subsegnumber - b->firstnumber] = mark(subsegloop);
14814  }
14815 #else /* not TRILIBRARY */
14816  /* Segment number, indices of its two endpoints, and possibly a marker. */
14817  if (b->nobound) {
14818  fprintf(outfile, "%4ld %4d %4d\n", subsegnumber,
14819  vertexmark(endpoint1), vertexmark(endpoint2));
14820  } else {
14821  fprintf(outfile, "%4ld %4d %4d %4d\n", subsegnumber,
14822  vertexmark(endpoint1), vertexmark(endpoint2), mark(subsegloop));
14823  }
14824 #endif /* not TRILIBRARY */
14825 
14826  subsegloop.ss = subsegtraverse(m);
14827  subsegnumber++;
14828  }
14829 
14830 #ifndef TRILIBRARY
14831 #ifndef CDT_ONLY
14832  fprintf(outfile, "%d\n", holes);
14833  if (holes > 0) {
14834  for (holenumber = 0; holenumber < holes; holenumber++) {
14835  /* Hole number, x and y coordinates. */
14836  fprintf(outfile, "%4ld %.17g %.17g\n", b->firstnumber + holenumber,
14837  holelist[2 * holenumber], holelist[2 * holenumber + 1]);
14838  }
14839  }
14840  if (regions > 0) {
14841  fprintf(outfile, "%d\n", regions);
14842  for (regionnumber = 0; regionnumber < regions; regionnumber++) {
14843  /* Region number, x and y coordinates, attribute, maximum area. */
14844  fprintf(outfile, "%4ld %.17g %.17g %.17g %.17g\n",
14845  b->firstnumber + regionnumber,
14846  regionlist[4 * regionnumber], regionlist[4 * regionnumber + 1],
14847  regionlist[4 * regionnumber + 2],
14848  regionlist[4 * regionnumber + 3]);
14849  }
14850  }
14851 #endif /* not CDT_ONLY */
14852 
14853  finishfile(outfile, argc, argv);
14854 #endif /* not TRILIBRARY */
14855 }
14856 
14857 /*****************************************************************************/
14858 /* */
14859 /* writeedges() Write the edges to an .edge file. */
14860 /* */
14861 /*****************************************************************************/
14862 
14863 #ifdef TRILIBRARY
14864 
14865 #ifdef ANSI_DECLARATORS
14866 void writeedges(struct mesh *m, struct behavior *b,
14867  int **edgelist, int **edgemarkerlist)
14868 #else /* not ANSI_DECLARATORS */
14869 void writeedges(m, b, edgelist, edgemarkerlist)
14870 struct mesh *m;
14871 struct behavior *b;
14872 int **edgelist;
14873 int **edgemarkerlist;
14874 #endif /* not ANSI_DECLARATORS */
14875 
14876 #else /* not TRILIBRARY */
14877 
14878 #ifdef ANSI_DECLARATORS
14879 void writeedges(struct mesh *m, struct behavior *b, char *edgefilename,
14880  int argc, char **argv)
14881 #else /* not ANSI_DECLARATORS */
14882 void writeedges(m, b, edgefilename, argc, argv)
14883 struct mesh *m;
14884 struct behavior *b;
14885 char *edgefilename;
14886 int argc;
14887 char **argv;
14888 #endif /* not ANSI_DECLARATORS */
14889 
14890 #endif /* not TRILIBRARY */
14891 
14892 {
14893 #ifdef TRILIBRARY
14894  int *elist;
14895  int *emlist;
14896  int index;
14897 #else /* not TRILIBRARY */
14898  FILE *outfile;
14899 #endif /* not TRILIBRARY */
14900  struct otri triangleloop, trisym;
14901  struct osub checkmark;
14902  vertex p1, p2;
14903  long edgenumber;
14904  triangle ptr; /* Temporary variable used by sym(). */
14905  subseg sptr; /* Temporary variable used by tspivot(). */
14906 
14907 #ifdef TRILIBRARY
14908  if (!b->quiet) {
14909  printf("Writing edges.\n");
14910  }
14911  /* Allocate memory for edges if necessary. */
14912  if (*edgelist == (int *) NULL) {
14913  *edgelist = (int *) trimalloc((int) (m->edges * 2 * sizeof(int)));
14914  }
14915  /* Allocate memory for edge markers if necessary. */
14916  if (!b->nobound && (*edgemarkerlist == (int *) NULL)) {
14917  *edgemarkerlist = (int *) trimalloc((int) (m->edges * sizeof(int)));
14918  }
14919  elist = *edgelist;
14920  emlist = *edgemarkerlist;
14921  index = 0;
14922 #else /* not TRILIBRARY */
14923  if (!b->quiet) {
14924  printf("Writing %s.\n", edgefilename);
14925  }
14926  outfile = fopen(edgefilename, "w");
14927  if (outfile == (FILE *) NULL) {
14928  printf(" Error: Cannot create file %s.\n", edgefilename);
14929  triexit(1);
14930  }
14931  /* Number of edges, number of boundary markers (zero or one). */
14932  fprintf(outfile, "%ld %d\n", m->edges, 1 - b->nobound);
14933 #endif /* not TRILIBRARY */
14934 
14935  traversalinit(&m->triangles);
14936  triangleloop.tri = triangletraverse(m);
14937  edgenumber = b->firstnumber;
14938  /* To loop over the set of edges, loop over all triangles, and look at */
14939  /* the three edges of each triangle. If there isn't another triangle */
14940  /* adjacent to the edge, operate on the edge. If there is another */
14941  /* adjacent triangle, operate on the edge only if the current triangle */
14942  /* has a smaller pointer than its neighbor. This way, each edge is */
14943  /* considered only once. */
14944  while (triangleloop.tri != (triangle *) NULL) {
14945  for (triangleloop.orient = 0; triangleloop.orient < 3;
14946  triangleloop.orient++) {
14947  sym(triangleloop, trisym);
14948  if ((triangleloop.tri < trisym.tri) || (trisym.tri == m->dummytri)) {
14949  org(triangleloop, p1);
14950  dest(triangleloop, p2);
14951 #ifdef TRILIBRARY
14952  elist[index++] = vertexmark(p1);
14953  elist[index++] = vertexmark(p2);
14954 #endif /* TRILIBRARY */
14955  if (b->nobound) {
14956 #ifndef TRILIBRARY
14957  /* Edge number, indices of two endpoints. */
14958  fprintf(outfile, "%4ld %d %d\n", edgenumber,
14959  vertexmark(p1), vertexmark(p2));
14960 #endif /* not TRILIBRARY */
14961  } else {
14962  /* Edge number, indices of two endpoints, and a boundary marker. */
14963  /* If there's no subsegment, the boundary marker is zero. */
14964  if (b->usesegments) {
14965  tspivot(triangleloop, checkmark);
14966  if (checkmark.ss == m->dummysub) {
14967 #ifdef TRILIBRARY
14968  emlist[edgenumber - b->firstnumber] = 0;
14969 #else /* not TRILIBRARY */
14970  fprintf(outfile, "%4ld %d %d %d\n", edgenumber,
14971  vertexmark(p1), vertexmark(p2), 0);
14972 #endif /* not TRILIBRARY */
14973  } else {
14974 #ifdef TRILIBRARY
14975  emlist[edgenumber - b->firstnumber] = mark(checkmark);
14976 #else /* not TRILIBRARY */
14977  fprintf(outfile, "%4ld %d %d %d\n", edgenumber,
14978  vertexmark(p1), vertexmark(p2), mark(checkmark));
14979 #endif /* not TRILIBRARY */
14980  }
14981  } else {
14982 #ifdef TRILIBRARY
14983  emlist[edgenumber - b->firstnumber] = trisym.tri == m->dummytri;
14984 #else /* not TRILIBRARY */
14985  fprintf(outfile, "%4ld %d %d %d\n", edgenumber,
14986  vertexmark(p1), vertexmark(p2), trisym.tri == m->dummytri);
14987 #endif /* not TRILIBRARY */
14988  }
14989  }
14990  edgenumber++;
14991  }
14992  }
14993  triangleloop.tri = triangletraverse(m);
14994  }
14995 
14996 #ifndef TRILIBRARY
14997  finishfile(outfile, argc, argv);
14998 #endif /* not TRILIBRARY */
14999 }
15000 
15001 /*****************************************************************************/
15002 /* */
15003 /* writevoronoi() Write the Voronoi diagram to a .v.node and .v.edge */
15004 /* file. */
15005 /* */
15006 /* The Voronoi diagram is the geometric dual of the Delaunay triangulation. */
15007 /* Hence, the Voronoi vertices are listed by traversing the Delaunay */
15008 /* triangles, and the Voronoi edges are listed by traversing the Delaunay */
15009 /* edges. */
15010 /* */
15011 /* WARNING: In order to assign numbers to the Voronoi vertices, this */
15012 /* procedure messes up the subsegments or the extra nodes of every */
15013 /* element. Hence, you should call this procedure last. */
15014 /* */
15015 /*****************************************************************************/
15016 
15017 #ifdef TRILIBRARY
15018 
15019 #ifdef ANSI_DECLARATORS
15020 void writevoronoi(struct mesh *m, struct behavior *b, REAL **vpointlist,
15021  REAL **vpointattriblist, int **vpointmarkerlist,
15022  int **vedgelist, int **vedgemarkerlist, REAL **vnormlist)
15023 #else /* not ANSI_DECLARATORS */
15024 void writevoronoi(m, b, vpointlist, vpointattriblist, vpointmarkerlist,
15025  vedgelist, vedgemarkerlist, vnormlist)
15026 struct mesh *m;
15027 struct behavior *b;
15028 REAL **vpointlist;
15029 REAL **vpointattriblist;
15030 int **vpointmarkerlist;
15031 int **vedgelist;
15032 int **vedgemarkerlist;
15033 REAL **vnormlist;
15034 #endif /* not ANSI_DECLARATORS */
15035 
15036 #else /* not TRILIBRARY */
15037 
15038 #ifdef ANSI_DECLARATORS
15039 void writevoronoi(struct mesh *m, struct behavior *b, char *vnodefilename,
15040  char *vedgefilename, int argc, char **argv)
15041 #else /* not ANSI_DECLARATORS */
15042 void writevoronoi(m, b, vnodefilename, vedgefilename, argc, argv)
15043 struct mesh *m;
15044 struct behavior *b;
15045 char *vnodefilename;
15046 char *vedgefilename;
15047 int argc;
15048 char **argv;
15049 #endif /* not ANSI_DECLARATORS */
15050 
15051 #endif /* not TRILIBRARY */
15052 
15053 {
15054 #ifdef TRILIBRARY
15055  REAL* plist;
15056  REAL* palist;
15057  int *elist;
15058  REAL *normlist;
15059  int coordindex;
15060  int attribindex;
15061 #else /* not TRILIBRARY */
15062  FILE *outfile;
15063 #endif /* not TRILIBRARY */
15064  struct otri triangleloop, trisym;
15065  vertex torg, tdest, tapex;
15066  REAL circumcenter[2];
15067  REAL xi, eta;
15068  long vnodenumber, vedgenumber;
15069  int p1, p2;
15070  int i;
15071  triangle ptr; /* Temporary variable used by sym(). */
15072 
15073 #ifdef TRILIBRARY
15074  if (!b->quiet) {
15075  printf("Writing Voronoi vertices.\n");
15076  }
15077  /* Allocate memory for Voronoi vertices if necessary. */
15078  if (*vpointlist == (REAL *) NULL) {
15079  *vpointlist = (REAL *) trimalloc((int) (m->triangles.items * 2 *
15080  sizeof(REAL)));
15081  }
15082  /* Allocate memory for Voronoi vertex attributes if necessary. */
15083  if (*vpointattriblist == (REAL *) NULL) {
15084  *vpointattriblist = (REAL *) trimalloc((int) (m->triangles.items *
15085  m->nextras * sizeof(REAL)));
15086  }
15087  *vpointmarkerlist = (int *) NULL;
15088  plist = *vpointlist;
15089  palist = *vpointattriblist;
15090  coordindex = 0;
15091  attribindex = 0;
15092 #else /* not TRILIBRARY */
15093  if (!b->quiet) {
15094  printf("Writing %s.\n", vnodefilename);
15095  }
15096  outfile = fopen(vnodefilename, "w");
15097  if (outfile == (FILE *) NULL) {
15098  printf(" Error: Cannot create file %s.\n", vnodefilename);
15099  triexit(1);
15100  }
15101  /* Number of triangles, two dimensions, number of vertex attributes, */
15102  /* no markers. */
15103  fprintf(outfile, "%ld %d %d %d\n", m->triangles.items, 2, m->nextras, 0);
15104 #endif /* not TRILIBRARY */
15105 
15106  traversalinit(&m->triangles);
15107  triangleloop.tri = triangletraverse(m);
15108  triangleloop.orient = 0;
15109  vnodenumber = b->firstnumber;
15110  while (triangleloop.tri != (triangle *) NULL) {
15111  org(triangleloop, torg);
15112  dest(triangleloop, tdest);
15113  apex(triangleloop, tapex);
15114  findcircumcenter(m, b, torg, tdest, tapex, circumcenter, &xi, &eta, 0);
15115 #ifdef TRILIBRARY
15116  /* X and y coordinates. */
15117  plist[coordindex++] = circumcenter[0];
15118  plist[coordindex++] = circumcenter[1];
15119  for (i = 2; i < 2 + m->nextras; i++) {
15120  /* Interpolate the vertex attributes at the circumcenter. */
15121  palist[attribindex++] = torg[i] + xi * (tdest[i] - torg[i])
15122  + eta * (tapex[i] - torg[i]);
15123  }
15124 #else /* not TRILIBRARY */
15125  /* Voronoi vertex number, x and y coordinates. */
15126  fprintf(outfile, "%4ld %.17g %.17g", vnodenumber, circumcenter[0],
15127  circumcenter[1]);
15128  for (i = 2; i < 2 + m->nextras; i++) {
15129  /* Interpolate the vertex attributes at the circumcenter. */
15130  fprintf(outfile, " %.17g", torg[i] + xi * (tdest[i] - torg[i])
15131  + eta * (tapex[i] - torg[i]));
15132  }
15133  fprintf(outfile, "\n");
15134 #endif /* not TRILIBRARY */
15135 
15136  * (int *) (triangleloop.tri + 6) = (int) vnodenumber;
15137  triangleloop.tri = triangletraverse(m);
15138  vnodenumber++;
15139  }
15140 
15141 #ifndef TRILIBRARY
15142  finishfile(outfile, argc, argv);
15143 #endif /* not TRILIBRARY */
15144 
15145 #ifdef TRILIBRARY
15146  if (!b->quiet) {
15147  printf("Writing Voronoi edges.\n");
15148  }
15149  /* Allocate memory for output Voronoi edges if necessary. */
15150  if (*vedgelist == (int *) NULL) {
15151  *vedgelist = (int *) trimalloc((int) (m->edges * 2 * sizeof(int)));
15152  }
15153  *vedgemarkerlist = (int *) NULL;
15154  /* Allocate memory for output Voronoi norms if necessary. */
15155  if (*vnormlist == (REAL *) NULL) {
15156  *vnormlist = (REAL *) trimalloc((int) (m->edges * 2 * sizeof(REAL)));
15157  }
15158  elist = *vedgelist;
15159  normlist = *vnormlist;
15160  coordindex = 0;
15161 #else /* not TRILIBRARY */
15162  if (!b->quiet) {
15163  printf("Writing %s.\n", vedgefilename);
15164  }
15165  outfile = fopen(vedgefilename, "w");
15166  if (outfile == (FILE *) NULL) {
15167  printf(" Error: Cannot create file %s.\n", vedgefilename);
15168  triexit(1);
15169  }
15170  /* Number of edges, zero boundary markers. */
15171  fprintf(outfile, "%ld %d\n", m->edges, 0);
15172 #endif /* not TRILIBRARY */
15173 
15174  traversalinit(&m->triangles);
15175  triangleloop.tri = triangletraverse(m);
15176  vedgenumber = b->firstnumber;
15177  /* To loop over the set of edges, loop over all triangles, and look at */
15178  /* the three edges of each triangle. If there isn't another triangle */
15179  /* adjacent to the edge, operate on the edge. If there is another */
15180  /* adjacent triangle, operate on the edge only if the current triangle */
15181  /* has a smaller pointer than its neighbor. This way, each edge is */
15182  /* considered only once. */
15183  while (triangleloop.tri != (triangle *) NULL) {
15184  for (triangleloop.orient = 0; triangleloop.orient < 3;
15185  triangleloop.orient++) {
15186  sym(triangleloop, trisym);
15187  if ((triangleloop.tri < trisym.tri) || (trisym.tri == m->dummytri)) {
15188  /* Find the number of this triangle (and Voronoi vertex). */
15189  p1 = * (int *) (triangleloop.tri + 6);
15190  if (trisym.tri == m->dummytri) {
15191  org(triangleloop, torg);
15192  dest(triangleloop, tdest);
15193 #ifdef TRILIBRARY
15194  /* Copy an infinite ray. Index of one endpoint, and -1. */
15195  elist[coordindex] = p1;
15196  normlist[coordindex++] = tdest[1] - torg[1];
15197  elist[coordindex] = -1;
15198  normlist[coordindex++] = torg[0] - tdest[0];
15199 #else /* not TRILIBRARY */
15200  /* Write an infinite ray. Edge number, index of one endpoint, -1, */
15201  /* and x and y coordinates of a vector representing the */
15202  /* direction of the ray. */
15203  fprintf(outfile, "%4ld %d %d %.17g %.17g\n", vedgenumber,
15204  p1, -1, tdest[1] - torg[1], torg[0] - tdest[0]);
15205 #endif /* not TRILIBRARY */
15206  } else {
15207  /* Find the number of the adjacent triangle (and Voronoi vertex). */
15208  p2 = * (int *) (trisym.tri + 6);
15209  /* Finite edge. Write indices of two endpoints. */
15210 #ifdef TRILIBRARY
15211  elist[coordindex] = p1;
15212  normlist[coordindex++] = 0.0;
15213  elist[coordindex] = p2;
15214  normlist[coordindex++] = 0.0;
15215 #else /* not TRILIBRARY */
15216  fprintf(outfile, "%4ld %d %d\n", vedgenumber, p1, p2);
15217 #endif /* not TRILIBRARY */
15218  }
15219  vedgenumber++;
15220  }
15221  }
15222  triangleloop.tri = triangletraverse(m);
15223  }
15224 
15225 #ifndef TRILIBRARY
15226  finishfile(outfile, argc, argv);
15227 #endif /* not TRILIBRARY */
15228 }
15229 
15230 #ifdef TRILIBRARY
15231 
15232 #ifdef ANSI_DECLARATORS
15233 void writeneighbors(struct mesh *m, struct behavior *b, int **neighborlist)
15234 #else /* not ANSI_DECLARATORS */
15235 void writeneighbors(m, b, neighborlist)
15236 struct mesh *m;
15237 struct behavior *b;
15238 int **neighborlist;
15239 #endif /* not ANSI_DECLARATORS */
15240 
15241 #else /* not TRILIBRARY */
15242 
15243 #ifdef ANSI_DECLARATORS
15244 void writeneighbors(struct mesh *m, struct behavior *b, char *neighborfilename,
15245  int argc, char **argv)
15246 #else /* not ANSI_DECLARATORS */
15247 void writeneighbors(m, b, neighborfilename, argc, argv)
15248 struct mesh *m;
15249 struct behavior *b;
15250 char *neighborfilename;
15251 int argc;
15252 char **argv;
15253 #endif /* not ANSI_DECLARATORS */
15254 
15255 #endif /* not TRILIBRARY */
15256 
15257 {
15258 #ifdef TRILIBRARY
15259  int *nlist;
15260  int index;
15261 #else /* not TRILIBRARY */
15262  FILE *outfile;
15263 #endif /* not TRILIBRARY */
15264  struct otri triangleloop, trisym;
15265  long elementnumber;
15266  int neighbor1, neighbor2, neighbor3;
15267  triangle ptr; /* Temporary variable used by sym(). */
15268 
15269 #ifdef TRILIBRARY
15270  if (!b->quiet) {
15271  printf("Writing neighbors.\n");
15272  }
15273  /* Allocate memory for neighbors if necessary. */
15274  if (*neighborlist == (int *) NULL) {
15275  *neighborlist = (int *) trimalloc((int) (m->triangles.items * 3 *
15276  sizeof(int)));
15277  }
15278  nlist = *neighborlist;
15279  index = 0;
15280 #else /* not TRILIBRARY */
15281  if (!b->quiet) {
15282  printf("Writing %s.\n", neighborfilename);
15283  }
15284  outfile = fopen(neighborfilename, "w");
15285  if (outfile == (FILE *) NULL) {
15286  printf(" Error: Cannot create file %s.\n", neighborfilename);
15287  triexit(1);
15288  }
15289  /* Number of triangles, three neighbors per triangle. */
15290  fprintf(outfile, "%ld %d\n", m->triangles.items, 3);
15291 #endif /* not TRILIBRARY */
15292 
15293  traversalinit(&m->triangles);
15294  triangleloop.tri = triangletraverse(m);
15295  triangleloop.orient = 0;
15296  elementnumber = b->firstnumber;
15297  while (triangleloop.tri != (triangle *) NULL) {
15298  * (int *) (triangleloop.tri + 6) = (int) elementnumber;
15299  triangleloop.tri = triangletraverse(m);
15300  elementnumber++;
15301  }
15302  * (int *) (m->dummytri + 6) = -1;
15303 
15304  traversalinit(&m->triangles);
15305  triangleloop.tri = triangletraverse(m);
15306  elementnumber = b->firstnumber;
15307  while (triangleloop.tri != (triangle *) NULL) {
15308  triangleloop.orient = 1;
15309  sym(triangleloop, trisym);
15310  neighbor1 = * (int *) (trisym.tri + 6);
15311  triangleloop.orient = 2;
15312  sym(triangleloop, trisym);
15313  neighbor2 = * (int *) (trisym.tri + 6);
15314  triangleloop.orient = 0;
15315  sym(triangleloop, trisym);
15316  neighbor3 = * (int *) (trisym.tri + 6);
15317 #ifdef TRILIBRARY
15318  nlist[index++] = neighbor1;
15319  nlist[index++] = neighbor2;
15320  nlist[index++] = neighbor3;
15321 #else /* not TRILIBRARY */
15322  /* Triangle number, neighboring triangle numbers. */
15323  fprintf(outfile, "%4ld %d %d %d\n", elementnumber,
15324  neighbor1, neighbor2, neighbor3);
15325 #endif /* not TRILIBRARY */
15326 
15327  triangleloop.tri = triangletraverse(m);
15328  elementnumber++;
15329  }
15330 
15331 #ifndef TRILIBRARY
15332  finishfile(outfile, argc, argv);
15333 #endif /* not TRILIBRARY */
15334 }
15335 
15336 /*****************************************************************************/
15337 /* */
15338 /* writeoff() Write the triangulation to an .off file. */
15339 /* */
15340 /* OFF stands for the Object File Format, a format used by the Geometry */
15341 /* Center's Geomview package. */
15342 /* */
15343 /*****************************************************************************/
15344 
15345 #ifndef TRILIBRARY
15346 
15347 #ifdef ANSI_DECLARATORS
15348 void writeoff(struct mesh *m, struct behavior *b, char *offfilename,
15349  int argc, char **argv)
15350 #else /* not ANSI_DECLARATORS */
15351 void writeoff(m, b, offfilename, argc, argv)
15352 struct mesh *m;
15353 struct behavior *b;
15354 char *offfilename;
15355 int argc;
15356 char **argv;
15357 #endif /* not ANSI_DECLARATORS */
15358 
15359 {
15360  FILE *outfile;
15361  struct otri triangleloop;
15362  vertex vertexloop;
15363  vertex p1, p2, p3;
15364  long outvertices;
15365 
15366  if (!b->quiet) {
15367  printf("Writing %s.\n", offfilename);
15368  }
15369 
15370  if (b->jettison) {
15371  outvertices = m->vertices.items - m->undeads;
15372  } else {
15373  outvertices = m->vertices.items;
15374  }
15375 
15376  outfile = fopen(offfilename, "w");
15377  if (outfile == (FILE *) NULL) {
15378  printf(" Error: Cannot create file %s.\n", offfilename);
15379  triexit(1);
15380  }
15381  /* Number of vertices, triangles, and edges. */
15382  fprintf(outfile, "OFF\n%ld %ld %ld\n", outvertices, m->triangles.items,
15383  m->edges);
15384 
15385  /* Write the vertices. */
15386  traversalinit(&m->vertices);
15387  vertexloop = vertextraverse(m);
15388  while (vertexloop != (vertex) NULL) {
15389  if (!b->jettison || (vertextype(vertexloop) != UNDEADVERTEX)) {
15390  /* The "0.0" is here because the OFF format uses 3D coordinates. */
15391  fprintf(outfile, " %.17g %.17g %.17g\n", vertexloop[0], vertexloop[1],
15392  0.0);
15393  }
15394  vertexloop = vertextraverse(m);
15395  }
15396 
15397  /* Write the triangles. */
15398  traversalinit(&m->triangles);
15399  triangleloop.tri = triangletraverse(m);
15400  triangleloop.orient = 0;
15401  while (triangleloop.tri != (triangle *) NULL) {
15402  org(triangleloop, p1);
15403  dest(triangleloop, p2);
15404  apex(triangleloop, p3);
15405  /* The "3" means a three-vertex polygon. */
15406  fprintf(outfile, " 3 %4d %4d %4d\n", vertexmark(p1) - b->firstnumber,
15407  vertexmark(p2) - b->firstnumber, vertexmark(p3) - b->firstnumber);
15408  triangleloop.tri = triangletraverse(m);
15409  }
15410  finishfile(outfile, argc, argv);
15411 }
15412 
15413 #endif /* not TRILIBRARY */
15414 
15417 /********* File I/O routines end here *********/
15418 
15419 /*****************************************************************************/
15420 /* */
15421 /* quality_statistics() Print statistics about the quality of the mesh. */
15422 /* */
15423 /*****************************************************************************/
15424 
15425 #ifdef ANSI_DECLARATORS
15426 void quality_statistics(struct mesh *m, struct behavior *b)
15427 #else /* not ANSI_DECLARATORS */
15428 void quality_statistics(m, b)
15429 struct mesh *m;
15430 struct behavior *b;
15431 #endif /* not ANSI_DECLARATORS */
15432 
15433 {
15434  struct otri triangleloop;
15435  vertex p[3];
15436  REAL cossquaretable[8];
15437  REAL ratiotable[16];
15438  REAL dx[3], dy[3];
15439  REAL edgelength[3];
15440  REAL dotproduct;
15441  REAL cossquare;
15442  REAL triarea;
15443  REAL shortest, longest;
15444  REAL trilongest2;
15445  REAL smallestarea, biggestarea;
15446  REAL triminaltitude2;
15447  REAL minaltitude;
15448  REAL triaspect2;
15449  REAL worstaspect;
15450  REAL smallestangle, biggestangle;
15451  REAL radconst, degconst;
15452  int angletable[18];
15453  int aspecttable[16];
15454  int aspectindex;
15455  int tendegree;
15456  int acutebiggest;
15457  int i, ii, j, k;
15458 
15459  printf("Mesh quality statistics:\n\n");
15460  radconst = PI / 18.0;
15461  degconst = 180.0 / PI;
15462  for (i = 0; i < 8; i++) {
15463  cossquaretable[i] = cos(radconst * (REAL) (i + 1));
15464  cossquaretable[i] = cossquaretable[i] * cossquaretable[i];
15465  }
15466  for (i = 0; i < 18; i++) {
15467  angletable[i] = 0;
15468  }
15469 
15470  ratiotable[0] = 1.5; ratiotable[1] = 2.0;
15471  ratiotable[2] = 2.5; ratiotable[3] = 3.0;
15472  ratiotable[4] = 4.0; ratiotable[5] = 6.0;
15473  ratiotable[6] = 10.0; ratiotable[7] = 15.0;
15474  ratiotable[8] = 25.0; ratiotable[9] = 50.0;
15475  ratiotable[10] = 100.0; ratiotable[11] = 300.0;
15476  ratiotable[12] = 1000.0; ratiotable[13] = 10000.0;
15477  ratiotable[14] = 100000.0; ratiotable[15] = 0.0;
15478  for (i = 0; i < 16; i++) {
15479  aspecttable[i] = 0;
15480  }
15481 
15482  worstaspect = 0.0;
15483  minaltitude = m->xmax - m->xmin + m->ymax - m->ymin;
15484  minaltitude = minaltitude * minaltitude;
15485  shortest = minaltitude;
15486  longest = 0.0;
15487  smallestarea = minaltitude;
15488  biggestarea = 0.0;
15489  worstaspect = 0.0;
15490  smallestangle = 0.0;
15491  biggestangle = 2.0;
15492  acutebiggest = 1;
15493 
15494  traversalinit(&m->triangles);
15495  triangleloop.tri = triangletraverse(m);
15496  triangleloop.orient = 0;
15497  while (triangleloop.tri != (triangle *) NULL) {
15498  org(triangleloop, p[0]);
15499  dest(triangleloop, p[1]);
15500  apex(triangleloop, p[2]);
15501  trilongest2 = 0.0;
15502 
15503  for (i = 0; i < 3; i++) {
15504  j = plus1mod3[i];
15505  k = minus1mod3[i];
15506  dx[i] = p[j][0] - p[k][0];
15507  dy[i] = p[j][1] - p[k][1];
15508  edgelength[i] = dx[i] * dx[i] + dy[i] * dy[i];
15509  if (edgelength[i] > trilongest2) {
15510  trilongest2 = edgelength[i];
15511  }
15512  if (edgelength[i] > longest) {
15513  longest = edgelength[i];
15514  }
15515  if (edgelength[i] < shortest) {
15516  shortest = edgelength[i];
15517  }
15518  }
15519 
15520  triarea = counterclockwise(m, b, p[0], p[1], p[2]);
15521  if (triarea < smallestarea) {
15522  smallestarea = triarea;
15523  }
15524  if (triarea > biggestarea) {
15525  biggestarea = triarea;
15526  }
15527  triminaltitude2 = triarea * triarea / trilongest2;
15528  if (triminaltitude2 < minaltitude) {
15529  minaltitude = triminaltitude2;
15530  }
15531  triaspect2 = trilongest2 / triminaltitude2;
15532  if (triaspect2 > worstaspect) {
15533  worstaspect = triaspect2;
15534  }
15535  aspectindex = 0;
15536  while ((triaspect2 > ratiotable[aspectindex] * ratiotable[aspectindex])
15537  && (aspectindex < 15)) {
15538  aspectindex++;
15539  }
15540  aspecttable[aspectindex]++;
15541 
15542  for (i = 0; i < 3; i++) {
15543  j = plus1mod3[i];
15544  k = minus1mod3[i];
15545  dotproduct = dx[j] * dx[k] + dy[j] * dy[k];
15546  cossquare = dotproduct * dotproduct / (edgelength[j] * edgelength[k]);
15547  tendegree = 8;
15548  for (ii = 7; ii >= 0; ii--) {
15549  if (cossquare > cossquaretable[ii]) {
15550  tendegree = ii;
15551  }
15552  }
15553  if (dotproduct <= 0.0) {
15554  angletable[tendegree]++;
15555  if (cossquare > smallestangle) {
15556  smallestangle = cossquare;
15557  }
15558  if (acutebiggest && (cossquare < biggestangle)) {
15559  biggestangle = cossquare;
15560  }
15561  } else {
15562  angletable[17 - tendegree]++;
15563  if (acutebiggest || (cossquare > biggestangle)) {
15564  biggestangle = cossquare;
15565  acutebiggest = 0;
15566  }
15567  }
15568  }
15569  triangleloop.tri = triangletraverse(m);
15570  }
15571 
15572  shortest = sqrt(shortest);
15573  longest = sqrt(longest);
15574  minaltitude = sqrt(minaltitude);
15575  worstaspect = sqrt(worstaspect);
15576  smallestarea *= 0.5;
15577  biggestarea *= 0.5;
15578  if (smallestangle >= 1.0) {
15579  smallestangle = 0.0;
15580  } else {
15581  smallestangle = degconst * acos(sqrt(smallestangle));
15582  }
15583  if (biggestangle >= 1.0) {
15584  biggestangle = 180.0;
15585  } else {
15586  if (acutebiggest) {
15587  biggestangle = degconst * acos(sqrt(biggestangle));
15588  } else {
15589  biggestangle = 180.0 - degconst * acos(sqrt(biggestangle));
15590  }
15591  }
15592 
15593  printf(" Smallest area: %16.5g | Largest area: %16.5g\n",
15594  smallestarea, biggestarea);
15595  printf(" Shortest edge: %16.5g | Longest edge: %16.5g\n",
15596  shortest, longest);
15597  printf(" Shortest altitude: %12.5g | Largest aspect ratio: %8.5g\n\n",
15598  minaltitude, worstaspect);
15599 
15600  printf(" Triangle aspect ratio histogram:\n");
15601  printf(" 1.1547 - %-6.6g : %8d | %6.6g - %-6.6g : %8d\n",
15602  ratiotable[0], aspecttable[0], ratiotable[7], ratiotable[8],
15603  aspecttable[8]);
15604  for (i = 1; i < 7; i++) {
15605  printf(" %6.6g - %-6.6g : %8d | %6.6g - %-6.6g : %8d\n",
15606  ratiotable[i - 1], ratiotable[i], aspecttable[i],
15607  ratiotable[i + 7], ratiotable[i + 8], aspecttable[i + 8]);
15608  }
15609  printf(" %6.6g - %-6.6g : %8d | %6.6g - : %8d\n",
15610  ratiotable[6], ratiotable[7], aspecttable[7], ratiotable[14],
15611  aspecttable[15]);
15612  printf(" (Aspect ratio is longest edge divided by shortest altitude)\n\n");
15613 
15614  printf(" Smallest angle: %15.5g | Largest angle: %15.5g\n\n",
15615  smallestangle, biggestangle);
15616 
15617  printf(" Angle histogram:\n");
15618  for (i = 0; i < 9; i++) {
15619  printf(" %3d - %3d degrees: %8d | %3d - %3d degrees: %8d\n",
15620  i * 10, i * 10 + 10, angletable[i],
15621  i * 10 + 90, i * 10 + 100, angletable[i + 9]);
15622  }
15623  printf("\n");
15624 }
15625 
15626 /*****************************************************************************/
15627 /* */
15628 /* statistics() Print all sorts of cool facts. */
15629 /* */
15630 /*****************************************************************************/
15631 
15632 #ifdef ANSI_DECLARATORS
15633 void statistics(struct mesh *m, struct behavior *b)
15634 #else /* not ANSI_DECLARATORS */
15635 void statistics(m, b)
15636 struct mesh *m;
15637 struct behavior *b;
15638 #endif /* not ANSI_DECLARATORS */
15639 
15640 {
15641  printf("\nStatistics:\n\n");
15642  printf(" Input vertices: %d\n", m->invertices);
15643  if (b->refine) {
15644  printf(" Input triangles: %d\n", m->inelements);
15645  }
15646  if (b->poly) {
15647  printf(" Input segments: %d\n", m->insegments);
15648  if (!b->refine) {
15649  printf(" Input holes: %d\n", m->holes);
15650  }
15651  }
15652 
15653  printf("\n Mesh vertices: %ld\n", m->vertices.items - m->undeads);
15654  printf(" Mesh triangles: %ld\n", m->triangles.items);
15655  printf(" Mesh edges: %ld\n", m->edges);
15656  printf(" Mesh exterior boundary edges: %ld\n", m->hullsize);
15657  if (b->poly || b->refine) {
15658  printf(" Mesh interior boundary edges: %ld\n",
15659  m->subsegs.items - m->hullsize);
15660  printf(" Mesh subsegments (constrained edges): %ld\n",
15661  m->subsegs.items);
15662  }
15663  printf("\n");
15664 
15665  if (b->verbose) {
15666  quality_statistics(m, b);
15667  printf("Memory allocation statistics:\n\n");
15668  printf(" Maximum number of vertices: %ld\n", m->vertices.maxitems);
15669  printf(" Maximum number of triangles: %ld\n", m->triangles.maxitems);
15670  if (m->subsegs.maxitems > 0) {
15671  printf(" Maximum number of subsegments: %ld\n", m->subsegs.maxitems);
15672  }
15673  if (m->viri.maxitems > 0) {
15674  printf(" Maximum number of viri: %ld\n", m->viri.maxitems);
15675  }
15676  if (m->badsubsegs.maxitems > 0) {
15677  printf(" Maximum number of encroached subsegments: %ld\n",
15678  m->badsubsegs.maxitems);
15679  }
15680  if (m->badtriangles.maxitems > 0) {
15681  printf(" Maximum number of bad triangles: %ld\n",
15682  m->badtriangles.maxitems);
15683  }
15684  if (m->flipstackers.maxitems > 0) {
15685  printf(" Maximum number of stacked triangle flips: %ld\n",
15686  m->flipstackers.maxitems);
15687  }
15688  if (m->splaynodes.maxitems > 0) {
15689  printf(" Maximum number of splay tree nodes: %ld\n",
15690  m->splaynodes.maxitems);
15691  }
15692  printf(" Approximate heap memory use (bytes): %ld\n\n",
15693  m->vertices.maxitems * m->vertices.itembytes +
15694  m->triangles.maxitems * m->triangles.itembytes +
15695  m->subsegs.maxitems * m->subsegs.itembytes +
15696  m->viri.maxitems * m->viri.itembytes +
15697  m->badsubsegs.maxitems * m->badsubsegs.itembytes +
15698  m->badtriangles.maxitems * m->badtriangles.itembytes +
15699  m->flipstackers.maxitems * m->flipstackers.itembytes +
15700  m->splaynodes.maxitems * m->splaynodes.itembytes);
15701 
15702  printf("Algorithmic statistics:\n\n");
15703  if (!b->weighted) {
15704  printf(" Number of incircle tests: %ld\n", m->incirclecount);
15705  } else {
15706  printf(" Number of 3D orientation tests: %ld\n", m->orient3dcount);
15707  }
15708  printf(" Number of 2D orientation tests: %ld\n", m->counterclockcount);
15709  if (m->hyperbolacount > 0) {
15710  printf(" Number of right-of-hyperbola tests: %ld\n",
15711  m->hyperbolacount);
15712  }
15713  if (m->circletopcount > 0) {
15714  printf(" Number of circle top computations: %ld\n",
15715  m->circletopcount);
15716  }
15717  if (m->circumcentercount > 0) {
15718  printf(" Number of triangle circumcenter computations: %ld\n",
15719  m->circumcentercount);
15720  }
15721  printf("\n");
15722  }
15723 }
15724 
15725 /*****************************************************************************/
15726 /* */
15727 /* main() or triangulate() Gosh, do everything. */
15728 /* */
15729 /* The sequence is roughly as follows. Many of these steps can be skipped, */
15730 /* depending on the command line switches. */
15731 /* */
15732 /* - Initialize constants and parse the command line. */
15733 /* - Read the vertices from a file and either */
15734 /* - triangulate them (no -r), or */
15735 /* - read an old mesh from files and reconstruct it (-r). */
15736 /* - Insert the PSLG segments (-p), and possibly segments on the convex */
15737 /* hull (-c). */
15738 /* - Read the holes (-p), regional attributes (-pA), and regional area */
15739 /* constraints (-pa). Carve the holes and concavities, and spread the */
15740 /* regional attributes and area constraints. */
15741 /* - Enforce the constraints on minimum angle (-q) and maximum area (-a). */
15742 /* Also enforce the conforming Delaunay property (-q and -a). */
15743 /* - Compute the number of edges in the resulting mesh. */
15744 /* - Promote the mesh's linear triangles to higher order elements (-o). */
15745 /* - Write the output files and print the statistics. */
15746 /* - Check the consistency and Delaunay property of the mesh (-C). */
15747 /* */
15748 /*****************************************************************************/
15749 
15750 #ifdef TRILIBRARY
15751 
15752 #ifdef ANSI_DECLARATORS
15753 void triangulate(char *triswitches, struct triangulateio *in,
15754  struct triangulateio *out, struct triangulateio *vorout)
15755 #else /* not ANSI_DECLARATORS */
15756 void triangulate(triswitches, in, out, vorout)
15757 char *triswitches;
15758 struct triangulateio *in;
15759 struct triangulateio *out;
15760 struct triangulateio *vorout;
15761 #endif /* not ANSI_DECLARATORS */
15762 
15763 #else /* not TRILIBRARY */
15764 
15765 #ifdef ANSI_DECLARATORS
15766 int main(int argc, char **argv)
15767 #else /* not ANSI_DECLARATORS */
15768 int main(argc, argv)
15769 int argc;
15770 char **argv;
15771 #endif /* not ANSI_DECLARATORS */
15772 
15773 #endif /* not TRILIBRARY */
15774 
15775 {
15776  struct mesh m;
15777  struct behavior b;
15778  REAL *holearray; /* Array of holes. */
15779  REAL *regionarray; /* Array of regional attributes and area constraints. */
15780 #ifndef TRILIBRARY
15781  FILE* polyfile;
15782 #endif /* not TRILIBRARY */
15783 #ifndef NO_TIMER
15784  /* Variables for timing the performance of Triangle. The types are */
15785  /* defined in sys/time.h. */
15786  struct timeval tv0, tv1, tv2, tv3, tv4, tv5, tv6;
15787  struct timezone tz;
15788 #endif /* not NO_TIMER */
15789 
15790 #ifndef NO_TIMER
15791  gettimeofday(&tv0, &tz);
15792 #endif /* not NO_TIMER */
15793 
15794  triangleinit(&m);
15795 #ifdef TRILIBRARY
15796  parsecommandline(1, &triswitches, &b);
15797 #else /* not TRILIBRARY */
15798  parsecommandline(argc, argv, &b);
15799 #endif /* not TRILIBRARY */
15800  m.steinerleft = b.steiner;
15801 
15802 #ifdef TRILIBRARY
15803  transfernodes(&m, &b, in->pointlist, in->pointattributelist,
15804  in->pointmarkerlist, in->numberofpoints,
15805  in->numberofpointattributes);
15806 #else /* not TRILIBRARY */
15807  readnodes(&m, &b, b.innodefilename, b.inpolyfilename, &polyfile);
15808 #endif /* not TRILIBRARY */
15809 
15810 #ifndef NO_TIMER
15811  if (!b.quiet) {
15812  gettimeofday(&tv1, &tz);
15813  }
15814 #endif /* not NO_TIMER */
15815 
15816 #ifdef CDT_ONLY
15817  m.hullsize = delaunay(&m, &b); /* Triangulate the vertices. */
15818 #else /* not CDT_ONLY */
15819  if (b.refine) {
15820  /* Read and reconstruct a mesh. */
15821 #ifdef TRILIBRARY
15822  m.hullsize = reconstruct(&m, &b, in->trianglelist,
15823  in->triangleattributelist, in->trianglearealist,
15824  in->numberoftriangles, in->numberofcorners,
15825  in->numberoftriangleattributes,
15826  in->segmentlist, in->segmentmarkerlist,
15827  in->numberofsegments);
15828 #else /* not TRILIBRARY */
15829  m.hullsize = reconstruct(&m, &b, b.inelefilename, b.areafilename,
15830  b.inpolyfilename, polyfile);
15831 #endif /* not TRILIBRARY */
15832  } else {
15833  m.hullsize = delaunay(&m, &b); /* Triangulate the vertices. */
15834  }
15835 #endif /* not CDT_ONLY */
15836 
15837 #ifndef NO_TIMER
15838  if (!b.quiet) {
15839  gettimeofday(&tv2, &tz);
15840  if (b.refine) {
15841  printf("Mesh reconstruction");
15842  } else {
15843  printf("Delaunay");
15844  }
15845  printf(" milliseconds: %ld\n", 1000l * (tv2.tv_sec - tv1.tv_sec) +
15846  (tv2.tv_usec - tv1.tv_usec) / 1000l);
15847  }
15848 #endif /* not NO_TIMER */
15849 
15850  /* Ensure that no vertex can be mistaken for a triangular bounding */
15851  /* box vertex in insertvertex(). */
15852  m.infvertex1 = (vertex) NULL;
15853  m.infvertex2 = (vertex) NULL;
15854  m.infvertex3 = (vertex) NULL;
15855 
15856  if (b.usesegments) {
15857  m.checksegments = 1; /* Segments will be introduced next. */
15858  if (!b.refine) {
15859  /* Insert PSLG segments and/or convex hull segments. */
15860 #ifdef TRILIBRARY
15861  formskeleton(&m, &b, in->segmentlist,
15862  in->segmentmarkerlist, in->numberofsegments);
15863 #else /* not TRILIBRARY */
15864  formskeleton(&m, &b, polyfile, b.inpolyfilename);
15865 #endif /* not TRILIBRARY */
15866  }
15867  }
15868 
15869 #ifndef NO_TIMER
15870  if (!b.quiet) {
15871  gettimeofday(&tv3, &tz);
15872  if (b.usesegments && !b.refine) {
15873  printf("Segment milliseconds: %ld\n",
15874  1000l * (tv3.tv_sec - tv2.tv_sec) +
15875  (tv3.tv_usec - tv2.tv_usec) / 1000l);
15876  }
15877  }
15878 #endif /* not NO_TIMER */
15879 
15880  if (b.poly && (m.triangles.items > 0)) {
15881 #ifdef TRILIBRARY
15882  holearray = in->holelist;
15883  m.holes = in->numberofholes;
15884  regionarray = in->regionlist;
15885  m.regions = in->numberofregions;
15886 #else /* not TRILIBRARY */
15887  readholes(&m, &b, polyfile, b.inpolyfilename, &holearray, &m.holes,
15888  &regionarray, &m.regions);
15889 #endif /* not TRILIBRARY */
15890  if (!b.refine) {
15891  /* Carve out holes and concavities. */
15892  carveholes(&m, &b, holearray, m.holes, regionarray, m.regions);
15893  }
15894  } else {
15895  /* Without a PSLG, there can be no holes or regional attributes */
15896  /* or area constraints. The following are set to zero to avoid */
15897  /* an accidental free() later. */
15898  m.holes = 0;
15899  m.regions = 0;
15900  }
15901 
15902 #ifndef NO_TIMER
15903  if (!b.quiet) {
15904  gettimeofday(&tv4, &tz);
15905  if (b.poly && !b.refine) {
15906  printf("Hole milliseconds: %ld\n", 1000l * (tv4.tv_sec - tv3.tv_sec) +
15907  (tv4.tv_usec - tv3.tv_usec) / 1000l);
15908  }
15909  }
15910 #endif /* not NO_TIMER */
15911 
15912 #ifndef CDT_ONLY
15913  if (b.quality && (m.triangles.items > 0)) {
15914  enforcequality(&m, &b); /* Enforce angle and area constraints. */
15915  }
15916 #endif /* not CDT_ONLY */
15917 
15918 #ifndef NO_TIMER
15919  if (!b.quiet) {
15920  gettimeofday(&tv5, &tz);
15921 #ifndef CDT_ONLY
15922  if (b.quality) {
15923  printf("Quality milliseconds: %ld\n",
15924  1000l * (tv5.tv_sec - tv4.tv_sec) +
15925  (tv5.tv_usec - tv4.tv_usec) / 1000l);
15926  }
15927 #endif /* not CDT_ONLY */
15928  }
15929 #endif /* not NO_TIMER */
15930 
15931  /* Calculate the number of edges. */
15932  m.edges = (3l * m.triangles.items + m.hullsize) / 2l;
15933 
15934  if (b.order > 1) {
15935  highorder(&m, &b); /* Promote elements to higher polynomial order. */
15936  }
15937  if (!b.quiet) {
15938  printf("\n");
15939  }
15940 
15941 #ifdef TRILIBRARY
15942  if (b.jettison) {
15943  out->numberofpoints = m.vertices.items - m.undeads;
15944  } else {
15945  out->numberofpoints = m.vertices.items;
15946  }
15947  out->numberofpointattributes = m.nextras;
15948  out->numberoftriangles = m.triangles.items;
15949  out->numberofcorners = (b.order + 1) * (b.order + 2) / 2;
15950  out->numberoftriangleattributes = m.eextras;
15951  out->numberofedges = m.edges;
15952  if (b.usesegments) {
15953  out->numberofsegments = m.subsegs.items;
15954  } else {
15955  out->numberofsegments = m.hullsize;
15956  }
15957  if (vorout != (struct triangulateio *) NULL) {
15958  vorout->numberofpoints = m.triangles.items;
15959  vorout->numberofpointattributes = m.nextras;
15960  vorout->numberofedges = m.edges;
15961  }
15962 #endif /* TRILIBRARY */
15963  /* If not using iteration numbers, don't write a .node file if one was */
15964  /* read, because the original one would be overwritten! */
15965  if (b.nonodewritten || (b.noiterationnum && m.readnodefile)) {
15966  if (!b.quiet) {
15967 #ifdef TRILIBRARY
15968  printf("NOT writing vertices.\n");
15969 #else /* not TRILIBRARY */
15970  printf("NOT writing a .node file.\n");
15971 #endif /* not TRILIBRARY */
15972  }
15973  numbernodes(&m, &b); /* We must remember to number the vertices. */
15974  } else {
15975  /* writenodes() numbers the vertices too. */
15976 #ifdef TRILIBRARY
15977  writenodes(&m, &b, &out->pointlist, &out->pointattributelist,
15978  &out->pointmarkerlist);
15979 #else /* not TRILIBRARY */
15980  writenodes(&m, &b, b.outnodefilename, argc, argv);
15981 #endif /* TRILIBRARY */
15982  }
15983  if (b.noelewritten) {
15984  if (!b.quiet) {
15985 #ifdef TRILIBRARY
15986  printf("NOT writing triangles.\n");
15987 #else /* not TRILIBRARY */
15988  printf("NOT writing an .ele file.\n");
15989 #endif /* not TRILIBRARY */
15990  }
15991  } else {
15992 #ifdef TRILIBRARY
15993  writeelements(&m, &b, &out->trianglelist, &out->triangleattributelist);
15994 #else /* not TRILIBRARY */
15995  writeelements(&m, &b, b.outelefilename, argc, argv);
15996 #endif /* not TRILIBRARY */
15997  }
15998  /* The -c switch (convex switch) causes a PSLG to be written */
15999  /* even if none was read. */
16000  if (b.poly || b.convex) {
16001  /* If not using iteration numbers, don't overwrite the .poly file. */
16002  if (b.nopolywritten || b.noiterationnum) {
16003  if (!b.quiet) {
16004 #ifdef TRILIBRARY
16005  printf("NOT writing segments.\n");
16006 #else /* not TRILIBRARY */
16007  printf("NOT writing a .poly file.\n");
16008 #endif /* not TRILIBRARY */
16009  }
16010  } else {
16011 #ifdef TRILIBRARY
16012  writepoly(&m, &b, &out->segmentlist, &out->segmentmarkerlist);
16013  out->numberofholes = m.holes;
16014  out->numberofregions = m.regions;
16015  if (b.poly) {
16016  out->holelist = in->holelist;
16017  out->regionlist = in->regionlist;
16018  } else {
16019  out->holelist = (REAL *) NULL;
16020  out->regionlist = (REAL *) NULL;
16021  }
16022 #else /* not TRILIBRARY */
16023  writepoly(&m, &b, b.outpolyfilename, holearray, m.holes, regionarray,
16024  m.regions, argc, argv);
16025 #endif /* not TRILIBRARY */
16026  }
16027  }
16028 #ifndef TRILIBRARY
16029 #ifndef CDT_ONLY
16030  if (m.regions > 0) {
16031  trifree((VOID *) regionarray);
16032  }
16033 #endif /* not CDT_ONLY */
16034  if (m.holes > 0) {
16035  trifree((VOID *) holearray);
16036  }
16037  if (b.geomview) {
16038  writeoff(&m, &b, b.offfilename, argc, argv);
16039  }
16040 #endif /* not TRILIBRARY */
16041  if (b.edgesout) {
16042 #ifdef TRILIBRARY
16043  writeedges(&m, &b, &out->edgelist, &out->edgemarkerlist);
16044 #else /* not TRILIBRARY */
16045  writeedges(&m, &b, b.edgefilename, argc, argv);
16046 #endif /* not TRILIBRARY */
16047  }
16048  if (b.voronoi) {
16049 #ifdef TRILIBRARY
16050  writevoronoi(&m, &b, &vorout->pointlist, &vorout->pointattributelist,
16051  &vorout->pointmarkerlist, &vorout->edgelist,
16052  &vorout->edgemarkerlist, &vorout->normlist);
16053 #else /* not TRILIBRARY */
16054  writevoronoi(&m, &b, b.vnodefilename, b.vedgefilename, argc, argv);
16055 #endif /* not TRILIBRARY */
16056  }
16057  if (b.neighbors) {
16058 #ifdef TRILIBRARY
16059  writeneighbors(&m, &b, &out->neighborlist);
16060 #else /* not TRILIBRARY */
16061  writeneighbors(&m, &b, b.neighborfilename, argc, argv);
16062 #endif /* not TRILIBRARY */
16063  }
16064 
16065  if (!b.quiet) {
16066 #ifndef NO_TIMER
16067  gettimeofday(&tv6, &tz);
16068  printf("\nOutput milliseconds: %ld\n",
16069  1000l * (tv6.tv_sec - tv5.tv_sec) +
16070  (tv6.tv_usec - tv5.tv_usec) / 1000l);
16071  printf("Total running milliseconds: %ld\n",
16072  1000l * (tv6.tv_sec - tv0.tv_sec) +
16073  (tv6.tv_usec - tv0.tv_usec) / 1000l);
16074 #endif /* not NO_TIMER */
16075 
16076  statistics(&m, &b);
16077  }
16078 
16079 #ifndef REDUCED
16080  if (b.docheck) {
16081  checkmesh(&m, &b);
16082  checkdelaunay(&m, &b);
16083  }
16084 #endif /* not REDUCED */
16085 
16086  triangledeinit(&m, &b);
16087 #ifndef TRILIBRARY
16088  return 0;
16089 #endif /* not TRILIBRARY */
16090 }