【问题标题】:Quadtrees: a common intersect method failing to handle a simple case四叉树:一种常见的相交方法无法处理简单的情况
【发布时间】:2016-08-13 20:00:20
【问题描述】:

我正在编写一个简单的 GUI 库并使用四叉树来确定在鼠标事件期间与哪些对象进行交互(如果有)。我在 github 上浏览了许多四叉树库,它们都包含一种将矩形对象添加到四叉树的方法。 在所有情况下,该方法都只是检查矩形是否与给定的四叉树相交:

return quadtree.x2 >= rect.x1
    and quadtree.x1 <= rect.x2
    and quadtree.y2 >= rect.y1
    and quadtree.y1 <= rect.y2

但是,这会在最简单的情况之一中产生不希望的结果:想象一个 100x100 的正方形区域。我将四个 50x50 的正方形对象放入坐标为 (0,0)、(0,50)、(50,0) 和 (50,50) 的区域中。如果将这些对象放入最大容量为一个对象的 100x100 四叉树中,我会(视觉上)期望四叉树的第一层会分裂,并且生成的四棵树将分别包含一个正方形。

如果我使用上述方法来确定将方块放入哪棵树,我发现每个对象都与所有四棵树相交。这将导致每棵树快速分裂,直到达到最大深度。

我认为避免这种情况的唯一方法是使用两个检查:

return (quadtree.x2 > rect.x1
    and quadtree.x1 < rect.x2
    and quadtree.y2 > rect.y1
    and quadtree.y1 < rect.y2)
    or (quadtree.x2 == rect.x1
    and quadtree.x1 == rect.x2
    and quadtree.y2 == rect.y1
    and quadtree.y1 == rect.y2)

(在最简单的情况下。较大的对象必须在边界框中查看,例如,坐标为 (0,0)、w=100、h=100 的对象将属于左上角四叉树也是。)

我还可以计算矩形和四叉树之间的重叠,看看它是否非零。

我错过了什么吗?看起来这应该是四叉树的理想情况,但是,在大多数实现中,它是一个巨大的混乱。

【问题讨论】:

    标签: intersection rectangles quadtree


    【解决方案1】:

    我不会将此称为理想情况,因为四个矩形重叠了一小部分。例如,如果我们假设(虚构)浮点精度为 10^(-10),则每个“点”实际上是一个长度为 10^(-10) 的小矩形,因此矩形重叠 10^(-10) .这就是你得到深树的原因。

    但我也认为可以通过稍微修改重叠检查来改进树。使用您的代码,子节点都会有少量重叠。排除最小值(或最大值)会更好,例如:

    return quadtree.x2 >= rect.x1
        and quadtree.x1 < rect.x2
        and quadtree.y2 >= rect.y1
        and quadtree.y1 < rect.y2
    

    所以一个节点的左下角坐标实际上是在那个节点的外面。这样至少可以避免点在多个节点中出现(比如点(50,50)),并且左下角的矩形只存储在一个节点中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-08
      • 1970-01-01
      • 1970-01-01
      • 2012-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多