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

Algorithm 确定一个矩形是否完全被另一组矩形覆盖所需的算法,algorithm,mapping,overlap,Algorithm,Mapping,Overlap,我正在寻找一种算法,该算法将确定一个新矩形是否完全被一组现有矩形覆盖。提出这个问题的另一种方式是,新矩形是否完全存在,而现有矩形所覆盖的区域是否完全存在 似乎有很多算法来确定矩形重叠等,但我真的找不到任何解决这个确切问题的方法 矩形将使用x、y坐标表示。这个问题与地理制图有关 编辑-根据OP发布的评论: 矩形在X/Y轴上对齐 我过去也做过类似的事情。 其想法是将新矩形与现有矩形进行比较(一个接一个) 如果存在交点,则放弃该交点(相交部分),并将未覆盖的线段添加到矩形阵列中 接下来,搜索新线段与其

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

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

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

编辑-根据OP发布的评论:

矩形在X/Y轴上对齐


我过去也做过类似的事情。 其想法是将新矩形与现有矩形进行比较(一个接一个)

如果存在交点,则放弃该交点(相交部分),并将未覆盖的线段添加到矩形阵列中

接下来,搜索新线段与其他现有(仍未选中)矩形之间的交点

执行递归算法,丢弃交点,只留下未覆盖的部分

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

如果阵列中仍有一些矩形,则重叠部分未满,因为仍有一些部分剩余

希望这有帮助

我可以尝试找到我的代码,如果这是你正在寻找的。我想是C语言#


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

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

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


编辑:我认为这是O(n^2 log(n)^2)的复杂性,因为有两种类型是您必须做的所有艰苦工作

如果矩形对齐,这很容易:

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

可能有用。 如果可能有旋转的矩形,可以将它们括在边界矩形中。

试试这个

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

//基本上是比较边缘


如果((X0>=xi)&&(X0+width=Yi)&&(Y0+height,这是我的代码,按照您的要求:

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

第二种方法是从基础矩形中减去矩形列表

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

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

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;
    }
公共静态列表减去矩形(矩形baseRect、矩形splitterRect)
{
List newRectaglesList=新列表();
矩形相交=矩形。相交(baseRect,splitterRect);
如果(!intersection.IsEmpty)
{
矩形topRect=新矩形(baseRect.Left,baseRect.Top,baseRect.Width,(intersection.Top-baseRect.Top));
矩形bottomRect=新矩形(baseRect.Left,intersection.Bottom,baseRect.Width,(baseRect.Bottom-intersection.Bottom));
如果((topRect!=交点)&&(topRect.Height!=0))
{
newRectaglesList.Add(topRect);
}
如果((bottomRect!=交点)&&(bottomRect.Height!=0))
{
newRectaglesList.Add(bottomRect);
}
}
其他的
{
newRectaglesList.Add(baseRect);
}
返回newRectaglesList;
}
公共静态列表减去矩形(矩形baseRect、列表拆分器RectList)
{
List fragmentsList=新列表();
fragmentsList.Add(baseRect);
foreach(splitterRectList中的矩形拆分器)
{
List TOADLIST=新列表();
foreach(fragmentsList中的矩形片段)
{
List newFragmentsList=减去矩形(片段、拆分器);
toAddList.AddRange(newFragmentsList);
}
if(toAddList.Count!=0)
{
碎片列表。清除();
fragmentsList.AddRange(toAddList);
}
}
返回碎片;
}

您可以使用用于计算矩形并集面积的算法。因为您想检查矩形a是否被矩形B={B_1,B_2,…}覆盖。

首先计算B中矩形的并集面积,我们得到面积_1作为值。

然后计算B+{a}中矩形的并集面积,我们得到面积_2作为值。
因此,如果area_1==area_2,那么您可以确定矩形a被矩形B覆盖。否则,答案为false。


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

所有的矩形都对齐了吗,或者可能有b旋转45度的矩形?所有矩形相对于坐标系的角度都一样吗?因为它被一个新问题引用了,所以将其坏死。@Twibbles:如果有机会,最好接受你使用的答案(salva的答案)。非常感谢各位。让我们来看看
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;
    }