OGS
AABB.h
Go to the documentation of this file.
1
15#pragma once
16
17#include <spdlog/fmt/bundled/ostream.h>
18
19#include <Eigen/Core>
20#include <bitset>
21#include <cassert>
22#include <cmath>
23#include <cstddef>
24#include <cstdlib>
25#include <iterator>
26#include <limits>
27#include <tuple>
28#include <vector>
29
30#include "BaseLib/Error.h"
31
32namespace GeoLib
33{
34struct MinMaxPoints final
35{
36 Eigen::Vector3d min;
37 Eigen::Vector3d max;
38};
39
55class AABB
56{
57public:
63 template <typename PNT_TYPE>
64 AABB(std::vector<PNT_TYPE*> const& pnts,
65 std::vector<std::size_t> const& ids)
66 {
67 assert(!ids.empty());
68 init(pnts[ids[0]]);
69 for (std::size_t i = 1; i < ids.size(); ++i)
70 {
71 updateWithoutEnlarge(*(pnts[ids[i]]));
72 }
73 enlarge();
74 }
75
86 template <typename InputIterator>
87 AABB(InputIterator first, InputIterator last)
88 {
89 if (std::distance(first, last) <= 0)
90 {
92 "AABB::AABB(InputIterator first, InputIterator last): first > "
93 "last");
94 }
95 init(*first);
96 InputIterator it(first);
97 while (it != last)
98 {
100 it++;
101 }
102 enlarge();
103 }
104
107 template <typename PNT_TYPE>
108 bool update(PNT_TYPE const& p)
109 {
110 // First component of the pair signals if the minimum point is changed
111 // Second component signals not only if the max point is changed.
112 // Furthermore it is signaled what coordinate (0,1,2) is changed.
113 std::pair<bool, std::bitset<3>> updated(false, 0);
114 for (std::size_t k(0); k < 3; k++)
115 {
116 // if the minimum point is updated pair.first==true
117 if (p[k] < _min_pnt[k])
118 {
119 _min_pnt[k] = p[k];
120 updated.first = true;
121 }
122 // if the kth coordinate of the maximum point is updated
123 // pair.second[k]==true
124 if (p[k] >= _max_pnt[k])
125 {
126 _max_pnt[k] = p[k];
127 updated.second[k] = true;
128 }
129 }
130
131 if (updated.second.any())
132 {
133 enlarge(updated.second);
134 return true;
135 }
136 return updated.first;
137 }
138
142 template <typename T>
143 bool containsPoint(T const& pnt, double eps) const
144 {
145 if (pnt[0] < _min_pnt[0] - eps || _max_pnt[0] + eps <= pnt[0])
146 {
147 return false;
148 }
149 if (pnt[1] < _min_pnt[1] - eps || _max_pnt[1] + eps <= pnt[1])
150 {
151 return false;
152 }
153 if (pnt[2] < _min_pnt[2] - eps || _max_pnt[2] + eps <= pnt[2])
154 {
155 return false;
156 }
157 return true;
158 }
159
160 template <typename T>
161 bool containsPointXY(T const& pnt) const
162 {
163 if (pnt[0] < _min_pnt[0] || _max_pnt[0] <= pnt[0])
164 {
165 return false;
166 }
167 if (pnt[1] < _min_pnt[1] || _max_pnt[1] <= pnt[1])
168 {
169 return false;
170 }
171 return true;
172 }
173
180 Eigen::Vector3d const& getMinPoint() const { return _min_pnt; }
181
187 Eigen::Vector3d const& getMaxPoint() const { return _max_pnt; }
188
196 bool containsAABB(AABB const& other_aabb) const
197 {
198 return containsPoint(other_aabb.getMinPoint(), 0) &&
199 containsPoint(other_aabb.getMaxPoint(), 0);
200 }
201
202 friend std::ostream& operator<<(std::ostream& os, AABB const& aabb)
203 {
204 auto const [min, max] = aabb.getMinMaxPoints();
205 os << "\tx [" << min[0] << ", " << max[0] << ") (extent "
206 << max[0] - min[0] << ")\n";
207 os << "\ty [" << min[1] << ", " << max[1] << ") (extent "
208 << max[1] - min[1] << ")\n";
209 os << "\tz [" << min[2] << ", " << max[2] << ") (extent "
210 << max[2] - min[2] << ")";
211 return os;
212 }
213
214private:
215 Eigen::Vector3d _min_pnt{std::numeric_limits<double>::max(),
216 std::numeric_limits<double>::max(),
217 std::numeric_limits<double>::max()};
218 Eigen::Vector3d _max_pnt{std::numeric_limits<double>::lowest(),
219 std::numeric_limits<double>::lowest(),
220 std::numeric_limits<double>::lowest()};
221
222private:
226 void enlarge(std::bitset<3> to_update = 7)
227 {
228 for (std::size_t k = 0; k < 3; ++k)
229 {
230 if (to_update[k])
231 {
232 _max_pnt[k] = std::nextafter(
233 _max_pnt[k], std::numeric_limits<double>::max());
234 }
235 }
236 }
237
238 template <typename PNT_TYPE>
239 void init(PNT_TYPE const& pnt)
240 {
241 _min_pnt[0] = _max_pnt[0] = pnt[0];
242 _min_pnt[1] = _max_pnt[1] = pnt[1];
243 _min_pnt[2] = _max_pnt[2] = pnt[2];
244 }
245
246 template <typename PNT_TYPE>
247 void init(PNT_TYPE* const& pnt)
248 {
249 init(*pnt);
250 }
251
257 template <typename PNT_TYPE>
258 void updateWithoutEnlarge(PNT_TYPE const& p)
259 {
260 for (std::size_t k(0); k < 3; k++)
261 {
262 if (p[k] < _min_pnt[k])
263 {
264 _min_pnt[k] = p[k];
265 }
266 if (p[k] >= _max_pnt[k])
267 {
268 _max_pnt[k] = p[k];
269 }
270 }
271 }
272
273 template <typename PNT_TYPE>
274 void updateWithoutEnlarge(PNT_TYPE* const& pnt)
275 {
277 }
278
279 template <typename PNT_TYPE>
280 void update(PNT_TYPE const* pnt)
281 {
282 update(*pnt);
283 }
284};
285} // namespace GeoLib
286
287namespace fmt
288{
289template <>
290struct formatter<::GeoLib::AABB> : ostream_formatter
291{
292};
293} // namespace fmt
#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:56
void updateWithoutEnlarge(PNT_TYPE *const &pnt)
Definition AABB.h:274
Eigen::Vector3d const & getMaxPoint() const
Definition AABB.h:187
AABB(InputIterator first, InputIterator last)
Definition AABB.h:87
friend std::ostream & operator<<(std::ostream &os, AABB const &aabb)
Definition AABB.h:202
AABB(std::vector< PNT_TYPE * > const &pnts, std::vector< std::size_t > const &ids)
Definition AABB.h:64
bool containsPoint(T const &pnt, double eps) const
Definition AABB.h:143
void update(PNT_TYPE const *pnt)
Definition AABB.h:280
Eigen::Vector3d _min_pnt
Definition AABB.h:215
void init(PNT_TYPE const &pnt)
Definition AABB.h:239
void updateWithoutEnlarge(PNT_TYPE const &p)
Definition AABB.h:258
Eigen::Vector3d const & getMinPoint() const
Definition AABB.h:180
void init(PNT_TYPE *const &pnt)
Definition AABB.h:247
Eigen::Vector3d _max_pnt
Definition AABB.h:218
MinMaxPoints getMinMaxPoints() const
Definition AABB.h:174
bool update(PNT_TYPE const &p)
Definition AABB.h:108
bool containsAABB(AABB const &other_aabb) const
Definition AABB.h:196
bool containsPointXY(T const &pnt) const
Definition AABB.h:161
void enlarge(std::bitset< 3 > to_update=7)
Definition AABB.h:226
Definition AABB.h:288
Eigen::Vector3d max
Definition AABB.h:37
Eigen::Vector3d min
Definition AABB.h:36