MOAB: Mesh Oriented datABase
(version 5.2.1)
|
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 00012 class BoundBox 00013 { 00014 public: 00015 BoundBox() : bMin( DBL_MAX ), bMax( -DBL_MAX ) {} 00016 BoundBox( const CartVect& min, const CartVect& max ) : bMin( min ), bMax( max ) {} 00017 BoundBox( const double* corners ); 00018 // constructor used in element maps 00019 BoundBox( std::vector< CartVect > points ) : bMin( DBL_MAX ), bMax( -DBL_MAX ) 00020 { 00021 for( size_t i = 0; i < points.size(); i++ ) 00022 { 00023 update_min( points[i].array() ); 00024 update_max( points[i].array() ); 00025 } 00026 } 00027 ~BoundBox() {} 00028 00029 bool contains_point( const double* point, const double tol = 0.0 ) const; 00030 bool intersects_box( const BoundBox& b, const double tol = 0.0 ) const; 00031 void compute_center( CartVect& center ); 00032 void update( const BoundBox& other_box ); 00033 void update( const double* coords ); 00034 ErrorCode update( Interface& iface, const Range& elems, bool spherical = false, double radius = 1. ); 00035 ErrorCode update( Interface& iface, const EntityHandle ent, bool spherical = false, double radius = 1. ); 00036 void update_min( const BoundBox& other_box ); 00037 void update_min( const double* coords ); 00038 void update_max( const BoundBox& other_box ); 00039 void update_max( const double* coords ); 00040 ErrorCode get( double* coords ); 00041 /** in case of spherical elements, account for curvature if needed 00042 */ 00043 void update_box_spherical_elem( const CartVect* coordverts, int len, double radius ); 00044 00045 /** \brief Return the diagonal length of this box 00046 */ 00047 double diagonal_length() const; 00048 00049 /** \brief Return the square of the diagonal length of this box 00050 */ 00051 double diagonal_squared() const; 00052 00053 /** \brief Return square of distance from box, or zero if inside 00054 * \param from_point Point from which you want distance_sq 00055 */ 00056 double distance_squared( const double* from_point ) const; 00057 00058 /** \brief Return distance from box, or zero if inside 00059 * \param from_point Point from which you want distance 00060 */ 00061 double distance( const double* from_point ) const; 00062 00063 BoundBox& operator=( const BoundBox& from ) 00064 { 00065 bMin = from.bMin; 00066 bMax = from.bMax; 00067 return *this; 00068 } 00069 inline bool operator==( const BoundBox& box ) const 00070 { 00071 return ( bMin == box.bMin && bMax == box.bMax ); 00072 } 00073 00074 CartVect bMin, bMax; 00075 }; 00076 00077 inline BoundBox::BoundBox( const double* corners ) 00078 { 00079 // relies on CartVect being Plain Old Data, no virtual table 00080 double* arr = bMin.array(); 00081 for( int i = 0; i < 6; i++ ) 00082 arr[i] = corners[i]; 00083 } 00084 00085 inline bool BoundBox::contains_point( const double* point, const double tol ) const 00086 { 00087 if( point[0] < bMin[0] - tol || point[0] > bMax[0] + tol || point[1] < bMin[1] - tol || point[1] > bMax[1] + tol || 00088 point[2] < bMin[2] - tol || point[2] > bMax[2] + tol ) 00089 return false; 00090 else 00091 return true; 00092 } 00093 00094 inline bool BoundBox::intersects_box( const BoundBox& b, const double tol ) const 00095 { 00096 if( b.bMax[0] < bMin[0] - tol || b.bMin[0] > bMax[0] + tol || b.bMax[1] < bMin[1] - tol || 00097 b.bMin[1] > bMax[1] + tol || b.bMax[2] < bMin[2] - tol || b.bMin[2] > bMax[2] + tol ) 00098 return false; 00099 00100 else 00101 return true; 00102 } 00103 00104 inline void BoundBox::update( const BoundBox& other_box ) 00105 { 00106 update_min( other_box ); 00107 update_max( other_box ); 00108 } 00109 00110 inline void BoundBox::update( const double* coords ) 00111 { 00112 update_min( coords ); 00113 update_max( coords + 3 ); 00114 } 00115 00116 inline void BoundBox::update_min( const BoundBox& other_box ) 00117 { 00118 bMin[0] = std::min( bMin[0], other_box.bMin[0] ); 00119 bMin[1] = std::min( bMin[1], other_box.bMin[1] ); 00120 bMin[2] = std::min( bMin[2], other_box.bMin[2] ); 00121 } 00122 00123 inline void BoundBox::update_min( const double* coords ) 00124 { 00125 bMin[0] = std::min( bMin[0], coords[0] ); 00126 bMin[1] = std::min( bMin[1], coords[1] ); 00127 bMin[2] = std::min( bMin[2], coords[2] ); 00128 } 00129 00130 inline void BoundBox::update_max( const BoundBox& other_box ) 00131 { 00132 bMax[0] = std::max( bMax[0], other_box.bMax[0] ); 00133 bMax[1] = std::max( bMax[1], other_box.bMax[1] ); 00134 bMax[2] = std::max( bMax[2], other_box.bMax[2] ); 00135 } 00136 00137 inline void BoundBox::update_max( const double* coords ) 00138 { 00139 bMax[0] = std::max( bMax[0], coords[0] ); 00140 bMax[1] = std::max( bMax[1], coords[1] ); 00141 bMax[2] = std::max( bMax[2], coords[2] ); 00142 } 00143 00144 inline ErrorCode BoundBox::get( double* coords ) 00145 { 00146 bMin.get( coords ); 00147 bMax.get( coords + 3 ); 00148 return MB_SUCCESS; 00149 } 00150 00151 inline void BoundBox::compute_center( CartVect& center ) 00152 { 00153 center = 0.5 * ( bMin + bMax ); 00154 } 00155 00156 inline std::ostream& operator<<( std::ostream& out, const BoundBox& box ) 00157 { 00158 out << ( std::string ) "Min: "; 00159 out << box.bMin; 00160 out << ( std::string ) ", Max: "; 00161 out << box.bMax; 00162 return out; 00163 } 00164 00165 inline ErrorCode BoundBox::update( Interface& iface, const EntityHandle ent, bool spherical, double radius ) 00166 { 00167 Range tmp_range( ent, ent ); 00168 return update( iface, tmp_range, spherical, radius ); 00169 } 00170 00171 inline double BoundBox::distance_squared( const double* from_point ) const 00172 { 00173 double dist_sq = 0.0; 00174 for( int i = 0; i < 3; ++i ) 00175 { 00176 if( from_point[i] < bMin[i] ) 00177 dist_sq += ( bMin[i] - from_point[i] ) * ( bMin[i] - from_point[i] ); 00178 else if( from_point[i] > bMax[i] ) 00179 dist_sq += ( bMax[i] - from_point[i] ) * ( bMax[i] - from_point[i] ); 00180 } 00181 return dist_sq; 00182 } 00183 00184 inline double BoundBox::distance( const double* from_point ) const 00185 { 00186 double dist_sq = distance_squared( from_point ); 00187 return sqrt( dist_sq ); 00188 } 00189 00190 inline double BoundBox::diagonal_length() const 00191 { 00192 if( DBL_MAX == bMax[0] || DBL_MAX == bMax[1] || DBL_MAX == bMax[2] || DBL_MAX == bMin[0] || DBL_MAX == bMin[1] || 00193 DBL_MAX == bMin[2] ) 00194 return DBL_MAX; 00195 return ( bMax - bMin ).length(); 00196 } 00197 00198 inline double BoundBox::diagonal_squared() const 00199 { 00200 if( DBL_MAX == bMax[0] || DBL_MAX == bMax[1] || DBL_MAX == bMax[2] || DBL_MAX == bMin[0] || DBL_MAX == bMin[1] || 00201 DBL_MAX == bMin[2] ) 00202 return DBL_MAX; 00203 return ( bMax - bMin ).length_squared(); 00204 } 00205 00206 } // namespace moab 00207 00208 #endif