繁体   English   中英

确定矩形是否完全被另一组矩形覆盖所需的算法

[英]Algorithm required to determine if a rectangle is completely covered by another set of rectangles

我正在寻找一种算法,该算法将确定一个新矩形是否被一组现有矩形完全覆盖。 提出问题的另一种方法是,新矩形是否完全存在于现有矩形覆盖的区域?

似乎有很多算法来确定矩形重叠等等,但我找不到能解决这个问题的任何东西。

矩形将使用x,y坐标表示。 该问题涉及地理绘图。

编辑 - 来自OP发布的评论:

矩形在X / Y轴上对齐

如果矩形对齐很容易:

假设您有矩形A0并想知道它是否被(B1,B2,B3 ......)完全覆盖= B

A := (A0)
while P := pop B
  for R in A
    if P fully covers R:
      remove R from A
    else if P and R does overlap:
      remove R from A
      break R in subrentangles S := (S1, S2, S3,...) following the intersections \
                                                     with P edges
      push S into A
if A is empty:
   say B covers A0
else:
   say B does not fully cover A0

如果矩形都具有相同的角度; 然后以下可能会更有效,更容易编程:

确定矩形覆盖y坐标的每个y坐标(您只需对覆盖变化的y坐标执行此操作;即对应于矩形的上限或下限)。 一旦你知道了,解决每个这样的y坐标的问题(即检查所有x值是否被该Y坐标“活动”的矩形覆盖)。

编辑:我认为这是O(n ^ 2 log(n)^ 2)的复杂性,因为两种类型都是你需要做的艰苦工作

我过去做过类似的事。 我的想法是将新矩形与现有的每个矩形进行比较(逐个)

如果有一个交叉点丢弃它(相交的部分),并将未覆盖的段添加到矩形数组中

接下来,搜索新段与其他现有(仍未检查)矩形之间的交集。

算法递归地丢弃交叉点,只留下未覆盖的部分。

最后,如果数组中没有矩形,则表示完全重叠

如果阵列中仍有一些矩形,则重叠不完整,因为仍有一些部分留下。

希望这可以帮助

如果这是您正在寻找的,我可以尝试找到我的代码。 我认为它在C#

另一个想法是将所有现有的矩形转换为多边形,然后检查新的矩形是否在多边形内部,但如果您没有使用知道如何使用多边形的语言(或框架),我不建议这样做。

R树可能很有用。 如果可能有旋转的矩形,则可以将它们包含在边界矩形中。

试试这个

源矩形:X0,Y0,宽度,高度

//基本上比较边缘

if(((X0> = xi)&&(X0 + breadth <= Xi))&&((Y0> = Yi)&&(Y0 + height <= Yi)){//考虑矩形} else {// discard}

这是我的代码,正如您所要求的:

第一种方法是“减去”(返回未覆盖的部分)的2个矩形。

第二种方法从基本矩形中减去矩形列表。

在您的案例列表中包含现有的矩形,新的矩形是基础

检查是否存在完整的交集,从第二个方法返回的列表应该没有元素。

public static List<Rectangle> SubtractRectangles(Rectangle baseRect, Rectangle splitterRect)
    {
        List<Rectangle> newRectaglesList = new List<Rectangle>();

        Rectangle intersection = Rectangle.Intersect(baseRect, splitterRect);
        if (!intersection.IsEmpty)
        {
            Rectangle topRect = new Rectangle(baseRect.Left, baseRect.Top, baseRect.Width, (intersection.Top - baseRect.Top));
            Rectangle bottomRect = new Rectangle(baseRect.Left, intersection.Bottom, baseRect.Width, (baseRect.Bottom - intersection.Bottom));

            if ((topRect != intersection) && (topRect.Height != 0))
            {
                newRectaglesList.Add(topRect);
            }

            if ((bottomRect != intersection) && (bottomRect.Height != 0))
            {
                newRectaglesList.Add(bottomRect);
            }
        }
        else
        {
            newRectaglesList.Add(baseRect);
        }

        return newRectaglesList;
    }

    public static List<Rectangle> SubtractRectangles(Rectangle baseRect, List<Rectangle> splitterRectList)
    {
        List<Rectangle> fragmentsList = new List<Rectangle>();
        fragmentsList.Add(baseRect);

        foreach (Rectangle splitter in splitterRectList)
        {
            List<Rectangle> toAddList = new List<Rectangle>();

            foreach (Rectangle fragment in fragmentsList)
            {
                List<Rectangle> newFragmentsList = SubtractRectangles(fragment, splitter);
                toAddList.AddRange(newFragmentsList);
            }

            if (toAddList.Count != 0)
            {
                fragmentsList.Clear();
                fragmentsList.AddRange(toAddList);
            }
        }

        return fragmentsList;
    }

您可以使用用于计算矩形的并集区域的算法。 如您要检查矩形a是否被矩形B = {b_1,b_2,...,}覆盖。

首先计算B中矩形的联合区域,我们得到area_1作为值。

然后你计算B + {a}中矩形的联合区域,我们得到area_2作为值。
因此,如果area_1 == area_2,那么您确定矩形a被矩形B覆盖。否则,答案是错误的。

所以主要问题是如何计算矩形的联合面积。 这个问题可以通过现有的优秀算法来解决。 该算法可以简要介绍为首先对矩形点的值进行离散化,然后使用分割树来加速每个块的面积计算。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM