Mesh Oriented datABase  (version 5.5.0)
An array-based unstructured mesh library
BoundBox.hpp
Go to the documentation of this file.
1 #ifndef BOUND_BOX_HPP
2 #define BOUND_BOX_HPP
3 
4 #include "moab/Interface.hpp"
5 #include "moab/CartVect.hpp"
6 
7 #include <cfloat>
8 
9 namespace moab
10 {
11 
12 class BoundBox
13 {
14  public:
15  BoundBox() : bMin( DBL_MAX ), bMax( -DBL_MAX ) {}
16  BoundBox( const CartVect& min, const CartVect& max ) : bMin( min ), bMax( max ) {}
17  BoundBox( const double* corners );
18  // constructor used in element maps
19  BoundBox( std::vector< CartVect > points ) : bMin( DBL_MAX ), bMax( -DBL_MAX )
20  {
21  for( size_t i = 0; i < points.size(); i++ )
22  {
23  update_min( points[i].array() );
24  update_max( points[i].array() );
25  }
26  }
27  BoundBox( const BoundBox& from ) : bMin( from.bMin ), bMax( from.bMax ) {}
28 
29  ~BoundBox() {}
30 
31  bool contains_point( const double* point, const double tol = 0.0 ) const;
32  bool intersects_box( const BoundBox& b, const double tol = 0.0 ) const;
34  void update( const BoundBox& other_box );
35  void update( const double* coords );
36  ErrorCode update( Interface& iface, const Range& elems, bool spherical = false, double radius = 1. );
37  ErrorCode update( Interface& iface, const EntityHandle ent, bool spherical = false, double radius = 1. );
38  void update_min( const BoundBox& other_box );
39  void update_min( const double* coords );
40  void update_max( const BoundBox& other_box );
41  void update_max( const double* coords );
42  ErrorCode get( double* coords );
43  /** in case of spherical elements, account for curvature if needed
44  */
45  void update_box_spherical_elem( const CartVect* coordverts, int len, double radius );
46 
47  /** \brief Return the diagonal length of this box
48  */
49  double diagonal_length() const;
50 
51  /** \brief Return the square of the diagonal length of this box
52  */
53  double diagonal_squared() const;
54 
55  /** \brief Return square of distance from box, or zero if inside
56  * \param from_point Point from which you want distance_sq
57  */
58  double distance_squared( const double* from_point ) const;
59 
60  /** \brief Return distance from box, or zero if inside
61  * \param from_point Point from which you want distance
62  */
63  double distance( const double* from_point ) const;
64 
65  BoundBox& operator=( const BoundBox& from )
66  {
67  bMin = from.bMin;
68  bMax = from.bMax;
69  return *this;
70  }
71  inline bool operator==( const BoundBox& box ) const
72  {
73  return ( bMin == box.bMin && bMax == box.bMax );
74  }
75 
77 };
78 
79 inline BoundBox::BoundBox( const double* corners )
80 {
81  // relies on CartVect being Plain Old Data, no virtual table
82  double* arr = bMin.array();
83  for( int i = 0; i < 6; i++ )
84  arr[i] = corners[i];
85 }
86 
87 inline bool BoundBox::contains_point( const double* point, const double tol ) const
88 {
89  if( point[0] < bMin[0] - tol || point[0] > bMax[0] + tol || point[1] < bMin[1] - tol || point[1] > bMax[1] + tol ||
90  point[2] < bMin[2] - tol || point[2] > bMax[2] + tol )
91  return false;
92  else
93  return true;
94 }
95 
96 inline bool BoundBox::intersects_box( const BoundBox& b, const double tol ) const
97 {
98  if( b.bMax[0] < bMin[0] - tol || b.bMin[0] > bMax[0] + tol || b.bMax[1] < bMin[1] - tol ||
99  b.bMin[1] > bMax[1] + tol || b.bMax[2] < bMin[2] - tol || b.bMin[2] > bMax[2] + tol )
100  return false;
101 
102  else
103  return true;
104 }
105 
106 inline void BoundBox::update( const BoundBox& other_box )
107 {
108  update_min( other_box );
109  update_max( other_box );
110 }
111 
112 inline void BoundBox::update( const double* coords )
113 {
114  update_min( coords );
115  update_max( coords + 3 );
116 }
117 
118 inline void BoundBox::update_min( const BoundBox& other_box )
119 {
120  bMin[0] = std::min( bMin[0], other_box.bMin[0] );
121  bMin[1] = std::min( bMin[1], other_box.bMin[1] );
122  bMin[2] = std::min( bMin[2], other_box.bMin[2] );
123 }
124 
125 inline void BoundBox::update_min( const double* coords )
126 {
127  bMin[0] = std::min( bMin[0], coords[0] );
128  bMin[1] = std::min( bMin[1], coords[1] );
129  bMin[2] = std::min( bMin[2], coords[2] );
130 }
131 
132 inline void BoundBox::update_max( const BoundBox& other_box )
133 {
134  bMax[0] = std::max( bMax[0], other_box.bMax[0] );
135  bMax[1] = std::max( bMax[1], other_box.bMax[1] );
136  bMax[2] = std::max( bMax[2], other_box.bMax[2] );
137 }
138 
139 inline void BoundBox::update_max( const double* coords )
140 {
141  bMax[0] = std::max( bMax[0], coords[0] );
142  bMax[1] = std::max( bMax[1], coords[1] );
143  bMax[2] = std::max( bMax[2], coords[2] );
144 }
145 
146 inline ErrorCode BoundBox::get( double* coords )
147 {
148  bMin.get( coords );
149  bMax.get( coords + 3 );
150  return MB_SUCCESS;
151 }
152 
154 {
155  center = 0.5 * ( bMin + bMax );
156 }
157 
158 inline std::ostream& operator<<( std::ostream& out, const BoundBox& box )
159 {
160  out << ( std::string ) "Min: ";
161  out << box.bMin;
162  out << ( std::string ) ", Max: ";
163  out << box.bMax;
164  return out;
165 }
166 
167 inline ErrorCode BoundBox::update( Interface& iface, const EntityHandle ent, bool spherical, double radius )
168 {
169  Range tmp_range( ent, ent );
170  return update( iface, tmp_range, spherical, radius );
171 }
172 
173 inline double BoundBox::distance_squared( const double* from_point ) const
174 {
175  double dist_sq = 0.0;
176  for( int i = 0; i < 3; ++i )
177  {
178  if( from_point[i] < bMin[i] )
179  dist_sq += ( bMin[i] - from_point[i] ) * ( bMin[i] - from_point[i] );
180  else if( from_point[i] > bMax[i] )
181  dist_sq += ( bMax[i] - from_point[i] ) * ( bMax[i] - from_point[i] );
182  }
183  return dist_sq;
184 }
185 
186 inline double BoundBox::distance( const double* from_point ) const
187 {
188  double dist_sq = distance_squared( from_point );
189  return sqrt( dist_sq );
190 }
191 
192 inline double BoundBox::diagonal_length() const
193 {
194  if( DBL_MAX == bMax[0] || DBL_MAX == bMax[1] || DBL_MAX == bMax[2] || DBL_MAX == bMin[0] || DBL_MAX == bMin[1] ||
195  DBL_MAX == bMin[2] )
196  return DBL_MAX;
197  return ( bMax - bMin ).length();
198 }
199 
200 inline double BoundBox::diagonal_squared() const
201 {
202  if( DBL_MAX == bMax[0] || DBL_MAX == bMax[1] || DBL_MAX == bMax[2] || DBL_MAX == bMin[0] || DBL_MAX == bMin[1] ||
203  DBL_MAX == bMin[2] )
204  return DBL_MAX;
205  return ( bMax - bMin ).length_squared();
206 }
207 
208 } // namespace moab
209 
210 #endif