105 lines
2.9 KiB
C++
105 lines
2.9 KiB
C++
#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
|