#pragma once #include "vde/core/point.h" #include #include namespace vde::core { /** * @brief 轴对齐包围盒(AABB) * * 用最小/最大两个角点表示的三维轴对齐包围盒。 * 支持增量扩展、包含/相交测试、几何属性查询。 * * @tparam T 标量类型(通常为 double 或 float) * * @note 初始状态为空(min = +∞, max = -∞),需要通过 expand() 初始化 * * @ingroup core */ template class AABB { public: /** * @brief 构造空包围盒 * * min 初始化为 T 最大值,max 初始化为 T 最小值, * 表示"无内容"的空状态。 */ AABB() : min_(Point3D::Constant(std::numeric_limits::max())), max_(Point3D::Constant(std::numeric_limits::lowest())) {} /** * @brief 从两个角点构造包围盒 * * @param min 最小角点 * @param max 最大角点 * * @pre min 的各分量 ≤ max 的各分量 */ AABB(const Point3D& min, const Point3D& max) : min_(min), max_(max) {} /** * @brief 扩展包围盒以包含给定点 * * 逐分量取 min/max,保证包围盒包含该点。 * 若包围盒为空,此调用等效于初始化为包含该点的退化盒。 * * @param p 要包含的点 * * @code{.cpp} * AABB3D box; * for (auto& p : points) box.expand(p); * @endcode */ void expand(const Point3D& p) { min_ = min_.cwiseMin(p); max_ = max_.cwiseMax(p); } /** * @brief 扩展包围盒以包含另一个 AABB * * @param other 另一个包围盒 */ void expand(const AABB& other) { min_ = min_.cwiseMin(other.min_); max_ = max_.cwiseMax(other.max_); } /** * @brief 包围盒中心点 * @return (min + max) / 2 */ [[nodiscard]] Point3D center() const { return (min_ + max_) * 0.5; } /** * @brief 包围盒对角线向量(从 min 到 max) * @return max - min */ [[nodiscard]] Vector3D extent() const { return max_ - min_; } /** * @brief 包围盒表面积 * @return 2 * (dx*dy + dy*dz + dz*dx) */ [[nodiscard]] T surface_area() const { Vector3D e = extent(); return 2.0 * (e.x() * e.y() + e.y() * e.z() + e.z() * e.x()); } /** * @brief 包围盒体积 * @return dx * dy * dz */ [[nodiscard]] T volume() const { Vector3D e = extent(); return e.x() * e.y() * e.z(); } /** * @brief 测试点是否在包围盒内部(含边界) * * @param p 测试点 * @return true 若 min ≤ p ≤ max(各分量) */ [[nodiscard]] bool contains(const Point3D& p) const { return (p.array() >= min_.array()).all() && (p.array() <= max_.array()).all(); } /** * @brief 测试两个包围盒是否相交(含边界接触) * * @param other 另一个包围盒 * @return true 若存在交集 */ [[nodiscard]] bool intersects(const AABB& other) const { return (min_.array() <= other.max_.array()).all() && (max_.array() >= other.min_.array()).all(); } /// 获取最小角点 [[nodiscard]] const Point3D& min() const { return min_; } /// 获取最大角点 [[nodiscard]] const Point3D& max() const { return max_; } private: Point3D min_, max_; }; /// 双精度三维包围盒 using AABB3D = AABB; /// 单精度三维包围盒 using AABB3f = AABB; } // namespace vde::core