Easy3D 2.6.1
Loading...
Searching...
No Matches
box.h
1/********************************************************************
2 * Copyright (C) 2015 Liangliang Nan <liangliang.nan@gmail.com>
3 * https://3d.bk.tudelft.nl/liangliang/
4 *
5 * This file is part of Easy3D. If it is useful in your research/work,
6 * I would be grateful if you show your appreciation by citing it:
7 * ------------------------------------------------------------------
8 * Liangliang Nan.
9 * Easy3D: a lightweight, easy-to-use, and efficient C++ library
10 * for processing and rendering 3D data.
11 * Journal of Open Source Software, 6(64), 3255, 2021.
12 * ------------------------------------------------------------------
13 *
14 * Easy3D is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License Version 3
16 * as published by the Free Software Foundation.
17 *
18 * Easy3D is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 ********************************************************************/
26
27#ifndef EASY3D_CORE_GENERIC_BOX_H
28#define EASY3D_CORE_GENERIC_BOX_H
29
30#include <cassert>
31#include <limits>
32
33#include <easy3d/core/vec.h>
34
35
36namespace easy3d {
37
44 template<int DIM, typename FT>
45 class GenericBox {
46 public:
50
51 public:
56 : min_(std::numeric_limits<FT>::max()) // is_valid to an invalid value
57 , max_(-std::numeric_limits<FT>::max()) {
58 }
59
65 GenericBox(const Point &pmin, const Point &pmax) {
66 grow(pmin);
67 grow(pmax);
68 }
69
75 GenericBox(const Point &c, FT r) {
76 Vector dir(1.0);
77 dir.normalize();
78 min_ = c - dir * r;
79 max_ = c + dir * r;
80 }
81
86 bool is_valid() const {
87 for (int i = 0; i < DIM; ++i) {
88 if (max_[i] >= min_[i] - std::numeric_limits<FT>::epsilon())
89 return true;
90 }
91 return false;
92 }
93
97 void clear() {
98 min_ = Point(std::numeric_limits<FT>::max());
99 max_ = Point(-std::numeric_limits<FT>::max());
100 }
101
106 const Point& min_point() const { return min_; }
111 Point& min_point() { return min_; }
112
117 const Point& max_point() const { return max_; }
122 Point& max_point() { return max_; }
123
129 FT min_coord(unsigned int axis) const {
130 assert(axis >= 0 && axis < DIM);
131 if (is_valid())
132 return min_[axis];
133 return FT(0.0);
134 }
135
141 FT max_coord(unsigned int axis) const {
142 assert(axis >= 0 && axis < DIM);
143 if (is_valid())
144 return max_[axis];
145 return FT(0.0);
146 }
147
153 FT range(unsigned int axis) const {
154 assert(axis >= 0 && axis < DIM);
155 if (is_valid())
156 return max_[axis] - min_[axis];
157 return FT(0.0);
158 }
159
164 FT max_range() const {
165 FT max_value = max_[0] - min_[0];
166 for (int i = 1; i < DIM; ++i)
167 max_value = std::max(max_value, max_[i] - min_[i]);
168 return max_value;
169 }
170
175 FT min_range() const {
176 FT min_value = max_[0] - min_[0];
177 for (int i = 1; i < DIM; ++i)
178 min_value = std::min(min_value, max_[i] - min_[i]);
179 return min_value;
180 }
181
186 unsigned int max_range_axis() const {
187 unsigned int axis = 0;
188 FT max_value = max_[0] - min_[0];
189 for (int i = 1; i < DIM; ++i) {
190 FT range = max_[i] - min_[i];
191 if (range > max_value) {
192 axis = i;
193 max_value = range;
194 }
195 }
196 return axis;
197 }
198
203 unsigned int min_range_axis() const {
204 unsigned int axis = 0;
205 FT min_value = max_[0] - min_[0];
206 for (int i = 1; i < DIM; ++i) {
207 FT range = max_[i] - min_[i];
208 if (range < min_value) {
209 axis = i;
210 min_value = range;
211 }
212 }
213 return axis;
214 }
215
220 Point center() const {
221 if (is_valid())
222 return FT(0.5) * (min_ + max_);
223 return Point(0.0);
224 }
225
230 Vector diagonal_vector() const { return max_ - min_; }
231
236 FT diagonal_length() const {
237 if (is_valid()) {
238 FT sqr_len(0.0);
239 for (int i = 0; i < DIM; ++i) {
240 FT d = max_[i] - min_[i];
241 sqr_len += d * d;
242 }
243 return std::sqrt(sqr_len);
244 }
245 return FT(0.0);
246 }
247
252 FT radius() const {
253 return diagonal_length() * FT(0.5);
254 }
255
260 FT surface_area() const {
261 Vector ext = max_ - min_;
262 if (DIM == 3)
263 return FT(2.0) * (ext[0] * ext[1] + ext[0] * ext[2] + ext[1] * ext[2]);
264 else if (DIM == 2)
265 return ext[0] * ext[1];
266 else {
267 std::cerr << "surface_area() is for 2D and 3D boxes" << std::endl;
268 return FT(0);
269 }
270 }
271
276 void grow(const Point &p) {
277 if (is_valid()) {
278 for (int i = 0; i < DIM; ++i) {
279 min_[i] = std::min(min_[i], p[i]);
280 max_[i] = std::max(max_[i], p[i]);
281 }
282 } else {
283 min_ = p;
284 max_ = p;
285 }
286 }
287
292 void grow(const thisclass &b) {
293 if (b.is_valid()) {
294 grow(b.min_point());
295 grow(b.max_point());
296 }
297 }
298
304 thisclass operator+(const thisclass &b) const {
305 thisclass result = *this;
306 if (b.is_valid())
307 result += b;
308 return result;
309 }
310
317 if (b.is_valid()) {
318 grow(b.min_point());
319 grow(b.max_point());
320 }
321 return *this;
322 }
323
329 bool contains(Point const& p) const {
330 for (int i = 0; i < DIM; ++i) {
331 if (p[i] <= min_[i] || p[i] >= max_[i])
332 return false;
333 }
334 return true;
335 }
336
342 bool contains(thisclass const& b) const {
343 return contains(b.min_point()) && contains(b.max_point());
344 }
345
351 bool intersects(thisclass const& b) const {
352 for (int i = 0; i < DIM; ++i) {
353 if (b.min_coord(i) > max_[i] || b.max_coord(i) < min_[i])
354 return false;
355 }
356 return true;
357 }
358
359 private:
360 Point min_;
361 Point max_;
362 };
363
364
372 template<int DIM, typename FT>
373 bool has_nan(const GenericBox<DIM, FT> &box) {
374 return has_nan(box.min_point()) || has_nan(box.max_point());
375 }
376
377
378 namespace geom {
379
380#if 1
389 template<int DIM, typename FT>
393
402 template<int DIM, typename FT>
407#else
408 template<int DIM, typename FT>
409 GenericBox<DIM, FT> box_union(GenericBox<DIM, FT> const& a, GenericBox<DIM, FT> const& b) { return a + b; }
410
411 template<int DIM, typename FT>
412 GenericBox<DIM, FT> box_intersection(GenericBox<DIM, FT> const& a, GenericBox<DIM, FT> const& b) {
413 if (a.intersects(b))
414 return GenericBox<DIM, FT>(comp_max(a.min_point(), b.min_point()), comp_min(a.max_point(), b.max_point()));
415 else
416 return GenericBox<DIM, FT>();
417 }
418#endif
419
420 }
421
422} // namespace easy3d
423
424
425#endif // EASY3D_CORE_GENERIC_BOX_H
GenericBox represents the bounding box of shapes.
Definition box.h:45
bool contains(Point const &p) const
Check if this box contains a point p.
Definition box.h:329
Point center() const
Return the center of the box.
Definition box.h:220
GenericBox()
Construct a box uninitialized (which is invalid).
Definition box.h:55
FT max_coord(unsigned int axis) const
Return a component of the coordinates of the max corner.
Definition box.h:141
bool contains(thisclass const &b) const
Check if this box contains another box b.
Definition box.h:342
const Point & min_point() const
Return the coordinates of the min corner (const version).
Definition box.h:106
FT range(unsigned int axis) const
Return the range of the box along the axis.
Definition box.h:153
Vector diagonal_vector() const
Return the diagonal vector of the box.
Definition box.h:230
FT radius() const
Return the radius of the box (i.e., half of its diagonal length).
Definition box.h:252
Point & min_point()
Return the coordinates of the min corner.
Definition box.h:111
FT min_coord(unsigned int axis) const
Return a component of the coordinates of the min corner.
Definition box.h:129
FT max_range() const
Return the max range.
Definition box.h:164
FT diagonal_length() const
Return the length of the diagonal of the box.
Definition box.h:236
FT min_range() const
Return the min range.
Definition box.h:175
GenericBox< DIM, FT > thisclass
This class.
Definition box.h:49
thisclass & operator+=(const thisclass &b)
Modify this box by adding another box b.
Definition box.h:316
void grow(const thisclass &b)
Add a box to this box. This will compute its new extent.
Definition box.h:292
unsigned int min_range_axis() const
Return the axis index of the min range of the box.
Definition box.h:203
const Point & max_point() const
Return the coordinates of the max corner (const version).
Definition box.h:117
bool is_valid() const
Check if the box is valid.
Definition box.h:86
FT surface_area() const
Return the surface area of the box.
Definition box.h:260
GenericBox(const Point &c, FT r)
Construct a box from its center and radius.
Definition box.h:75
thisclass operator+(const thisclass &b) const
Return the bounding box of 'this' and another box b.
Definition box.h:304
Vec< DIM, FT > Vector
Vector type.
Definition box.h:48
void clear()
Invalidate the box.
Definition box.h:97
Vec< DIM, FT > Point
Point type.
Definition box.h:47
unsigned int max_range_axis() const
Return the axis index of the max range of the box.
Definition box.h:186
GenericBox(const Point &pmin, const Point &pmax)
Construct a box from its diagonal corners.
Definition box.h:65
bool intersects(thisclass const &b) const
Check if this box intersects another box b.
Definition box.h:351
void grow(const Point &p)
Add a point to this box. This will compute its new extent.
Definition box.h:276
Point & max_point()
Return the coordinates of the max corner.
Definition box.h:122
Base class for vector types. It provides generic functionality for N dimensional vectors.
Definition vec.h:30
thisclass & normalize()
Normalizes this vector.
Definition vec.h:135
GenericBox< DIM, FT > box_union(GenericBox< DIM, FT > const &a, GenericBox< DIM, FT > const &b)
Compute the union of two boxes.
Definition box.h:390
GenericBox< DIM, FT > box_intersection(GenericBox< DIM, FT > const &a, GenericBox< DIM, FT > const &b)
Compute the intersection of two boxes.
Definition box.h:403
Definition collider.cpp:182
Vec< N, T > comp_min(const Vec< N, T > &v1, const Vec< N, T > &v2)
Component-wise minimum vector.
Definition vec.h:1027
Vec< N, T > comp_max(const Vec< N, T > &v1, const Vec< N, T > &v2)
Component-wise maximum vector.
Definition vec.h:1036
FT max()
Function returning maximum representable value for a given type.
bool has_nan(const GenericBox< DIM, FT > &box)
Check if the representation of a box has NaN.
Definition box.h:373