BambuStudio学习笔记:KDTreeIndirect类
# KDTreeIndirect.hpp 代码分析
## 核心组件
### KDTreeIndirect 类模板
```cpp
template<size_t ANumDimensions, typename ACoordType, typename ACoordinateFn>
class KDTreeIndirect {
// 构建参数
CoordinateFn coordinate; // 外部坐标获取函数
std::vector<size_t> m_nodes; // 平衡二叉树的数组存储
};
- 三维特性:
- 维度数通过模板参数ANumDimensions指定
- 支持任意数值类型(CoordType)
- 通过函数对象获取坐标值,实现数据解耦
关键方法
方法 | 功能说明 | 时间复杂度 |
---|---|---|
build() | 构建平衡KD树 | O(n log n) |
partition_input() | 快速选择算法划分数据 | 平均O(n) |
visit() | 访问者模式遍历树节点 | O(log n) ~ O(n) |
算法实现
树构建流程
- 内存优化:使用
next_highest_power_of_2
预分配空间 - 维度循环:每次递归切换分割维度
最近邻搜索
template<size_t K, typename PointType, typename FilterFn, ...>
std::array<size_t, K> find_closest_points(...)
- 核心机制:
- 维护Top-K最近点列表
- 动态剪枝搜索路径(通过descent_mask)
- 性能特征:
- 最佳情况:O(log n)
- 最差情况:O(n)
关键设计特点
-
数据解耦:
- 不存储实际坐标数据
- 通过索引+坐标函数访问数据
- 优势:支持大规模动态数据
-
空间划分策略:
void partition_input(...) { // 三数取中法选择pivot // 快速选择算法划分数据集 }
- 保证树的近似平衡
- 避免最差情况下的性能下降
-
访问者模式扩展:
template<typename Visitor> void visit(Visitor &visitor) const
- 支持多种查询类型(最近邻/范围查询)
- 用户自定义过滤条件(FilterFn)
典型应用场景
3D打印路径优化
// 创建KD树
KDTreeIndirect<3, double, CoordinateFn> tree(coordinate_fn);
tree.build(points.size());
// 查找最近5个点
auto closest = find_closest_points<5>(tree, query_point);
碰撞检测
// 查找半径10mm内的所有点
auto nearby = find_nearby_points(tree, center, 10.0);
性能优化点
- 内存布局:使用连续数组存储树节点,提升缓存命中率
- 距离计算:使用平方距离避免开方运算
- 分支剪枝:通过descent_mask减少不必要的子树访问
潜在改进方向
-
批量查询优化:
- 实现多查询点的并行处理
- 缓存重用树遍历路径
-
动态更新支持:
- 增量式树更新算法
- 支持插入/删除操作
-
近似算法扩展:
- 添加epsilon参数控制近似度
- 实现ANN(Approximate Nearest Neighbor)功能
接口扩展性
// 自定义过滤条件示例(排除奇数索引)
auto filtered = find_closest_points<5>(tree, point, [](size_t idx){
return (idx % 2) == 0;
});
// 立方体区域查询
vector<size_t> in_cube = find_nearby_points(tree, bb_min, bb_max);
注意事项
- 坐标函数要求:必须实现
CoordType operator()(size_t idx, size_t dim)
- 模板实例化:高维场景可能增加编译后代码体积
- 浮点精度:比较运算需考虑EPSILON容差