proj home

Files   Classes   Functions   Hierarchy  

quickhull2D.h

Go to the documentation of this file.
00001 #ifndef QUICKHULL2D_H
00002 #define QUICKHULL2D_H
00003 
00004 #include <cassert>
00005 #include <vector>
00006 #include <algorithm>
00007 using namespace std;
00008 
00009 #include <halfspaceD2.h>
00010 #include <halfspaceContainer.h>
00011 #include <indextable.h>
00012 #include <typedefs.h>
00013 #include <typeop.h>
00014 
00020 template< typename PT, typename D >
00021 class quickhull2D
00022 {
00025   void findMinMax(uint & xmin, uint & xmax) const;
00026 
00027   typedef halfspaceD2<PT,D> HS;
00028   typedef halfspaceContainer<HS,PT> HSC;
00029 
00031   vector< HSC* > cs;
00032 
00034   void process();
00035 
00042   void partition( HSC & h );
00043 public:
00044   
00046   vector<PT> const & pts;
00047 
00049   vector< uint > boundary;
00050 
00052   quickhull2D(vector<PT> const & _pts);
00053 };
00054 
00055 
00056 
00057 
00070 template< typename PT, typename D >
00071 class quickhull2Drandomized
00072 {
00073 public:
00074 
00076   vector<PT> const & pts;
00077 
00079   vector< uint > boundary;
00080 
00082   quickhull2Drandomized(vector<PT> const & pts_);
00083 };
00084 
00085 
00086 //---------------------------------------------------------
00087 //  Implementation.
00088 
00089 template< typename PT, typename D >
00090 void quickhull2D<PT,D>::findMinMax
00091 (
00092   uint & xmin, 
00093   uint & xmax
00094 ) const
00095 {
00096   xmin = 0;
00097   xmax = 0;
00098   uintc imax=pts.size();
00099   assert(imax>0);
00100   for (uint i=1; i<imax; ++i)
00101   {
00102     if (pts[i].x<pts[xmin].x)
00103       xmin=i;
00104     if (pts[i].x>pts[xmax].x)
00105       xmax=i;
00106   }
00107 }
00108     
00109 template< typename PT, typename D >
00110 quickhull2D<PT,D>::quickhull2D(vector<PT> const & pts_)
00111   : pts(pts_)
00112 {
00113   uintc n(pts.size());
00114   if (n<3)
00115     return;
00116 
00117   uint x0;
00118   uint x1;
00119   findMinMax(x0,x1);
00120   boundary.push_back(x0);
00121   boundary.push_back(x1);
00122 
00123   assert(x0<n);
00124   assert(x1<n);
00125 
00126   list<uint> index;
00127   for (uint i=0; i<n; ++i)
00128   {
00129     if (i==x0)
00130       continue;
00131     if (i==x1)
00132       continue;
00133 
00134      index.push_back(i);
00135   }
00136 
00137   HSC * h1 = 
00138     new HSC( HS(pts[x0],pts[x1]) ,pts );
00139   h1->isInsideOrOnBoundary(index);
00140 
00141   HSC * h2 = 
00142     new HSC( HS(pts[x1],pts[x0]), pts );
00143   h2->isInsideOrOnBoundary(index);
00144 
00145   cs.push_back(h1);
00146   cs.push_back(h2);
00147 
00148   process();
00149 }
00150 
00151 template< typename PT, typename D >
00152 void quickhull2D<PT,D>::process()
00153 {
00154 
00155   uint sz = cs.size();
00156   HSC* hc;
00157   for ( ; sz!=0; sz=cs.size() )
00158   {
00159     hc = cs[sz-1];
00160     cs.pop_back();
00161 
00162     partition(*hc);
00163     delete hc;
00164   } 
00165 
00166 }
00167 
00168 template< typename PT, typename D >
00169 void quickhull2D<PT,D>::partition
00170 (
00171   HSC & h
00172 )
00173 {
00174   list<uint> & target(h.index);
00175   list<uint>::iterator i=target.begin();
00176   list<uint>::iterator iend=target.end();
00177   if (i==iend)
00178     return;
00179 
00180   list<uint>::iterator imax=i;
00181   ++i;
00182   D dmax = h.halfspace.distancefromhalfspace(pts[*imax]);
00183   D d;
00184   for (; i!=iend; ++i)
00185   {
00186     d=h.halfspace.distancefromhalfspace(pts[*i]);
00187     if( dmax < d )
00188     {
00189       dmax=d;
00190       imax=i;
00191     }
00192   }
00193 
00194   uint k(*imax);
00195   boundary.push_back(k);
00196   target.erase(imax);
00197   HSC* h1 = new
00198     HSC( HS(h.halfspace.p0,pts[k]), pts );
00199   h1->isInsideOrOnBoundary(target);
00200   cs.push_back(h1);
00201 
00202   HSC* h2 = new
00203     HSC( HS(pts[k],h.halfspace.p1), pts );
00204   h2->isInsideOrOnBoundary(target);
00205   cs.push_back(h2);
00206 }
00207 
00208 template< typename PT, typename D >
00209 quickhull2Drandomized<PT,D>::quickhull2Drandomized
00210 (
00211   vector<PT> const & pts_
00212 )
00213   : pts(pts_)
00214 {
00215   vector<uint> index;
00216   vector<PT> pts2(pts.begin(),pts.end());
00217   vectorshuffle(pts2,index);
00218   quickhull2D<PT,D> qh(pts2);
00219   uintc n=qh.boundary.size();
00220   boundary.resize(n);
00221   for (uint i=0; i<n; ++i)
00222     boundary[i] = index[qh.boundary[i]];
00223 }
00224 
00225 
00226 
00227 #endif
00228 
00229 

Generated on Fri Mar 4 00:49:30 2011 for Chelton Evans Source by  doxygen 1.5.8