找出点是否在小于O(N)的N(可能重叠)矩形之一内

时间:2013-05-16 09:37:43

标签: c++ algorithm

我有一张图片,我想在鼠标移动到某些矩形区域时显示工具提示。矩形区域最多可以为1000.但是,只要检查每个矩形(如果该点在其中,即O(N)),则在移动鼠标时会使界面无响应。

有没有办法在低于O(N)的情况下做到这一点?我可以预先对矩形进行排序(我假设它是需要的)。矩形可能(很少)重叠,但不超过4-5个矩形可以重叠在同一区域。在这种情况下,我可能需要获得所有矩形的列表,但即使只是其中任何一个矩形仍然足够好。

但我假设这个问题已经由窗口管理员等解决了。

4 个答案:

答案 0 :(得分:7)

听起来你想将你的矩形存储在R-Tree中,然后查询它。有一些实现可用:

查看他们的STRtree课程。

答案 1 :(得分:2)

比图像树(以及可以渲染到相当小的图像上的网页)更快更简单(虽然内存效率更低)的方法是使用模板。即如果你有一个x乘y像素的图像,则创建一个x乘y的二维数组,并用你的工具提示ID填充它。这具有从像素位置到ID为O(1)(我最喜欢的O)的搜索速度

答案 2 :(得分:1)

使用空间搜索数据结构,例如the quad-tree

您需要事先将矩形添加到树中,但平均搜索速度会很快。在最坏的情况下,你可能仍然有O(N)。

答案 3 :(得分:1)

如果矩形是轴对齐的,则可以避免使用专门的数据结构。

首先在一个维度中细分空间,例如将屏幕水平细分为垂直条带。每个矩形可以是多个条带。然后根据与该条带重叠的矩形细分每个条带。然后搜索涉及两个O(log n)二进制搜索或二叉树 - 一个用于识别条带,一个用于识别哪个矩形。

这个 是一个公认的空间数据结构,但对我来说它实际上并不重要 - 它只是使用普通的二叉树。您甚至可以使用std::map<int, std::map<int, int>>

但实际上有一个支持O(1)搜索的选项,称为“像素选择”。基本上,在屏幕外的位图中绘制矩形,每个矩形使用不同的颜色,最前面的矩形像普通绘图一样(画家算法)。您可以通过简单地读取该像素来识别任何点的最前面的矩形。

额外奖励 - 您的图形卡甚至可以加速绘制矩形,因此当矩形集变化时(显然不包括在O(1)中),您不必过于担心重绘。它的内存有点贵,但在现代机器上,你可能并不关心它。