MeshKernel
Loading...
Searching...
No Matches
BoundingBox.hpp
1//---- GPL ---------------------------------------------------------------------
2//
3// Copyright (C) Stichting Deltares, 2011-2021.
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation version 3.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16//
17// contact: delft3d.support@deltares.nl
18// Stichting Deltares
19// P.O. Box 177
20// 2600 MH Delft, The Netherlands
21//
22// All indications and logos of, and references to, "Delft3D" and "Deltares"
23// are registered trademarks of Stichting Deltares, and remain the property of
24// Stichting Deltares. All rights reserved.
25//
26//------------------------------------------------------------------------------
27
28#pragma once
29
30#include "MeshKernel/Point.hpp"
31
32#include <algorithm>
33#include <concepts>
34#include <limits>
35#include <span>
36#include <vector>
37
38namespace meshkernel
39{
40
43 {
44 public:
46 BoundingBox() : m_lowerLeft(std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest()),
47 m_upperRight(std::numeric_limits<double>::max(), std::numeric_limits<double>::max()) {}
48
53 : m_lowerLeft(lowerLeft),
54 m_upperRight(upperRight)
55 {
56 }
57
61 template <typename T>
62 explicit BoundingBox(const std::span<const T> points)
63 {
64 Reset(points);
65 }
66
70 template <typename T>
71 explicit BoundingBox(const std::vector<T>& points)
72 {
73 Reset(points);
74 }
75
81 template <typename T>
82 BoundingBox(const std::vector<T>& points, size_t start, size_t end)
83 {
84 Reset(points, start, end);
85 }
86
90 template <typename T>
91 void Reset(const std::vector<T>& points);
92
96 template <typename T>
97 void Reset(const std::span<const T> points);
98
104 template <typename T>
105 void Reset(const std::vector<T>& points, size_t start, size_t end);
106
112 template <typename T>
113 void Reset(const std::span<const T> points, size_t start, size_t end);
114
118 bool operator!=(const BoundingBox& other) const
119 {
120 return other.m_lowerLeft != m_lowerLeft || other.m_upperRight != m_upperRight;
121 }
122
127 template <typename T>
128 bool Contains(const T& point) const
129 {
130
131 return point.x >= m_lowerLeft.x && point.x <= m_upperRight.x &&
132 point.y >= m_lowerLeft.y && point.y <= m_upperRight.y;
133 }
134
138 bool Overlaps(const BoundingBox& boundingBox) const;
139
142 [[nodiscard]] const auto& lowerLeft() const { return m_lowerLeft; }
143
146 [[nodiscard]] auto& lowerLeft() { return m_lowerLeft; }
147
150 [[nodiscard]] const auto& upperRight() const { return m_upperRight; }
151
154 [[nodiscard]] auto& upperRight() { return m_upperRight; }
155
158 Point MassCentre() const { return (m_lowerLeft + m_upperRight) * 0.5; }
159
162 double Width() const { return m_upperRight.x - m_lowerLeft.x; }
163
166 double Height() const { return m_upperRight.y - m_lowerLeft.y; }
167
169 void Extend(double factor)
170 {
171 // TODO should check that the BB does not cover the entire fp space.
172 const double width = Width();
173 const double height = Height();
174 m_lowerLeft.x -= width * factor;
175 m_lowerLeft.y -= height * factor;
176 m_upperRight.x += width * factor;
177 m_upperRight.y += height * factor;
178 }
179
181 Vector Delta() const;
182
184 template <std::derived_from<Point> T>
185 static BoundingBox CreateBoundingBox(const T& first, const T& second)
186 {
187 const auto lowerLeftX = std::min(first.x, second.x);
188 const auto lowerLeftY = std::min(first.y, second.y);
189 const auto upperRightX = std::max(first.x, second.x);
190 const auto upperRightY = std::max(first.y, second.y);
191
192 return BoundingBox({lowerLeftX, lowerLeftY}, {upperRightX, upperRightY});
193 }
194
195 private:
196 Point m_lowerLeft;
197 Point m_upperRight;
198 };
199
201 static BoundingBox Merge(const BoundingBox& b1, const BoundingBox& b2);
202
204 static BoundingBox CreateNonOverlappingBoundingBox();
205
206} // namespace meshkernel
207
208template <typename T>
209void meshkernel::BoundingBox::Reset(const std::vector<T>& points)
210{
211 Reset(std::span(points));
212} // namespace meshkernel
213
214template <typename T>
215void meshkernel::BoundingBox::Reset(const std::span<const T> points)
216{
217 if (points.size() > 0)
218 {
219 Reset(points, 0, points.size() - 1);
220 }
221 else
222 {
223 m_lowerLeft = Point(std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest());
224 m_upperRight = Point(std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
225 }
226
227} // namespace meshkernel
228
229template <typename T>
230void meshkernel::BoundingBox::Reset(const std::vector<T>& points, size_t start, size_t end)
231{
232 Reset(std::span(points), start, end);
233}
234
235template <typename T>
236void meshkernel::BoundingBox::Reset(const std::span<const T> points, size_t start, size_t end)
237{
238 double minx = std::numeric_limits<double>::max();
239 double maxx = std::numeric_limits<double>::lowest();
240 double miny = std::numeric_limits<double>::max();
241 double maxy = std::numeric_limits<double>::lowest();
242
243 for (size_t i = start; i <= end; ++i)
244 {
245 const auto& point = points[i];
246
247 if (point.IsValid())
248 {
249 minx = std::min(minx, point.x);
250 maxx = std::max(maxx, point.x);
251 miny = std::min(miny, point.y);
252 maxy = std::max(maxy, point.y);
253 }
254 }
255 m_lowerLeft = Point(minx, miny);
256 m_upperRight = Point(maxx, maxy);
257}
258
259meshkernel::BoundingBox meshkernel::Merge(const BoundingBox& b1, const BoundingBox& b2)
260{
261 Point lowerLeft{std::min(b1.lowerLeft().x, b2.lowerLeft().x), std::min(b1.lowerLeft().y, b2.lowerLeft().y)};
262 Point upperRight{std::max(b1.upperRight().x, b2.upperRight().x), std::max(b1.upperRight().y, b2.upperRight().y)};
263
264 return {lowerLeft, upperRight};
265}
266
267meshkernel::BoundingBox meshkernel::CreateNonOverlappingBoundingBox()
268{
269 Point lowerLeft(std::numeric_limits<double>::max(), std::numeric_limits<double>::max());
270 Point upperRight(std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest());
271 return {lowerLeft, upperRight};
272}
273
275{
276 return Vector(m_upperRight.x - m_lowerLeft.x, m_upperRight.y - m_lowerLeft.y);
277}
278
279inline bool meshkernel::BoundingBox::Overlaps(const BoundingBox& other) const
280{
281 const auto& otherLowerleft = other.lowerLeft();
282 const auto& otherUpperRight = other.upperRight();
283 if (m_upperRight.x < otherLowerleft.x ||
284 otherUpperRight.x < m_lowerLeft.x ||
285 m_upperRight.y < otherLowerleft.y ||
286 otherUpperRight.y < m_lowerLeft.y)
287 {
288 return false;
289 }
290
291 return true;
292}
A class defining a bounding box.
Definition BoundingBox.hpp:43
BoundingBox(const std::vector< T > &points)
Constructor taking a vector of coordinates types.
Definition BoundingBox.hpp:71
const auto & lowerLeft() const
Returns the lower left corner of the bounding box.
Definition BoundingBox.hpp:142
BoundingBox()
Default constructor.
Definition BoundingBox.hpp:46
double Width() const
Returns the bounding box width.
Definition BoundingBox.hpp:162
void Reset(const std::vector< T > &points)
Reset bounding box with a vector of coordinates types.
Definition BoundingBox.hpp:209
bool Overlaps(const BoundingBox &boundingBox) const
Checks if two bounding boxes overlaps.
Definition BoundingBox.hpp:279
bool Contains(const T &point) const
Checks if a point is inside a bounding box.
Definition BoundingBox.hpp:128
double Height() const
Returns the bounding box height.
Definition BoundingBox.hpp:166
BoundingBox(const Point &lowerLeft, const Point &upperRight)
Constructor taking the corner points of the bounding box.
Definition BoundingBox.hpp:52
void Extend(double factor)
Extends the bounding box by a factor.
Definition BoundingBox.hpp:169
auto & lowerLeft()
Returns the lower left corner of the bounding box.
Definition BoundingBox.hpp:146
const auto & upperRight() const
Returns the upper right corner.
Definition BoundingBox.hpp:150
Vector Delta() const
Return the delta of the bounding box.
Definition BoundingBox.hpp:274
BoundingBox(const std::span< const T > points)
Constructor taking a vector of coordinates types.
Definition BoundingBox.hpp:62
auto & upperRight()
Returns the upper right corner.
Definition BoundingBox.hpp:154
static BoundingBox CreateBoundingBox(const T &first, const T &second)
Create a bounding box from two points.
Definition BoundingBox.hpp:185
bool operator!=(const BoundingBox &other) const
Not equal operator.
Definition BoundingBox.hpp:118
BoundingBox(const std::vector< T > &points, size_t start, size_t end)
Constructor taking a vector of coordinates types.
Definition BoundingBox.hpp:82
Point MassCentre() const
Returns the mass centre.
Definition BoundingBox.hpp:158
A struct describing a point in a two-dimensional space.
Definition Point.hpp:41
double x
X-coordinate.
Definition Point.hpp:43
double y
Y-coordinate.
Definition Point.hpp:44
A class defining a vector.
Definition Vector.hpp:39
Contains the logic of the C++ static library.
Definition AveragingInterpolation.hpp:37