libMesh
Loading...
Searching...
No Matches
bounding_box.h
Go to the documentation of this file.
1// The libMesh Finite Element Library.
2// Copyright (C) 2002-2026 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3
4// This library is free software; you can redistribute it and/or
5// modify it under the terms of the GNU Lesser General Public
6// License as published by the Free Software Foundation; either
7// version 2.1 of the License, or (at your option) any later version.
8
9// This library is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12// Lesser General Public License for more details.
13
14// You should have received a copy of the GNU Lesser General Public
15// License along with this library; if not, write to the Free Software
16// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18
19
20#ifndef LIBMESH_BOUNDING_BOX_H
21#define LIBMESH_BOUNDING_BOX_H
22
23// Local Includes
24#include "libmesh/libmesh.h"
25#include "libmesh/point.h" // some compilers want the full definition - I think so they can do
26// return-value-optimization for BoundingBox'es - BSK
27
28// C++ Includes
29#include <vector>
30#include <set>
31#include <limits>
32
33namespace libMesh
34{
35
40class BoundingBox : public std::pair<Point, Point>
41{
42public:
43
44 BoundingBox (const Point & new_min,
45 const Point & new_max) :
46 std::pair<Point, Point>(new_min, new_max)
47 {}
48
49 BoundingBox (const std::pair<Point, Point> & bbox) :
50 std::pair<Point, Point> (bbox)
51 {}
52
57 {
58 this->invalidate();
59 }
60
65 void invalidate ()
66 {
67 for (unsigned int i=0; i<LIBMESH_DIM; i++)
68 {
69 this->first(i) = std::numeric_limits<Real>::max();
70 this->second(i) = -std::numeric_limits<Real>::max();
71 }
72 }
73
77 const Point & min() const
78 { return this->first; }
79
81 { return this->first; }
82
86 const Point & max() const
87 { return this->second; }
88
90 { return this->second; }
91
96 bool contains (const BoundingBox &) const;
97
103 bool intersects (const BoundingBox &) const;
104
119 bool intersects (const BoundingBox &, Real abstol) const;
120
124 bool contains_point (const Point &) const;
125
135 bool contains_point (const Point & p, Real abs_tol, Real rel_tol) const;
136
141 void intersect_with (const BoundingBox &);
142
146 void union_with (const Point & p);
147
152 void union_with (const BoundingBox &);
153
160 Real signed_distance(const Point & p) const;
161
171 void scale(const Real factor);
172
180 Real max_size() const;
181
185 void print(std::ostream & os = libMesh::out) const;
186
195 friend std::ostream & operator << (std::ostream & os, const BoundingBox & b)
196 {
197 b.print(os);
198 return os;
199 }
200};
201
202
203
204// ------------------------------------------------------------
205// BoundingBox class member functions
206
207inline
208bool
209BoundingBox::contains(const BoundingBox & other_box) const
210{
211 const libMesh::Point & my_lower = this->first;
212 const libMesh::Point & my_upper = this->second;
213
214 const libMesh::Point & other_lower = other_box.first;
215 const libMesh::Point & other_upper = other_box.second;
216
217 for (unsigned int dir=0; dir<LIBMESH_DIM; ++dir)
218 if (my_lower(dir) > other_lower(dir) ||
219 other_upper(dir) > my_upper(dir))
220 return false;
221
222 return true;
223}
224
225
226
227// BoundingBox::intersects() is about 30% faster when inlined, so its definition
228// is here instead of in the source file.
229inline
230bool
231BoundingBox::intersects(const BoundingBox & other_box) const
232{
233 const libMesh::Point & my_lower = this->first;
234 const libMesh::Point & my_upper = this->second;
235
236 const libMesh::Point & other_lower = other_box.first;
237 const libMesh::Point & other_upper = other_box.second;
238
239 // Since boxes are tensor products of line intervals it suffices to check
240 // that the line segments for each coordinate axis overlap.
241 for (unsigned int dir=0; dir<LIBMESH_DIM; ++dir)
242 {
243 // Line segments can intersect in two ways:
244 // 1. They can overlap.
245 // 2. One can be inside the other.
246 //
247 // In the first case we want to see if either end point of the second
248 // line segment lies within the first. In the second case we can simply
249 // check that one end point of the first line segment lies in the second
250 // line segment. Note that we don't need, in the second case, to do two
251 // checks since that case is already covered by the first.
252 if (!((my_lower(dir) <= other_lower(dir) &&
253 other_lower(dir) <= my_upper(dir)) ||
254 (my_lower(dir) <= other_upper(dir) &&
255 other_upper(dir) <= my_upper(dir))) &&
256 !((other_lower(dir) <= my_lower(dir) &&
257 my_lower(dir) <= other_upper(dir))))
258 {
259 return false;
260 }
261 }
262
263 return true;
264}
265
266inline
267bool
269 Real abstol) const
270{
271 // If you want to use abstol==0, you need to call the "exact"
272 // comparison version of the intersects() function.
273 libmesh_assert(abstol > 0.);
274
275 BoundingBox expanded_my_box = *this;
276 for (unsigned int dir=0; dir<LIBMESH_DIM; ++dir)
277 {
278 expanded_my_box.first(dir) -= abstol;
279 expanded_my_box.second(dir) += abstol;
280 }
281 return expanded_my_box.intersects(other_box);
282}
283
284inline
285void
287{
288 for (unsigned int i=0; i<LIBMESH_DIM; i++)
289 {
290 min()(i) = std::min(min()(i), p(i));
291 max()(i) = std::max(max()(i), p(i));
292 }
293}
294
295} // namespace libMesh
296
297
298#endif // LIBMESH_BOUNDING_BOX_H
Defines a Cartesian bounding box by the two corner extremum.
bool intersects(const BoundingBox &) const
Real signed_distance(const Point &p) const
Computes the signed distance, d, from a given Point p to this BoundingBox.
Real max_size() const
Returns the maximum size of a finite box extent.
const Point & max() const
BoundingBox(const Point &new_min, const Point &new_max)
BoundingBox(const std::pair< Point, Point > &bbox)
BoundingBox()
Default constructor sets invalid bounds.
void invalidate()
Sets the bounding box to be "inverted".
void scale(const Real factor)
Scales each dimension of the bounding box by factor.
friend std::ostream & operator<<(std::ostream &os, const BoundingBox &b)
Formatted print as above but supports the syntax:
bool contains(const BoundingBox &) const
const Point & min() const
bool contains_point(const Point &) const
void union_with(const Point &p)
Enlarges this bounding box to include the given point.
void intersect_with(const BoundingBox &)
Sets this bounding box to be the intersection with the other bounding box.
void print(std::ostream &os=libMesh::out) const
Formatted print, by default to libMesh::out.
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:40
static const Real b
The libMesh namespace provides an interface to certain functionality in the library.
libmesh_assert(ctx)
OStreamProxy out
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real