42#ifndef UFO_GEOMETRY_OBB_HPP
43#define UFO_GEOMETRY_OBB_HPP
46#include <ufo/geometry/aabb.hpp>
47#include <ufo/numeric/mat.hpp>
48#include <ufo/numeric/quat.hpp>
49#include <ufo/numeric/vec.hpp>
60template <std::
size_t Dim = 3, std::
floating_po
int T =
float>
69template <std::
floating_po
int T>
91 constexpr OBB() noexcept = default;
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))
104 auto dir = end - start;
106 this->half_length =
Vec<2, T>(
norm(dir) * T(0.5), half_length[0]);
108 auto theta = std::atan2(dir.y, dir.x);
109 auto cos_theta = std::cos(theta);
110 auto sin_theta = std::sin(theta);
112 rotation[0][0] = cos_theta;
113 rotation[0][1] = sin_theta;
114 rotation[1][0] = -sin_theta;
115 rotation[1][1] = cos_theta;
126 :
OBB(start, end,
Vec<1, T>(half_length))
137 : center_(center), half_length(half_length)
150 : center_(center), half_length(half_length), rotation(rotation)
157 constexpr OBB(
OBB const&)
noexcept =
default;
165 template <std::convertible_to<T> U>
168 , half_length(
Vec<2, T>(other.half_length))
189 [[nodiscard]]
static constexpr std::size_t
dimension() noexcept {
return 2; }
196 [[nodiscard]]
constexpr T
diagonal() const noexcept {
return norm(half_length) * T(2); }
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];
209 return AABB<2, T>(center_ - extent, center_ + extent);
225 [[nodiscard]]
constexpr T
volume() const noexcept
227 return T(4) * half_length[0] * half_length[1];
235 return half_length * rotation;
245 auto cos_theta = std::cos(
angle);
246 auto sin_theta = std::sin(
angle);
248 rotation[0][0] = cos_theta;
249 rotation[0][1] = sin_theta;
250 rotation[1][0] = -sin_theta;
251 rotation[1][1] = cos_theta;
266template <std::
floating_po
int T>
268 using value_type = T;
288 constexpr OBB() noexcept = default;
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))
298 auto dir = end - start;
300 this->half_length =
Vec<3, T>(
norm(dir) * T(0.5), half_length);
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;
322 : center_(center), half_length(half_length)
331 : center_(center), half_length(half_length), rotation(rotation)
339 Quat<T> const& rotation) noexcept
340 : center_(center), half_length(half_length), rotation(rotation)
347 constexpr OBB(
OBB const&)
noexcept =
default;
352 template <std::convertible_to<T> U>
355 , half_length(
Vec<3, T>(other.half_length))
376 [[nodiscard]]
static constexpr std::size_t
dimension() noexcept {
return 3; }
381 [[nodiscard]]
constexpr T
diagonal() const noexcept {
return norm(half_length) * T(2); }
386 [[nodiscard]]
constexpr T
volume() const noexcept
388 return T(8) * half_length[0] * half_length[1] * half_length[2];
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];
403 return AABB<3, T>(center_ - extent, center_ + extent);
419 return half_length * rotation;
437template <std::
floating_po
int T>
439 using value_type = T;
445 constexpr OBB()
noexcept =
default;
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);
457 : center_(center), half_length(half_length)
463 : center_(center), half_length(half_length), rotation(rotation)
467 constexpr OBB(
OBB const&)
noexcept =
default;
469 template <std::convertible_to<T> U>
472 , half_length(
Vec<4, T>(other.half_length))
493 [[nodiscard]]
static constexpr std::size_t
dimension() noexcept {
return 4; }
498 [[nodiscard]]
constexpr T
diagonal() const noexcept {
return norm(half_length) * T(2); }
503 [[nodiscard]]
constexpr T
volume() const noexcept
505 return T(16) * half_length[0] * half_length[1] * half_length[2] * half_length[3];
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];
521 return AABB<4, T>(center_ - extent, center_ + extent);
537 return half_length * rotation;
549template <std::
floating_po
int T>
550std::ostream& operator<<(std::ostream& out,
OBB<2, T> const& obb)
552 return out <<
"Center: [" << obb.center() <<
"], Half length: [" << obb.half_length
553 <<
"], Rotation: [" << obb.rotation <<
"]";
559template <std::
floating_po
int T>
560std::ostream& operator<<(std::ostream& out,
OBB<3, T> const& obb)
562 return out <<
"Center: [" << obb.center() <<
"], Half length: [" << obb.half_length
563 <<
"], Rotation: [" << obb.rotation <<
"]";
569template <std::
floating_po
int T>
570std::ostream& operator<<(std::ostream& out,
OBB<4, T> const& obb)
572 return out <<
"Center: [" << obb.center() <<
"], Half length: [" << obb.half_length
573 <<
"], Rotation: [" << obb.rotation <<
"]";
577using OBB1 = OBB<1, T>;
579using OBB2 = OBB<2, T>;
581using OBB3 = OBB<3, T>;
583using OBB4 = OBB<4, T>;
585using OBB1f = OBB<1, float>;
586using OBB2f = OBB<2, float>;
587using OBB3f = OBB<3, float>;
588using OBB4f = OBB<4, float>;
590using OBB1d = OBB<1, double>;
591using OBB2d = OBB<2, double>;
592using OBB3d = OBB<3, double>;
593using OBB4d = OBB<4, double>;
597template <std::
size_t Dim, std::
floating_po
int 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(); }
604 return std::format_to(ctx.out(),
"Center: [{}], Half length: [{}], Rotation: [{}]",
605 obb.center(), obb.half_length, obb.rotation);
T angle(Quat< T > const &q) noexcept
Extracts the rotation angle (in radians) from a unit quaternion.
All vision-related classes and functions.
constexpr bool any(Vec< Dim, bool > const &v) noexcept
Returns true if at least one component of a bool vector is true.
constexpr Quat< T > normalize(Quat< T > const &q) noexcept
Returns a unit quaternion in the same direction as q.
constexpr T norm(Quat< T > const &q) noexcept
Returns the Euclidean norm sqrt(w² + x² + y² + z²).
constexpr Quat< T > cross(Quat< T > const &q1, Quat< T > const &q2) noexcept
Computes the Hamilton cross product of two quaternions.
Axis-Aligned Bounding Box (AABB) in Dim-dimensional space.
A fixed-size matrix with Rows rows and Cols columns.
constexpr Vec< 2, T > & center() noexcept
Returns the center of the OBB.
Vec< 2, T > center_
The center of the OBB.
constexpr T volume() const noexcept
Returns the area of the OBB.
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.
Vec< 2, T > half_length
The half-lengths of the OBB along its local axes.
bool operator==(OBB const &) const =default
Equality operator.
void setRotation(T angle)
Sets the rotation of the OBB.
constexpr OBB(OBB const &) noexcept=default
Copy constructor.
constexpr Vec< 2, T > rotatedHalfLength() const
Returns the rotated half-length vector.
constexpr OBB(OBB< 2, U > const &other) noexcept
Converting constructor from an OBB with a different scalar type.
constexpr OBB(Vec< 2, T > const ¢er, Vec< 2, T > const &half_length, Mat< 2, 2, T > const &rotation) noexcept
Constructs an OBB from center, half-lengths, and rotation.
static constexpr std::size_t dimension() noexcept
Returns the dimensionality of the OBB.
constexpr bool isDegenerate() const noexcept
Returns whether the OBB is degenerate.
constexpr Vec< 2, T > const & center() const noexcept
Returns the center of the OBB.
constexpr OBB(Vec< 2, T > const ¢er, Vec< 2, T > const &half_length) noexcept
Constructs an OBB from center and half-lengths with identity rotation.
constexpr T diagonal() const noexcept
Returns the distance from the center to a corner.
constexpr OBB() noexcept=default
Default constructor.
constexpr AABB< 2, T > aabb() const noexcept
Returns the AABB of the OBB.
Mat< 2, 2, T > rotation
The rotation matrix of the OBB.
constexpr OBB(OBB const &) noexcept=default
Copy constructor.
constexpr Vec< 3, T > const & center() const noexcept
Returns the center of the OBB.
constexpr T diagonal() const noexcept
Returns the diagonal length of the OBB.
constexpr Vec< 3, T > rotatedHalfLength() const
Returns the rotated half-length vector.
bool operator==(OBB const &) const =default
Equality operator.
constexpr Vec< 3, T > & center() noexcept
Returns the center of the OBB.
constexpr OBB(Vec< 3, T > const ¢er, Vec< 3, T > const &half_length, Quat< T > const &rotation) noexcept
Constructs an OBB from center, half-lengths, and quaternion rotation.
constexpr OBB() noexcept=default
Default constructor.
Mat< 3, 3, T > rotation
The rotation matrix of the OBB.
constexpr AABB< 3, T > aabb() const noexcept
Returns the AABB of the OBB.
constexpr OBB(Vec< 3, T > const ¢er, Vec< 3, T > const &half_length, Mat< 3, 3, T > const &rotation) noexcept
Constructs an OBB from center, half-lengths, and rotation matrix.
Vec< 3, T > center_
The center of the OBB.
void setRotation(Quat< T > const &rotation)
Sets the rotation of the OBB from a quaternion.
static constexpr std::size_t dimension() noexcept
Returns the dimensionality of the OBB.
constexpr T volume() const noexcept
Returns the volume of the OBB.
constexpr OBB(Vec< 3, T > const ¢er, Vec< 3, T > const &half_length) noexcept
Constructs an OBB from center and half-lengths with identity rotation.
Vec< 3, T > half_length
The half-lengths of the OBB along its local axes.
constexpr bool isDegenerate() const noexcept
Returns whether the OBB is degenerate.
constexpr OBB(OBB< 3, U > const &other) noexcept
Converting constructor from an OBB with a different scalar type.
bool operator==(OBB const &) const =default
Equality operator.
constexpr Vec< 4, T > rotatedHalfLength() const
Returns the rotated half-length vector.
constexpr Vec< 4, T > & center() noexcept
Returns the center of the OBB.
constexpr T volume() const noexcept
Returns the volume of the OBB.
constexpr Vec< 4, T > const & center() const noexcept
Returns the center of the OBB.
constexpr AABB< 4, T > aabb() const noexcept
Returns the AABB of the OBB.
constexpr bool isDegenerate() const noexcept
Returns whether the OBB is degenerate.
constexpr T diagonal() const noexcept
Returns the diagonal length of the OBB.
static constexpr std::size_t dimension() noexcept
Returns the dimensionality of the OBB.
Oriented Bounding Box in 2D space.
Unit quaternion representing an orientation or rotation in 3-D space.
A fixed-size arithmetic vector of up to 4 dimensions.
constexpr auto & y(this auto &self) noexcept
Accesses the second component (y).
constexpr auto & z(this auto &self) noexcept
Accesses the third component (z).
constexpr auto & x(this auto &self) noexcept
Accesses the first component (x).