shape_doc 0.1
|
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