Ocean
Box3.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #ifndef META_OCEAN_MATH_BOX_3_H
9 #define META_OCEAN_MATH_BOX_3_H
10 
11 #include "ocean/math/Math.h"
13 #include "ocean/math/Line3.h"
14 #include "ocean/math/Plane3.h"
15 #include "ocean/math/Vector3.h"
16 
17 namespace Ocean
18 {
19 
20 // Forward declaration.
21 template <typename T> class BoxT3;
22 
23 /**
24  * Definition of the Box3 object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION either with single or double precision float data type.
25  * @see BoxT3
26  * @ingroup math
27  */
29 
30 /**
31  * Instantiation of the BoxT3 template class using a double precision float data type.
32  * @see BoxT3
33  * @ingroup math
34  */
36 
37 /**
38  * Instantiation of the BoxT3 template class using a single precision float data type.
39  * @see BoxT3
40  * @ingroup math
41  */
43 
44 /**
45  * Definition of a typename alias for vectors with BoxT3 objects.
46  * @see BoxT3
47  * @ingroup math
48  */
49 template <typename T>
50 using BoxesT3 = std::vector<BoxT3<T>>;
51 
52 /**
53  * Definition of a vector holding Box3 objects.
54  * @see Box3
55  * @ingroup math
56  */
57 typedef std::vector<Box3> Boxes3;
58 
59 /**
60  * This class implements an axis aligned 3D bounding box.
61  * @tparam T The data type of the scalar to be used, either 'float' or 'double'
62  * @see Box2, BoxF3, BoxD3, BoxT2.
63  * @ingroup math
64  */
65 template <typename T>
66 class BoxT3
67 {
68  public:
69 
70  /**
71  * Creates an invalid bounding box.
72  */
73  BoxT3() = default;
74 
75  /**
76  * Creates a new bounding box by two given corners.
77  * @param lower The lower corner
78  * @param higher The higher corner
79  */
81 
82  /**
83  * Creates a new bounding box enclosing a given set of 3D points.
84  * @param points The points to be enclosed by the bounding box
85  */
86  explicit BoxT3(const VectorsT3<T>& points);
87 
88  /**
89  * Creates a new bounding box enclosing a given set of 3D points.
90  * @param points The points to be enclosed by the bounding box, must be valid
91  * @param number The number of points, with range [1, infinity)
92  */
93  BoxT3(const VectorT3<T>* points, const size_t number);
94 
95  /**
96  * Creates a new bounding box with defined dimensions centered at a given 3D location.
97  * @param center The center position of the new bounding box, with range (-infinity, infinity)x(-infinity, infinity)x(-infinity, infinity)
98  * @param xSize The size of the bounding box in the x-axis, with range [0, infinity)
99  * @param ySize The size of the bounding box in the y-axis, with range [0, infinity)
100  * @param zSize The size of the bounding box in the z-axis, with range [0, infinity)
101  */
102  BoxT3(const VectorT3<T>& center, const T xSize, const T ySize, const T zSize);
103 
104  /**
105  * Returns the center of the box.
106  * @return Box center
107  */
109 
110  /**
111  * Returns the square diagonal of this box.
112  * @return Square diagonal
113  */
114  T sqrDiagonal() const;
115 
116  /**
117  * Returns the diagonal of this box.
118  * @return Box diagonal
119  */
120  T diagonal() const;
121 
122  /**
123  * Returns the dimension in x axis, which could e.g. be the width of this box.
124  * Beware: The result is undefined for an invalid box.
125  * @return Dimension in x axis
126  */
127  T xDimension() const;
128 
129  /**
130  * Returns the dimension in y axis, which could e.g. be the height of this box.
131  * Beware: The result is undefined for an invalid box.
132  * @return Dimension in y axis
133  */
134  T yDimension() const;
135 
136  /**
137  * Returns the dimension in z axis, which could e.g. be the depth of this box.
138  * Beware: The result is undefined for an invalid box.
139  * @return Dimension in z axis
140  */
141  T zDimension() const;
142 
143  /**
144  * Returns the dimension of this box for all three axis.
145  * @return The box's dimension
146  */
148 
149  /**
150  * Returns whether this box defines one single point only.
151  * @param point Optional resulting point defined by the box
152  * @return True, if so
153  */
154  bool isPoint(VectorT3<T>* point = nullptr) const;
155 
156  /**
157  * Returns whether this box is planar aligned to one axis.
158  * A planar box has no expansion in one axis.
159  * @param plane The plane the box is part of
160  * @return True, if so
161  */
162  bool isPlanar(PlaneT3<T>& plane) const;
163 
164  /**
165  * Returns the lower corner of the box.
166  * @return Lower corner
167  */
168  const VectorT3<T>& lower() const;
169 
170  /**
171  * Returns the higher corner of the box.
172  * @return Higher corner
173  */
174  const VectorT3<T>& higher() const;
175 
176  /**
177  * Returns whether a given point is inside this bounding box.
178  * @param point The point to check
179  * @param eps The optional epsilon adding an additional thin tolerance boundary, with range [0, infinity)
180  * @return True, if so
181  */
182  bool isInside(const VectorT3<T>& point, const T eps = T(0)) const;
183 
184  /**
185  * Returns whether a given point lies on the surface of this box.
186  * @param point The point to be checked
187  * @param epsilon The accuracy value allowing some tolerance, with range [0, infinity)
188  * @return True, if so
189  */
190  bool isOnSurface(const VectorT3<T>& point, const T epsilon = NumericT<T>::eps()) const;
191 
192  /**
193  * Returns whether a given ray has an intersection with this box.
194  * @param ray The ray to be tested, must be valid
195  * @return True, if so
196  */
197  bool hasIntersection(const LineT3<T>& ray) const;
198 
199  /**
200  * Returns whether a given ray has an intersection with this box while applying a distance-dependent epsilon threshold.
201  * The larger the distance between the ray's origin and the box, the bigger the applied epsilon threshold.
202  * @param ray The ray to be tested, must be valid
203  * @param epsPerDistance The epsilon for distance 1 which will be multiplied with the (approximated) distance to determine the actual epsilon to be used, with range [0, infinity)
204  * @return True, if so
205  */
206  bool hasIntersection(const LineT3<T>& ray, const T epsPerDistance) const;
207 
208  /**
209  * Returns whether a given ray has an intersection with this box.
210  * @param ray The ray to be tested, must be valid
211  * @param box_T_ray The transformation between ray and box, must be valid
212  * @return True, if so
213  */
214  bool hasIntersection(const LineT3<T>& ray, const HomogenousMatrixT4<T>& box_T_ray) const;
215 
216  /**
217  * Returns the corner positions of this box.
218  * If this box is planar the four points are returned only.
219  * @param corners Resulting corners, must provide space for at least eight points
220  * @return Number of resulting corners
221  */
222  unsigned int corners(VectorT3<T>* corners) const;
223 
224  /**
225  * Returns an expanded box of this box.
226  * Positive offsets will increase the box, negative offsets will decrease the box; offsets smaller than the dimension are clamped to zero.
227  * @param offsets The offsets along all three axis, an offset of +/-1 makes the box 1 unit larger/smaller, with range (-infinity, infinity)x(-infinity, infinity)x(-infinity, infinity)
228  * @return The new expanded box
229  */
230  BoxT3<T> expanded(const VectorT3<T>& offsets) const;
231 
232  /**
233  * Expands this box.
234  * Positive offsets will increase the box, negative offsets will decrease the box; offsets smaller than the dimension are clamped to zero.
235  * @param offsets The offsets along all three axis, an offset of +/-1 makes the box 1 unit larger/smaller, with range (-infinity, infinity)x(-infinity, infinity)x(-infinity, infinity)
236  * @return Reference to this box
237  */
238  BoxT3<T>& expand(const VectorT3<T>& offsets);
239 
240  /**
241  * Clears and resets the bounding box to an invalid box.
242  */
243  void clear();
244 
245  /**
246  * Returns whether two box objects are equal up to an epsilon.
247  * @param box The Box to compare with, can be invalid
248  * @param epsilon The accuracy epsilon, with range [0, infinity)
249  * @return True, if so
250  */
251  bool isEqual(const BoxT3<T>& box, const T epsilon = NumericT<T>::eps()) const;
252 
253  /**
254  * Returns whether the bounding box is valid.
255  * @return True, if so
256  */
257  bool isValid() const;
258 
259  /**
260  * Returns an enlarged bounding box of this one.
261  * @param factor The factor to enlarge the bounding box in each dimension, with range (-infinity, infinity)
262  * @return New enlarged bounding box
263  */
264  BoxT3<T> operator*(const T factor) const;
265 
266  /**
267  * Enlarges the bounding box by a given factor in each dimension.
268  * @param factor The factor to enlarge the bounding box in each dimension, with range (-infinity, infinity)
269  * @return Reference to this (enlarged) bounding box
270  */
271  BoxT3<T>& operator*=(const T factor);
272 
273  /**
274  * Adds a new point to this bounding box and updates it's dimension.
275  * @param point The point to add to the bounding box
276  * @return Reference to this bounding box
277  */
279 
280  /**
281  * Returns the union of two bounding boxes.
282  * @param right The right bounding box
283  * @return New joined bounding box
284  */
285  BoxT3<T> operator+(const BoxT3<T>& right) const;
286 
287  /**
288  * Joins to bounding boxes.
289  * @param right The right bounding box to join
290  * @return Reference to this (joined) bounding box
291  */
292  BoxT3<T>& operator+=(const BoxT3<T>& right);
293 
294  /**
295  * Returns the (axis-aligned) world bounding box for a given transformation between the box and world.
296  * @param world_T_box The transformation between box and world, must be valid
297  * @return The new (still) axis-aligned bounding box, defined in world, most likely the new box will have a larger volume than this box
298  */
299  BoxT3<T> operator*(const HomogenousMatrixT4<T>& world_T_box) const;
300 
301  /**
302  * Transforms this bounding box with a given transformation so that the this bounding box is defined in world afterwards.
303  * @param world_T_box The transformation between box and world, must be valid
304  * @return Reference to this new bounding box now defined in world
305  */
307 
308  /**
309  * Returns whether two boxes are identical.
310  * @param right Second box object
311  * @return True, if so
312  */
313  bool operator==(const BoxT3<T>& right) const;
314 
315  /**
316  * Returns whether two boxes are not identical.
317  * @param right Second box object
318  * @return True, if so
319  */
320  bool operator!=(const BoxT3<T>& right) const;
321 
322  /**
323  * Returns whether this box is not a default box.
324  * @return True, if so
325  */
326  operator bool() const;
327 
328  protected:
329 
330  /// Lower corner of the bounding box.
332 
333  /// Higher corner of the bounding box.
335 };
336 
337 }
338 
339 #endif // META_OCEAN_MATH_BOX_3_H
VectorT3< T > dimension() const
Returns the dimension of this box for all three axis.
bool isInside(const VectorT3< T > &point, const T eps=T(0)) const
Returns whether a given point is inside this bounding box.
bool isValid() const
Returns whether the bounding box is valid.
BoxT3< T > & expand(const VectorT3< T > &offsets)
Expands this box.
BoxT3(const VectorT3< T > *points, const size_t number)
Creates a new bounding box enclosing a given set of 3D points.
T yDimension() const
Returns the dimension in y axis, which could e.g.
BoxT3()=default
Creates an invalid bounding box.
bool isPoint(VectorT3< T > *point=nullptr) const
Returns whether this box defines one single point only.
BoxT3< T > & operator*=(const T factor)
Enlarges the bounding box by a given factor in each dimension.
BoxT3< T > operator*(const HomogenousMatrixT4< T > &world_T_box) const
Returns the (axis-aligned) world bounding box for a given transformation between the box and world.
void clear()
Clears and resets the bounding box to an invalid box.
BoxT3(const VectorsT3< T > &points)
Creates a new bounding box enclosing a given set of 3D points.
BoxT3< T > & operator*=(const HomogenousMatrixT4< T > &world_T_box)
Transforms this bounding box with a given transformation so that the this bounding box is defined in ...
VectorT3< T > higher_
Higher corner of the bounding box.
Definition: Box3.h:334
bool hasIntersection(const LineT3< T > &ray, const HomogenousMatrixT4< T > &box_T_ray) const
Returns whether a given ray has an intersection with this box.
bool isOnSurface(const VectorT3< T > &point, const T epsilon=NumericT< T >::eps()) const
Returns whether a given point lies on the surface of this box.
VectorT3< T > lower_
Lower corner of the bounding box.
Definition: Box3.h:331
BoxT3< T > & operator+=(const BoxT3< T > &right)
Joins to bounding boxes.
T sqrDiagonal() const
Returns the square diagonal of this box.
T diagonal() const
Returns the diagonal of this box.
BoxT3(const VectorT3< T > &lower, const VectorT3< T > &higher)
Creates a new bounding box by two given corners.
T xDimension() const
Returns the dimension in x axis, which could e.g.
bool operator!=(const BoxT3< T > &right) const
Returns whether two boxes are not identical.
BoxT3< T > operator*(const T factor) const
Returns an enlarged bounding box of this one.
BoxT3< T > expanded(const VectorT3< T > &offsets) const
Returns an expanded box of this box.
T zDimension() const
Returns the dimension in z axis, which could e.g.
BoxT3< T > & operator+=(const VectorT3< T > &point)
Adds a new point to this bounding box and updates it's dimension.
BoxT3< T > operator+(const BoxT3< T > &right) const
Returns the union of two bounding boxes.
const VectorT3< T > & lower() const
Returns the lower corner of the box.
bool hasIntersection(const LineT3< T > &ray, const T epsPerDistance) const
Returns whether a given ray has an intersection with this box while applying a distance-dependent eps...
VectorT3< T > center() const
Returns the center of the box.
bool operator==(const BoxT3< T > &right) const
Returns whether two boxes are identical.
bool isEqual(const BoxT3< T > &box, const T epsilon=NumericT< T >::eps()) const
Returns whether two box objects are equal up to an epsilon.
bool hasIntersection(const LineT3< T > &ray) const
Returns whether a given ray has an intersection with this box.
const VectorT3< T > & higher() const
Returns the higher corner of the box.
unsigned int corners(VectorT3< T > *corners) const
Returns the corner positions of this box.
bool isPlanar(PlaneT3< T > &plane) const
Returns whether this box is planar aligned to one axis.
BoxT3(const VectorT3< T > &center, const T xSize, const T ySize, const T zSize)
Creates a new bounding box with defined dimensions centered at a given 3D location.
This class implements a 4x4 homogeneous transformation matrix using floating point values with the pr...
Definition: HomogenousMatrix4.h:110
This class implements an infinite line in 3D space.
Definition: Line3.h:70
This class provides basic numeric functionalities.
Definition: Numeric.h:57
This class implements a plane in 3D space.
Definition: Plane3.h:73
This class implements a vector with three elements.
Definition: Vector3.h:97
BoxT3< Scalar > Box3
Definition of the Box3 object, depending on the OCEAN_MATH_USE_SINGLE_PRECISION either with single or...
Definition: Box3.h:21
std::vector< BoxT3< T > > BoxesT3
Definition of a typename alias for vectors with BoxT3 objects.
Definition: Box3.h:50
std::vector< Box3 > Boxes3
Definition of a vector holding Box3 objects.
Definition: Box3.h:57
BoxT3< float > BoxF3
Instantiation of the BoxT3 template class using a single precision float data type.
Definition: Box3.h:42
std::vector< VectorT3< T > > VectorsT3
Definition of a typename alias for vectors with VectorT3 objects.
Definition: Vector3.h:58
BoxT3< double > BoxD3
Instantiation of the BoxT3 template class using a double precision float data type.
Definition: Box3.h:35
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15