OGS
AABB.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) OpenGeoSys Community (opengeosys.org)
2// SPDX-License-Identifier: BSD-3-Clause
3
4#pragma once
5
6#include <spdlog/fmt/ostr.h>
7
8#include <Eigen/Core>
9#include <bitset>
10#include <cassert>
11#include <cmath>
12#include <cstddef>
13#include <cstdlib>
14#include <iterator>
15#include <limits>
16#include <tuple>
17#include <vector>
18
19#include "BaseLib/Error.h"
20
21namespace GeoLib
22{
23struct MinMaxPoints final
24{
25 Eigen::Vector3d min;
26 Eigen::Vector3d max;
27};
28
44class AABB
45{
46public:
52 template <typename PNT_TYPE>
53 AABB(std::vector<PNT_TYPE*> const& pnts,
54 std::vector<std::size_t> const& ids)
55 {
56 assert(!ids.empty());
57 init(pnts[ids[0]]);
58 for (std::size_t i = 1; i < ids.size(); ++i)
59 {
60 updateWithoutEnlarge(*(pnts[ids[i]]));
61 }
62 enlarge();
63 }
64
75 template <typename InputIterator>
76 AABB(InputIterator first, InputIterator last)
77 {
78 if (std::distance(first, last) <= 0)
79 {
81 "AABB::AABB(InputIterator first, InputIterator last): first > "
82 "last");
83 }
84 init(*first);
85 InputIterator it(first);
86 while (it != last)
87 {
89 it++;
90 }
91 enlarge();
92 }
93
96 template <typename PNT_TYPE>
97 bool update(PNT_TYPE const& p)
98 {
99 // First component of the pair signals if the minimum point is changed
100 // Second component signals not only if the max point is changed.
101 // Furthermore it is signaled what coordinate (0,1,2) is changed.
102 std::pair<bool, std::bitset<3>> updated(false, 0);
103 for (std::size_t k(0); k < 3; k++)
104 {
105 // if the minimum point is updated pair.first==true
106 if (p[k] < _min_pnt[k])
107 {
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 {
115 _max_pnt[k] = p[k];
116 updated.second[k] = true;
117 }
118 }
119
120 if (updated.second.any())
121 {
122 enlarge(updated.second);
123 return true;
124 }
125 return updated.first;
126 }
127
131 template <typename T>
132 bool containsPoint(T const& pnt, double eps) const
133 {
134 if (pnt[0] < _min_pnt[0] - eps || _max_pnt[0] + eps <= pnt[0])
135 {
136 return false;
137 }
138 if (pnt[1] < _min_pnt[1] - eps || _max_pnt[1] + eps <= pnt[1])
139 {
140 return false;
141 }
142 if (pnt[2] < _min_pnt[2] - eps || _max_pnt[2] + eps <= pnt[2])
143 {
144 return false;
145 }
146 return true;
147 }
148
149 template <typename T>
150 bool containsPointXY(T const& pnt) const
151 {
152 if (pnt[0] < _min_pnt[0] || _max_pnt[0] <= pnt[0])
153 {
154 return false;
155 }
156 if (pnt[1] < _min_pnt[1] || _max_pnt[1] <= pnt[1])
157 {
158 return false;
159 }
160 return true;
161 }
162
169 Eigen::Vector3d const& getMinPoint() const { return _min_pnt; }
170
176 Eigen::Vector3d const& getMaxPoint() const { return _max_pnt; }
177
185 bool containsAABB(AABB const& other_aabb) const
186 {
187 return containsPoint(other_aabb.getMinPoint(), 0) &&
188 containsPoint(other_aabb.getMaxPoint(), 0);
189 }
190
191 friend std::ostream& operator<<(std::ostream& os, AABB const& aabb)
192 {
193 auto const [min, max] = aabb.getMinMaxPoints();
194 os << "\tx [" << min[0] << ", " << max[0] << ") (extent "
195 << max[0] - min[0] << ")\n";
196 os << "\ty [" << min[1] << ", " << max[1] << ") (extent "
197 << max[1] - min[1] << ")\n";
198 os << "\tz [" << min[2] << ", " << max[2] << ") (extent "
199 << max[2] - min[2] << ")";
200 return os;
201 }
202
203private:
204 Eigen::Vector3d _min_pnt{std::numeric_limits<double>::max(),
205 std::numeric_limits<double>::max(),
206 std::numeric_limits<double>::max()};
207 Eigen::Vector3d _max_pnt{std::numeric_limits<double>::lowest(),
208 std::numeric_limits<double>::lowest(),
209 std::numeric_limits<double>::lowest()};
210
211private:
215 void enlarge(std::bitset<3> to_update = 7)
216 {
217 for (std::size_t k = 0; k < 3; ++k)
218 {
219 if (to_update[k])
220 {
221 _max_pnt[k] = std::nextafter(
222 _max_pnt[k], std::numeric_limits<double>::max());
223 }
224 }
225 }
226
227 template <typename PNT_TYPE>
228 void init(PNT_TYPE const& pnt)
229 {
230 _min_pnt[0] = _max_pnt[0] = pnt[0];
231 _min_pnt[1] = _max_pnt[1] = pnt[1];
232 _min_pnt[2] = _max_pnt[2] = pnt[2];
233 }
234
235 template <typename PNT_TYPE>
236 void init(PNT_TYPE* const& pnt)
237 {
238 init(*pnt);
239 }
240
246 template <typename PNT_TYPE>
247 void updateWithoutEnlarge(PNT_TYPE const& p)
248 {
249 for (std::size_t k(0); k < 3; k++)
250 {
251 if (p[k] < _min_pnt[k])
252 {
253 _min_pnt[k] = p[k];
254 }
255 if (p[k] >= _max_pnt[k])
256 {
257 _max_pnt[k] = p[k];
258 }
259 }
260 }
261
262 template <typename PNT_TYPE>
263 void updateWithoutEnlarge(PNT_TYPE* const& pnt)
264 {
266 }
267
268 template <typename PNT_TYPE>
269 void update(PNT_TYPE const* pnt)
270 {
271 update(*pnt);
272 }
273};
274} // namespace GeoLib
275
276namespace fmt
277{
278template <>
279struct formatter<::GeoLib::AABB> : ostream_formatter
280{
281};
282} // namespace fmt
#define OGS_FATAL(...)
Definition Error.h:19
Class AABB is an axis aligned bounding box around a given set of geometric points of (template) type ...
Definition AABB.h:45
void updateWithoutEnlarge(PNT_TYPE *const &pnt)
Definition AABB.h:263
Eigen::Vector3d const & getMaxPoint() const
Definition AABB.h:176
AABB(InputIterator first, InputIterator last)
Definition AABB.h:76
friend std::ostream & operator<<(std::ostream &os, AABB const &aabb)
Definition AABB.h:191
AABB(std::vector< PNT_TYPE * > const &pnts, std::vector< std::size_t > const &ids)
Definition AABB.h:53
bool containsPoint(T const &pnt, double eps) const
Definition AABB.h:132
void update(PNT_TYPE const *pnt)
Definition AABB.h:269
Eigen::Vector3d _min_pnt
Definition AABB.h:204
void init(PNT_TYPE const &pnt)
Definition AABB.h:228
void updateWithoutEnlarge(PNT_TYPE const &p)
Definition AABB.h:247
Eigen::Vector3d const & getMinPoint() const
Definition AABB.h:169
void init(PNT_TYPE *const &pnt)
Definition AABB.h:236
Eigen::Vector3d _max_pnt
Definition AABB.h:207
MinMaxPoints getMinMaxPoints() const
Definition AABB.h:163
bool update(PNT_TYPE const &p)
Definition AABB.h:97
bool containsAABB(AABB const &other_aabb) const
Definition AABB.h:185
bool containsPointXY(T const &pnt) const
Definition AABB.h:150
void enlarge(std::bitset< 3 > to_update=7)
Definition AABB.h:215
Definition AABB.h:277
Eigen::Vector3d max
Definition AABB.h:26
Eigen::Vector3d min
Definition AABB.h:25