shape_doc 0.1
/Users/mourrain/Devel/mmx/shape/include/shape/bounding_box.hpp
Go to the documentation of this file.
00001 /*****************************************************************************
00002  * M a t h e m a  g i x
00003  *****************************************************************************
00004  * BoundingBox
00005  * 2008-03-20
00006  * Julien Wintz
00007  *****************************************************************************
00008  *               Copyright (C) 2008 INRIA Sophia-Antipolis
00009  *****************************************************************************
00010  * Comments :
00011  ****************************************************************************/
00012 
00013 # ifndef shape_boundingbox_hpp
00014 # define shape_boundingbox_hpp
00015 
00016 # include <iostream>
00017 # include <shape/shape.hpp>
00018 # include <shape/edge.hpp>
00019 
00020 # define TMPL template<class C, class V>
00021 # define STMPL template<>
00022 # define SELF bounding_box<C,V>
00023 
00024 namespace mmx {
00025 namespace shape {
00026 
00027 TMPL struct bounding_box;
00028 
00029 // TMPL struct with_bounding_box { 
00030 //   typedef bounding_box<K> BoundingBox; 
00031 // };
00032 
00033 // TMPL struct bounding_box_def 
00034 //   :public shape_def<K>
00035 //   ,public with_bounding_box<K>
00036 // {};
00037 
00038 struct bounding_box_def {}; 
00039 
00040 template<> struct use<bounding_box_def> {
00041   typedef bounding_box<double,default_env> BoundingBox;
00042 }; 
00043 
00044 template<class C, class V=default_env>
00045 class bounding_box : public use<shape_def,V>::Shape {
00046 
00047 public:
00048      bounding_box(void) ;
00049      bounding_box(double xmin, double xmax) ;
00050      bounding_box(double xmin, double xmax, double ymin, double ymax) ;
00051      bounding_box(double xmin, double xmax, double ymin, double ymax, double zmin, double zmax) ;
00052      bounding_box(const SELF&) ;
00053     ~bounding_box(void) {};
00054     
00055     inline double xmin(void) { return m_xmin ; }
00056     inline double xmax(void) { return m_xmax ; }
00057     inline double ymin(void) { return m_ymin ; }
00058     inline double ymax(void) { return m_ymax ; }
00059     inline double zmin(void) { return m_zmin ; }
00060     inline double zmax(void) { return m_zmax ; }
00061 
00062     inline double xmin(void) const { return m_xmin ; }
00063     inline double xmax(void) const { return m_xmax ; }
00064     inline double ymin(void) const { return m_ymin ; }
00065     inline double ymax(void) const { return m_ymax ; }
00066     inline double zmin(void) const { return m_zmin ; }
00067     inline double zmax(void) const { return m_zmax ; }
00068 
00069     inline double xsize(void) const { return m_xmax-m_xmin ; }
00070     inline double ysize(void) const { return m_ymax-m_ymin ; }
00071     inline double zsize(void) const { return m_zmax-m_zmin ; }
00072 
00073     inline void set_xmin(double x) { this->m_xmin = x ; }
00074     inline void set_xmax(double x) { this->m_xmax = x ; }
00075     inline void set_ymin(double y) { this->m_ymin = y ; }
00076     inline void set_ymax(double y) { this->m_ymax = y ; }
00077     inline void set_zmin(double z) { this->m_zmin = z ; }
00078     inline void set_zmax(double z) { this->m_zmax = z ; }
00079 
00080     inline bool is0D(void) const { return ((m_xmin == m_xmax) && (m_ymin == m_ymax) && (m_zmin == m_zmax)) ; }
00081     inline bool is1D(void) const { return ((m_xmin != m_xmax) && (m_ymin == m_ymax) && (m_zmin == m_zmax)) ; }
00082     inline bool is2D(void) const { return ((m_xmin != m_xmax) && (m_ymin != m_ymax) && (m_zmin == m_zmax)) ; }
00083     inline bool is3d(void) const { return ((m_xmin != m_xmax) && (m_ymin != m_ymax) && (m_zmin != m_zmax)) ; }
00084 
00085     double  operator()(unsigned v, unsigned s) const;
00086     double& operator()(unsigned v, unsigned s);
00087 
00088     double size(void) ;
00089 
00090     bool contains(double x, bool strict = false) ;
00091     bool contains(double x, double y, bool strict = false) ;
00092     bool contains(double x, double y, double z, bool strict = false) ;
00093 
00094     bool intersects(SELF * other, bool strict = true) ;
00095     bool     unites(SELF * other, bool strict = true) ;
00096 
00097     void intersected(SELF * other) ;
00098     void      united(SELF * other) ;
00099 
00100     SELF * intersect(const SELF& other) ;
00101     SELF *     unite(SELF * other) ;
00102 
00103     inline SELF * operator * (const SELF& other) { return intersect(other) ; }
00104     inline SELF * operator + (const SELF& other) { return     unite(other) ; }
00105 
00106 protected:
00107     double m_xmin, m_xmax ;
00108     double m_ymin, m_ymax ;
00109     double m_zmin, m_zmax ;
00110 } ;
00111 
00112 TMPL inline double 
00113 lower(const SELF& bx, int v) {
00114   switch(v) {
00115   case 0:
00116     return bx.xmin(); break ;
00117   case 1:
00118     return bx.ymin(); break ;
00119     default:
00120       return bx.zmin(); break ;
00121   }
00122 } 
00123     
00124 TMPL inline double 
00125 upper(const SELF& bx, int v) {
00126   switch(v) {
00127   case 0:
00128     return bx.xmax(); break ;
00129   case 1:
00130     return bx.ymax(); break ;
00131   default:
00132     return bx.zmax(); break ;
00133   }
00134 }
00135 
00136 
00137 inline double mmxmin(double a, double b) 
00138 {
00139     return (a <= b) ? a : b ;
00140 }
00141 
00142 inline double mmxmax(double a, double b) 
00143 {
00144     return (a >= b) ? a : b ;
00145 }
00146 
00147 TMPL SELF::bounding_box(void)
00148 {
00149     this->m_xmin = 0.0 ;
00150     this->m_xmax = 1.0 ;
00151     this->m_ymin = 0.0 ;
00152     this->m_ymax = 1.0 ;
00153     this->m_zmin = 0.0 ;
00154     this->m_zmax = 1.0 ;
00155 }
00156 
00157 TMPL SELF::bounding_box(double xmin, double xmax)
00158 {
00159     this->m_xmin = xmin ;
00160     this->m_xmax = xmax ;
00161     this->m_ymin = 0.0 ;
00162     this->m_ymax = 1.0 ;
00163     this->m_zmin = 0.0 ;
00164     this->m_zmax = 1.0 ;
00165 }
00166 
00167 TMPL SELF::bounding_box(double xmin, double xmax, double ymin, double ymax)
00168 {
00169     this->m_xmin = xmin ;
00170     this->m_xmax = xmax ;
00171     this->m_ymin = ymin ;
00172     this->m_ymax = ymax ;
00173     this->m_zmin = 0.0 ;
00174     this->m_zmax = 0.0 ;
00175 }
00176 
00177 TMPL SELF::bounding_box(double xmin, double xmax, double ymin, double ymax, double zmin, double zmax)
00178 {
00179     this->m_xmin = xmin ;
00180     this->m_xmax = xmax ;
00181     this->m_ymin = ymin ;
00182     this->m_ymax = ymax ;
00183     this->m_zmin = zmin ;
00184     this->m_zmax = zmax ;
00185 }
00186 
00187 TMPL SELF::bounding_box(const SELF& bx)
00188 {
00189   m_xmin = bx.xmin() ;
00190   m_xmax = bx.xmax() ;
00191   m_ymin = bx.ymin() ;
00192   m_ymax = bx.ymax() ;
00193   m_zmin = bx.zmin() ;
00194   m_zmax = bx.zmax() ;
00195 }
00196 
00197 
00198 TMPL double 
00199 SELF::size(void)
00200 {
00201     return std::max(m_xmax-m_xmin, std::max(m_ymax-m_ymin, m_zmax-m_zmin)) ;
00202 }
00203 
00204 TMPL bool 
00205 SELF::contains(double x, bool strict)
00206 {
00207     if(!strict)
00208         return (((m_xmin <= x) && (x <= m_xmax))) ;
00209     else 
00210         return (((m_xmin <  x) && (x <  m_xmax))) ;
00211 }
00212 
00213 TMPL bool 
00214 SELF::contains(double x, double y, bool strict)
00215 {
00216     if(!strict)
00217         return (((m_xmin <= x) && (x <= m_xmax)) 
00218            &&   ((m_ymin <= y) && (y <= m_ymax))) ;
00219     else 
00220         return (((m_xmin <  x) && (x <  m_xmax)) 
00221            &&   ((m_ymin <  y) && (y <  m_ymax))) ;
00222 }
00223 
00224 TMPL bool 
00225 SELF::contains(double x, double y, double z, bool strict)
00226 {
00227     if(!strict)
00228         return (((m_xmin <= x) && (x <= m_xmax)) 
00229            &&   ((m_ymin <= y) && (y <= m_ymax)) 
00230            &&   ((m_zmin <= z) && (z <= m_zmax)))  ;
00231     else 
00232         return (((m_xmin <  x) && (x <  m_xmax)) 
00233            &&   ((m_ymin <  y) && (y <  m_ymax)) 
00234            &&   ((m_zmin <  z) && (z <  m_zmax)))  ;
00235 }
00236 
00237 TMPL bool 
00238 SELF::intersects(SELF * other, bool strict)
00239 {
00240          if(this->is0D())
00241             return (this->xmin() == other->xmin()) ;
00242     else if(this->is1D())
00243         if(strict)
00244             return ((mmxmax(this->xmin(), other->xmin()) <  mmxmin(this->xmax(), other->xmax()))) ;
00245         else
00246             return ((mmxmax(this->xmin(), other->xmin()) <= mmxmin(this->xmax(), other->xmax()))) ;
00247     else if(this->is2D())
00248         if(strict)
00249             return ((mmxmax(this->xmin(), other->xmin()) <  mmxmin(this->xmax(), other->xmax())) &&
00250                     (mmxmax(this->ymin(), other->ymin()) <  mmxmin(this->ymax(), other->ymax()))) ;
00251         else
00252             return ((mmxmax(this->xmin(), other->xmin()) <= mmxmin(this->xmax(), other->xmax())) &&
00253                     (mmxmax(this->ymin(), other->ymin()) <= mmxmin(this->ymax(), other->ymax()))) ;
00254     else if(this->is3d()) {
00255         if(strict)
00256             return ((mmxmax(this->xmin(), other->xmin()) <  mmxmin(this->xmax(), other->xmax())) &&
00257                     (mmxmax(this->ymin(), other->ymin()) <  mmxmin(this->ymax(), other->ymax())) &&
00258                     (mmxmax(this->zmin(), other->zmin()) <  mmxmin(this->zmax(), other->zmax()))) ;
00259         else
00260             return ((mmxmax(this->xmin(), other->xmin()) <= mmxmin(this->xmax(), other->xmax())) &&
00261                     (mmxmax(this->ymin(), other->ymin()) <= mmxmin(this->ymax(), other->ymax())) &&
00262                     (mmxmax(this->zmin(), other->zmin()) <= mmxmin(this->zmax(), other->zmax()))) ;
00263     }
00264          return false ;
00265 }
00266 
00267 TMPL bool 
00268 SELF::unites(SELF * other, bool strict)
00269 {
00270   if(this->is0D())
00271     return (this->xmin() == other->xmin()) ;
00272   else if(this->is1D()) {
00273     if(strict)
00274       return ((mmxmin(this->xmin(), other->xmin()) <  mmxmax(this->xmax(), other->xmax()))) ;
00275     else
00276       return ((mmxmin(this->xmin(), other->xmin()) <= mmxmax(this->xmax(), other->xmax()))) ;
00277   } else if(this->is2D()) {
00278     if(strict)
00279       return ((mmxmin(this->xmin(), other->xmin()) <  mmxmax(this->xmax(), other->xmax())) &&
00280               (mmxmin(this->ymin(), other->ymin()) <  mmxmax(this->ymax(), other->ymax()))) ;
00281     else
00282       return ((mmxmin(this->xmin(), other->xmin()) <= mmxmax(this->xmax(), other->xmax())) &&
00283               (mmxmin(this->ymin(), other->ymin()) <= mmxmax(this->ymax(), other->ymax()))) ;
00284   } else if(this->is3d()) {
00285     if(strict)
00286       return ((mmxmin(this->xmin(), other->xmin()) <  mmxmax(this->xmax(), other->xmax())) &&
00287                     (mmxmin(this->ymin(), other->ymin()) <  mmxmax(this->ymax(), other->ymax())) &&
00288               (mmxmin(this->zmin(), other->zmin()) <  mmxmax(this->zmax(), other->zmax()))) ;
00289     else
00290       return ((mmxmin(this->xmin(), other->xmin()) <= mmxmax(this->xmax(), other->xmax())) &&
00291               (mmxmin(this->ymin(), other->ymin()) <= mmxmax(this->ymax(), other->ymax())) &&
00292               (mmxmin(this->zmin(), other->zmin()) <= mmxmax(this->zmax(), other->zmax()))) ;
00293     }
00294   return false ;
00295 }
00296 
00297 TMPL void 
00298 SELF::intersected(SELF * other) {
00299   set_xmin(mmxmax(this->xmin(), other->xmin())) ;
00300   set_xmax(mmxmin(this->xmax(), other->xmax())) ;
00301   set_ymin(mmxmax(this->ymin(), other->ymin())) ;
00302   set_ymax(mmxmin(this->ymax(), other->ymax())) ;
00303   set_zmin(mmxmax(this->zmin(), other->zmin())) ;
00304   set_zmax(mmxmin(this->zmax(), other->zmax())) ;
00305 }
00306 
00307 TMPL void 
00308 SELF::united(SELF * other) {
00309   set_xmin(mmxmin(this->xmin(), other->xmin())) ;
00310   set_xmax(mmxmax(this->xmax(), other->xmax())) ;
00311   set_ymin(mmxmin(this->ymin(), other->ymin())) ;
00312   set_ymax(mmxmax(this->ymax(), other->ymax())) ;
00313   set_zmin(mmxmin(this->zmin(), other->zmin())) ;
00314   set_zmax(mmxmax(this->zmax(), other->zmax())) ;
00315 }
00316 
00317 TMPL SELF* 
00318 SELF::intersect(const SELF& other) {
00319   SELF * cell = new SELF ;
00320   cell->set_xmin(mmxmax(this->xmin(), other.xmin())) ;
00321   cell->set_xmax(mmxmin(this->xmax(), other.xmax())) ;
00322   cell->set_ymin(mmxmax(this->ymin(), other.ymin())) ;
00323   cell->set_ymax(mmxmin(this->ymax(), other.ymax())) ;
00324   cell->set_zmin(mmxmax(this->zmin(), other.zmin())) ;
00325   cell->set_zmax(mmxmin(this->zmax(), other.zmax())) ;
00326   return cell ;
00327 }
00328 
00329 TMPL SELF * 
00330 SELF::unite(SELF * other) {
00331   SELF * cell = new SELF ;
00332   cell->set_xmin(mmxmin(this->xmin(), other->xmin())) ;
00333   cell->set_xmax(mmxmax(this->xmax(), other->xmax())) ;
00334   cell->set_ymin(mmxmin(this->ymin(), other->ymin())) ;
00335   cell->set_ymax(mmxmax(this->ymax(), other->ymax())) ;
00336   cell->set_zmin(mmxmin(this->zmin(), other->zmin())) ;
00337   cell->set_zmax(mmxmax(this->zmax(), other->zmax())) ;
00338   return cell ;
00339 }
00340 
00341 TMPL double 
00342 SELF::operator()(unsigned v, unsigned s) const {
00343   switch(v) {
00344   case 0:
00345     if(s==0) return xmin(); else return xmax();
00346   case 1:
00347     if(s==0) return ymin(); else return ymax();
00348   default:
00349     if(s==0) return zmin(); else return zmax();
00350   }
00351   
00352 }
00353 
00354 TMPL double& 
00355 SELF::operator()(unsigned v, unsigned s) {
00356   switch(v) {
00357   case 0:
00358     if(s==0) return m_xmin; else return m_xmax;
00359   case 1:
00360     if(s==0) return m_ymin; else return m_ymax;
00361   default:
00362     if(s==0) return m_zmin; else return m_zmax;
00363   }
00364   
00365 }
00366 
00367 TMPL std::ostream& 
00368 operator << (std::ostream& stream, const SELF & c) {
00369   if(c.is0D())
00370     return stream << "[]" ;
00371   else if(c.is1D())
00372     return stream << "[" << c.xmin() << ", " << c.xmax() << "]" ;
00373   else if(c.is2D())
00374     return stream << "[" << c.xmin() << ", " << c.xmax() << "] x [" << c.ymin() << ", " << c.ymax() << "]" ;
00375   else if(c.is3d())
00376     return stream << "[" << c.xmin() << ", " << c.xmax() << "] x [" << c.ymin() << ", " << c.ymax() << "] x [" << c.zmin() << ", " << c.zmax() << "]" ;
00377   else
00378     return stream << "???" ;
00379 }
00380 
00381 // TMPL std::ostream& 
00382 // operator << (std::ostream& stream, SELF * c) {
00383 //   if(c->is0D())
00384 //     return stream << "[]" ;
00385 //   else if(c->is1D())
00386 //     return stream << "[" << c->xmin() << ", " << c->xmax() << "]" ;
00387 //   else if(c->is2D())
00388 //     return stream << "[" << c->xmin() << ", " << c->xmax() << "] x [" << c->ymin() << ", " << c->ymax() << "]" ;
00389 //   else if(c->is3d())
00390 //     return stream << "[" << c->xmin() << ", " << c->xmax() << "] x [" << c->ymin() << ", " << c->ymax() << "] x [" << c->zmin() << ", " << c->zmax() << "]" ;
00391 //   else
00392 //     return stream << "???" ;
00393 // }
00394 
00395 
00396 //--------------------------------------------------------------------
00397   template<class C, class V, class T> void
00398 insert_bbx(T* t,SELF* bx) {
00399   typedef typename T::Point Point;
00400   typedef typename T::Edge   Edge;
00401   Point 
00402     *p0= new Point(bx->xmin(),bx->ymin(),bx->zmin()),
00403     *p1= new Point(bx->xmin(),bx->ymax(),bx->zmin()),
00404     *p2= new Point(bx->xmax(),bx->ymax(),bx->zmin()),
00405     *p3= new Point(bx->xmax(),bx->ymin(),bx->zmin());
00406   t->insert(p0);t->insert(p1); t->insert(new Edge(p0,p1));
00407   t->insert(p1);t->insert(p2); t->insert(new Edge(p1,p2));
00408   t->insert(p2);t->insert(p3); t->insert(new Edge(p2,p3));
00409   t->insert(p3);t->insert(p0); t->insert(new Edge(p3,p0));
00410   
00411   Point 
00412     *q0= new Point(bx->xmin(),bx->ymin(),bx->zmax()),
00413     *q1= new Point(bx->xmin(),bx->ymax(),bx->zmax()),
00414     *q2= new Point(bx->xmax(),bx->ymax(),bx->zmax()),
00415     *q3= new Point(bx->xmax(),bx->ymin(),bx->zmax());
00416   t->insert(q0);t->insert(q1); t->insert(new Edge(q0,q1));
00417   t->insert(q1);t->insert(q2); t->insert(new Edge(q1,q2));
00418   t->insert(q2);t->insert(q3); t->insert(new Edge(q2,q3));
00419   t->insert(q3);t->insert(q0); t->insert(new Edge(q3,q0));
00420   
00421   t->insert(p0);t->insert(q0);t->insert(new Edge(p0,q0));
00422   t->insert(p1);t->insert(q1);t->insert(new Edge(p1,q1));
00423   t->insert(p2);t->insert(q2);t->insert(new Edge(p2,q2));
00424   t->insert(p3);t->insert(q3);t->insert(new Edge(p3,q3));
00425 }
00426 
00427 
00428 
00429   template<class C, class V, class T> void
00430 insert_bbx(T* t,SELF* bx, int v, int s) {
00431   typedef typename T::Point Point;
00432   typedef typename T::Edge   Edge;
00433 
00434   Point 
00435     *p0= new Point(bx->xmin(),bx->ymin(),bx->zmin()),
00436     *p1= new Point(bx->xmin(),bx->ymax(),bx->zmin()),
00437     *p2= new Point(bx->xmax(),bx->ymax(),bx->zmin()),
00438     *p3= new Point(bx->xmax(),bx->ymin(),bx->zmin());
00439   Point 
00440     *q0= new Point(bx->xmin(),bx->ymin(),bx->zmax()),
00441     *q1= new Point(bx->xmin(),bx->ymax(),bx->zmax()),
00442     *q2= new Point(bx->xmax(),bx->ymax(),bx->zmax()),
00443     *q3= new Point(bx->xmax(),bx->ymin(),bx->zmax());
00444 
00445   if(v==2) {
00446     if(s==0) {
00447       t->insert(p0);t->insert(p1); t->insert(new Edge(p0,p1));
00448       t->insert(p1);t->insert(p2); t->insert(new Edge(p1,p2));
00449       t->insert(p2);t->insert(p3); t->insert(new Edge(p2,p3));
00450       t->insert(p3);t->insert(p0); t->insert(new Edge(p3,p0));
00451     } else {
00452       t->insert(q0);t->insert(q1); t->insert(new Edge(q0,q1));
00453       t->insert(q1);t->insert(q2); t->insert(new Edge(q1,q2));
00454       t->insert(q2);t->insert(q3); t->insert(new Edge(q2,q3));
00455       t->insert(q3);t->insert(q0); t->insert(new Edge(q3,q0));
00456     }
00457   } else if(v==1) {
00458     if(s==0) {
00459       t->insert(p0);t->insert(q0);t->insert(new Edge(p0,q0));
00460       t->insert(q0);t->insert(q3);t->insert(new Edge(q0,q3));
00461       t->insert(q3);t->insert(p3);t->insert(new Edge(q3,p3));
00462       t->insert(p3);t->insert(p0);t->insert(new Edge(p3,p0));
00463     } else {
00464       t->insert(p1);t->insert(q1);t->insert(new Edge(p1,q1));
00465       t->insert(q1);t->insert(q2);t->insert(new Edge(q1,q2));
00466       t->insert(q2);t->insert(p2);t->insert(new Edge(q2,p2));
00467       t->insert(p2);t->insert(p1);t->insert(new Edge(p2,p1));
00468     }
00469   } else if (v==0) {
00470     if(s==0) {
00471       t->insert(p0);t->insert(q0);t->insert(new Edge(p0,q0));
00472       t->insert(q0);t->insert(q1);t->insert(new Edge(q0,q1));
00473       t->insert(q1);t->insert(p1);t->insert(new Edge(p1,q1));
00474       t->insert(p1);t->insert(p0);t->insert(new Edge(p1,p0));
00475     } else {
00476       t->insert(p2);t->insert(q2);t->insert(new Edge(p2,q2));
00477       t->insert(q2);t->insert(q3);t->insert(new Edge(q2,q3));
00478       t->insert(q3);t->insert(p3);t->insert(new Edge(p3,q3));
00479       t->insert(p3);t->insert(p2);t->insert(new Edge(p3,p2));
00480     }
00481   }
00482 }
00483 
00484 
00485 //--------------------------------------------------------------------
00486 } ; // namespace shape
00487 } ; // namespace mmx
00488 # undef TMPL
00489 # undef SELF
00490 # endif // shape_bounding_box_hpp