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