Wm4TriangulateEC.h

Go to the documentation of this file.
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

Generated on Wed Nov 23 19:01:10 2011 for FreeCAD by  doxygen 1.6.1