Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/275.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 递归查找矩形_C#_Recursion - Fatal编程技术网

C# 递归查找矩形

C# 递归查找矩形,c#,recursion,C#,Recursion,我有一个重叠矩形的列表。我需要找到一个列表,其中返回所有重叠的矩形。例如,在一个包含7个矩形的列表中,如果4个矩形重叠,其余矩形分开,则列表的列表应如下所示: [0]: r1, r2, r3, r4 [1]: r5 [2]: r6 [3]: r7 [0]: 1 rectangle [1]: 3 rectangles [2]: 1 rectangle [3]: 1 rectangle <?xml version="1.0" encoding="utf-1

我有一个重叠矩形的列表。我需要找到一个列表,其中返回所有重叠的矩形。例如,在一个包含7个矩形的列表中,如果4个矩形重叠,其余矩形分开,则列表的列表应如下所示:

[0]: r1, r2, r3, r4
[1]: r5
[2]: r6
[3]: r7
    [0]: 1 rectangle
    [1]: 3 rectangles
    [2]: 1 rectangle
    [3]: 1 rectangle


<?xml version="1.0" encoding="utf-16"?>
<rectangles>
  <rectangle>
    <X1>50.833333344375</X1>
    <Y1>100</Y1>
    <X2>53.833333344375</X2>
    <Y2>127.00000004975</Y2>
  </rectangle>
  <rectangle>
    <X1>136.500000033125</X1>
    <Y1>100</Y1>
    <X2>139.516666655625</X2>
    <Y2>127.00000004975</Y2>
  </rectangle>
  <rectangle>
    <X1>50.833333344375</X1>
    <Y1>130.647222172472</Y1>
    <X2>53.833333344375</X2>
    <Y2>157.647222222222</Y2>
  </rectangle>
  <rectangle>
    <X1>136.500000033125</X1>
    <Y1>130.647222172472</Y1>
    <X2>139.516666655625</X2>
    <Y2>157.647222222222</Y2>
  </rectangle>
  <rectangle>
    <X1>136.500000033125</X1>
    <Y1>100</Y1>
    <X2>139.516666655625</X2>
    <Y2>157.3333333830833</Y2>
  </rectangle>
  <rectangle>
    <X1>179.3333333775</X1>
    <Y1>100</Y1>
    <X2>182.3333333775</X2>
    <Y2>157.3333333830833</Y2>
  </rectangle>
</rectangles>
我知道我必须进行命中测试。我正在寻找一个算法或一个例子来创建链请

谢谢

我已经尝试过这段代码:有时它可以工作,有时它会抛出一个有点异常的索引

while (rects.Count != 0)
            {
                listOfRects.Add(joinRectangles(rects, new List<Rectangle>(), rects[rects.Count - 1]));
            }

        private List<Rectangle> joinRectangles(List<Rectangle> rects, List<Rectangle> tempRects, Rectangle curRect)
        {
            for (int j = rects.Count; j-- > 0; )
            {
                if (hitTest(curRect, rects[j]) == true)
                {
                    if (tempRects.Contains(rects[j]) == false)
                    {
                        tempRects.Add(rects[j]);
                        curRect = rects[j];
                        rects.Remove(rects[j]);

                        j--;

                        joinRectangles(rects, tempRects, curRect);
                    }
                }


            }


            return tempRects;
        }
while(rects.Count!=0)
{
Add(joinRectangles(rects,new List(),rects[rects.Count-1]);
}
私有列表连接矩形(列表矩形、列表临时矩形、矩形当前)
{
对于(int j=rects.Count;j-->0;)
{
if(hitTest(curRect,rects[j])==true)
{
if(tempRects.Contains(rects[j])==false)
{
添加(rects[j]);
curRect=rects[j];
rects.Remove(rects[j]);
j--;
连接矩形(矩形、临时矩形、电流);
}
}
}
返回tempRects;
}
如果我提供这些坐标,那么我应该得到一个包含4个列表的列表,如下所示:

[0]: r1, r2, r3, r4
[1]: r5
[2]: r6
[3]: r7
    [0]: 1 rectangle
    [1]: 3 rectangles
    [2]: 1 rectangle
    [3]: 1 rectangle


<?xml version="1.0" encoding="utf-16"?>
<rectangles>
  <rectangle>
    <X1>50.833333344375</X1>
    <Y1>100</Y1>
    <X2>53.833333344375</X2>
    <Y2>127.00000004975</Y2>
  </rectangle>
  <rectangle>
    <X1>136.500000033125</X1>
    <Y1>100</Y1>
    <X2>139.516666655625</X2>
    <Y2>127.00000004975</Y2>
  </rectangle>
  <rectangle>
    <X1>50.833333344375</X1>
    <Y1>130.647222172472</Y1>
    <X2>53.833333344375</X2>
    <Y2>157.647222222222</Y2>
  </rectangle>
  <rectangle>
    <X1>136.500000033125</X1>
    <Y1>130.647222172472</Y1>
    <X2>139.516666655625</X2>
    <Y2>157.647222222222</Y2>
  </rectangle>
  <rectangle>
    <X1>136.500000033125</X1>
    <Y1>100</Y1>
    <X2>139.516666655625</X2>
    <Y2>157.3333333830833</Y2>
  </rectangle>
  <rectangle>
    <X1>179.3333333775</X1>
    <Y1>100</Y1>
    <X2>182.3333333775</X2>
    <Y2>157.3333333830833</Y2>
  </rectangle>
</rectangles>
[0]:1个矩形
[1] :3个矩形
[2] :1矩形
[3] :1矩形
50.833333344375
100
53.833333344375
127.00000004975
136.500000033125
100
139.516666655625
127.00000004975
50.833333344375
130.647222172472
53.833333344375
157.647222222222
136.500000033125
130.647222172472
139.516666655625
157.647222222222
136.500000033125
100
139.516666655625
157.3333333830833
179.3333333775
100
182.3333333775
157.3333333830833

在发布自己的代码之前,要从头开始快速编写。 您有一个矩形列表,并希望按重叠组对其进行分组

您可以使用这个group矩形函数

public List<List<Rectangle>> groupRectangles(List<Rectangle> rectangleList) {

List<List<Rectangle>> groupOverlappedRectangles = new List<List<Rectangle>>();

foreach (Rectangle r : rectangleList) {
    bool overLap = false;
    foreach (List<Rectangle> liste : groupOverlappedRectangles) {
        if (overlapsRectangleList(r,liste))
        {
                liste.add(r);
            overLap = true;
            break;
        }
    }
    if (!overLap) {
        List<Rectangle> newOverlapList = new List<Rectangle>();
        newOverlapList.add(r);
        groupOverlappedRectangles.add(newOverlapList);
    }
}
return groupOverlappedRectangles;
}

public bool overlapsRectangleList(Rectangle r, List<Rectangle> listeOver)
{
    foreach (Rectangle rOver : listeOver) {
        if (r.IntersectsWith(rOver)) {
            return true;
    }
    }
    return false;
}
公共列表组矩形(列表矩形列表){
List groupOverlappedRectangles=新列表();
foreach(矩形r:矩形列表){
布尔重叠=假;
foreach(列表列表:groupOverlappedRectangles){
if(重叠矩形列表(r,列表))
{
添加(r);
重叠=真;
打破
}
}
如果(!重叠){
List newOverlappList=新列表();
添加(r);
groupOverlappedRectangles.add(newOverlappedList);
}
}
返回组重叠矩形;
}
公共布尔重叠矩形列表(矩形r,列表列表覆盖)
{
foreach(矩形漫游者:ListOver){
如果(与月球车相交){
返回true;
}
}
返回false;
}

以下是另一种使用和Linq延迟执行的方法:

var intersectingRectangles = new List<List<Rectangle>>();
var alreadyChecked = new HashSet<Rectangle>();
var toCheck = rectangles.Except(alreadyChecked);
while (alreadyChecked.Count != rectangles.Count)
{
    var intersections = toCheck.Where(r => r.IntersectsWith(toCheck.ElementAt(0)))
                               .ToList();
    intersectingRectangles.Add(intersections);
    foreach (var r in intersections)
        alreadyChecked.Add(r);
}
intersectingRectangles.Sort((rl1, rl2) => (-1) * rl1.Count.CompareTo(rl2.Count));
var intersecting矩形=新列表();
var alreadyChecked=new HashSet();
var toCheck=矩形。除(ALREADYCHECK)外;
while(alreadyChecked.Count!=rectangles.Count)
{
var crossions=toCheck.Where(r=>r.IntersectsWith(toCheck.ElementAt(0)))
.ToList();
相交矩形。添加(相交);
foreach(交叉口中的var r)
已检查。添加(r);
}
交叉矩形。排序((rl1,rl2)=>(-1)*rl1.Count.CompareTo(rl2.Count));
也许不是最易读的方式,但却是最短的方式之一:)

编辑:下面是一个演示(没有系统,单声道很难进行。绘图和矩形):


对于每个矩形,必须检查之前的所有矩形组。例如,如果A和C重叠,B和C重叠,而不是A和B重叠。如果算法接收到A、B、C,它将首先将A放在一个列表中,然后将B放在另一个列表中。但当C出现时,它必须将列表与A和列表与B合并到包含C的新列表中(其他答案似乎都忽略了这一点)

公共静态列表SortOverlap(矩形[]矩形)
{
var result=新列表();
对于(int i=0;ir.Overlap(newList[0]))
{
AddRange(结果[j]);
结果[j]=null;
}
}
结果。添加(新列表);
result.RemoveAll(list=>list==null);
}
返回结果;
}
编辑: 重叠检查的实现非常简单,因此不需要使用System.Drawing或类似工具来进行检查

public class Rectangle {
    ....
    public bool Overlap(Rectangle other)
    {
        return !(this.MinX >= other.MaxX || this.MaxX <= other.MinX ||
                 this.MinY >= other.MaxY || this.MaxY <= other.MinY);
    }
}
公共类矩形{
....
公共边界重叠(矩形其他)
{

return!(this.MinX>=other.MaxX | | | this.MaxX=other.MaxY | | | this.MaxY编码效率有多高?有多少个矩形(四舍五入)?我脑子里有一些解决方案,但它们不是最优的。当
r8和r9
r9和r10
重叠时会发生什么情况,但
r8和r10
不是?这是一个链,它应该连接r8、r9和r10。你是根据它们开始的点和宽度/高度等计算它们的重叠吗?还是没有那么复杂?还有,是ca上的矩形WPF或windows窗体中的NVA或仅对象?矩形是对象。正在使用x1、y1、x2和y2坐标计算重叠感谢您的答复。但代码没有返回链。@贾帕克:我添加了return语句。它返回一个矩形列表。每个矩形列表包含一个重叠矩形链gles,并且它们都在全局列表中。问题不在于return语句。groupOverlappedRectangles不包含正确的链列表。请参阅我对示例的原始帖子。谢谢我不明白:让我们