/contrib/gtkgensurf/triangle.c
C | 12631 lines | 8857 code | 874 blank | 2900 comment | 1792 complexity | 8758741fd6acfa480a2e2328d8de068f MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, LGPL-2.0
Large files files are truncated, but you can click here to view the full file
- #define ANSI_DECLARATORS
- /*****************************************************************************/
- /* */
- /* 888888888 ,o, / 888 */
- /* 888 88o88o " o8888o 88o8888o o88888o 888 o88888o */
- /* 888 888 888 88b 888 888 888 888 888 d888 88b */
- /* 888 888 888 o88^o888 888 888 "88888" 888 8888oo888 */
- /* 888 888 888 C888 888 888 888 / 888 q888 */
- /* 888 888 888 "88o^888 888 888 Cb 888 "88oooo" */
- /* "8oo8D */
- /* */
- /* A Two-Dimensional Quality Mesh Generator and Delaunay Triangulator. */
- /* (triangle.c) */
- /* */
- /* Version 1.3 */
- /* July 19, 1996 */
- /* */
- /* Copyright 1996 */
- /* Jonathan Richard Shewchuk */
- /* School of Computer Science */
- /* Carnegie Mellon University */
- /* 5000 Forbes Avenue */
- /* Pittsburgh, Pennsylvania 15213-3891 */
- /* jrs@cs.cmu.edu */
- /* */
- /* This program may be freely redistributed under the condition that the */
- /* copyright notices (including this entire header and the copyright */
- /* notice printed when the `-h' switch is selected) are not removed, and */
- /* no compensation is received. Private, research, and institutional */
- /* use is free. You may distribute modified versions of this code UNDER */
- /* THE CONDITION THAT THIS CODE AND ANY MODIFICATIONS MADE TO IT IN THE */
- /* SAME FILE REMAIN UNDER COPYRIGHT OF THE ORIGINAL AUTHOR, BOTH SOURCE */
- /* AND OBJECT CODE ARE MADE FREELY AVAILABLE WITHOUT CHARGE, AND CLEAR */
- /* NOTICE IS GIVEN OF THE MODIFICATIONS. Distribution of this code as */
- /* part of a commercial system is permissible ONLY BY DIRECT ARRANGEMENT */
- /* WITH THE AUTHOR. (If you are not directly supplying this code to a */
- /* customer, and you are instead telling them how they can obtain it for */
- /* free, then you are not required to make any arrangement with me.) */
- /* */
- /* Hypertext instructions for Triangle are available on the Web at */
- /* */
- /* http://www.cs.cmu.edu/~quake/triangle.html */
- /* */
- /* Some of the references listed below are marked [*]. These are available */
- /* for downloading from the Web page */
- /* */
- /* http://www.cs.cmu.edu/~quake/triangle.research.html */
- /* */
- /* A paper discussing some aspects of Triangle is available. See Jonathan */
- /* Richard Shewchuk, "Triangle: Engineering a 2D Quality Mesh Generator */
- /* and Delaunay Triangulator," First Workshop on Applied Computational */
- /* Geometry, ACM, May 1996. [*] */
- /* */
- /* Triangle was created as part of the Archimedes project in the School of */
- /* Computer Science at Carnegie Mellon University. Archimedes is a */
- /* system for compiling parallel finite element solvers. For further */
- /* information, see Anja Feldmann, Omar Ghattas, John R. Gilbert, Gary L. */
- /* Miller, David R. O'Hallaron, Eric J. Schwabe, Jonathan R. Shewchuk, */
- /* and Shang-Hua Teng, "Automated Parallel Solution of Unstructured PDE */
- /* Problems." To appear in Communications of the ACM, we hope. */
- /* */
- /* The quality mesh generation algorithm is due to Jim Ruppert, "A */
- /* Delaunay Refinement Algorithm for Quality 2-Dimensional Mesh */
- /* Generation," Journal of Algorithms 18(3):548-585, May 1995. [*] */
- /* */
- /* My implementation of the divide-and-conquer and incremental Delaunay */
- /* triangulation algorithms follows closely the presentation of Guibas */
- /* and Stolfi, even though I use a triangle-based data structure instead */
- /* of their quad-edge data structure. (In fact, I originally implemented */
- /* Triangle using the quad-edge data structure, but switching to a */
- /* triangle-based data structure sped Triangle by a factor of two.) The */
- /* mesh manipulation primitives and the two aforementioned Delaunay */
- /* triangulation algorithms are described by Leonidas J. Guibas and Jorge */
- /* Stolfi, "Primitives for the Manipulation of General Subdivisions and */
- /* the Computation of Voronoi Diagrams," ACM Transactions on Graphics */
- /* 4(2):74-123, April 1985. */
- /* */
- /* Their O(n log n) divide-and-conquer algorithm is adapted from Der-Tsai */
- /* Lee and Bruce J. Schachter, "Two Algorithms for Constructing the */
- /* Delaunay Triangulation," International Journal of Computer and */
- /* Information Science 9(3):219-242, 1980. The idea to improve the */
- /* divide-and-conquer algorithm by alternating between vertical and */
- /* horizontal cuts was introduced by Rex A. Dwyer, "A Faster Divide-and- */
- /* Conquer Algorithm for Constructing Delaunay Triangulations," */
- /* Algorithmica 2(2):137-151, 1987. */
- /* */
- /* The incremental insertion algorithm was first proposed by C. L. Lawson, */
- /* "Software for C1 Surface Interpolation," in Mathematical Software III, */
- /* John R. Rice, editor, Academic Press, New York, pp. 161-194, 1977. */
- /* For point location, I use the algorithm of Ernst P. Mucke, Isaac */
- /* Saias, and Binhai Zhu, "Fast Randomized Point Location Without */
- /* Preprocessing in Two- and Three-dimensional Delaunay Triangulations," */
- /* Proceedings of the Twelfth Annual Symposium on Computational Geometry, */
- /* ACM, May 1996. [*] If I were to randomize the order of point */
- /* insertion (I currently don't bother), their result combined with the */
- /* result of Leonidas J. Guibas, Donald E. Knuth, and Micha Sharir, */
- /* "Randomized Incremental Construction of Delaunay and Voronoi */
- /* Diagrams," Algorithmica 7(4):381-413, 1992, would yield an expected */
- /* O(n^{4/3}) bound on running time. */
- /* */
- /* The O(n log n) sweepline Delaunay triangulation algorithm is taken from */
- /* Steven Fortune, "A Sweepline Algorithm for Voronoi Diagrams", */
- /* Algorithmica 2(2):153-174, 1987. A random sample of edges on the */
- /* boundary of the triangulation are maintained in a splay tree for the */
- /* purpose of point location. Splay trees are described by Daniel */
- /* Dominic Sleator and Robert Endre Tarjan, "Self-Adjusting Binary Search */
- /* Trees," Journal of the ACM 32(3):652-686, July 1985. */
- /* */
- /* The algorithms for exact computation of the signs of determinants are */
- /* described in Jonathan Richard Shewchuk, "Adaptive Precision Floating- */
- /* Point Arithmetic and Fast Robust Geometric Predicates," Technical */
- /* Report CMU-CS-96-140, School of Computer Science, Carnegie Mellon */
- /* University, Pittsburgh, Pennsylvania, May 1996. [*] (Submitted to */
- /* Discrete & Computational Geometry.) An abbreviated version appears as */
- /* Jonathan Richard Shewchuk, "Robust Adaptive Floating-Point Geometric */
- /* Predicates," Proceedings of the Twelfth Annual Symposium on Computa- */
- /* tional Geometry, ACM, May 1996. [*] Many of the ideas for my exact */
- /* arithmetic routines originate with Douglas M. Priest, "Algorithms for */
- /* Arbitrary Precision Floating Point Arithmetic," Tenth Symposium on */
- /* Computer Arithmetic, 132-143, IEEE Computer Society Press, 1991. [*] */
- /* Many of the ideas for the correct evaluation of the signs of */
- /* determinants are taken from Steven Fortune and Christopher J. Van Wyk, */
- /* "Efficient Exact Arithmetic for Computational Geometry," Proceedings */
- /* of the Ninth Annual Symposium on Computational Geometry, ACM, */
- /* pp. 163-172, May 1993, and from Steven Fortune, "Numerical Stability */
- /* of Algorithms for 2D Delaunay Triangulations," International Journal */
- /* of Computational Geometry & Applications 5(1-2):193-213, March-June */
- /* 1995. */
- /* */
- /* For definitions of and results involving Delaunay triangulations, */
- /* constrained and conforming versions thereof, and other aspects of */
- /* triangular mesh generation, see the excellent survey by Marshall Bern */
- /* and David Eppstein, "Mesh Generation and Optimal Triangulation," in */
- /* Computing and Euclidean Geometry, Ding-Zhu Du and Frank Hwang, */
- /* editors, World Scientific, Singapore, pp. 23-90, 1992. */
- /* */
- /* The time for incrementally adding PSLG (planar straight line graph) */
- /* segments to create a constrained Delaunay triangulation is probably */
- /* O(n^2) per segment in the worst case and O(n) per edge in the common */
- /* case, where n is the number of triangles that intersect the segment */
- /* before it is inserted. This doesn't count point location, which can */
- /* be much more expensive. (This note does not apply to conforming */
- /* Delaunay triangulations, for which a different method is used to */
- /* insert segments.) */
- /* */
- /* The time for adding segments to a conforming Delaunay triangulation is */
- /* not clear, but does not depend upon n alone. In some cases, very */
- /* small features (like a point lying next to a segment) can cause a */
- /* single segment to be split an arbitrary number of times. Of course, */
- /* floating-point precision is a practical barrier to how much this can */
- /* happen. */
- /* */
- /* The time for deleting a point from a Delaunay triangulation is O(n^2) in */
- /* the worst case and O(n) in the common case, where n is the degree of */
- /* the point being deleted. I could improve this to expected O(n) time */
- /* by "inserting" the neighboring vertices in random order, but n is */
- /* usually quite small, so it's not worth the bother. (The O(n) time */
- /* for random insertion follows from L. Paul Chew, "Building Voronoi */
- /* Diagrams for Convex Polygons in Linear Expected Time," Technical */
- /* Report PCS-TR90-147, Department of Mathematics and Computer Science, */
- /* Dartmouth College, 1990. */
- /* */
- /* Ruppert's Delaunay refinement algorithm typically generates triangles */
- /* at a linear rate (constant time per triangle) after the initial */
- /* triangulation is formed. There may be pathological cases where more */
- /* time is required, but these never arise in practice. */
- /* */
- /* The segment intersection formulae are straightforward. If you want to */
- /* see them derived, see Franklin Antonio. "Faster Line Segment */
- /* Intersection." In Graphics Gems III (David Kirk, editor), pp. 199- */
- /* 202. Academic Press, Boston, 1992. */
- /* */
- /* If you make any improvements to this code, please please please let me */
- /* know, so that I may obtain the improvements. Even if you don't change */
- /* the code, I'd still love to hear what it's being used for. */
- /* */
- /* Disclaimer: Neither I nor Carnegie Mellon warrant this code in any way */
- /* whatsoever. This code is provided "as-is". Use at your own risk. */
- /* */
- /*****************************************************************************/
- /* For single precision (which will save some memory and reduce paging), */
- /* define the symbol SINGLE by using the -DSINGLE compiler switch or by */
- /* writing "#define SINGLE" below. */
- /* */
- /* For double precision (which will allow you to refine meshes to a smaller */
- /* edge length), leave SINGLE undefined. */
- /* */
- /* Double precision uses more memory, but improves the resolution of the */
- /* meshes you can generate with Triangle. It also reduces the likelihood */
- /* of a floating exception due to overflow. Finally, it is much faster */
- /* than single precision on 64-bit architectures like the DEC Alpha. I */
- /* recommend double precision unless you want to generate a mesh for which */
- /* you do not have enough memory. */
- #define SINGLE
- #ifdef SINGLE
- #define REAL float
- #else /* not SINGLE */
- #define REAL double
- #endif /* not SINGLE */
- /* If yours is not a Unix system, define the NO_TIMER compiler switch to */
- /* remove the Unix-specific timing code. */
- #define NO_TIMER
- /* To insert lots of self-checks for internal errors, define the SELF_CHECK */
- /* symbol. This will slow down the program significantly. It is best to */
- /* define the symbol using the -DSELF_CHECK compiler switch, but you could */
- /* write "#define SELF_CHECK" below. If you are modifying this code, I */
- /* recommend you turn self-checks on. */
- /* #define SELF_CHECK */
- /* To compile Triangle as a callable object library (triangle.o), define the */
- /* TRILIBRARY symbol. Read the file triangle.h for details on how to call */
- /* the procedure triangulate() that results. */
- #define TRILIBRARY
- /* It is possible to generate a smaller version of Triangle using one or */
- /* both of the following symbols. Define the REDUCED symbol to eliminate */
- /* all features that are primarily of research interest; specifically, the */
- /* -i, -F, -s, and -C switches. Define the CDT_ONLY symbol to eliminate */
- /* all meshing algorithms above and beyond constrained Delaunay */
- /* triangulation; specifically, the -r, -q, -a, -S, and -s switches. */
- /* These reductions are most likely to be useful when generating an object */
- /* library (triangle.o) by defining the TRILIBRARY symbol. */
- #define REDUCED
- #define CDT_ONLY
- /* On some machines, the exact arithmetic routines might be defeated by the */
- /* use of internal extended precision floating-point registers. Sometimes */
- /* this problem can be fixed by defining certain values to be volatile, */
- /* thus forcing them to be stored to memory and rounded off. This isn't */
- /* a great solution, though, as it slows Triangle down. */
- /* */
- /* To try this out, write "#define INEXACT volatile" below. Normally, */
- /* however, INEXACT should be defined to be nothing. ("#define INEXACT".) */
- #define INEXACT /* Nothing */
- /* #define INEXACT volatile */
- /* Maximum number of characters in a file name (including the null). */
- #define FILENAMESIZE 512
- /* Maximum number of characters in a line read from a file (including the */
- /* null). */
- #define INPUTLINESIZE 512
- /* For efficiency, a variety of data structures are allocated in bulk. The */
- /* following constants determine how many of each structure is allocated */
- /* at once. */
- #define TRIPERBLOCK 4092 /* Number of triangles allocated at once. */
- #define SHELLEPERBLOCK 508 /* Number of shell edges allocated at once. */
- #define POINTPERBLOCK 4092 /* Number of points allocated at once. */
- #define VIRUSPERBLOCK 1020 /* Number of virus triangles allocated at once. */
- /* Number of encroached segments allocated at once. */
- #define BADSEGMENTPERBLOCK 252
- /* Number of skinny triangles allocated at once. */
- #define BADTRIPERBLOCK 4092
- /* Number of splay tree nodes allocated at once. */
- #define SPLAYNODEPERBLOCK 508
- /* The point marker DEADPOINT is an arbitrary number chosen large enough to */
- /* (hopefully) not conflict with user boundary markers. Make sure that it */
- /* is small enough to fit into your machine's integer size. */
- #define DEADPOINT -1073741824
- /* The next line is used to outsmart some very stupid compilers. If your */
- /* compiler is smarter, feel free to replace the "int" with "void". */
- /* Not that it matters. */
- #define VOID int
- /* Two constants for algorithms based on random sampling. Both constants */
- /* have been chosen empirically to optimize their respective algorithms. */
- /* Used for the point location scheme of Mucke, Saias, and Zhu, to decide */
- /* how large a random sample of triangles to inspect. */
- #define SAMPLEFACTOR 11
- /* Used in Fortune's sweepline Delaunay algorithm to determine what fraction */
- /* of boundary edges should be maintained in the splay tree for point */
- /* location on the front. */
- #define SAMPLERATE 10
- /* A number that speaks for itself, every kissable digit. */
- #define PI 3.141592653589793238462643383279502884197169399375105820974944592308
- /* Another fave. */
- #define SQUAREROOTTWO 1.4142135623730950488016887242096980785696718753769480732
- /* And here's one for those of you who are intimidated by math. */
- #define ONETHIRD 0.333333333333333333333333333333333333333333333333333333333333
- #include <stdio.h>
- #include <string.h>
- #include <math.h>
- #ifndef NO_TIMER
- #include <sys/time.h>
- #endif /* NO_TIMER */
- #ifdef TRILIBRARY
- #include "triangle.h"
- #endif /* TRILIBRARY */
- /* The following obscenity seems to be necessary to ensure that this program */
- /* will port to Dec Alphas running OSF/1, because their stdio.h file commits */
- /* the unpardonable sin of including stdlib.h. Hence, malloc(), free(), and */
- /* exit() may or may not already be defined at this point. I declare these */
- /* functions explicitly because some non-ANSI C compilers lack stdlib.h. */
- #ifndef _STDLIB_H_
- extern void *malloc();
- extern void free();
- extern void exit();
- extern double strtod();
- extern long strtol();
- #endif /* _STDLIB_H_ */
- /* A few forward declarations. */
- void poolrestart();
- #ifndef TRILIBRARY
- char *readline();
- char *findfield();
- #endif /* not TRILIBRARY */
- /* Labels that signify whether a record consists primarily of pointers or of */
- /* floating-point words. Used to make decisions about data alignment. */
- enum wordtype {POINTER, FLOATINGPOINT};
- /* Labels that signify the result of point location. The result of a */
- /* search indicates that the point falls in the interior of a triangle, on */
- /* an edge, on a vertex, or outside the mesh. */
- enum locateresult {INTRIANGLE, ONEDGE, ONVERTEX, OUTSIDE};
- /* Labels that signify the result of site insertion. The result indicates */
- /* that the point was inserted with complete success, was inserted but */
- /* encroaches on a segment, was not inserted because it lies on a segment, */
- /* or was not inserted because another point occupies the same location. */
- enum insertsiteresult {SUCCESSFULPOINT, ENCROACHINGPOINT, VIOLATINGPOINT,
- DUPLICATEPOINT};
- /* Labels that signify the result of direction finding. The result */
- /* indicates that a segment connecting the two query points falls within */
- /* the direction triangle, along the left edge of the direction triangle, */
- /* or along the right edge of the direction triangle. */
- enum finddirectionresult {WITHIN, LEFTCOLLINEAR, RIGHTCOLLINEAR};
- /* Labels that signify the result of the circumcenter computation routine. */
- /* The return value indicates which edge of the triangle is shortest. */
- enum circumcenterresult {OPPOSITEORG, OPPOSITEDEST, OPPOSITEAPEX};
- /*****************************************************************************/
- /* */
- /* The basic mesh data structures */
- /* */
- /* There are three: points, triangles, and shell edges (abbreviated */
- /* `shelle'). These three data structures, linked by pointers, comprise */
- /* the mesh. A point simply represents a point in space and its properties.*/
- /* A triangle is a triangle. A shell edge is a special data structure used */
- /* to represent impenetrable segments in the mesh (including the outer */
- /* boundary, boundaries of holes, and internal boundaries separating two */
- /* triangulated regions). Shell edges represent boundaries defined by the */
- /* user that triangles may not lie across. */
- /* */
- /* A triangle consists of a list of three vertices, a list of three */
- /* adjoining triangles, a list of three adjoining shell edges (when shell */
- /* edges are used), an arbitrary number of optional user-defined floating- */
- /* point attributes, and an optional area constraint. The latter is an */
- /* upper bound on the permissible area of each triangle in a region, used */
- /* for mesh refinement. */
- /* */
- /* For a triangle on a boundary of the mesh, some or all of the neighboring */
- /* triangles may not be present. For a triangle in the interior of the */
- /* mesh, often no neighboring shell edges are present. Such absent */
- /* triangles and shell edges are never represented by NULL pointers; they */
- /* are represented by two special records: `dummytri', the triangle that */
- /* fills "outer space", and `dummysh', the omnipresent shell edge. */
- /* `dummytri' and `dummysh' are used for several reasons; for instance, */
- /* they can be dereferenced and their contents examined without causing the */
- /* memory protection exception that would occur if NULL were dereferenced. */
- /* */
- /* However, it is important to understand that a triangle includes other */
- /* information as well. The pointers to adjoining vertices, triangles, and */
- /* shell edges are ordered in a way that indicates their geometric relation */
- /* to each other. Furthermore, each of these pointers contains orientation */
- /* information. Each pointer to an adjoining triangle indicates which face */
- /* of that triangle is contacted. Similarly, each pointer to an adjoining */
- /* shell edge indicates which side of that shell edge is contacted, and how */
- /* the shell edge is oriented relative to the triangle. */
- /* */
- /* Shell edges are found abutting edges of triangles; either sandwiched */
- /* between two triangles, or resting against one triangle on an exterior */
- /* boundary or hole boundary. */
- /* */
- /* A shell edge consists of a list of two vertices, a list of two */
- /* adjoining shell edges, and a list of two adjoining triangles. One of */
- /* the two adjoining triangles may not be present (though there should */
- /* always be one), and neighboring shell edges might not be present. */
- /* Shell edges also store a user-defined integer "boundary marker". */
- /* Typically, this integer is used to indicate what sort of boundary */
- /* conditions are to be applied at that location in a finite element */
- /* simulation. */
- /* */
- /* Like triangles, shell edges maintain information about the relative */
- /* orientation of neighboring objects. */
- /* */
- /* Points are relatively simple. A point is a list of floating point */
- /* numbers, starting with the x, and y coordinates, followed by an */
- /* arbitrary number of optional user-defined floating-point attributes, */
- /* followed by an integer boundary marker. During the segment insertion */
- /* phase, there is also a pointer from each point to a triangle that may */
- /* contain it. Each pointer is not always correct, but when one is, it */
- /* speeds up segment insertion. These pointers are assigned values once */
- /* at the beginning of the segment insertion phase, and are not used or */
- /* updated at any other time. Edge swapping during segment insertion will */
- /* render some of them incorrect. Hence, don't rely upon them for */
- /* anything. For the most part, points do not have any information about */
- /* what triangles or shell edges they are linked to. */
- /* */
- /*****************************************************************************/
- /*****************************************************************************/
- /* */
- /* Handles */
- /* */
- /* The oriented triangle (`triedge') and oriented shell edge (`edge') data */
- /* structures defined below do not themselves store any part of the mesh. */
- /* The mesh itself is made of `triangle's, `shelle's, and `point's. */
- /* */
- /* Oriented triangles and oriented shell edges will usually be referred to */
- /* as "handles". A handle is essentially a pointer into the mesh; it */
- /* allows you to "hold" one particular part of the mesh. Handles are used */
- /* to specify the regions in which one is traversing and modifying the mesh.*/
- /* A single `triangle' may be held by many handles, or none at all. (The */
- /* latter case is not a memory leak, because the triangle is still */
- /* connected to other triangles in the mesh.) */
- /* */
- /* A `triedge' is a handle that holds a triangle. It holds a specific side */
- /* of the triangle. An `edge' is a handle that holds a shell edge. It */
- /* holds either the left or right side of the edge. */
- /* */
- /* Navigation about the mesh is accomplished through a set of mesh */
- /* manipulation primitives, further below. Many of these primitives take */
- /* a handle and produce a new handle that holds the mesh near the first */
- /* handle. Other primitives take two handles and glue the corresponding */
- /* parts of the mesh together. The exact position of the handles is */
- /* important. For instance, when two triangles are glued together by the */
- /* bond() primitive, they are glued by the sides on which the handles lie. */
- /* */
- /* Because points have no information about which triangles they are */
- /* attached to, I commonly represent a point by use of a handle whose */
- /* origin is the point. A single handle can simultaneously represent a */
- /* triangle, an edge, and a point. */
- /* */
- /*****************************************************************************/
- /* The triangle data structure. Each triangle contains three pointers to */
- /* adjoining triangles, plus three pointers to vertex points, plus three */
- /* pointers to shell edges (defined below; these pointers are usually */
- /* `dummysh'). It may or may not also contain user-defined attributes */
- /* and/or a floating-point "area constraint". It may also contain extra */
- /* pointers for nodes, when the user asks for high-order elements. */
- /* Because the size and structure of a `triangle' is not decided until */
- /* runtime, I haven't simply defined the type `triangle' to be a struct. */
- typedef REAL **triangle; /* Really: typedef triangle *triangle */
- /* An oriented triangle: includes a pointer to a triangle and orientation. */
- /* The orientation denotes an edge of the triangle. Hence, there are */
- /* three possible orientations. By convention, each edge is always */
- /* directed to point counterclockwise about the corresponding triangle. */
- struct triedge {
- triangle *tri;
- int orient; /* Ranges from 0 to 2. */
- };
- /* The shell data structure. Each shell edge contains two pointers to */
- /* adjoining shell edges, plus two pointers to vertex points, plus two */
- /* pointers to adjoining triangles, plus one shell marker. */
- typedef REAL **shelle; /* Really: typedef shelle *shelle */
- /* An oriented shell edge: includes a pointer to a shell edge and an */
- /* orientation. The orientation denotes a side of the edge. Hence, there */
- /* are two possible orientations. By convention, the edge is always */
- /* directed so that the "side" denoted is the right side of the edge. */
- struct edge {
- shelle *sh;
- int shorient; /* Ranges from 0 to 1. */
- };
- /* The point data structure. Each point is actually an array of REALs. */
- /* The number of REALs is unknown until runtime. An integer boundary */
- /* marker, and sometimes a pointer to a triangle, is appended after the */
- /* REALs. */
- typedef REAL *point;
- /* A queue used to store encroached segments. Each segment's vertices are */
- /* stored so that one can check whether a segment is still the same. */
- struct badsegment {
- struct edge encsegment; /* An encroached segment. */
- point segorg, segdest; /* The two vertices. */
- struct badsegment *nextsegment; /* Pointer to next encroached segment. */
- };
- /* A queue used to store bad triangles. The key is the square of the cosine */
- /* of the smallest angle of the triangle. Each triangle's vertices are */
- /* stored so that one can check whether a triangle is still the same. */
- struct badface {
- struct triedge badfacetri; /* A bad triangle. */
- REAL key; /* cos^2 of smallest (apical) angle. */
- point faceorg, facedest, faceapex; /* The three vertices. */
- struct badface *nextface; /* Pointer to next bad triangle. */
- };
- /* A node in a heap used to store events for the sweepline Delaunay */
- /* algorithm. Nodes do not point directly to their parents or children in */
- /* the heap. Instead, each node knows its position in the heap, and can */
- /* look up its parent and children in a separate array. The `eventptr' */
- /* points either to a `point' or to a triangle (in encoded format, so that */
- /* an orientation is included). In the latter case, the origin of the */
- /* oriented triangle is the apex of a "circle event" of the sweepline */
- /* algorithm. To distinguish site events from circle events, all circle */
- /* events are given an invalid (smaller than `xmin') x-coordinate `xkey'. */
- struct event {
- REAL xkey, ykey; /* Coordinates of the event. */
- VOID *eventptr; /* Can be a point or the location of a circle event. */
- int heapposition; /* Marks this event's position in the heap. */
- };
- /* A node in the splay tree. Each node holds an oriented ghost triangle */
- /* that represents a boundary edge of the growing triangulation. When a */
- /* circle event covers two boundary edges with a triangle, so that they */
- /* are no longer boundary edges, those edges are not immediately deleted */
- /* from the tree; rather, they are lazily deleted when they are next */
- /* encountered. (Since only a random sample of boundary edges are kept */
- /* in the tree, lazy deletion is faster.) `keydest' is used to verify */
- /* that a triangle is still the same as when it entered the splay tree; if */
- /* it has been rotated (due to a circle event), it no longer represents a */
- /* boundary edge and should be deleted. */
- struct splaynode {
- struct triedge keyedge; /* Lprev of an edge on the front. */
- point keydest; /* Used to verify that splay node is still live. */
- struct splaynode *lchild, *rchild; /* Children in splay tree. */
- };
- /* A type used to allocate memory. firstblock is the first block of items. */
- /* nowblock is the block from which items are currently being allocated. */
- /* nextitem points to the next slab of free memory for an item. */
- /* deaditemstack is the head of a linked list (stack) of deallocated items */
- /* that can be recycled. unallocateditems is the number of items that */
- /* remain to be allocated from nowblock. */
- /* */
- /* Traversal is the process of walking through the entire list of items, and */
- /* is separate from allocation. Note that a traversal will visit items on */
- /* the "deaditemstack" stack as well as live items. pathblock points to */
- /* the block currently being traversed. pathitem points to the next item */
- /* to be traversed. pathitemsleft is the number of items that remain to */
- /* be traversed in pathblock. */
- /* */
- /* itemwordtype is set to POINTER or FLOATINGPOINT, and is used to suggest */
- /* what sort of word the record is primarily made up of. alignbytes */
- /* determines how new records should be aligned in memory. itembytes and */
- /* itemwords are the length of a record in bytes (after rounding up) and */
- /* words. itemsperblock is the number of items allocated at once in a */
- /* single block. items is the number of currently allocated items. */
- /* maxitems is the maximum number of items that have been allocated at */
- /* once; it is the current number of items plus the number of records kept */
- /* on deaditemstack. */
- struct memorypool {
- VOID **firstblock, **nowblock;
- VOID *nextitem;
- VOID *deaditemstack;
- VOID **pathblock;
- VOID *pathitem;
- enum wordtype itemwordtype;
- int alignbytes;
- int itembytes, itemwords;
- int itemsperblock;
- long items, maxitems;
- int unallocateditems;
- int pathitemsleft;
- };
- /* Variables used to allocate memory for triangles, shell edges, points, */
- /* viri (triangles being eaten), bad (encroached) segments, bad (skinny */
- /* or too large) triangles, and splay tree nodes. */
- static struct memorypool triangles;
- static struct memorypool shelles;
- static struct memorypool points;
- static struct memorypool viri;
- static struct memorypool badsegments;
- static struct memorypool badtriangles;
- static struct memorypool splaynodes;
- /* Variables that maintain the bad triangle queues. The tails are pointers */
- /* to the pointers that have to be filled in to enqueue an item. */
- static struct badface *queuefront[64];
- static struct badface **queuetail[64];
- static REAL xmin, xmax, ymin, ymax; /* x and y bounds. */
- static REAL xminextreme; /* Nonexistent x value used as a flag in sweepline. */
- static int inpoints; /* Number of input points. */
- static int inelements; /* Number of input triangles. */
- static int insegments; /* Number of input segments. */
- static int holes; /* Number of input holes. */
- static int regions; /* Number of input regions. */
- static long edges; /* Number of output edges. */
- static int mesh_dim; /* Dimension (ought to be 2). */
- static int nextras; /* Number of attributes per point. */
- static int eextras; /* Number of attributes per triangle. */
- static long hullsize; /* Number of edges of convex hull. */
- static int triwords; /* Total words per triangle. */
- static int shwords; /* Total words per shell edge. */
- static int pointmarkindex; /* Index to find boundary marker of a point. */
- static int point2triindex; /* Index to find a triangle adjacent to a point. */
- static int highorderindex; /* Index to find extra nodes for high-order elements. */
- static int elemattribindex; /* Index to find attributes of a triangle. */
- static int areaboundindex; /* Index to find area bound of a triangle. */
- static int checksegments; /* Are there segments in the triangulation yet? */
- static int readnodefile; /* Has a .node file been read? */
- static long samples; /* Number of random samples for point location. */
- static unsigned long randomseed; /* Current random number seed. */
- static REAL splitter; /* Used to split REAL factors for exact multiplication. */
- static REAL epsilon; /* Floating-point machine epsilon. */
- static REAL resulterrbound;
- static REAL ccwerrboundA, ccwerrboundB, ccwerrboundC;
- static REAL iccerrboundA, iccerrboundB, iccerrboundC;
- static long incirclecount; /* Number of incircle tests performed. */
- static long counterclockcount; /* Number of counterclockwise tests performed. */
- static long hyperbolacount; /* Number of right-of-hyperbola tests performed. */
- static long circumcentercount; /* Number of circumcenter calculations performed. */
- static long circletopcount; /* Number of circle top calculations performed. */
- /* Switches for the triangulator. */
- /* poly: -p switch. refine: -r switch. */
- /* quality: -q switch. */
- /* minangle: minimum angle bound, specified after -q switch. */
- /* goodangle: cosine squared of minangle. */
- /* vararea: -a switch without number. */
- /* fixedarea: -a switch with number. */
- /* maxarea: maximum area bound, specified after -a switch. */
- /* regionattrib: -A switch. convex: -c switch. */
- /* firstnumber: inverse of -z switch. All items are numbered starting */
- /* from firstnumber. */
- /* edgesout: -e switch. voronoi: -v switch. */
- /* neighbors: -n switch. geomview: -g switch. */
- /* nobound: -B switch. nopolywritten: -P switch. */
- /* nonodewritten: -N switch. noelewritten: -E switch. */
- /* noiterationnum: -I switch. noholes: -O switch. */
- /* noexact: -X switch. */
- /* order: element order, specified after -o switch. */
- /* nobisect: count of how often -Y switch is selected. */
- /* steiner: maximum number of Steiner points, specified after -S switch. */
- /* steinerleft: number of Steiner points not yet used. */
- /* incremental: -i switch. sweepline: -F switch. */
- /* dwyer: inverse of -l switch. */
- /* splitseg: -s switch. */
- /* docheck: -C switch. */
- /* quiet: -Q switch. verbose: count of how often -V switch is selected. */
- /* useshelles: -p, -r, -q, or -c switch; determines whether shell edges */
- /* are used at all. */
- /* */
- /* Read the instructions to find out the meaning of these switches. */
- static int poly, refine, quality, vararea, fixedarea, regionattrib, convex;
- static int firstnumber;
- static int edgesout, voronoi, neighbors, geomview;
- static int nobound, nopolywritten, nonodewritten, noelewritten, noiterationnum;
- static int noholes, noexact;
- static int incremental, sweepline, dwyer;
- static int splitseg;
- static int docheck;
- static int quiet, verbose;
- static int useshelles;
- static int order;
- static int nobisect;
- static int steiner, steinerleft;
- static REAL minangle, goodangle;
- static REAL maxarea;
- /* Variables for file names. */
- #ifndef TRILIBRARY
- char innodefilename[FILENAMESIZE];
- char inelefilename[FILENAMESIZE];
- char inpolyfilename[FILENAMESIZE];
- char areafilename[FILENAMESIZE];
- char outnodefilename[FILENAMESIZE];
- char outelefilename[FILENAMESIZE];
- char outpolyfilename[FILENAMESIZE];
- char edgefilename[FILENAMESIZE];
- char vnodefilename[FILENAMESIZE];
- char vedgefilename[FILENAMESIZE];
- char neighborfilename[FILENAMESIZE];
- char offfilename[FILENAMESIZE];
- #endif /* not TRILIBRARY */
- /* Triangular bounding box points. */
- static point infpoint1, infpoint2, infpoint3;
- /* Pointer to the `triangle' that occupies all of "outer space". */
- static triangle *dummytri;
- static triangle *dummytribase; /* Keep base address so we can free() it later. */
- /* Pointer to the omnipresent shell edge. Referenced by any triangle or */
- /* shell edge that isn't really connected to a shell edge at that */
- /* location. */
- static shelle *dummysh;
- static shelle *dummyshbase; /* Keep base address so we can free() it later. */
- /* Pointer to a recently visited triangle. Improves point location if */
- /* proximate points are inserted sequentially. */
- static struct triedge recenttri;
- /*****************************************************************************/
- /* */
- /* Mesh manipulation primitives. Each triangle contains three pointers to */
- /* other triangles, with orientations. Each pointer points not to the */
- /* first byte of a triangle, but to one of the first three bytes of a */
- /* triangle. It is necessary to extract both the triangle itself and the */
- /* orientation. To save memory, I keep both pieces of information in one */
- /* pointer. To make this possible, I assume that all triangles are aligned */
- /* to four-byte boundaries. The `decode' routine below decodes a pointer, */
- /* extracting an orientation (in the range 0 to 2) and a pointer to the */
- /* beginning of a triangle. The `encode' routine compresses a pointer to a */
- /* triangle and an orientation into a single pointer. My assumptions that */
- /* triangles are four-byte-aligned and that the `unsigned long' type is */
- /* long enough to hold a pointer are two of the few kludges in this program.*/
- /* */
- /* Shell edges are manipulated similarly. A pointer to a shell edge */
- /* carries both an address and an orientation in the range 0 to 1. */
- /* */
- /* The other primitives take an oriented triangle or oriented shell edge, */
- /* and return an oriented triangle or oriented shell edge or point; or they */
- /* change the connections in the data structure. */
- /* */
- /*****************************************************************************/
- /********* Mesh manipulation primitives begin here *********/
- /** **/
- /** **/
- /* Fast lookup arrays to speed some of the mesh manipulation primitives. */
- int plus1mod3[3] = {1, 2, 0};
- int minus1mod3[3] = {2, 0, 1};
- /********* Primitives for triangles *********/
- /* */
- /* */
- /* decode() converts a pointer to an oriented triangle. The orientation is */
- /* extracted from the two least significant bits of the pointer. */
- #define decode( ptr, triedge ) \
- ( triedge ).orient = (int) ( (unsigned long) ( ptr ) & (unsigned long) 3l ); \
- ( triedge ).tri = (triangle *) \
- ( (unsigned long) ( ptr ) ^ (unsigned long) ( triedge ).orient )
- /* encode() compresses an oriented triangle into a single pointer. It */
- /* relies on the assumption that all triangles are aligned to four-byte */
- /* boundaries, so the two least significant bits of (triedge).tri are zero.*/
- #define encode( triedge ) \
- (triangle) ( (unsigned long) ( triedge ).tri | (unsigned long) ( triedge ).orient )
- /* The following edge manipulation primitives are all described by Guibas */
- /* and Stolfi. However, they use an edge-based data structure, whereas I */
- /* am using a triangle-based data structure. */
- /* sym() finds the abutting triangle, on the same edge. Note that the */
- /* edge direction is necessarily reversed…
Large files files are truncated, but you can click here to view the full file