Files Classes Functions Hierarchy
00001 #ifndef QUICKHULL3D_H 00002 #define QUICKHULL3D_H 00003 00004 #include <cassert> 00005 #include <vector> 00006 #include <algorithm> 00007 #include <iostream> 00008 using namespace std; 00009 00010 #include <halfspaceD3.h> 00011 #include <halfspaceD3display.h> 00012 #include <gobj.h> 00013 #include <halfspaceContainer.h> 00014 #include <indextable.h> 00015 #include <print.h> 00016 #include <typedefs.h> 00017 #include <typeop.h> 00018 00027 template< typename PT, typename D > 00028 class quickhull3D 00029 { 00030 public: 00031 00032 typedef halfspaceD3<PT,D> HS; 00033 typedef halfspaceContainer<HS,PT> HSC; 00034 00036 vector< HSC* > cs; 00037 00039 vector<PT> const & pts; 00040 00042 vector< uint > boundary; 00043 00046 quickhull3D(vector<PT> const & pts_); 00047 00049 void reset(); 00050 00052 boolc operator ! () const 00053 { return cs.empty()==false; } 00054 00056 void operator ++ (); 00057 00058 private: 00059 00062 void findMinMax(uint & q0, uint & q1, uint& q2) const; 00063 00070 void partition( HSC & h ); 00071 00072 }; 00073 00074 00088 // Changing algorithm, <TODO> re-implement later. 00089 //template< typename PT, typename D > 00090 //class quickhull3Drandomized 00091 //{ 00092 //public: 00093 00095 // vector<PT> const & pts; 00096 00098 // vector< uint > boundary; 00099 00101 // quickhull3Drandomized(vector<PT> const & pts_); 00102 //}; 00103 00104 00105 00106 //--------------------------------------------------------- 00107 // Implementation. 00108 00109 00110 template< typename PT, typename D > 00111 void quickhull3D<PT,D>::findMinMax 00112 ( 00113 uint & q0, 00114 uint & q1, 00115 uint & q2 00116 ) const 00117 { 00118 q0= 1; 00119 q1= 1; 00120 q2= 1; 00121 uintc imax=pts.size(); 00122 assert(imax>1); 00123 for (uint i=1; i<imax; ++i) 00124 { 00125 if (pts[i].x<pts[q0].x) 00126 q0=i; 00127 if (pts[i].x>pts[q1].x) 00128 q1=i; 00129 if (pts[i].y<pts[q2].y) 00130 q2=i; 00131 } 00132 if ((q0!=q2)&&(q1!=q2)) 00133 return; 00134 00135 q2=1; 00136 for (uint i=1; i<imax; ++i) 00137 { 00138 if (pts[i].y>pts[q2].y) 00139 q2=i; 00140 } 00141 if ((q0!=q2)&&(q1!=q2)) 00142 return; 00143 00144 q2=1; 00145 for (uint i=1; i<imax; ++i) 00146 { 00147 if (pts[i].z>pts[q2].z) 00148 q2=i; 00149 } 00150 if ((q0!=q2)&&(q1!=q2)) 00151 return; 00152 00153 q2=1; 00154 for (uint i=1; i<imax; ++i) 00155 { 00156 if (pts[i].z<pts[q2].z) 00157 q2=i; 00158 } 00159 if ((q0!=q2)&&(q1!=q2)) 00160 return; 00161 00162 assert(false); 00163 } 00164 00165 template< typename PT, typename D > 00166 void quickhull3D<PT,D>::operator ++ () 00167 { 00168 assert(cs.size()>0); 00169 00170 HSC* hc = cs[cs.size()-1]; 00171 cs.pop_back(); 00172 00173 partition(*hc); 00174 delete hc; 00175 } 00176 00177 template< typename PT, typename D > 00178 void quickhull3D<PT,D>::reset() 00179 { 00180 boundary.clear(); 00181 00182 uintc n(pts.size()); 00183 if (n<4) 00184 return; 00185 00186 uint x0; 00187 uint x1; 00188 uint x2; 00189 00190 findMinMax(x0,x1,x2); 00191 boundary.push_back(x0); 00192 boundary.push_back(x1); 00193 boundary.push_back(x2); 00194 00195 assert(x0<n); 00196 assert(x1<n); 00197 assert(x2<n); 00198 00199 list<uint> index; 00200 for (uint i=1; i<n; ++i) 00201 { 00202 if (i==x0) 00203 continue; 00204 if (i==x1) 00205 continue; 00206 if (i==x2) 00207 continue; 00208 00209 index.push_back(i); 00210 } 00211 00212 if (cs.empty()==false) 00213 { 00214 for ( uint i=0; i<cs.size(); ++i) 00215 { delete cs[i]; } 00216 00217 cs.clear(); 00218 } 00219 00220 HSC * h1 = 00221 new HSC( HS(&pts[0],x0,x1,x2) ,pts ); 00222 //new HSC( HS(pts[x0],pts[x1],pts[x2]) ,pts ); 00223 h1->isInsideOrOnBoundary(index); 00224 cs.push_back(h1); 00225 00226 HSC * h2 = 00227 new HSC( HS(pts[x2],pts[x1],pts[x0]), pts ); 00228 h2->isInsideOrOnBoundary(index); 00229 cs.push_back(h2); 00230 } 00231 00232 00233 template< typename PT, typename D > 00234 quickhull3D<PT,D>::quickhull3D(vector<PT> const & pts_) 00235 : pts(pts_) 00236 { 00237 } 00238 00239 template< typename PT, typename D > 00240 void quickhull3D<PT,D>::partition 00241 ( 00242 HSC & h 00243 ) 00244 { 00245 //cout << "partition" << endl; 00246 //cout << SHOW(h.halfspace.p0) << " " 00247 // << SHOW(h.halfspace.p1) << " " 00248 // << SHOW(h.halfspace.p2) << endl; 00249 00250 list<uint> & target(h.index); 00251 //cout << SHOW(print(target)) << endl; 00252 list<uint>::iterator i=target.begin(); 00253 list<uint>::iterator iend=target.end(); 00254 if (i==iend) 00255 return; 00256 00257 list<uint>::iterator imax=i; 00258 ++i; 00259 D dmax = h.halfspace.distancefromhalfspace(pts[*imax]); 00260 //cout << SHOW(dmax) << endl; 00261 D d; 00262 for (; i!=iend; ++i) 00263 { 00264 d=h.halfspace.distancefromhalfspace(pts[*i]); 00265 //cout << SHOW(*i) << " " << SHOW(d) << endl; 00266 if( dmax < d ) 00267 { 00268 dmax=d; 00269 imax=i; 00270 } 00271 } 00272 00273 uint k(*imax); 00274 //cout << SHOW(k) << endl; 00275 boundary.push_back(k); 00276 target.erase(imax); 00277 //cout << SHOW(print(target)) << endl; 00278 00279 00280 HSC* h1 = new 00281 HSC( HS(pts[k],h.halfspace.p1,h.halfspace.p2), pts ); 00282 //h1->isInsideOrOnBoundary(target); 00283 h1->subtractfrom(target); 00284 HSC* h2 = new 00285 HSC( HS(pts[k],h.halfspace.p0,h.halfspace.p1), pts ); 00286 //h2->isInsideOrOnBoundary(target); 00287 h2->subtractfrom(target); 00288 HSC* h3 = new 00289 HSC( HS(pts[k],h.halfspace.p2,h.halfspace.p0), pts ); 00290 //h3->isInsideOrOnBoundary(target); 00291 h3->subtractfrom(target); 00292 00293 cs.push_back(h1); 00294 cs.push_back(h2); 00295 cs.push_back(h3); 00296 00297 //cout << SHOW(print(h1->index)) << endl; 00298 //cout << SHOW(print(h2->index)) << endl; 00299 //cout << SHOW(print(h3->index)) << endl; 00300 } 00301 00302 00303 /* 00304 template< typename PT, typename D > 00305 quickhull3Drandomized<PT,D>::quickhull3Drandomized 00306 ( 00307 vector<PT> const & pts_ 00308 ) 00309 : pts(pts_) 00310 { 00311 vector<uint> index; 00312 vector<PT> pts2(pts.begin(),pts.end()); 00313 vectorshuffle(pts2,index); 00314 quickhull3D<PT,D> qh(pts2); 00315 uintc n=qh.boundary.size(); 00316 boundary.resize(n); 00317 for (uint i=0; i<n; ++i) 00318 boundary[i] = index[qh.boundary[i]]; 00319 } 00320 */ 00321 00322 00323 00324 00325 #endif 00326 00327
1.5.8