Files
j3ml/include/J3ML/Geometry/AABB2D.hpp
josh e4dd7058e1
All checks were successful
Run ReCI Build Test / Explore-Gitea-Actions (push) Successful in 1m31s
Build Docs With Doxygen / Explore-Gitea-Actions (push) Successful in 23s
Implement Geometry::Rect2D class, which will work in tandem with 2D geometry tools such as Transform2D, AABB2D, OBB2D, Polygon2D
2025-04-18 15:31:22 -04:00

102 lines
3.0 KiB
C++

/// Josh's 3D Math Library
/// A C++20 Library for 3D Math, Computer Graphics, and Scientific Computing.
/// Developed and Maintained by Josh O'Leary @ Redacted Software.
/// Special Thanks to William Tomasine II and Maxine Hayes.
/// (c) 2024 Redacted Software
/// This work is dedicated to the public domain.
/// @file AABB2D.hpp
/// @desc A 2D Axis-Aligned Bounding Box structure.
/// @edit 2025-04-18
#pragma once
#include <J3ML/LinearAlgebra.hpp>
#include <J3ML/Geometry/Shape.hpp>
#include <J3ML/Geometry/Forward.hpp>
/// See Christer Ericson's Real-time Collision Detection, p. 87, or
/// James Arvo's "Transforming Axis-aligned Bounding Boxes" in Graphics Gems 1, pp. 548-550.
/// http://www.graphicsgems.org/
template <typename Matrix>
void AABB2DTransformAsAABB2D(AABB2D& aabb, Matrix& m);
namespace J3ML::Geometry
{
using LinearAlgebra::Vector2;
// TODO: Integer AABB2D for even leaner box computation.
// CaveGame AABB
class AABB2D : public Shape2D
{
public:
Vector2 minPoint;
Vector2 maxPoint;
AABB2D() {}
AABB2D(const Vector2& min, const Vector2& max):
minPoint(min), maxPoint(max)
{}
[[nodiscard]] float Width() const;
[[nodiscard]] float Height() const;
Vector2 Centroid() const;
[[nodiscard]] float DistanceSq(const Vector2& pt) const;
void SetNegativeInfinity();
void Enclose(const Vector2& point);
[[nodiscard]] bool Intersects(const AABB2D& rhs) const;
[[nodiscard]] bool Contains(const AABB2D& rhs) const;
[[nodiscard]] bool Contains(const Vector2& pt) const;
[[nodiscard]] bool Contains(int x, int y) const;
[[nodiscard]] bool IsDegenerate() const;
[[nodiscard]] bool HasNegativeVolume() const;
[[nodiscard]] bool IsFinite() const;
Vector2 PosInside(const Vector2 &normalizedPos) const;
Vector2 ToNormalizedLocalSpace(const Vector2 &pt) const;
AABB2D operator+(const Vector2& pt) const;
AABB2D operator-(const Vector2& pt) const;
Vector2 CornerPoint(int cornerIndex);
void TransformAsAABB(const Matrix3x3& transform);
void TransformAsAABB(const Matrix4x4& transform);
};
template<typename Matrix>
void AABB2DTransformAsAABB2D(AABB2D &aabb, Matrix &m) {
float ax = m[0][0] * aabb.minPoint.x;
float bx = m[0][0] * aabb.maxPoint.x;
float ay = m[0][1] * aabb.minPoint.y;
float by = m[0][1] * aabb.maxPoint.y;
float ax2 = m[1][0] * aabb.minPoint.x;
float bx2 = m[1][0] * aabb.maxPoint.x;
float ay2 = m[1][1] * aabb.minPoint.y;
float by2 = m[1][1] * aabb.maxPoint.y;
aabb.minPoint.x = J3ML::Math::Min(ax, bx) + J3ML::Math::Min(ay, by) + m[0][3];
aabb.maxPoint.x = J3ML::Math::Max(ax, bx) + J3ML::Math::Max(ay, by) + m[0][3];
aabb.minPoint.y = J3ML::Math::Min(ax2, bx2) + J3ML::Math::Min(ay2, by2) + m[1][3];
aabb.maxPoint.y = J3ML::Math::Max(ax2, bx2) + J3ML::Math::Max(ay2, by2) + m[1][3];
}
}