moab
BoundBox.hpp
Go to the documentation of this file.
00001 #ifndef BOUND_BOX_HPP
00002 #define BOUND_BOX_HPP
00003 
00004 #include "moab/Interface.hpp"
00005 #include "moab/CartVect.hpp"
00006 
00007 #include <cfloat>
00008 
00009 namespace moab {
00010 
00011     class BoundBox {
00012   public:
00013       BoundBox() : bMin(DBL_MAX), bMax(-DBL_MAX) {}
00014       BoundBox(const CartVect &min, const CartVect &max) : 
00015               bMin(min), bMax(max) {}
00016       BoundBox(const double *corners);
00017       ~BoundBox() {}
00018 
00019       bool contains_point(const double *point, const double tol = 0.0) const;
00020       bool intersects_box(const BoundBox &b, const double tol = 0.0) const;
00021       void compute_center(CartVect &center);
00022       void update(const BoundBox &other_box);
00023       void update(const double *coords);
00024       ErrorCode update(Interface &iface, const Range& elems);
00025       ErrorCode update(Interface &iface, const EntityHandle ent);
00026       void update_min(const BoundBox &other_box);
00027       void update_min(const double *coords);
00028       void update_max(const BoundBox &other_box);
00029       void update_max(const double *coords);
00030       ErrorCode get(double *coords);
00031 
00034       double diagonal_length() const;
00035       
00038       double diagonal_squared() const;
00039       
00043       double distance_squared(const double *from_point) const;
00044 
00048       double distance(const double *from_point) const;
00049       
00050       BoundBox &operator=(const BoundBox &from) {
00051         bMin = from.bMin;
00052         bMax = from.bMax;
00053         return *this;
00054       }
00055       inline bool operator==(const BoundBox &box) const {
00056         return (bMin == box.bMin && bMax == box.bMax);
00057       }
00058 
00059       CartVect bMin, bMax;
00060     };
00061     
00062     inline BoundBox::BoundBox(const double *corners) 
00063     {
00064         // relies on CartVect being Plain Old Data, no virtual table
00065       double *arr = bMin.array();
00066       for (int i = 0; i < 6; i++)
00067         arr[i] = corners[i];
00068     }
00069 
00070     inline bool BoundBox::contains_point(const double *point, const double tol) const {
00071       if (point[0] < bMin[0]-tol || point[0] > bMax[0]+tol ||
00072           point[1] < bMin[1]-tol || point[1] > bMax[1]+tol ||
00073           point[2] < bMin[2]-tol || point[2] > bMax[2]+tol)
00074         return false;
00075       else return true;
00076     }
00077 
00078     inline bool BoundBox::intersects_box(const BoundBox &b, const double tol) const {
00079       if (b.bMax[0] < bMin[0]-tol || b.bMin[0] > bMax[0]+tol ||
00080           b.bMax[1] < bMin[1]-tol || b.bMin[1] > bMax[1]+tol ||
00081           b.bMax[2] < bMin[2]-tol || b.bMin[2] > bMax[2]+tol) 
00082         return false;
00083 
00084       else return true;
00085     }
00086 
00087     inline void BoundBox::update(const BoundBox &other_box) 
00088     {
00089       update_min(other_box);
00090       update_max(other_box);
00091     }
00092 
00093     inline void BoundBox::update(const double *coords) 
00094     {
00095       update_min(coords);
00096       update_max(coords+3);
00097     }
00098 
00099     inline void BoundBox::update_min(const BoundBox &other_box) 
00100     {
00101       bMin[0] = std::min(bMin[0], other_box.bMin[0]);
00102       bMin[1] = std::min(bMin[1], other_box.bMin[1]);
00103       bMin[2] = std::min(bMin[2], other_box.bMin[2]);
00104     }
00105       
00106     inline void BoundBox::update_min(const double *coords) 
00107     {
00108       bMin[0] = std::min(bMin[0], coords[0]);
00109       bMin[1] = std::min(bMin[1], coords[1]);
00110       bMin[2] = std::min(bMin[2], coords[2]);
00111     }
00112       
00113     inline void BoundBox::update_max(const BoundBox &other_box)
00114     {
00115       bMax[0] = std::max(bMax[0], other_box.bMax[0]);
00116       bMax[1] = std::max(bMax[1], other_box.bMax[1]);
00117       bMax[2] = std::max(bMax[2], other_box.bMax[2]);
00118     }
00119 
00120     inline void BoundBox::update_max(const double *coords)
00121     {
00122       bMax[0] = std::max(bMax[0], coords[0]);
00123       bMax[1] = std::max(bMax[1], coords[1]);
00124       bMax[2] = std::max(bMax[2], coords[2]);
00125     }
00126 
00127     inline ErrorCode BoundBox::get(double *coords)
00128     {
00129       bMin.get(coords);
00130       bMax.get(coords+3);
00131       return MB_SUCCESS;
00132     }
00133 
00134     inline void BoundBox::compute_center(CartVect &center){
00135       center = 0.5 * (bMin + bMax);
00136     }
00137 
00138     inline std::ostream &operator<<(std::ostream& out, const BoundBox &box) {
00139       out << (std::string) "Min: ";
00140       out << box.bMin;
00141       out << (std::string) ", Max: ";
00142       out << box.bMax;
00143       return out;
00144     }
00145 
00146     inline ErrorCode BoundBox::update(Interface &iface, const EntityHandle ent) 
00147     {
00148       Range tmp_range(ent, ent);
00149       return update(iface, tmp_range);
00150     }
00151 
00152     inline double BoundBox::distance_squared(const double *from_point) const
00153     {
00154       double dist_sq = 0.0;
00155       for (int i = 0; i < 3; ++i) {
00156         if (from_point[i] < bMin[i])
00157           dist_sq += (bMin[i] - from_point[i]) * (bMin[i] - from_point[i]);
00158         else if (from_point[i] > bMax[i]) 
00159           dist_sq += (bMax[i] - from_point[i]) * (bMax[i] - from_point[i]);
00160       }
00161       return dist_sq;
00162     }
00163 
00164     inline double BoundBox::distance(const double *from_point) const
00165     {
00166       double dist_sq = distance_squared(from_point);
00167       return sqrt(dist_sq);
00168     }
00169 
00170     inline double BoundBox::diagonal_length() const 
00171     {
00172       if (DBL_MAX == bMax[0] || DBL_MAX == bMax[1] || DBL_MAX == bMax[2] ||
00173           DBL_MAX == bMin[0] || DBL_MAX == bMin[1] || DBL_MAX == bMin[2]) return DBL_MAX;
00174       return (bMax - bMin).length();
00175     }
00176 
00177     inline double BoundBox::diagonal_squared() const 
00178     {
00179       if (DBL_MAX == bMax[0] || DBL_MAX == bMax[1] || DBL_MAX == bMax[2] ||
00180           DBL_MAX == bMin[0] || DBL_MAX == bMin[1] || DBL_MAX == bMin[2]) return DBL_MAX;
00181       return (bMax - bMin).length_squared();
00182     }
00183 }
00184 
00185 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines