153 lines
4.5 KiB
C++
153 lines
4.5 KiB
C++
#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
|