Files
ViewDesignEngine/include/vde/core/aabb.h
T
茂之钳 4c9ee4f760
CI / Build & Test (push) Failing after 29s
CI / Release Build (push) Failing after 38s
docs: doxygen annotations for curves + mesh + sketch
2026-07-24 11:04:04 +00:00

136 lines
3.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#pragma once
#include "vde/core/point.h"
#include <algorithm>
#include <limits>
namespace vde::core {
/**
* @brief 轴对齐包围盒(AABB
*
* 用最小/最大两个角点表示的三维轴对齐包围盒。
* 支持增量扩展、包含/相交测试、几何属性查询。
*
* @tparam T 标量类型(通常为 double 或 float
*
* @note 初始状态为空(min = +∞, max = -∞),需要通过 expand() 初始化
*
* @ingroup core
*/
template <typename T>
class AABB {
public:
/**
* @brief 构造空包围盒
*
* min 初始化为 T 最大值,max 初始化为 T 最小值,
* 表示"无内容"的空状态。
*/
AABB() : min_(Point3D::Constant(std::numeric_limits<T>::max())),
max_(Point3D::Constant(std::numeric_limits<T>::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<double>;
/// 单精度三维包围盒
using AABB3f = AABB<float>;
} // namespace vde::core