16个版本
0.6.1 | 2024年7月18日 |
---|---|
0.6.0 | 2023年8月3日 |
0.5.1 | 2023年4月30日 |
0.5.0 | 2022年7月22日 |
0.3.1 |
|
#302 in 算法
每月64次下载
38KB
644 行
flat_spatial
flat_spatial是一个用于动态空间划分结构(不是基于树(递归)的,而是基于简单的平面结构,如单元格网格(也称为存储单元))的crate。
使用网格或其他平面结构可以非常快地更新(常量时间)和查询,前提是单元格大小适应问题。
选择正确的单元格大小非常重要
- 如果单元格大小太小,网格将太细,查询将变慢,因为需要迭代所有匹配的单元格。
- 如果单元格大小太大,网格将太粗,查询将变慢,因为需要迭代所有匹配的对象。
尽量选择一个单元格大小,使每个单元格平均有10-20个对象。请注意,空单元格不会消耗任何内存,但它们确实会消耗一些查询时间,因为我们需要检查它们是否存在。
MSRV: 1.60
网格
网格的想法是有一个HashMap的单元格,存储插入对象的位...
执行查询就像查找受影响的单元格并返回其关联的对象一样简单。
由于它非常简单,因此网格支持动态功能,如基于句柄的位置更新或对象删除(使用slotmap
)。位置更新是懒惰的,以提高性能,因此需要调用maintain()来更新网格。
建议查询的大小与单元格大小大致相同。
AABBGrid
aabbgrid就像一个网格,但它存储轴对齐的边界框(AABB)而不是位置。它作为HashMap的单元格实现,存储接触到的AABB。对于每个接触单元格的AABB,它被添加到单元格中。尽量保持aabb大小尽可能小。
添加/更新/删除不是懒惰的,不需要调用maintain。
示例
这里是一个非常基本的网格示例
fn main() {
use flat_spatial::Grid;
let mut g: Grid<(), [f32; 2]> = Grid::new(10);
let a = g.insert([3.0, 3.0], ());
let _b = g.insert([12.0, -8.0], ());
let around: Vec<_> = g.query_around([2.0, 2.0], 5.0)
.map(|(id, _pos)| id)
.collect();
assert_eq!(vec![a], around);
}
依赖项
~0.3–1.5MB
~30K SLoC