UFO 1.0.0
An Efficient Probabilistic 3D Mapping Framework That Embraces the Unknown
Loading...
Searching...
No Matches
obb.hpp
1
42#ifndef UFO_GEOMETRY_OBB_HPP
43#define UFO_GEOMETRY_OBB_HPP
44
45// UFO
46#include <ufo/geometry/aabb.hpp>
47#include <ufo/numeric/mat.hpp>
48#include <ufo/numeric/quat.hpp>
49#include <ufo/numeric/vec.hpp>
50
51// STL
52#include <cmath>
53#include <concepts>
54#include <cstddef>
55#include <format>
56#include <ostream>
57
58namespace ufo
59{
60template <std::size_t Dim = 3, std::floating_point T = float>
61struct OBB;
62
69template <std::floating_point T>
70struct OBB<2, T> {
71 using value_type = T;
72
77
82
87
91 constexpr OBB() noexcept = default;
92
100 constexpr OBB(Vec<2, T> const& start, Vec<2, T> const& end,
101 Vec<1, T> const& half_length)
102 : center_((start + end) * T(0.5))
103 {
104 auto dir = end - start;
105
106 this->half_length = Vec<2, T>(norm(dir) * T(0.5), half_length[0]);
107
108 auto theta = std::atan2(dir.y, dir.x);
109 auto cos_theta = std::cos(theta);
110 auto sin_theta = std::sin(theta);
111
112 rotation[0][0] = cos_theta;
113 rotation[0][1] = sin_theta;
114 rotation[1][0] = -sin_theta;
115 rotation[1][1] = cos_theta;
116 }
117
125 constexpr OBB(Vec<2, T> const& start, Vec<2, T> const& end, T const& half_length)
126 : OBB(start, end, Vec<1, T>(half_length))
127 {
128 }
129
136 constexpr OBB(Vec<2, T> const& center, Vec<2, T> const& half_length) noexcept
137 : center_(center), half_length(half_length)
138 {
139 }
140
148 constexpr OBB(Vec<2, T> const& center, Vec<2, T> const& half_length,
149 Mat<2, 2, T> const& rotation) noexcept
150 : center_(center), half_length(half_length), rotation(rotation)
151 {
152 }
153
157 constexpr OBB(OBB const&) noexcept = default;
158
165 template <std::convertible_to<T> U>
166 constexpr explicit OBB(OBB<2, U> const& other) noexcept
167 : center_(Vec<2, T>(other.center()))
168 , half_length(Vec<2, T>(other.half_length))
169 , rotation(Mat<2, 2, T>(other.rotation))
170 {
171 }
172
177 [[nodiscard]] constexpr Vec<2, T>& center() noexcept { return center_; }
178
183 [[nodiscard]] constexpr Vec<2, T> const& center() const noexcept { return center_; }
184
189 [[nodiscard]] static constexpr std::size_t dimension() noexcept { return 2; }
190
196 [[nodiscard]] constexpr T diagonal() const noexcept { return norm(half_length) * T(2); }
197
202 [[nodiscard]] constexpr AABB<2, T> aabb() const noexcept
203 {
204 Vec<2, T> extent;
205 for (std::size_t i = 0; i < 2; ++i) {
206 extent[i] = std::abs(rotation[0][i]) * half_length[0] +
207 std::abs(rotation[1][i]) * half_length[1];
208 }
209 return AABB<2, T>(center_ - extent, center_ + extent);
210 }
211
215 [[nodiscard]] constexpr bool isDegenerate() const noexcept
216 {
217 return any(lessThan(half_length, Vec<2, T>()));
218 }
219
225 [[nodiscard]] constexpr T volume() const noexcept
226 {
227 return T(4) * half_length[0] * half_length[1];
228 }
229
233 [[nodiscard]] constexpr Vec<2, T> rotatedHalfLength() const
234 {
235 return half_length * rotation;
236 }
237
244 {
245 auto cos_theta = std::cos(angle);
246 auto sin_theta = std::sin(angle);
247
248 rotation[0][0] = cos_theta;
249 rotation[0][1] = sin_theta;
250 rotation[1][0] = -sin_theta;
251 rotation[1][1] = cos_theta;
252 }
253
257 [[nodiscard]] bool operator==(OBB const&) const = default;
258};
259
266template <std::floating_point T>
267struct OBB<3, T> {
268 using value_type = T;
269
274
279
284
288 constexpr OBB() noexcept = default;
289
293 constexpr OBB(Vec<3, T> const& start, Vec<3, T> const& end,
294 Vec<2, T> const& half_length,
295 Vec<3, T> const& up = Vec<3, T>(T(0), T(0), T(1)))
296 : center_((start + end) * T(0.5))
297 {
298 auto dir = end - start;
299
300 this->half_length = Vec<3, T>(norm(dir) * T(0.5), half_length);
301
302 // Similar to right handed lookAt
303 Vec<3, T> const f(normalize(dir));
304 Vec<3, T> const s(normalize(cross(f, up)));
305 Vec<3, T> const u(cross(s, f));
306
307 rotation[0][0] = s.x;
308 rotation[1][0] = s.y;
309 rotation[2][0] = s.z;
310 rotation[0][1] = u.x;
311 rotation[1][1] = u.y;
312 rotation[2][1] = u.z;
313 rotation[0][2] = -f.x;
314 rotation[1][2] = -f.y;
315 rotation[2][2] = -f.z;
316 }
317
321 constexpr OBB(Vec<3, T> const& center, Vec<3, T> const& half_length) noexcept
322 : center_(center), half_length(half_length)
323 {
324 }
325
329 constexpr OBB(Vec<3, T> const& center, Vec<3, T> const& half_length,
330 Mat<3, 3, T> const& rotation) noexcept
331 : center_(center), half_length(half_length), rotation(rotation)
332 {
333 }
334
338 constexpr OBB(Vec<3, T> const& center, Vec<3, T> const& half_length,
339 Quat<T> const& rotation) noexcept
340 : center_(center), half_length(half_length), rotation(rotation)
341 {
342 }
343
347 constexpr OBB(OBB const&) noexcept = default;
348
352 template <std::convertible_to<T> U>
353 constexpr explicit OBB(OBB<3, U> const& other) noexcept
354 : center_(Vec<3, T>(other.center()))
355 , half_length(Vec<3, T>(other.half_length))
356 , rotation(Mat<3, 3, T>(other.rotation))
357 {
358 }
359
364 [[nodiscard]] constexpr Vec<3, T>& center() noexcept { return center_; }
365
370 [[nodiscard]] constexpr Vec<3, T> const& center() const noexcept { return center_; }
371
376 [[nodiscard]] static constexpr std::size_t dimension() noexcept { return 3; }
377
381 [[nodiscard]] constexpr T diagonal() const noexcept { return norm(half_length) * T(2); }
382
386 [[nodiscard]] constexpr T volume() const noexcept
387 {
388 return T(8) * half_length[0] * half_length[1] * half_length[2];
389 }
390
395 [[nodiscard]] constexpr AABB<3, T> aabb() const noexcept
396 {
397 Vec<3, T> extent;
398 for (std::size_t i = 0; i < 3; ++i) {
399 extent[i] = std::abs(rotation[0][i]) * half_length[0] +
400 std::abs(rotation[1][i]) * half_length[1] +
401 std::abs(rotation[2][i]) * half_length[2];
402 }
403 return AABB<3, T>(center_ - extent, center_ + extent);
404 }
405
409 [[nodiscard]] constexpr bool isDegenerate() const noexcept
410 {
411 return any(lessThan(half_length, Vec<3, T>()));
412 }
413
417 [[nodiscard]] constexpr Vec<3, T> rotatedHalfLength() const
418 {
419 return half_length * rotation;
420 }
421
425 void setRotation(Quat<T> const& rotation) { this->rotation = rotation; }
426
430 [[nodiscard]] bool operator==(OBB const&) const = default;
431};
432
437template <std::floating_point T>
438struct OBB<4, T> {
439 using value_type = T;
440
441 Vec<4, T> center_;
442 Vec<4, T> half_length;
443 Mat<4, 4, T> rotation;
444
445 constexpr OBB() noexcept = default;
446
447 constexpr OBB(Vec<4, T> const& start, Vec<4, T> const& end,
448 Vec<3, T> const& half_length)
449 {
450 auto dir = end - start;
451 center_ = (start + end) * T(0.5);
452 this->half_length = Vec<4, T>(norm(dir) * T(0.5), half_length);
453 // TODO: Implement rotation
454 }
455
456 constexpr OBB(Vec<4, T> const& center, Vec<4, T> const& half_length) noexcept
457 : center_(center), half_length(half_length)
458 {
459 }
460
461 constexpr OBB(Vec<4, T> const& center, Vec<4, T> const& half_length,
462 Mat<4, 4, T> const& rotation) noexcept
463 : center_(center), half_length(half_length), rotation(rotation)
464 {
465 }
466
467 constexpr OBB(OBB const&) noexcept = default;
468
469 template <std::convertible_to<T> U>
470 constexpr explicit OBB(OBB<4, U> const& other) noexcept
471 : center_(Vec<4, T>(other.center()))
472 , half_length(Vec<4, T>(other.half_length))
473 , rotation(Mat<4, 4, T>(other.rotation))
474 {
475 }
476
481 [[nodiscard]] constexpr Vec<4, T>& center() noexcept { return center_; }
482
487 [[nodiscard]] constexpr Vec<4, T> const& center() const noexcept { return center_; }
488
493 [[nodiscard]] static constexpr std::size_t dimension() noexcept { return 4; }
494
498 [[nodiscard]] constexpr T diagonal() const noexcept { return norm(half_length) * T(2); }
499
503 [[nodiscard]] constexpr T volume() const noexcept
504 {
505 return T(16) * half_length[0] * half_length[1] * half_length[2] * half_length[3];
506 }
507
512 [[nodiscard]] constexpr AABB<4, T> aabb() const noexcept
513 {
514 Vec<4, T> extent;
515 for (std::size_t i = 0; i < 4; ++i) {
516 extent[i] = std::abs(rotation[0][i]) * half_length[0] +
517 std::abs(rotation[1][i]) * half_length[1] +
518 std::abs(rotation[2][i]) * half_length[2] +
519 std::abs(rotation[3][i]) * half_length[3];
520 }
521 return AABB<4, T>(center_ - extent, center_ + extent);
522 }
523
527 [[nodiscard]] constexpr bool isDegenerate() const noexcept
528 {
529 return any(lessThan(half_length, Vec<4, T>()));
530 }
531
535 [[nodiscard]] constexpr Vec<4, T> rotatedHalfLength() const
536 {
537 return half_length * rotation;
538 }
539
543 [[nodiscard]] bool operator==(OBB const&) const = default;
544};
545
549template <std::floating_point T>
550std::ostream& operator<<(std::ostream& out, OBB<2, T> const& obb)
551{
552 return out << "Center: [" << obb.center() << "], Half length: [" << obb.half_length
553 << "], Rotation: [" << obb.rotation << "]";
554}
555
559template <std::floating_point T>
560std::ostream& operator<<(std::ostream& out, OBB<3, T> const& obb)
561{
562 return out << "Center: [" << obb.center() << "], Half length: [" << obb.half_length
563 << "], Rotation: [" << obb.rotation << "]";
564}
565
569template <std::floating_point T>
570std::ostream& operator<<(std::ostream& out, OBB<4, T> const& obb)
571{
572 return out << "Center: [" << obb.center() << "], Half length: [" << obb.half_length
573 << "], Rotation: [" << obb.rotation << "]";
574}
575
576template <class T>
577using OBB1 = OBB<1, T>;
578template <class T>
579using OBB2 = OBB<2, T>;
580template <class T>
581using OBB3 = OBB<3, T>;
582template <class T>
583using OBB4 = OBB<4, T>;
584
585using OBB1f = OBB<1, float>;
586using OBB2f = OBB<2, float>;
587using OBB3f = OBB<3, float>;
588using OBB4f = OBB<4, float>;
589
590using OBB1d = OBB<1, double>;
591using OBB2d = OBB<2, double>;
592using OBB3d = OBB<3, double>;
593using OBB4d = OBB<4, double>;
594
595} // namespace ufo
596
597template <std::size_t Dim, std::floating_point T>
598 requires std::formattable<T, char>
599struct std::formatter<ufo::OBB<Dim, T>> {
600 constexpr auto parse(std::format_parse_context& ctx) { return ctx.begin(); }
601
602 auto format(ufo::OBB<Dim, T> const& obb, std::format_context& ctx) const
603 {
604 return std::format_to(ctx.out(), "Center: [{}], Half length: [{}], Rotation: [{}]",
605 obb.center(), obb.half_length, obb.rotation);
606 }
607};
608
609#endif // UFO_GEOMETRY_OBB_HPP
T angle(Quat< T > const &q) noexcept
Extracts the rotation angle (in radians) from a unit quaternion.
Definition quat.hpp:852
All vision-related classes and functions.
Definition cloud.hpp:49
constexpr bool any(Vec< Dim, bool > const &v) noexcept
Returns true if at least one component of a bool vector is true.
Definition vec.hpp:1560
constexpr Quat< T > normalize(Quat< T > const &q) noexcept
Returns a unit quaternion in the same direction as q.
Definition quat.hpp:679
constexpr T norm(Quat< T > const &q) noexcept
Returns the Euclidean norm sqrt(w² + x² + y² + z²).
Definition quat.hpp:667
constexpr Quat< T > cross(Quat< T > const &q1, Quat< T > const &q2) noexcept
Computes the Hamilton cross product of two quaternions.
Definition quat.hpp:721
Axis-Aligned Bounding Box (AABB) in Dim-dimensional space.
Definition aabb.hpp:70
A fixed-size matrix with Rows rows and Cols columns.
Definition mat.hpp:113
constexpr Vec< 2, T > & center() noexcept
Returns the center of the OBB.
Definition obb.hpp:177
Vec< 2, T > center_
The center of the OBB.
Definition obb.hpp:76
constexpr T volume() const noexcept
Returns the area of the OBB.
Definition obb.hpp:225
constexpr OBB(Vec< 2, T > const &start, Vec< 2, T > const &end, T const &half_length)
Constructs an OBB from a line segment and a half-thickness.
Definition obb.hpp:125
Vec< 2, T > half_length
The half-lengths of the OBB along its local axes.
Definition obb.hpp:81
bool operator==(OBB const &) const =default
Equality operator.
void setRotation(T angle)
Sets the rotation of the OBB.
Definition obb.hpp:243
constexpr OBB(OBB const &) noexcept=default
Copy constructor.
constexpr Vec< 2, T > rotatedHalfLength() const
Returns the rotated half-length vector.
Definition obb.hpp:233
constexpr OBB(OBB< 2, U > const &other) noexcept
Converting constructor from an OBB with a different scalar type.
Definition obb.hpp:166
constexpr OBB(Vec< 2, T > const &center, Vec< 2, T > const &half_length, Mat< 2, 2, T > const &rotation) noexcept
Constructs an OBB from center, half-lengths, and rotation.
Definition obb.hpp:148
static constexpr std::size_t dimension() noexcept
Returns the dimensionality of the OBB.
Definition obb.hpp:189
constexpr bool isDegenerate() const noexcept
Returns whether the OBB is degenerate.
Definition obb.hpp:215
constexpr Vec< 2, T > const & center() const noexcept
Returns the center of the OBB.
Definition obb.hpp:183
constexpr OBB(Vec< 2, T > const &center, Vec< 2, T > const &half_length) noexcept
Constructs an OBB from center and half-lengths with identity rotation.
Definition obb.hpp:136
constexpr T diagonal() const noexcept
Returns the distance from the center to a corner.
Definition obb.hpp:196
constexpr OBB() noexcept=default
Default constructor.
constexpr AABB< 2, T > aabb() const noexcept
Returns the AABB of the OBB.
Definition obb.hpp:202
Mat< 2, 2, T > rotation
The rotation matrix of the OBB.
Definition obb.hpp:86
constexpr OBB(OBB const &) noexcept=default
Copy constructor.
constexpr Vec< 3, T > const & center() const noexcept
Returns the center of the OBB.
Definition obb.hpp:370
constexpr T diagonal() const noexcept
Returns the diagonal length of the OBB.
Definition obb.hpp:381
constexpr Vec< 3, T > rotatedHalfLength() const
Returns the rotated half-length vector.
Definition obb.hpp:417
bool operator==(OBB const &) const =default
Equality operator.
constexpr Vec< 3, T > & center() noexcept
Returns the center of the OBB.
Definition obb.hpp:364
constexpr OBB(Vec< 3, T > const &center, Vec< 3, T > const &half_length, Quat< T > const &rotation) noexcept
Constructs an OBB from center, half-lengths, and quaternion rotation.
Definition obb.hpp:338
constexpr OBB() noexcept=default
Default constructor.
Mat< 3, 3, T > rotation
The rotation matrix of the OBB.
Definition obb.hpp:283
constexpr AABB< 3, T > aabb() const noexcept
Returns the AABB of the OBB.
Definition obb.hpp:395
constexpr OBB(Vec< 3, T > const &center, Vec< 3, T > const &half_length, Mat< 3, 3, T > const &rotation) noexcept
Constructs an OBB from center, half-lengths, and rotation matrix.
Definition obb.hpp:329
Vec< 3, T > center_
The center of the OBB.
Definition obb.hpp:273
void setRotation(Quat< T > const &rotation)
Sets the rotation of the OBB from a quaternion.
Definition obb.hpp:425
static constexpr std::size_t dimension() noexcept
Returns the dimensionality of the OBB.
Definition obb.hpp:376
constexpr T volume() const noexcept
Returns the volume of the OBB.
Definition obb.hpp:386
constexpr OBB(Vec< 3, T > const &center, Vec< 3, T > const &half_length) noexcept
Constructs an OBB from center and half-lengths with identity rotation.
Definition obb.hpp:321
Vec< 3, T > half_length
The half-lengths of the OBB along its local axes.
Definition obb.hpp:278
constexpr bool isDegenerate() const noexcept
Returns whether the OBB is degenerate.
Definition obb.hpp:409
constexpr OBB(OBB< 3, U > const &other) noexcept
Converting constructor from an OBB with a different scalar type.
Definition obb.hpp:353
bool operator==(OBB const &) const =default
Equality operator.
constexpr Vec< 4, T > rotatedHalfLength() const
Returns the rotated half-length vector.
Definition obb.hpp:535
constexpr Vec< 4, T > & center() noexcept
Returns the center of the OBB.
Definition obb.hpp:481
constexpr T volume() const noexcept
Returns the volume of the OBB.
Definition obb.hpp:503
constexpr Vec< 4, T > const & center() const noexcept
Returns the center of the OBB.
Definition obb.hpp:487
constexpr AABB< 4, T > aabb() const noexcept
Returns the AABB of the OBB.
Definition obb.hpp:512
constexpr bool isDegenerate() const noexcept
Returns whether the OBB is degenerate.
Definition obb.hpp:527
constexpr T diagonal() const noexcept
Returns the diagonal length of the OBB.
Definition obb.hpp:498
static constexpr std::size_t dimension() noexcept
Returns the dimensionality of the OBB.
Definition obb.hpp:493
Oriented Bounding Box in 2D space.
Definition obb.hpp:61
Unit quaternion representing an orientation or rotation in 3-D space.
Definition quat.hpp:76
A fixed-size arithmetic vector of up to 4 dimensions.
Definition vec.hpp:76
constexpr auto & y(this auto &self) noexcept
Accesses the second component (y).
Definition vec.hpp:146
constexpr auto & z(this auto &self) noexcept
Accesses the third component (z).
Definition vec.hpp:156
constexpr auto & x(this auto &self) noexcept
Accesses the first component (x).
Definition vec.hpp:136