⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 triangle.c

📁 一个用于三角剖分的类.实用性非常好。对于需要从多边形
💻 C
📖 第 1 页 / 共 5 页
字号:
/*  exterior boundary or hole boundary.                                      *//*                                                                           *//*  A subsegment consists of a list of four vertices--the vertices of the    *//*  subsegment, and the vertices of the segment it is a part of--a list of   *//*  two adjoining subsegments, 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 subsegments might not be present.        *//*  Subsegments also store a user-defined integer "boundary marker".         *//*  Typically, this integer is used to indicate what boundary conditions are *//*  to be applied at that location in a finite element simulation.           *//*                                                                           *//*  Like triangles, subsegments maintain information about the relative      *//*  orientation of neighboring objects.                                      *//*                                                                           *//*  Vertices are relatively simple.  A vertex 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 vertex 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 except during this phase.  Edge flipping during segment          *//*  insertion will render some of them incorrect.  Hence, don't rely upon    *//*  them for anything.                                                       *//*                                                                           *//*  Other than the exception mentioned above, vertices have no information   *//*  about what triangles, subfacets, or subsegments they are linked to.      *//*                                                                           *//*****************************************************************************//*****************************************************************************//*                                                                           *//*  Handles                                                                  *//*                                                                           *//*  The oriented triangle (`otri') and oriented subsegment (`osub') data     *//*  structures defined below do not themselves store any part of the mesh.   *//*  The mesh itself is made of `triangle's, `subseg's, and `vertex's.        *//*                                                                           *//*  Oriented triangles and oriented subsegments 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.)                               *//*                                                                           *//*  An `otri' is a handle that holds a triangle.  It holds a specific edge   *//*  of the triangle.  An `osub' is a handle that holds a subsegment.  It     *//*  holds either the left or right side of the subsegment.                   *//*                                                                           *//*  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 orientation of the handles is           *//*  important.  For instance, when two triangles are glued together by the   *//*  bond() primitive, they are glued at the edges on which the handles lie.  *//*                                                                           *//*  Because vertices have no information about which triangles they are      *//*  attached to, I commonly represent a vertex by use of a handle whose      *//*  origin is the vertex.  A single handle can simultaneously represent a    *//*  triangle, an edge, and a vertex.                                         *//*                                                                           *//*****************************************************************************//* The triangle data structure.  Each triangle contains three pointers to    *//*   adjoining triangles, plus three pointers to vertices, plus three        *//*   pointers to subsegments (declared below; these pointers are usually     *//*   `dummysub').  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 declared the type `triangle' as 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 always points    *//*   counterclockwise about the corresponding triangle.                      */struct otri {  triangle *tri;  int orient;                                         /* Ranges from 0 to 2. */};/* The subsegment data structure.  Each subsegment contains two pointers to  *//*   adjoining subsegments, plus four pointers to vertices, plus two         *//*   pointers to adjoining triangles, plus one boundary marker, plus one     *//*   segment number.                                                         */typedef REAL **subseg;                  /* Really:  typedef subseg *subseg   *//* An oriented subsegment:  includes a pointer to a subsegment 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 osub {  subseg *ss;  int ssorient;                                       /* Ranges from 0 to 1. */};/* The vertex data structure.  Each vertex 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 *vertex;/* A queue used to store encroached subsegments.  Each subsegment's vertices *//*   are stored so that we can check whether a subsegment is still the same. */struct badsubseg {  subseg encsubseg;                             /* An encroached subsegment. */  vertex subsegorg, subsegdest;                         /* Its two vertices. */};/* 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 badtriang {  triangle poortri;                       /* A skinny or too-large triangle. */  REAL key;                             /* cos^2 of smallest (apical) angle. */  vertex triangorg, triangdest, triangapex;           /* Its three vertices. */  struct badtriang *nexttriang;             /* Pointer to next bad triangle. */};/* A stack of triangles flipped during the most recent vertex insertion.     *//*   The stack is used to undo the vertex insertion if the vertex encroaches *//*   upon a subsegment.                                                      */struct flipstacker {  triangle flippedtri;                       /* A recently flipped triangle. */  struct flipstacker *prevflip;               /* Previous flip in the stack. */};/* 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 `vertex' 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 vertex 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 otri keyedge;                     /* Lprev of an edge on the front. */  vertex 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.                                              *//*                                                                           *//* alignbytes determines how new records should be aligned in memory.        *//*   itembytes is the length of a record in bytes (after rounding up).       *//*   itemsperblock is the number of items allocated at once in a single      *//*   block.  itemsfirstblock is the number of items in the first block,      *//*   which can vary from the others.  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;  int alignbytes;  int itembytes;  int itemsperblock;  int itemsfirstblock;  long items, maxitems;  int unallocateditems;  int pathitemsleft;};/* Global constants.                                                         */REAL splitter;       /* Used to split REAL factors for exact multiplication. */REAL epsilon;                             /* Floating-point machine epsilon. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -