哪个数据结构适合查询“距离点p的距离d内的所有点”

时间:2009-08-23 13:46:38

标签: data-structures 3d geometry distance spatial

我有一个3D pointcloud,我想从任意点p(不一定是存储的pointcloud的一部分)中有效地查询距离d内的所有点。

查询看起来像

Pointcloud getAllPoints(Point p, float d);

什么加速结构适合这个?范围树似乎仅适用于查询矩形体积,而不是球体体积(当然,我可以查询球体的边界框,然后整理距离大于d的所有顶点 - 但也许有更好的方法可以做到此??)

谢谢!

根据Novelocrats的建议,我尝试定义结构的所需功能:

SearchStructure Create(Set<Point> cloud) 
Set<Point> Query(SearchStructure S, Point p, float maxDistance)
SearchStructure Remove(Point p)
SearchStructure Insert(Point p)
SearchStructure Displace(Set<Point> displacement) //where each value describes an offsetVector to the currently present points

通常,在n个查询之后,这些点会被取代,并且会进行一些(不是很多!)插入和删除。与所有点的边界框相比,偏移向量非常小

6 个答案:

答案 0 :(得分:6)

您想要的是一种分解空间的结构,以便有效地找到特定区域。正确分解的八叉树 kD-tree 应该可以让您做得很好,因为您只需“打开”包含您的点p的树的部分寻找附近的点。这应该让你在比较距离所需的额外点数上设置一个相当低的渐近界限(知道在某种程度的分解下,所有点都足够接近)。不幸的是,我不清楚这个领域的文献是否足以提供更详细的指示。我遇到这些事情来自Barnes-Hut n-Body模拟算法。

这里another question与此密切相关。 并且another。 并且a third,提到了我之前从未听说过的数据结构(Hilbert R-Trees)。

答案 1 :(得分:2)

VTK可以提供帮助:

void vtkAbstractPointLocator::FindPointsWithinRadius (
double R, double x, double y, double z, vtkIdList * result
)

vtkAbstractPointLocator的子类包含不同的搜索加速数据结构:常规存储桶,kd树和八叉树。

答案 2 :(得分:1)

我不了解您的API,您可以将位于任意球体内的PointCloud中的所有点对齐,但是您还说存储了点云?在这种情况下,你不应该得到一个在给定的球体内的PointClouds列表,否则存储PointClouds的重点是什么(借口双关语)?

不要事先尝试定义API,而是在需要时定义它。没有必要实现永远不会被使用的东西,更不用说优化永远不会被调用的函数(除非它当然是有趣的:))。

我认为你应该实现边界框剔除,然后将更详细的球体搜索作为第一个实现。也许它不像你想象的那样是瓶颈,也许你会有更严重的瓶颈需要考虑。当您真正看到所有事情都按照您的计划进行时,总是可以进行优化。

答案 3 :(得分:1)

看看A Template for the Nearest Neighbor Problem (Larry Andrews at DDJ)。它只有2D,具有O(log n)的检索复杂度,但也可以用于3D。

答案 4 :(得分:0)

使用等于距离的值的地图和作为点本身的值将允许您查询小于给定距离或在给定范围内的所有点。

答案 5 :(得分:0)

嗯,这取决于您对数据结构所需的其他用途。

您可以列出从点p到其他点的距离,按距离排序,并将这些列表映射到带有散列图的点。

map:
p1 -> [{p2, d12}, {p4, d14}, {p3, d13}]
p2 -> ...
...

您可以在地图中查找该点,并迭代列表,直到距离高于所需距离。