矩形边界内的有效点搜索

时间:2011-05-15 08:40:08

标签: algorithm data-structures geometry computational-geometry vector-graphics

我正在使用矢量地图编辑器,我有一组元素,每个元素都在视图中指定其边界框。当鼠标移动时,我想突出显示第一个元素,其边界框包含当前鼠标位置。现在我使用一个简单的列表并通过它,但由于元素的数量可能会增加,当前搜索算法的O(n)复杂性对于交互式应用程序将是有问题的。

什么是更好的算法/数据结构?

一些额外的约束/要求

  • 边界框数据结构的填充必须相对较快(因为每次地图移动或缩放或投影发生变化时我都需要这样做。)
  • 算法必须能够找到匹配元素的全部(而不仅仅是第一个)。原因是一些地图元素可能具有不规则的形状,因此简单的边界框匹配不够严格。然后我会浏览匹配列表并进行精确匹配。
  • 顺序,其中框已添加到集合需要以某种方式维护 - 在另一个元素上方绘制的地图元素在匹配时应具有优先级边界框。

3 个答案:

答案 0 :(得分:5)

在浏览书籍后,我在Computational Geometry书中找到了一个答案(第3页,第3页,第2页, rd ; 2008)。此类搜索通常称为刺入查询,通常使用 segment trees 来实施。

复杂性:

  • 查询:O(log2n + k),其中k是报告的边界框数
  • 数据结构使用O(n * log n)存储
  • 结构可以在O(n * log n)时间内构建

答案 1 :(得分:1)

如果按较低的x位置对元素进行排序,则可以在某个点之前跳过所有元素。如果你有第二个列表,上面有x位置,你知道什么时候完成。

另一个想法:创建网格可能会将整个区域分成100x100个部分。现在找到一次,你的网格中哪个部分的数字是重叠的:

5
4
3    xx 
2  xxxx
1  xx
0
 0 1 2 3 4 5 

对于这个数字,它将是(1,1),(1,2)(2,2)(2,3) x * y列表的地图现在将包含4个位置(1,1) - > s,(1,2) - > s,...的

的形状

如果您很少插入/删除,但经常进行比较,这会加快您的搜索速度。您只能访问与特定单元格关联的形状,并调查这些形状的确切坐标。

答案 2 :(得分:1)

查找表:用户往往会回到屏幕上的相同区域(因此边距访问率通常很低,中心访问率通常很高)。所以我们可以利用这些知识来改善我们的表现。 在找到一个点之后(可以是任何其他查找方法),您可以将结果缓存为列表,下次用户访问同一个地点时,查找将为O(1)。当然,一旦添加了新形状,您将需要转储缓存。
另一种可能性是使用Observer Pattern,每个新形状都会在需要的点上注册(这可能很昂贵,这取决于插入频繁的形状...)和鼠标一旦在这一点上,所有它要做的就是打电话给那些注册的人。

第三种可能性当然是像@user unknown所建议的那样削减你的搜索区域。这种可能性可以与查找表结合使用。