00001 // Wild Magic Source Code 00002 // David Eberly 00003 // http://www.geometrictools.com 00004 // Copyright (c) 1998-2007 00005 // 00006 // This library is free software; you can redistribute it and/or modify it 00007 // under the terms of the GNU Lesser General Public License as published by 00008 // the Free Software Foundation; either version 2.1 of the License, or (at 00009 // your option) any later version. The license is available for reading at 00010 // either of the locations: 00011 // http://www.gnu.org/copyleft/lgpl.html 00012 // http://www.geometrictools.com/License/WildMagicLicense.pdf 00013 // The license applies to versions 0 through 4 of Wild Magic. 00014 // 00015 // Version: 4.0.2 (2006/08/30) 00016 00017 #ifndef WM4TRIANGULATEEC_H 00018 #define WM4TRIANGULATEEC_H 00019 00020 #include "Wm4FoundationLIB.h" 00021 #include "Wm4Query2.h" 00022 #include "Wm4Vector2.h" 00023 00024 namespace Wm4 00025 { 00026 00027 template <class Real> 00028 class WM4_FOUNDATION_ITEM TriangulateEC 00029 { 00030 public: 00031 // This class implements triangulation of polygons using ear clipping. 00032 // The method is O(n^2) for n input points. There are five constructors. 00033 // The query type and epsilon parameters are discussed later. In all 00034 // cases, the output is 00035 // 00036 // triangles: 00037 // An array of 3*T indices representing T triangles. Each triple 00038 // (i0,i1,i2) corresponds to the triangle (P[i0],P[i1],P[i2]), 00039 // where P is the 'positions' input. These triangles are all 00040 // counterclockwise ordered. 00041 // 00042 // TriangulateEC(positions,queryType,epsilon,triangles) 00043 // positions: 00044 // An array of n vertex positions for a simple polygon. The 00045 // polygon is (P[0],P[1],...,P[n-1]). 00046 // 00047 // TriangulateEC(positions,queryType,epsilon,polygon,triangles) 00048 // positions: 00049 // An array of vertex positions, not necessarily the exact set of 00050 // positions for the polygon vertices. 00051 // polygon: 00052 // An array of n indices into 'positions'. If the array is 00053 // (I[0],I[1],...,I[n-1]), the polygon vertices are 00054 // (P[I[0]],P[I[1]],...,P[I[n-1]]). 00055 // 00056 // TriangulateEC(positions,queryType,epsilon,outerPolygon,innerPolygon, 00057 // triangles) 00058 // positions: 00059 // An array of vertex positions, not necessarily the exact set of 00060 // positions for the polygon vertices. 00061 // outerPolygon: 00062 // An array of n indices into 'positions' for the outer polygon. 00063 // If the array is (I[0],I[1],...,I[n-1]), the outer polygon 00064 // vertices are (P[I[0]],P[I[1]],...,P[I[n-1]]). 00065 // innerPolygon: 00066 // An array of m indices into 'positions' for the inner polygon. 00067 // The inner polygon must be strictly inside the outer polygon. 00068 // If the array is (J[0],J[1],...,J[m-1]), the inner polygon 00069 // vertices are (P[J[0]],P[J[1]],...,P[J[m-1]]). 00070 // 00071 // TriangulateEC(positions,queryType,epsilon,outerPolygon,innerPolygons, 00072 // triangles) 00073 // positions: 00074 // An array of vertex positions, not necessarily the exact set of 00075 // positions for the polygon vertices. 00076 // outerPolygon: 00077 // An array of n indices into 'positions' for the outer polygon. 00078 // If the array is (I[0],I[1],...,I[n-1]), the outer polygon 00079 // vertices are (P[I[0]],P[I[1]],...,P[I[n-1]]). 00080 // innerPolygons: 00081 // An array of arrays of indices, each index array representing 00082 // an inner polygon. The inner polygons must be nonoverlapping and 00083 // strictly contained in the outer polygon. If innerPolygons[i] 00084 // is the array (J[0],J[1],...,J[m-1]), the inner polygon 00085 // vertices are (P[J[0]],P[J[1]],...,P[J[m-1]]). 00086 // 00087 // TriangulateEC(positions,queryType,epsilon,tree,triangles) 00088 // positions: 00089 // An array of vertex positions, not necessarily the exact set of 00090 // positions for the polygon vertices. 00091 // tree: 00092 // A hierarchy of nested polygons. The root node corresponds to 00093 // the outermost outer polygon. The child nodes of the root 00094 // correspond to inner polygons contained by the outer polygon. 00095 // Each inner polygon may itself contain outer polygons, and 00096 // those outer polygons may themselves contain inner polygons. 00097 // 00098 // You have a choice of speed versus accuracy. The fastest choice is 00099 // Query::QT_INT64, but it gives up a lot of precision, scaling the points 00100 // to [0,2^{20}]^3. The choice Query::QT_INTEGER gives up less precision, 00101 // scaling the points to [0,2^{24}]^3. The choice Query::QT_RATIONAL uses 00102 // exact arithmetic, but is the slowest choice. The choice Query::QT_REAL 00103 // uses floating-point arithmetic, but is not robust in all cases. The 00104 // choice Query::QT_FILTERED uses floating-point arithmetic to compute 00105 // determinants whose signs are of interest. If the floating-point value 00106 // is nearly zero, the determinant is recomputed using exact rational 00107 // arithmetic in order to correctly classify the sign. The hope is to 00108 // have an exact result computed faster than with all rational arithmetic. 00109 // The value fEpsilon is used only for the Query::QT_FILTERED case and 00110 // should be in [0,1]. If 0, the method defaults to all exact rational 00111 // arithmetic. If 1, the method defaults to all floating-point 00112 // arithmetic. Generally, if M is the maximum absolute value of a 00113 // determinant and if d is the current determinant value computed as a 00114 // floating-point quantity, the recalculation with rational arithmetic 00115 // occurs when |d| < epsilon*M. 00116 00117 // Convenient typedefs. 00118 typedef std::vector<Vector2<Real> > Positions; 00119 typedef std::vector<int> Indices; 00120 typedef std::vector<Indices*> IndicesArray; 00121 typedef std::map<int,int> IndexMap; 00122 00123 // The input rkPosition represents an array of vertices for a simple 00124 // polygon. The vertices are rkPosition[0] through rkPosition[n-1], where 00125 // n = rkPolygon.size(), and are listed in counterclockwise order. 00126 TriangulateEC (const Positions& rkPositions, Query::Type eQueryType, 00127 Real fEpsilon, Indices& rkTriangles); 00128 00129 // The input rkPositions represents an array of vertices that contains the 00130 // vertices of a simple polygon. The input rkPolygon represents a simple 00131 // polygon whose vertices are rkPositions[rkPolygon[0]] through 00132 // rkPositions[rkPolygon[m-1]], where m = rkPolygon.size(), and are listed 00133 // in counterclockwise ordered. 00134 TriangulateEC (const Positions& rkPositions, Query::Type eQueryType, 00135 Real fEpsilon, const Indices& rkPolygon, Indices& rkTriangles); 00136 00137 // The input rkPositions is a shared array of vertices that contains the 00138 // vertices for two simple polygons, an outer polygon and an inner 00139 // polygon. The inner polygon must be strictly inside the outer polygon. 00140 // The input rkOuter represents the outer polygon whose vertices are 00141 // rkPositions[rkOuter[0]] through rkPositions[rkOuter[n-1]], where 00142 // n = rkOuter.size(), and are listed in counterclockwise order. The 00143 // input rkInner represents the inner polygon whose vertices are 00144 // rkPositions[rkInner[0]] through rkPositions[rkInner[m-1]], where 00145 // m = rkInner.size(), and are listed in clockwise order. 00146 TriangulateEC (const Positions& rkPositions, Query::Type eQueryType, 00147 Real fEpsilon, const Indices& rkOuter, const Indices& rkInner, 00148 Indices& rkTriangles); 00149 00150 // The input rkPositions is a shared array of vertices that contains the 00151 // vertices for multiple simple polygons, an outer polygon and one or more 00152 // inner polygons. The inner polygons must be nonoverlapping and strictly 00153 // inside the outer polygon. The input rkOuter represents the outer 00154 // polygon whose vertices are rkPositions[rkOuter[0]] through 00155 // rkPositions[rkOuter[n-1]], where n = rkOuter.size(), and are listed in 00156 // counterclockwise order. The input element rkInners[i] represents the 00157 // i-th inner polygon whose vertices are rkPositions[rkInners[i][0]] 00158 // through rkPositions[rkInners[i][m-1]], where m = rkInners[i].size(), 00159 // and are listed in clockwise order. 00160 TriangulateEC (const Positions& rkPositions, Query::Type eQueryType, 00161 Real fEpsilon, const Indices& rkOuter, const IndicesArray& rkInners, 00162 Indices& rkTriangles); 00163 00164 // A tree of nested polygons. The root node corresponds to an outer 00165 // polygon. The children of the root correspond to inner polygons, which 00166 // are nonoverlapping polygons strictly contained in the outer polygon. 00167 // Each inner polygon may itself contain an outer polygon, thus leading 00168 // to a hierarchy of polygons. The outer polygons have vertices listed 00169 // in counterclockwise order. The inner polygons have vertices listed in 00170 // clockwise order. 00171 class WM4_FOUNDATION_ITEM Tree 00172 { 00173 public: 00174 Indices Polygon; 00175 std::vector<Tree*> Child; 00176 }; 00177 00178 // The input rkPositions is a shared array of vertices that contains the 00179 // vertices for multiple simple polygons in a tree of polygons. 00180 TriangulateEC (const Positions& rkPositions, Query::Type eQueryType, 00181 Real fEpsilon, const Tree* pkTree, Indices& rkTriangles); 00182 00183 ~TriangulateEC (); 00184 00185 // Helper function to delete Tree objects. Call this only if all tree 00186 // nodes were dynamically allocated. 00187 static void Delete (Tree*& rpkRoot); 00188 00189 private: 00190 // Create the query object and scaled positions to be used during 00191 // triangulation. Extra elements are required when triangulating polygons 00192 // with holes. These are preallocated to avoid dynamic resizing during 00193 // the triangulation. 00194 void InitializePositions (const Positions& rkPositions, 00195 Query::Type eQueryType, Real fEpsilon, int iExtraElements); 00196 00197 // Create the vertex objects that store the various lists required by the 00198 // ear-clipping algorithm. 00199 void InitializeVertices (int iVQuantity, const int* aiIndex, 00200 Indices& rkTriangles); 00201 00202 // Apply ear clipping to the input polygon. Polygons with holes are 00203 // preprocessed to obtain an index array that is nearly a simple polygon. 00204 // This outer polygon has a pair of coincident edges per inner polygon. 00205 void DoEarClipping (int iVQuantity, const int* aiIndex, 00206 Indices& rkTriangles); 00207 00208 // This function is used to help determine a pair of visible vertices 00209 // for the purpose of triangulating polygons with holes. The query is 00210 // point-in-triangle, but is encapsulated here to use the same type of 00211 // query object that the user specified in the constructors. 00212 int TriangleQuery (const Vector2<Real>& rkPosition, 00213 Query::Type eQueryType, Real fEpsilon, 00214 const Vector2<Real> akTriangle[3]) const; 00215 00216 // Given an outer polygon that contains an inner polygon, this function 00217 // determines a pair of visible vertices and inserts two coincident edges 00218 // to generate a nearly simple polygon. 00219 void CombinePolygons (Query::Type eQueryType, Real fEpsilon, 00220 int iNextElement, const Indices& rkOuter, const Indices& rkInner, 00221 IndexMap& rkMap, Indices& rkCombined); 00222 00223 // Two extra elements are needed in the position array per outer-inners 00224 // polygon. This function computes the total number of extra elements 00225 // needed for the input tree. This number is passed to the function 00226 // InitializePositions. 00227 static int GetExtraElements (const Tree* pkTree); 00228 00229 // Given an outer polygon that contains a set of nonoverlapping inner 00230 // polygons, this function determines pairs of visible vertices and 00231 // inserts coincident edges to generate a nearly simple polygon. It 00232 // repeatedly calls CombinePolygons for each inner polygon of the outer 00233 // polygon. 00234 void ProcessOuterAndInners (Query::Type eQueryType, Real fEpsilon, 00235 const Indices& rkOuter, const IndicesArray& rkInners, 00236 int& rkNextElement, IndexMap& rkMap, Indices& rkCombined); 00237 00238 // The insertion of coincident edges to obtain a nearly simple polygon 00239 // requires duplication of vertices in order that the ear-clipping 00240 // algorithm work correctly. After the triangulation, the indices of 00241 // the duplicated vertices are converted to the original indices. 00242 void RemapIndices (const IndexMap& rkMap, Indices& rkTriangles) const; 00243 00244 // Doubly linked lists for storing specially tagged vertices. 00245 class WM4_FOUNDATION_ITEM Vertex 00246 { 00247 public: 00248 Vertex () 00249 { 00250 Index = -1; 00251 IsConvex = false; 00252 IsEar = false; 00253 VPrev = -1; 00254 VNext = -1; 00255 SPrev = -1; 00256 SNext = -1; 00257 EPrev = -1; 00258 ENext = -1; 00259 } 00260 00261 int Index; // index of vertex in position array 00262 bool IsConvex, IsEar; 00263 int VPrev, VNext; // vertex links for polygon 00264 int SPrev, SNext; // convex/reflex vertex links (disjoint lists) 00265 int EPrev, ENext; // ear links 00266 }; 00267 00268 Vertex& V (int i); 00269 bool IsConvex (int i); 00270 bool IsEar (int i); 00271 void InsertAfterC (int i); // insert convex vertex 00272 void InsertAfterR (int i); // insert reflex vertesx 00273 void InsertEndE (int i); // insert ear at end of list 00274 void InsertAfterE (int i); // insert ear after efirst 00275 void InsertBeforeE (int i); // insert ear before efirst 00276 void RemoveV (int i); // remove vertex 00277 int RemoveE (int i); // remove ear at i 00278 void RemoveR (int i); // remove reflex vertex 00279 00280 // The doubly linked list. 00281 std::vector<Vertex> m_kVertex; 00282 int m_iCFirst, m_iCLast; // linear list of convex vertices 00283 int m_iRFirst, m_iRLast; // linear list of reflex vertices 00284 int m_iEFirst, m_iELast; // cyclical list of ears 00285 00286 // For robust determinant calculation. 00287 Query2<Real>* m_pkQuery; 00288 std::vector<Vector2<Real> >m_kSPositions; 00289 }; 00290 00291 } 00292 00293 #endif