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 
69  AABB(AABB const&) = default;
70 
81  template <typename InputIterator>
82  AABB(InputIterator first, InputIterator last)
83  {
84  if (std::distance(first, last) <= 0)
85  {
86  OGS_FATAL(
87  "AABB::AABB(InputIterator first, InputIterator last): first > "
88  "last");
89  }
90  init(*first);
91  InputIterator it(first);
92  while (it != last)
93  {
95  it++;
96  }
97  enlarge();
98  }
99 
102  template <typename PNT_TYPE>
103  bool update(PNT_TYPE const& p)
104  {
105  // First component of the pair signals if the minimum point is changed
106  // Second component signals not only if the max point is changed.
107  // Furthermore it is signaled what coordinate (0,1,2) is changed.
108  std::pair<bool, std::bitset<3>> updated(false, 0);
109  for (std::size_t k(0); k < 3; k++)
110  {
111  // if the minimum point is updated pair.first==true
112  if (p[k] < _min_pnt[k])
113  {
114  _min_pnt[k] = p[k];
115  updated.first = true;
116  }
117  // if the kth coordinate of the maximum point is updated
118  // pair.second[k]==true
119  if (p[k] >= _max_pnt[k])
120  {
121  _max_pnt[k] = p[k];
122  updated.second[k] = true;
123  }
124  }
125 
126  if (updated.second.any())
127  {
128  enlarge(updated.second);
129  return true;
130  }
131  return updated.first;
132  }
133 
137  template <typename T>
138  bool containsPoint(T const& pnt, double eps) const
139  {
140  if (pnt[0] < _min_pnt[0] - eps || _max_pnt[0] + eps <= pnt[0])
141  {
142  return false;
143  }
144  if (pnt[1] < _min_pnt[1] - eps || _max_pnt[1] + eps <= pnt[1])
145  {
146  return false;
147  }
148  if (pnt[2] < _min_pnt[2] - eps || _max_pnt[2] + eps <= pnt[2])
149  {
150  return false;
151  }
152  return true;
153  }
154 
155  template <typename T>
156  bool containsPointXY(T const& pnt) const
157  {
158  if (pnt[0] < _min_pnt[0] || _max_pnt[0] <= pnt[0])
159  {
160  return false;
161  }
162  if (pnt[1] < _min_pnt[1] || _max_pnt[1] <= pnt[1])
163  {
164  return false;
165  }
166  return true;
167  }
168 
174  Eigen::Vector3d const& getMinPoint() const { return _min_pnt; }
175 
181  Eigen::Vector3d const& getMaxPoint() const { return _max_pnt; }
182 
190  bool containsAABB(AABB const& other_aabb) const
191  {
192  return containsPoint(other_aabb.getMinPoint(), 0) &&
193  containsPoint(other_aabb.getMaxPoint(), 0);
194  }
195 
196 private:
197  Eigen::Vector3d _min_pnt{std::numeric_limits<double>::max(),
198  std::numeric_limits<double>::max(),
199  std::numeric_limits<double>::max()};
200  Eigen::Vector3d _max_pnt{std::numeric_limits<double>::lowest(),
201  std::numeric_limits<double>::lowest(),
202  std::numeric_limits<double>::lowest()};
203 
204 private:
208  void enlarge(std::bitset<3> to_update = 7)
209  {
210  for (std::size_t k = 0; k < 3; ++k)
211  {
212  if (to_update[k])
213  {
214  _max_pnt[k] = std::nextafter(
215  _max_pnt[k], std::numeric_limits<double>::max());
216  }
217  }
218  }
219 
220  template <typename PNT_TYPE>
221  void init(PNT_TYPE const& pnt)
222  {
223  _min_pnt[0] = _max_pnt[0] = pnt[0];
224  _min_pnt[1] = _max_pnt[1] = pnt[1];
225  _min_pnt[2] = _max_pnt[2] = pnt[2];
226  }
227 
228  template <typename PNT_TYPE>
229  void init(PNT_TYPE* const& pnt)
230  {
231  init(*pnt);
232  }
233 
239  template <typename PNT_TYPE>
240  void updateWithoutEnlarge(PNT_TYPE const& p)
241  {
242  for (std::size_t k(0); k < 3; k++)
243  {
244  if (p[k] < _min_pnt[k])
245  {
246  _min_pnt[k] = p[k];
247  }
248  if (p[k] >= _max_pnt[k])
249  {
250  _max_pnt[k] = p[k];
251  }
252  }
253  }
254 
255  template <typename PNT_TYPE>
256  void updateWithoutEnlarge(PNT_TYPE* const& pnt)
257  {
258  updateWithoutEnlarge(*pnt);
259  }
260 
261  template <typename PNT_TYPE>
262  void update(PNT_TYPE const* pnt)
263  {
264  update(*pnt);
265  }
266 };
267 } // 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:256
AABB(InputIterator first, InputIterator last)
Definition: AABB.h:82
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:174
bool containsPoint(T const &pnt, double eps) const
Definition: AABB.h:138
void update(PNT_TYPE const *pnt)
Definition: AABB.h:262
AABB(AABB const &)=default
Eigen::Vector3d _min_pnt
Definition: AABB.h:197
void init(PNT_TYPE const &pnt)
Definition: AABB.h:221
Eigen::Vector3d const & getMaxPoint() const
Definition: AABB.h:181
void updateWithoutEnlarge(PNT_TYPE const &p)
Definition: AABB.h:240
void init(PNT_TYPE *const &pnt)
Definition: AABB.h:229
Eigen::Vector3d _max_pnt
Definition: AABB.h:200
bool update(PNT_TYPE const &p)
Definition: AABB.h:103
bool containsAABB(AABB const &other_aabb) const
Definition: AABB.h:190
bool containsPointXY(T const &pnt) const
Definition: AABB.h:156
void enlarge(std::bitset< 3 > to_update=7)
Definition: AABB.h:208