OGS
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 <Eigen/Eigen>
28 
29 #include "BaseLib/Error.h"
30 
31 namespace GeoLib
32 {
48 class AABB
49 {
50 public:
56  template <typename PNT_TYPE>
57  AABB(std::vector<PNT_TYPE*> const& pnts,
58  std::vector<std::size_t> const& ids)
59  {
60  assert(!ids.empty());
61  init(pnts[ids[0]]);
62  for (std::size_t i = 1; i < ids.size(); ++i)
63  {
64  updateWithoutEnlarge(*(pnts[ids[i]]));
65  }
66  enlarge();
67  }
68 
79  template <typename InputIterator>
80  AABB(InputIterator first, InputIterator last)
81  {
82  if (std::distance(first, last) <= 0)
83  {
84  OGS_FATAL(
85  "AABB::AABB(InputIterator first, InputIterator last): first > "
86  "last");
87  }
88  init(*first);
89  InputIterator it(first);
90  while (it != last)
91  {
93  it++;
94  }
95  enlarge();
96  }
97 
100  template <typename PNT_TYPE>
101  bool update(PNT_TYPE const& p)
102  {
103  // First component of the pair signals if the minimum point is changed
104  // Second component signals not only if the max point is changed.
105  // Furthermore it is signaled what coordinate (0,1,2) is changed.
106  std::pair<bool, std::bitset<3>> updated(false, 0);
107  for (std::size_t k(0); k < 3; k++)
108  {
109  // if the minimum point is updated pair.first==true
110  if (p[k] < _min_pnt[k])
111  {
112  _min_pnt[k] = p[k];
113  updated.first = true;
114  }
115  // if the kth coordinate of the maximum point is updated
116  // pair.second[k]==true
117  if (p[k] >= _max_pnt[k])
118  {
119  _max_pnt[k] = p[k];
120  updated.second[k] = true;
121  }
122  }
123 
124  if (updated.second.any())
125  {
126  enlarge(updated.second);
127  return true;
128  }
129  return updated.first;
130  }
131 
135  template <typename T>
136  bool containsPoint(T const& pnt, double eps) const
137  {
138  if (pnt[0] < _min_pnt[0] - eps || _max_pnt[0] + eps <= pnt[0])
139  {
140  return false;
141  }
142  if (pnt[1] < _min_pnt[1] - eps || _max_pnt[1] + eps <= pnt[1])
143  {
144  return false;
145  }
146  if (pnt[2] < _min_pnt[2] - eps || _max_pnt[2] + eps <= pnt[2])
147  {
148  return false;
149  }
150  return true;
151  }
152 
153  template <typename T>
154  bool containsPointXY(T const& pnt) const
155  {
156  if (pnt[0] < _min_pnt[0] || _max_pnt[0] <= pnt[0])
157  {
158  return false;
159  }
160  if (pnt[1] < _min_pnt[1] || _max_pnt[1] <= pnt[1])
161  {
162  return false;
163  }
164  return true;
165  }
166 
172  Eigen::Vector3d const& getMinPoint() const { return _min_pnt; }
173 
179  Eigen::Vector3d const& getMaxPoint() const { return _max_pnt; }
180 
188  bool containsAABB(AABB const& other_aabb) const
189  {
190  return containsPoint(other_aabb.getMinPoint(), 0) &&
191  containsPoint(other_aabb.getMaxPoint(), 0);
192  }
193 
194 private:
195  Eigen::Vector3d _min_pnt{std::numeric_limits<double>::max(),
196  std::numeric_limits<double>::max(),
197  std::numeric_limits<double>::max()};
198  Eigen::Vector3d _max_pnt{std::numeric_limits<double>::lowest(),
199  std::numeric_limits<double>::lowest(),
200  std::numeric_limits<double>::lowest()};
201 
202 private:
206  void enlarge(std::bitset<3> to_update = 7)
207  {
208  for (std::size_t k = 0; k < 3; ++k)
209  {
210  if (to_update[k])
211  {
212  _max_pnt[k] = std::nextafter(
213  _max_pnt[k], std::numeric_limits<double>::max());
214  }
215  }
216  }
217 
218  template <typename PNT_TYPE>
219  void init(PNT_TYPE const& pnt)
220  {
221  _min_pnt[0] = _max_pnt[0] = pnt[0];
222  _min_pnt[1] = _max_pnt[1] = pnt[1];
223  _min_pnt[2] = _max_pnt[2] = pnt[2];
224  }
225 
226  template <typename PNT_TYPE>
227  void init(PNT_TYPE* const& pnt)
228  {
229  init(*pnt);
230  }
231 
237  template <typename PNT_TYPE>
238  void updateWithoutEnlarge(PNT_TYPE const& p)
239  {
240  for (std::size_t k(0); k < 3; k++)
241  {
242  if (p[k] < _min_pnt[k])
243  {
244  _min_pnt[k] = p[k];
245  }
246  if (p[k] >= _max_pnt[k])
247  {
248  _max_pnt[k] = p[k];
249  }
250  }
251  }
252 
253  template <typename PNT_TYPE>
254  void updateWithoutEnlarge(PNT_TYPE* const& pnt)
255  {
256  updateWithoutEnlarge(*pnt);
257  }
258 
259  template <typename PNT_TYPE>
260  void update(PNT_TYPE const* pnt)
261  {
262  update(*pnt);
263  }
264 };
265 } // namespace GeoLib
#define OGS_FATAL(...)
Definition: Error.h:26
Class AABB is an axis aligned bounding box around a given set of geometric points of (template) type ...
Definition: AABB.h:49
void updateWithoutEnlarge(PNT_TYPE *const &pnt)
Definition: AABB.h:254
AABB(InputIterator first, InputIterator last)
Definition: AABB.h:80
AABB(std::vector< PNT_TYPE * > const &pnts, std::vector< std::size_t > const &ids)
Definition: AABB.h:57
Eigen::Vector3d const & getMinPoint() const
Definition: AABB.h:172
bool containsPoint(T const &pnt, double eps) const
Definition: AABB.h:136
void update(PNT_TYPE const *pnt)
Definition: AABB.h:260
Eigen::Vector3d _min_pnt
Definition: AABB.h:195
void init(PNT_TYPE const &pnt)
Definition: AABB.h:219
Eigen::Vector3d const & getMaxPoint() const
Definition: AABB.h:179
void updateWithoutEnlarge(PNT_TYPE const &p)
Definition: AABB.h:238
void init(PNT_TYPE *const &pnt)
Definition: AABB.h:227
Eigen::Vector3d _max_pnt
Definition: AABB.h:198
bool update(PNT_TYPE const &p)
Definition: AABB.h:101
bool containsAABB(AABB const &other_aabb) const
Definition: AABB.h:188
bool containsPointXY(T const &pnt) const
Definition: AABB.h:154
void enlarge(std::bitset< 3 > to_update=7)
Definition: AABB.h:206