moab
|
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 ¢er); 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 ¢er){ 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