#pragma once /** * @file exact_predicates.h * @brief 精确几何谓词 * * 使用 GMP/MPFR 进行精确算术运算,消除浮点误差。 * 关键路径:布尔运算分类、Delaunay 三角剖分、凸包计算。 * * 支持混合精度:先用 double,检测到不确定时自动升级到 GMP。 * * @ingroup foundation */ #include "vde/core/point.h" #include namespace vde::core { // ═══════════════════════════════════════════════════════════ // Exact Predicates (double → GMP fallback) // ═══════════════════════════════════════════════════════════ /** * @brief 精确三点定向 (orient2d) * * 计算 (ax,ay), (bx,by), (cx,cy) 的有向面积 × 2。 * > 0 → 逆时针, < 0 → 顺时针, = 0 → 共线。 * * 先使用浮点运算,若结果接近 0 则升级到 GMP。 * * @return 精确的 orient 值 */ [[nodiscard]] double exact_orient2d( double ax, double ay, double bx, double by, double cx, double cy); /** * @brief 精确四点定向 (orient3d) * * 计算四面体 (a,b,c,d) 的有向体积 × 6。 * > 0 → d 在平面 abc 上方, < 0 → 下方, = 0 → 共面。 */ [[nodiscard]] double exact_orient3d( double ax, double ay, double az, double bx, double by, double bz, double cx, double cy, double cz, double dx, double dy, double dz); /** * @brief 精确球内测试 (in_sphere) * * 判断点 d 是否在四面体 abc 的外接球内。 * > 0 → 内部, < 0 → 外部, = 0 → 在球面上。 */ [[nodiscard]] double exact_in_sphere( double ax, double ay, double az, double bx, double by, double bz, double cx, double cy, double cz, double dx, double dy, double dz, double ex, double ey, double ez); /** * @brief 精确点在多边形内测试 * * 射线投射法 + 精确算术处理边界情况。 * * @param point 测试点 * @param polygon 多边形顶点(逆时针) * @return true 如果点在多边形内或边界上 */ [[nodiscard]] bool exact_point_in_polygon( const Point3D& point, const std::vector& polygon); /** * @brief 精确点在多面体内测试 * * 射线投射法,使用精确算术处理共面/共线退化情况。 * * @param point 测试点 * @param vertices 多面体顶点 * @param faces 面索引(每面 3+ 个顶点索引) * @return true 如果点在体内 */ [[nodiscard]] bool exact_point_in_polyhedron( const Point3D& point, const std::vector& vertices, const std::vector>& faces); // ═══════════════════════════════════════════════════════════ // Adaptive precision wrapper // ═══════════════════════════════════════════════════════════ /// 精度模式 enum class PrecisionMode { Fast, ///< 仅使用 double(默认) Adaptive, ///< 先 double,不确定时升级到 GMP Exact, ///< 始终使用 GMP }; /** * @brief 设置全局精度模式 */ void set_precision_mode(PrecisionMode mode); /** * @brief 获取当前精度模式 */ [[nodiscard]] PrecisionMode precision_mode(); /** * @brief 检查和报告两浮点数是否在误差范围内"不确定" * * 用于自适应精度升级判断。 */ [[nodiscard]] bool is_uncertain(double value, double threshold = 1e-10); } // namespace vde::core