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

时间:2010-12-09 10:31:46

标签: algorithm mapping overlap

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

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

矩形将使用x,y坐标表示。这个问题与地理地图有关。

修改 - 来自OP发布的评论:

  

矩形在X / Y轴上对齐

7 个答案:

答案 0 :(得分:7)

如果矩形对齐很容易:

假设您有矩形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

答案 1 :(得分:3)

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

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

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

答案 2 :(得分:2)

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

答案 3 :(得分:1)

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

进行比较

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

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

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

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

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

希望这会有所帮助

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

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

答案 4 :(得分:1)

试试这个

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

//基本上比较边

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

答案 5 :(得分:1)

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

第一个方法是“减去”(返回未覆盖的部分)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;
    }

答案 6 :(得分:0)

您可以使用用于计算矩形的联合区域的算法。如您要检查矩形a是否被矩形B = {b_1,b_2,...,}覆盖
首先计算B中矩形的联合区域,我们得到area_1作为值
然后你计算B + {a}中矩形的联合区域,我们得到area_2作为值 因此,如果area_1 == area_2,那么您确定矩形a被矩形B覆盖。否则,答案是错误的。

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