1

我正在寻找一种可以找到相互重叠的相交矩形的算法。

问题是我的数据结构类似于带有边界框而不是点的四叉树。我正在做一个基本的矩形相交检查,但问题是当我放大树时,检测到子节点和父节点,如果父节点完全被给定相机矩形的子节点遮挡,我想排除父节点。

缩放动画

正如您从上图中看到的,当相机矩形(黑框)位于绿色节点内时,紫色节点仍然突出显示(填充),因此随着我越来越放大,父母总是突出显示,即使相机矩形可以仅用子节点完全填充。

这是有道理的,因为相机矩形仍在父级内部,但我已经搜索并考虑了一段时间,似乎无法找到一个优雅的解决方案。对于 3D 空间,似乎有几种方法可以做到这一点,但对于 2D AABB 矩形,我找不到任何简单的方法。

我想到的几个解决方案:

  • 从父节点中减去子节点,得到凹多边形,然后执行多边形相交。
  • 使用填充颜色检查哪些矩形是可见的,因此会遮挡后面的矩形。
  • 执行光线投射或细分并检查给定部分的最小节点。

有一个更好的方法吗?谢谢

更新 1

我已经通过将相机细分为更小的部分来解决这个问题,并且对于每个部分都找到了最小的相交节点。这可行,但必须有一种更有效和更清洁的方式来做到这一点。

更新 2

感谢 Trentium 的回答。我可以清楚地看到,像这样的算法会比我目前正在做的更高效。

最终我会将它实现为将一个矩形分割成更小的矩形,而不是多边形,这听起来像是一个有趣的挑战。

此外,我对当前方法做了一些非常不科学的基准测试,过滤和绘制所有内容需要 0.5ms-1ms,所以现在性能仍然不是问题。

4

1 回答 1

0

建议考虑您提出的第一个解决方案的变体“从父节点中减去子节点,从而产生凹多边形,然后执行多边形相交。”

具体来说,如果直接子级完全包含在父级中,则建议对于每个矩形,还维护一个相关联的可见剩余矩形数组。然后使用这个剩余矩形数组作为确定相机/视口矩形是否包含父级的手段。

例如,假设父矩形是 (0,0) - (100,100),并且在 (75,75)-(100,100) 处添加了一个初始子矩形。数据结构将显示为...

  • 父矩形 = {0,0,100,100}
  • parent.visible = [ {0,0,100,75}, {0,75,75,100} ]
  • child1.rectangle = {75,75,100,100}
  • child1.visible = [ {75,75,100,100} ]

在此处输入图像描述 ...然后如果出现第二个孩子,例如在 {50,50,75,90},则根据parent.visible数组中的每个剩余矩形检查这个新孩子,并根据需要进一步细分父可见矩形...

  • 父矩形 = {0,0,100,100}
  • parent.visible = [ {0,0,100,50},{0,50,50,75},{75,50,100,75},{0,75,50,100},{50,90,75,100} ]
  • child1.rectangle = {75,75,100,100}
  • child1.visible = [ {75,75,100,100} ]
  • child2.rectangle = {50,50,75,90}
  • child2.visible = [ {50,50,75,90} ]

此方法会在添加子项时预先调整直接父项的可见矩形,但相对于涉及摄像机/视口细分的当前算法,应该会大大减少矩形相交测试的数量。此外,这个提议的算法仅使用矩形到矩形的相交测试(在将孩子添加到父级时,以及在测试相机/视口相交时!)而不是建议的矩形到多边形测试......

于 2021-09-03T22:42:10.747 回答