proj home

Files   Classes   Functions   Hierarchy  

quickhull3D.h

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

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