OGS 6.1.0-1721-g6382411ad
AABB.h
Go to the documentation of this file.
1 
15 #pragma once
16 
17 #include <bitset>
18 #include <cassert>
19 #include <cmath>
20 #include <cstddef>
21 #include <cstdlib>
22 #include <iterator>
23 #include <limits>
24 #include <tuple>
25 #include <vector>
26 
27 #include <logog/include/logog.hpp>
28 
29 #include "BaseLib/Error.h"
30 #include "MathLib/Point3d.h"
31 #include "MathLib/MathTools.h"
32 
33 namespace GeoLib
34 {
50 class AABB
51 {
52 public:
58  template <typename PNT_TYPE>
59  AABB(std::vector<PNT_TYPE*> const& pnts, std::vector<std::size_t> const& ids)
60  {
61  assert(! ids.empty());
62  init(pnts[ids[0]]);
63  for (std::size_t i=1; i<ids.size(); ++i) {
64  updateWithoutEnlarge(*(pnts[ids[i]]));
65  }
66  enlarge();
67  }
68 
69  AABB(AABB const&) = default;
70 
80  template <typename InputIterator>
81  AABB(InputIterator first, InputIterator last)
82  {
83  if (std::distance(first,last) <= 0)
84  {
85  OGS_FATAL("AABB::AABB(InputIterator first, InputIterator last): first > last");
86  }
87  init(*first);
88  InputIterator it(first);
89  while (it != last) {
91  it++;
92  }
93  enlarge();
94  }
95 
98  template <typename PNT_TYPE>
99  bool update(PNT_TYPE const & p)
100  {
101  // First component of the pair signals if the minimum point is changed
102  // Second component signals not only if the max point is changed.
103  // Furthermore it is signaled what coordinate (0,1,2) is changed.
104  std::pair<bool, std::bitset<3>> updated(false, 0);
105  for (std::size_t k(0); k<3; k++) {
106  // if the minimum point is updated pair.first==true
107  if (p[k] < _min_pnt[k]) {
108  _min_pnt[k] = p[k];
109  updated.first = true;
110  }
111  // if the kth coordinate of the maximum point is updated
112  // pair.second[k]==true
113  if (p[k] >= _max_pnt[k]) {
114  _max_pnt[k] = p[k];
115  updated.second[k] = true;
116  }
117  }
118 
119  if (updated.second.any()) {
120  enlarge(updated.second);
121  return true;
122  }
123  return updated.first;
124  }
125 
129  template <typename T>
130  bool containsPoint(T const & pnt, double eps) const
131  {
132  if (pnt[0] < _min_pnt[0] - eps || _max_pnt[0] + eps <= pnt[0])
133  return false;
134  if (pnt[1] < _min_pnt[1] - eps || _max_pnt[1] + eps <= pnt[1])
135  return false;
136  if (pnt[2] < _min_pnt[2] - eps || _max_pnt[2] + eps <= pnt[2])
137  return false;
138  return true;
139  }
140 
141  template <typename T>
142  bool containsPointXY(T const & pnt) const
143  {
144  if (pnt[0] < _min_pnt[0] || _max_pnt[0] <= pnt[0]) return false;
145  if (pnt[1] < _min_pnt[1] || _max_pnt[1] <= pnt[1]) return false;
146  return true;
147  }
148 
154  MathLib::Point3d const& getMinPoint() const { return _min_pnt; }
155 
161  MathLib::Point3d const& getMaxPoint() const { return _max_pnt; }
162 
170  bool containsAABB(AABB const& other_aabb) const
171  {
172  return containsPoint(other_aabb.getMinPoint(), 0) &&
173  containsPoint(other_aabb.getMaxPoint(), 0);
174  }
175 
176 protected:
177  MathLib::Point3d _min_pnt = MathLib::Point3d{std::array<double,3>{{
178  std::numeric_limits<double>::max(),
179  std::numeric_limits<double>::max(),
180  std::numeric_limits<double>::max()}}};
181  MathLib::Point3d _max_pnt = MathLib::Point3d{std::array<double,3>{{
182  std::numeric_limits<double>::lowest(),
183  std::numeric_limits<double>::lowest(),
184  std::numeric_limits<double>::lowest()}}};
185 private:
189  void enlarge(std::bitset<3> to_update = 7)
190  {
191  for (std::size_t k=0; k<3; ++k) {
192  if (to_update[k]) {
193  _max_pnt[k] = std::nextafter(_max_pnt[k],
194  std::numeric_limits<double>::max());
195  }
196  }
197  }
198 
199  template <typename PNT_TYPE>
200  void init(PNT_TYPE const & pnt)
201  {
202  _min_pnt[0] = _max_pnt[0] = pnt[0];
203  _min_pnt[1] = _max_pnt[1] = pnt[1];
204  _min_pnt[2] = _max_pnt[2] = pnt[2];
205  }
206 
207  template <typename PNT_TYPE>
208  void init(PNT_TYPE * const & pnt)
209  {
210  init(*pnt);
211  }
212 
218  template <typename PNT_TYPE>
219  void updateWithoutEnlarge(PNT_TYPE const & p)
220  {
221  for (std::size_t k(0); k<3; k++) {
222  if (p[k] < _min_pnt[k]) {
223  _min_pnt[k] = p[k];
224  }
225  if (p[k] >= _max_pnt[k]) {
226  _max_pnt[k] = p[k];
227  }
228  }
229  }
230 
231  template <typename PNT_TYPE>
232  void updateWithoutEnlarge(PNT_TYPE * const & pnt)
233  {
234  updateWithoutEnlarge(*pnt);
235  }
236 
237  template <typename PNT_TYPE>
238  void update(PNT_TYPE const * pnt)
239  {
240  update(*pnt);
241  }
242 };
243 } // end namespace
bool containsPoint(T const &pnt, double eps) const
Definition: AABB.h:130
MathLib::Point3d const & getMaxPoint() const
Definition: AABB.h:161
void updateWithoutEnlarge(PNT_TYPE const &p)
Definition: AABB.h:219
void init(PNT_TYPE *const &pnt)
Definition: AABB.h:208
void init(PNT_TYPE const &pnt)
Definition: AABB.h:200
MathLib::Point3d _min_pnt
Definition: AABB.h:177
Definition of the Point3d class.
MathLib::Point3d const & getMinPoint() const
Definition: AABB.h:154
bool update(PNT_TYPE const &p)
Definition: AABB.h:99
void enlarge(std::bitset< 3 > to_update=7)
Definition: AABB.h:189
Definition of the GEOObjects class.
Definition: BaseItem.h:20
AABB(InputIterator first, InputIterator last)
Definition: AABB.h:81
void updateWithoutEnlarge(PNT_TYPE *const &pnt)
Definition: AABB.h:232
AABB(std::vector< PNT_TYPE *> const &pnts, std::vector< std::size_t > const &ids)
Definition: AABB.h:59
Class AABB is an axis aligned bounding box around a given set of geometric points of (template) type ...
Definition: AABB.h:50
bool containsAABB(AABB const &other_aabb) const
Definition: AABB.h:170
void update(PNT_TYPE const *pnt)
Definition: AABB.h:238
#define OGS_FATAL(fmt,...)
Definition: Error.h:71
bool containsPointXY(T const &pnt) const
Definition: AABB.h:142
MathLib::Point3d _max_pnt
Definition: AABB.h:181