BambuStudio学习笔记:VoronoiUtils

# Geometry::VoronoiUtils 类概述

本模块提供Voronoi图处理工具集,主要用于处理基于线段生成的Voronoi图元数据,支持单元格范围遍历、抛物线离散化等操作。关键功能包括:

- **Voronoi单元格分析**:计算围绕线段的梯形单元格范围
- **几何转换工具**:坐标类型转换与范围校验
- **抛物线离散化**:将Voronoi抛物线边转换为折线近似
- **源数据回溯**:通过Voronoi单元反向定位输入几何元素

---

## 核心数据结构

### `SegmentCellRange<PT>`
```cpp
template<typename PT> struct SegmentCellRange {
    const PT             segment_start_point;  // 源线段的起点
    const PT             segment_end_point;    // 源线段的终点
    const VD::edge_type *edge_begin;           // 单元格遍历起始边
    const VD::edge_type *edge_end;             // 单元格遍历终止边

    bool is_valid() const; // 验证范围有效性
};
  • 作用:表示围绕输入线段的梯形Voronoi单元格边界
  • 应用场景:遍历单元格周边边时作为迭代范围容器

静态工具类 VoronoiUtils

基础转换方法

static Vec2i64 to_point(const VD::vertex_type *vertex); // 顶点坐标转64位整型
static bool is_finite(const VD::vertex_type &vertex);   // 判断顶点是否有限
  • 实现细节:处理Boost.Polygon的double精度坐标到整型的转换

几何变换

static VD::vertex_type make_rotated_vertex(VD::vertex_type &vertex, double angle);
  • 功能:创建旋转后的顶点副本
  • 参数angle为弧度制的旋转角度

源数据回溯

template<typename SIter> 
static auto get_source_segment(...); // 获取生成该单元的源线段

template<typename SIter>
static auto get_source_point(...);  // 获取生成该单元的源端点

template<typename SIter>
static auto get_source_point_index(...); // 获取带索引的源点
  • 核心逻辑:通过cell.source_index()反向查找输入线段集合中的对应元素

抛物线离散化

template<typename Segment>
static Points discretize_parabola(...);
  • 参数
    • source_point:抛物线焦点(输入线段端点)
    • source_segment:输入线段
    • start/end:抛物线起止点
    • approximate_step_size:沿线段方向的离散步长
  • 输出:离散化后的点序列

单元格范围计算

template<typename SIter>
static SegmentCellRange<...> compute_segment_cell_range(...);
  • 流程
    1. 通过cell.incident_edge()遍历关联边
    2. 过滤有效边建立循环范围
    3. 返回包含源线段信息的SegmentCellRange

数值范围校验

template<typename T> static bool is_in_range(double value);
template<typename T> static bool is_in_range(const VD::vertex_type &vertex);
template<typename T> static bool is_in_range(const VD::edge_type &edge);
  • 作用:验证坐标是否在目标类型(T)的可表示范围内
  • 特化应用:防止整型溢出时使用

关键技术点

Voronoi单元格遍历

  • 双指针标记法edge_beginedge_end定义半开区间[begin, end)
  • 循环终止条件:通过next->twin()->next()链式遍历直到回到起点

抛物线近似算法

  • 自适应步长:根据transitioning_angle动态调整离散密度
  • 几何变换:将抛物线方程转换为参数形式计算采样点

类型安全处理

  • SFINAE约束:通过boost::polygon类型特征确保模板参数符合线段概念
  • 坐标溢出防护is_in_range<T>模板方法实现编译期类型安全检查

典型应用流程

  1. 获取单元格源数据
auto& cell = vd.cells()[0];
auto src_segment = VoronoiUtils::get_source_segment(cell, lines.begin(), lines.end());
  1. 计算单元格边界范围
auto range = VoronoiUtils::compute_segment_cell_range(cell, lines.begin(), lines.end());
for (auto* edge = range.edge_begin; edge != range.edge_end; edge = edge->next()) {
    // 处理每个边界边
}
  1. 离散化抛物线边
Points discretized = VoronoiUtils::discretize_parabola(
    source_point, source_segment, 
    start_point, end_point, 
    0.1mm, 15.0f);
  1. 坐标安全转换
if (VoronoiUtils::is_in_range<int32_t>(vertex)) {
    Point pt = VoronoiUtils::to_point(vertex).cast<int32_t>();
}

性能优化策略

  • 惰性计算compute_segment_cell_range仅在需要时遍历边
  • 内存预判discretize_parabola通过角度预判分配点容器大小
  • 分支预测is_finite快速过滤无限顶点避免复杂计算
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值