Files Classes Functions Hierarchy
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
1.5.8