MOAB: Mesh Oriented datABase  (version 5.2.1)
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 
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines