docs: doxygen annotations for spatial + boolean + collision
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user