OGS 6.2.1-97-g73d1aeda3
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  {
134  return false;
135  }
136  if (pnt[1] < _min_pnt[1] - eps || _max_pnt[1] + eps <= pnt[1])
137  {
138  return false;
139  }
140  if (pnt[2] < _min_pnt[2] - eps || _max_pnt[2] + eps <= pnt[2])
141  {
142  return false;
143  }
144  return true;
145  }
146
147  template <typename T>
148  bool containsPointXY(T const & pnt) const
149  {
150  if (pnt[0] < _min_pnt[0] || _max_pnt[0] <= pnt[0])
151  {
152  return false;
153  }
154  if (pnt[1] < _min_pnt[1] || _max_pnt[1] <= pnt[1])
155  {
156  return false;
157  }
158  return true;
159  }
160
166  MathLib::Point3d const& getMinPoint() const { return _min_pnt; }
167
173  MathLib::Point3d const& getMaxPoint() const { return _max_pnt; }
174
182  bool containsAABB(AABB const& other_aabb) const
183  {
184  return containsPoint(other_aabb.getMinPoint(), 0) &&
185  containsPoint(other_aabb.getMaxPoint(), 0);
186  }
187
188 protected:
189  MathLib::Point3d _min_pnt = MathLib::Point3d{std::array<double,3>{{
190  std::numeric_limits<double>::max(),
191  std::numeric_limits<double>::max(),
192  std::numeric_limits<double>::max()}}};
193  MathLib::Point3d _max_pnt = MathLib::Point3d{std::array<double,3>{{
194  std::numeric_limits<double>::lowest(),
195  std::numeric_limits<double>::lowest(),
196  std::numeric_limits<double>::lowest()}}};
197 private:
201  void enlarge(std::bitset<3> to_update = 7)
202  {
203  for (std::size_t k=0; k<3; ++k) {
204  if (to_update[k]) {
205  _max_pnt[k] = std::nextafter(_max_pnt[k],
206  std::numeric_limits<double>::max());
207  }
208  }
209  }
210
211  template <typename PNT_TYPE>
212  void init(PNT_TYPE const & pnt)
213  {
214  _min_pnt[0] = _max_pnt[0] = pnt[0];
215  _min_pnt[1] = _max_pnt[1] = pnt[1];
216  _min_pnt[2] = _max_pnt[2] = pnt[2];
217  }
218
219  template <typename PNT_TYPE>
220  void init(PNT_TYPE * const & pnt)
221  {
222  init(*pnt);
223  }
224
230  template <typename PNT_TYPE>
231  void updateWithoutEnlarge(PNT_TYPE const & p)
232  {
233  for (std::size_t k(0); k<3; k++) {
234  if (p[k] < _min_pnt[k]) {
235  _min_pnt[k] = p[k];
236  }
237  if (p[k] >= _max_pnt[k]) {
238  _max_pnt[k] = p[k];
239  }
240  }
241  }
242
243  template <typename PNT_TYPE>
244  void updateWithoutEnlarge(PNT_TYPE * const & pnt)
245  {
246  updateWithoutEnlarge(*pnt);
247  }
248
249  template <typename PNT_TYPE>
250  void update(PNT_TYPE const * pnt)
251  {
252  update(*pnt);
253  }
254 };
255 } // namespace GeoLib
bool containsPoint(T const &pnt, double eps) const
Definition: AABB.h:130
MathLib::Point3d const & getMaxPoint() const
Definition: AABB.h:173
void updateWithoutEnlarge(PNT_TYPE const &p)
Definition: AABB.h:231
void init(PNT_TYPE *const &pnt)
Definition: AABB.h:220
void init(PNT_TYPE const &pnt)
Definition: AABB.h:212
MathLib::Point3d _min_pnt
Definition: AABB.h:189
Definition of the Point3d class.
MathLib::Point3d const & getMinPoint() const
Definition: AABB.h:166
bool update(PNT_TYPE const &p)
Definition: AABB.h:99
void enlarge(std::bitset< 3 > to_update=7)
Definition: AABB.h:201
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:244
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:182
void update(PNT_TYPE const *pnt)
Definition: AABB.h:250
#define OGS_FATAL(fmt,...)
Definition: Error.h:63
bool containsPointXY(T const &pnt) const
Definition: AABB.h:148
MathLib::Point3d _max_pnt
Definition: AABB.h:193