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
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;
33 void compute_center( CartVect& center );
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
45 void update_box_spherical_elem( const CartVect* coordverts, int len, double radius );
46
47
49 double diagonal_length() const;
50
51
53 double diagonal_squared() const;
54
55
58 double distance_squared( const double* from_point ) const;
59
60
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
76 CartVect bMin, bMax;
77 };
78
79 inline BoundBox::BoundBox( const double* corners )
80 {
81
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
153 inline void BoundBox::compute_center( CartVect& center )
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 }
209
210 #endif