docs: doxygen annotations for spatial + boolean + collision

This commit is contained in:
茂之钳
2026-07-24 11:02:06 +00:00
parent 10847e61ad
commit b97b0415f5
11 changed files with 1262 additions and 76 deletions
+47 -3
View File
@@ -1,3 +1,13 @@
/**
* @file boolean_2d.h
* @brief 二维多边形布尔运算
*
* 支持并集、交集、差集、对称差等标准布尔操作。
* 基于 Vatti 算法实现。
*
* @ingroup boolean
*/
#pragma once
#include "vde/core/polygon.h"
#include <vector>
@@ -6,10 +16,44 @@ namespace vde::boolean {
using core::Point2D;
using core::Polygon2D;
enum class BooleanOp { Union, Intersection, Difference, SymDiff };
/**
* @brief 布尔运算类型
*/
enum class BooleanOp {
Union, /**< 并集 A B */
Intersection, /**< 交集 A ∩ B */
Difference, /**< 差集 A B */
SymDiff /**< 对称差 (A B) (B A) */
};
/// 2D polygon boolean operations (Vatti algorithm)
/// Currently implemented via a simple edge walking approach for convex polygons
/**
* @brief 二维多边形布尔运算
*
* 对两个简单多边形执行指定布尔操作。
* 当前实现:基于 Vatti 算法的边行走方式处理凸多边形,
* 可扩展支持任意简单多边形(含孔洞)。
*
* 算法流程:
* 1. 找到两条多边形的所有交点
* 2. 跟踪边界根据布尔操作选择进入/退出边
* 3. 组装结果多边形
*
* @note 当前版本优化了凸多边形路径。对于带孔洞或自交的
* 复杂多边形,建议先三角剖分或使用 mesh_boolean。
*
* @param a 第一个多边形
* @param b 第二个多边形
* @param op 布尔操作类型
* @return 结果多边形列表(可能有多个分离的组件)
*
* @code{.cpp}
* Polygon2D p1 = make_circle(10, Point2D{0,0}, 5.0);
* Polygon2D p2 = make_circle(10, Point2D{3,0}, 5.0);
* auto result = boolean_2d(p1, p2, BooleanOp::Union);
* @endcode
*
* @see BooleanOp, mesh_boolean, polygon_offset
*/
std::vector<Polygon2D> boolean_2d(const Polygon2D& a, const Polygon2D& b, BooleanOp op);
} // namespace vde::boolean
+158 -14
View File
@@ -1,3 +1,13 @@
/**
* @file boolean_mesh.h
* @brief 三维网格布尔运算
*
* 基于半边的网格布尔操作:并集、交集、差集、对称差。
* 通过面片重心内外判定 (ray-casting) 实现拓扑分类。
*
* @ingroup boolean
*/
#pragma once
#include "vde/boolean/boolean_2d.h"
#include "vde/core/polygon.h"
@@ -8,40 +18,174 @@ using core::Point2D;
using core::Polygon2D;
using mesh::HalfedgeMesh;
/// ── Core 3D mesh boolean operations ──────────────────────
// ── Core 3D mesh boolean operations ──────────────────────────────
/// Union: A B — keep faces of each mesh whose centroids lie outside the other
/**
* @brief 网格并集 A B
*
* 保留网格 A 中重心在网格 B 外的面片,
* 以及网格 B 中重心在网格 A 外的面片。
* 合并后形成两个网格的并集体积。
*
* 原理:对每个面片计算重心坐标,用射线投射判断
* 该点是否在对方网格内部,据此决定保留或剔除。
*
* @param a 网格 A
* @param b 网格 B
* @return A B 的合并网格
*
* @code{.cpp}
* HalfedgeMesh result = mesh_union(cube, sphere);
* @endcode
*
* @see mesh_intersection, mesh_difference, is_point_inside_mesh
*/
HalfedgeMesh mesh_union(const HalfedgeMesh& a, const HalfedgeMesh& b);
/// Intersection: A ∩ B — keep faces whose centroids lie inside the other
/**
* @brief 网格交集 A ∩ B
*
* 保留网格 A 中重心在网格 B 内的面片,
* 以及网格 B 中重心在网格 A 内的面片。
*
* @param a 网格 A
* @param b 网格 B
* @return A ∩ B 的交集网格
*
* @note 结果体积为两网格公共区域
*
* @see mesh_union, mesh_difference
*/
HalfedgeMesh mesh_intersection(const HalfedgeMesh& a, const HalfedgeMesh& b);
/// Difference: A B — keep A-faces outside B
/**
* @brief 网格差集 A B
*
* 保留网格 A 中重心在网格 B 外的面片,
* 以及网格 B 中重心在网格 A 内的面片(翻转法线)。
*
* @param a 网格 A
* @param b 网格 B
* @return A B 的差集网格
*
* @note 结果中来自 B 的面片会被翻转法线以保持内-外一致性
*
* @see mesh_union, mesh_intersection, mesh_sym_diff
*/
HalfedgeMesh mesh_difference(const HalfedgeMesh& a, const HalfedgeMesh& b);
/// Symmetric difference: (A B) (B A)
/**
* @brief 网格对称差 (A B) (B A)
*
* 等价于:
* @code{.cpp}
* mesh_union(mesh_difference(a, b), mesh_difference(b, a))
* @endcode
*
* @param a 网格 A
* @param b 网格 B
* @return 对称差网格
*
* @see mesh_difference, mesh_union
*/
HalfedgeMesh mesh_sym_diff(const HalfedgeMesh& a, const HalfedgeMesh& b);
/// ── Helpers ──────────────────────────────────────────────
// ── Helpers ─────────────────────────────────────────────────────
/// Crop mesh `a` by mesh `b`'s boundary: keep faces of `a` whose
/// centroids lie OUTSIDE the volume of `b`.
/// If `invert_b` is true, test against the flipped-volume (inside↔outside) of `b`.
/**
* @brief 用网格 B 裁剪网格 A
*
* 保留网格 A 中位于 B 体外的面片。
* 是 mesh_difference 的简化变体,仅输出来自 A 的面片。
*
* @param a 待裁剪网格
* @param b 裁剪体网格
* @param invert_b 若为 true,将 B 的内外判定取反(裁剪外部)
* @return 裁剪后的网格(仅包含 A 的面片)
*
* @code{.cpp}
* // 裁剪 cube 外部的 sphere 面片
* auto clipped = clip_mesh(sphere, cube, /*invert_b=*/false);
* // 保留 cube 内部的 sphere 面片
* auto inner = clip_mesh(sphere, cube, /*invert_b=*/true);
* @endcode
*
* @see mesh_difference, is_point_inside_mesh
*/
HalfedgeMesh clip_mesh(const HalfedgeMesh& a, const HalfedgeMesh& b,
bool invert_b = false);
/// Invert all face orientations in the mesh
/**
* @brief 翻转网格所有面片的法线方向
*
* 遍历所有面片,反转其顶点环绕顺序。
* 常用于生成负体积(反向外壳)或差集操作中。
*
* @param m 原始网格
* @return 法线翻转后的网格
*
* @see mesh_difference
*/
HalfedgeMesh invert_mesh(const HalfedgeMesh& m);
/// Merge two meshes into one (concatenate vertices and faces)
/**
* @brief 合并两个网格
*
* 将两个网格的顶点和面片直接拼接,不做布尔操作。
* 用于将分离的网格组件合并到单个数据结构中。
*
* @param a 网格 A
* @param b 网格 B
* @return 包含 A 和 B 全部顶点和面片的合并网格
*
* @note 不处理重叠区域;仅做纯几何拼接
*
* @see mesh_union(做布尔合并)
*/
HalfedgeMesh merge_meshes(const HalfedgeMesh& a, const HalfedgeMesh& b);
/// Convenience dispatcher — route by BooleanOp enum
/**
* @brief 网格布尔运算统一接口
*
* 根据布尔操作类型分发到对应的具体函数。
*
* @param a 网格 A
* @param b 网格 B
* @param op 布尔操作类型
* @return 结果网格
*
* @code{.cpp}
* auto result = mesh_boolean(cube, sphere, BooleanOp::Intersection);
* @endcode
*
* @see BooleanOp, mesh_union, mesh_intersection, mesh_difference, mesh_sym_diff
*/
HalfedgeMesh mesh_boolean(const HalfedgeMesh& a, const HalfedgeMesh& b, BooleanOp op);
/// ── Point classification ─────────────────────────────────
// ── Point classification ────────────────────────────────────────
/// Test whether point `p` is inside `mesh` using ray-casting
/**
* @brief 判断三维点是否在封闭网格内部
*
* 使用射线投射法:从点 p 向任意方向射出射线,
* 统计与网格面片的交点数量。
* 奇数表示在内部,偶数表示在外部。
*
* 算法:
* 1. 构造从 p 出发沿 +x 方向的射线
* 2. 遍历所有三角形进行射线-三角形求交
* 3. 统计交点数量
* 4. 返回奇偶性判定结果
*
* @param p 待判定点
* @param mesh 封闭网格
* @return 点在网格内部返回 true
*
* @note 网格必须是封闭(水密)的,否则结果不可靠。
* 点恰好落在面上时行为未定义。
*
* @see clip_mesh, mesh_difference
*/
bool is_point_inside_mesh(const core::Point3D& p, const HalfedgeMesh& mesh);
} // namespace vde::boolean
+42 -2
View File
@@ -1,3 +1,13 @@
/**
* @file polygon_offset.h
* @brief 多边形等距偏移 (Polygon Offset / Inset)
*
* 基于直骨架 (Straight Skeleton) 近似的多边形
* 膨胀/收缩操作。用于 2D 轮廓生成、刀具路径补偿等。
*
* @ingroup boolean
*/
#pragma once
#include "vde/core/polygon.h"
#include <vector>
@@ -6,8 +16,38 @@ namespace vde::boolean {
using core::Point2D;
using core::Polygon2D;
/// Offset a polygon by distance (positive = inflate, negative = deflate)
/// Uses straight skeleton approximation via edge normal displacement
/**
* @brief 多边形等距偏移
*
* 将多边形的每条边沿其法线方向平移指定距离,
* 在转角处自动生成圆弧/斜角连接。
*
* 算法:
* 1. 对每条边计算单位外法线
* 2. 沿法线平移 distance 距离
* 3. 相邻偏移边求交形成新的顶点
* 4. 检测自交并移除退化区域
*
* - 正距离 = 外扩(膨胀/Inflation
* - 负距离 = 内缩(偏置/Deflation
*
* @param poly 原始多边形
* @param distance 偏移距离(正=外扩,负=内缩)
* @return 偏移后的多边形列表(内缩或自交可能产生多个碎片)
*
* @note 使用直骨架近似而非精确圆弧偏移,转角处为斜角连接。
* 大距离负偏移可能导致多边形完全消失(返回空列表)。
*
* @code{.cpp}
* Polygon2D rect = {{0,0}, {10,0}, {10,5}, {0,5}};
* // 外扩 2 单位
* auto inflated = polygon_offset(rect, 2.0);
* // 内缩 1 单位(生成工具路径)
* auto toolpath = polygon_offset(rect, -1.0);
* @endcode
*
* @see boolean_2d
*/
std::vector<Polygon2D> polygon_offset(const Polygon2D& poly, double distance);
} // namespace vde::boolean