libMesh
bounding_box.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2025 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 
33 namespace libMesh
34 {
35 
40 class BoundingBox : public std::pair<Point, Point>
41 {
42 public:
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 
80  Point & min()
81  { return this->first; }
82 
86  const Point & max() const
87  { return this->second; }
88 
89  Point & max()
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 
207 inline
208 bool
209 BoundingBox::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.
229 inline
230 bool
231 BoundingBox::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 
266 inline
267 bool
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 
284 inline
285 void
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
friend std::ostream & operator<<(std::ostream &os, const BoundingBox &b)
Formatted print as above but supports the syntax:
Definition: bounding_box.h:195
BoundingBox()
Default constructor sets invalid bounds.
Definition: bounding_box.h:56
bool contains_point(const Point &) const
Definition: bounding_box.C:35
BoundingBox(const std::pair< Point, Point > &bbox)
Definition: bounding_box.h:49
void intersect_with(const BoundingBox &)
Sets this bounding box to be the intersection with the other bounding box.
Definition: bounding_box.C:123
bool intersects(const BoundingBox &) const
Definition: bounding_box.h:231
void invalidate()
Sets the bounding box to be "inverted".
Definition: bounding_box.h:65
The libMesh namespace provides an interface to certain functionality in the library.
Real signed_distance(const Point &p) const
Computes the signed distance, d, from a given Point p to this BoundingBox.
Definition: bounding_box.C:158
const Point & min() const
Definition: bounding_box.h:77
libmesh_assert(ctx)
Real max_size() const
Returns the maximum size of a finite box extent.
Definition: bounding_box.C:66
void print(std::ostream &os=libMesh::out) const
Formatted print, by default to libMesh::out.
Definition: bounding_box.C:212
BoundingBox(const Point &new_min, const Point &new_max)
Definition: bounding_box.h:44
Defines a Cartesian bounding box by the two corner extremum.
Definition: bounding_box.h:40
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
OStreamProxy out
bool contains(const BoundingBox &) const
Definition: bounding_box.h:209
void union_with(const Point &p)
Enlarges this bounding box to include the given point.
Definition: bounding_box.h:286
const Point & max() const
Definition: bounding_box.h:86
void scale(const Real factor)
Scales each dimension of the bounding box by factor.
Definition: bounding_box.C:195
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39