#pragma once #include "vde/foundation/exact_predicates.h" #ifdef VDE_USE_GMP #include "vde/foundation/exact_predicates_gmp.h" #endif namespace vde::foundation { /** * @brief 统一谓词接口 — 编译时选择 GMP 或自适应双精度后端 * * 根据 VDE_USE_GMP 宏自动选择 GmpExact 或 AdaptiveDouble 作为后端。 * 上层代码只需使用 Predicates,无需关心具体实现。 * * @ingroup foundation */ struct Predicates { #ifdef VDE_USE_GMP /// 使用 GMP 精确有理数算术(零误差,较慢) using Backend = exact::GmpExact; #else /// 使用自适应双精度算术(Shewchuk 算法,默认) using Backend = exact::AdaptiveDouble; #endif /** * @brief 二维定向测试 * @param a,b,c 三点 * @return 定向结果 */ static exact::Orientation orient_2d(const Point2D& a, const Point2D& b, const Point2D& c) { return Backend::orient_2d(a, b, c); } /** * @brief 三维定向测试 * @param a,b,c,d 四点 * @return 定向结果 */ static exact::Orientation orient_3d(const Point3D& a, const Point3D& b, const Point3D& c, const Point3D& d) { return Backend::orient_3d(a, b, c, d); } /** * @brief 圆内测试 * @param a,b,c 三角形三顶点 * @param d 测试点 * @return 圆测试结果 */ static exact::CircleTest in_circle(const Point2D& a, const Point2D& b, const Point2D& c, const Point2D& d) { return Backend::in_circle(a, b, c, d); } }; // ── Convenience wrappers (preferred API) ── /** * @brief 二维定向测试便捷封装 * * 使用 Predicates::orient_2d,无需指定后端。 * 这是推荐的对外 API。 * * @param a,b,c 三个二维点 * @return Orientation::Clockwise / CounterClockwise / Collinear * * @code{.cpp} * using namespace vde::foundation; * Point2D a(0,0), b(1,0), c(0,1); * auto result = orient(a, b, c); // CounterClockwise * @endcode * * @ingroup foundation */ inline exact::Orientation orient(const Point2D& a, const Point2D& b, const Point2D& c) { return Predicates::orient_2d(a, b, c); } /** * @brief 三维定向测试便捷封装 * * @param a,b,c 定义平面的三点 * @param d 测试点 * @return Orientation::Clockwise / CounterClockwise / Collinear * * @ingroup foundation */ inline exact::Orientation orient(const Point3D& a, const Point3D& b, const Point3D& c, const Point3D& d) { return Predicates::orient_3d(a, b, c, d); } /** * @brief 圆内测试便捷封装 * * @param a,b,c 三角形三顶点 * @param d 测试点 * @return CircleTest::Inside / On / Outside * * @ingroup foundation */ inline exact::CircleTest in_circle(const Point2D& a, const Point2D& b, const Point2D& c, const Point2D& d) { return Predicates::in_circle(a, b, c, d); } } // namespace vde::foundation