【问题标题】:How to get the closest Axis-Aligned Bounding Box to a point?如何让最近的轴对齐边界框到一个点?
【发布时间】:2022-01-09 19:28:21
【问题描述】:

我有一大堆 Axis-Aligned Bounding Boxes,我试图从一个点到最近的一个点的欧几里得距离,我试过曼哈顿距离,但它似乎与“蛮力”不匹配通过用欧几里德距离迭代所有这些结果。有什么有效的方法吗? 干杯

【问题讨论】:

  • 我编辑了您的问题以消除混淆的首字母缩写词。
  • 到最近的角落还是最近的盒子?
  • 最近的盒子@Neil

标签: algorithm shader raytracing raymarching


【解决方案1】:
  • 在您的输入框上构建一个 BVH(边界体积层次结构)。
  • 通过这个BVH递归遍历一个点:在每一步
    • 如果节点是叶子:
      • 计算这片叶子中点到框的距离
      • 跟踪找到的最近路口
    • 其他
      • 计算点到每个孩子的距离
      • (可选但推荐:)按距离对子项进行排序
      • 如果子距离>最近找到的距离:剔除它;
      • 否则:递归到那个孩子

计算点P和框B之间的(欧几里得)距离:

  • 计算点 PB 在最接近 P 的框中:PB = min(max(P,B.lower),B.upper)
  • 将P 的欧几里得长度返回到PB:return length(P-PB)

在这些盒子上构建 BVH:只是其中一种选择:Embree 确实有一个界面可以在盒子上构建 BVHe,并查询结果。

【讨论】:

    【解决方案2】:

    我提出以下解决方案。您有如下 5 个矩形,您的点 P 位于 (7,4)

    如果您构建两个按水平边缘和垂直边缘排序的排序列表,您将得到:

    List1 (Horizontal)
    0  ((4,0),(8,0))->Rec5       index 0
    1  ((4,1),(8,1))->Rec5       index 1
    2  ((4,2),(6,2))->Rec1       index 2
    3  ((8,3),(9,3))->Rec3       index 3
    4  ((4,4),(6,4))->Rec1       index 4
    4  ((10,4),(13,4))->Rec4     index 5
    5  ((1,5),(6,5))->Rec2       index 6
    6  ((10,6),(13,6))->Rec4     index 7
    7  ((8,7),(9,7))->Rec3       index 8
    8  ((1,8),(6,8))->Rec2       index 9
    
    List2 (Vertical)
    1  ((1,5),(1,8))->Rec2       index 0
    4  ((4,0),(4,1))->Rec5       index 1
    4  ((4,2),(4,4))->Rec4       index 2
    6  ((6,2),(6,4))->Rec1       index 3
    6  ((6,5),(6,8))->Rec2       index 4
    8  ((8,0),(8,1))->Rec5       index 5
    8  ((8,3),(8,7))->Rec3       index 6
    9  ((9,3),(9,7))->Rec3       index 7
    10 ((10,4,(10,6))->Rec4      index 8
    13 ((13,4,(13,6))->Rec4      index 9
    

    现在您可以在 Py = 4 上的水平列表上进行二进制搜索。这是您在两个方向上向外工作的起始索引。 Px = 7 也是如此。

    在您的水平列表中,您会发现 H_index = 4 (Rec1)

    在您的垂直列表中,您会发现 V-Index = 4 (Rec2)

    还没有匹配,将一个移出中心向所有方向(重复此步骤直到匹配一个)

    H_index = 3 (Rec3)
    H_index = 5 (Rec4)
    V_index = 3 (Rec1)
    V_index = 5 (Rec5)
    

    我们有一个匹配->Rec1 (H_index = 4, V_index = 3)

    如果你想找到所有的平等,你还没有完成。

    Px 和 rec1 之间的 x 距离 = 1。您需要在此限制内包含所有 Rectangles。

    UpperLimit = 7 + 1 = 8
    LowerLimit = 7 - 1 = 6
    

    这使 V_index 为 3 到 8。对于它们中的每一个,检查 Py 是否介于或等于该行的 y 值。

    6  ((6,2),(6,4))->Rec1       index 3      YES
    6  ((6,5),(6,8))->Rec2       index 4      NO
    8  ((8,0),(8,1))->Rec5       index 5      NO
    8  ((8,3),(8,7))->Rec3       index 6      YES
    

    所以 Rec3 也被认为是一种解决方案

    Py 和 rec1 之间的 y 距离 = 0。您需要在此限制内包含所有 Rectangles。

    UpperLimit = 4 + 0 = 4
    LowerLimit = 4 - 0 = 4
    

    这使 H_index 为 4 到 5。为每个检查 Px 是否介于或等于行的 x 值。

    4  ((4,4),(6,4))->Rec1       index 4     NO
    4  ((10,4),(13,4))->Rec4     index 5     NO
    

    没有找到其他解决方案,我们完成了:Rec1 和 Rec3 最接近。

    此解决方案对于多达 100.000 个矩形来说足够快。当你谈论 milj.矩形,您将需要使用线段树。

    【讨论】:

    • 非常智能的解决方案,非常感谢!! “向外工作”方法是否有特定名称?因为我已经可以为它想到一堆用于多维数据的用例。干杯!
    • 我不知道它是否有名字,我只是认为通过向外工作在两个维度上找到匹配项是有意义的。就像你一样,我也得出结论,这也适用于 3d 空间。我喜欢你喜欢它,请将答案标记为已回答并投票:-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-10
    • 1970-01-01
    • 2022-11-12
    • 2011-05-10
    相关资源
    最近更新 更多