Files

153 lines
4.5 KiB
C++
Raw Permalink Normal View History

#pragma once
#include "vde/foundation/math_types.h"
namespace vde::foundation::exact {
/**
* @brief 二维定向测试结果
*
* 判断三点构成的三角形的定向(顺时针 / 逆时针 / 共线)。
*
* @ingroup foundation
*/
enum class Orientation { Clockwise, CounterClockwise, Collinear };
/**
* @brief 圆测试结果
*
* 判断点 d 相对于三角形 abc 外接圆的位置。
*
* @ingroup foundation
*/
enum class CircleTest { Inside, On, Outside };
/**
* @brief 自适应精度二维定向测试(Shewchuk 算法)
*
* 判断点 a, b, c 的定向。使用自适应浮点精度:
* 先用双精度计算行列式,若结果不可靠则逐步提高精度,直至确定符号。
*
* @param a 第一个点
* @param b 第二个点
* @param c 第三个点
* @return Orientation::Clockwise 若 a→b→c 顺时针
* @return Orientation::CounterClockwise 若 a→b→c 逆时针
* @return Orientation::Collinear 若三点共线
*
* @note Delaunay 三角剖分、凸包计算等几何算法的核心原语
* @warning 输入点坐标必须为有限值,NaN/Inf 会导致未定义行为
*
* @code{.cpp}
* Point2D a(0,0), b(1,0), c(0,1);
* auto ori = exact::orient_2d(a, b, c);
* // ori == Orientation::CounterClockwise
* @endcode
*
* @see orient_3d, in_circle
* @ingroup foundation
*/
Orientation orient_2d(const Point2D& a, const Point2D& b, const Point2D& c);
/**
* @brief 自适应精度三维定向测试
*
* 判断点 a, b, c, d 的定向(即点 d 在平面 abc 的哪一侧)。
* 等价于计算四面体 abcd 的有向体积的符号。
*
* @param a 第一个点
* @param b 第二个点
* @param c 第三个点
* @param d 第四个点(测试点)
* @return Orientation::CounterClockwise 若 d 在平面 abc 上方(按右手法则)
* @return Orientation::Clockwise 若 d 在平面 abc 下方
* @return Orientation::Collinear 若四点共面
*
* @note 三维 Delaunay 剖分和凸包计算的核心原语
*
* @code{.cpp}
* Point3D a(0,0,0), b(1,0,0), c(0,1,0), d(0,0,1);
* auto ori = exact::orient_3d(a, b, c, d);
* // ori == Orientation::CounterClockwise
* @endcode
*
* @see orient_2d, in_circle
* @ingroup foundation
*/
Orientation orient_3d(const Point3D& a, const Point3D& b,
const Point3D& c, const Point3D& d);
/**
* @brief 自适应精度圆内测试(In-Circle Test
*
* 判断点 d 是否在三角形 abc 的外接圆内部、边界上或外部。
* 等价于计算 4×4 行列式的符号。
*
* @param a 三角形第一个顶点
* @param b 三角形第二个顶点
* @param c 三角形第三个顶点
* @param d 待测试点
* @return CircleTest::Inside 若 d 在三角形外接圆内部
* @return CircleTest::On 若 d 恰好在三角形外接圆上
* @return CircleTest::Outside 若 d 在三角形外接圆外部
*
* @note Delaunay 三角剖分的空圆性质检查核心原语
* @pre 三点 a、b、c 不共线
*
* @code{.cpp}
* Point2D a(0,0), b(2,0), c(0,2);
* Point2D d(0.5, 0.5); // 在外接圆内部
* auto result = exact::in_circle(a, b, c, d);
* // result == CircleTest::Inside
* @endcode
*
* @see orient_2d, orient_3d
* @ingroup foundation
*/
CircleTest in_circle(const Point2D& a, const Point2D& b,
const Point2D& c, const Point2D& d);
} // namespace vde::foundation::exact
/**
* @brief 自适应双精度谓词后端(默认)
*
* 封装 exact 命名空间下的自适应精度谓词函数,
* 作为 Predicates 的默认后端实现。
*
* @ingroup foundation
*/
namespace vde::foundation {
struct AdaptiveDouble {
/**
* @brief 二维定向测试
* @param a,b,c 三个二维点
* @return 定向结果
* @see exact::orient_2d
*/
static exact::Orientation orient_2d(const Point2D& a, const Point2D& b, const Point2D& c) {
return exact::orient_2d(a, b, c);
}
/**
* @brief 三维定向测试
* @param a,b,c,d 四个三维点
* @return 定向结果
* @see exact::orient_3d
*/
static exact::Orientation orient_3d(const Point3D& a, const Point3D& b,
const Point3D& c, const Point3D& d) {
return exact::orient_3d(a, b, c, d);
}
/**
* @brief 圆内测试
* @param a,b,c 三角形三顶点
* @param d 待测试点
* @return 圆测试结果
* @see exact::in_circle
*/
static exact::CircleTest in_circle(const Point2D& a, const Point2D& b,
const Point2D& c, const Point2D& d) {
return exact::in_circle(a, b, c, d);
}
};
} // namespace vde::foundation