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