C# 递归查找矩形
我有一个重叠矩形的列表。我需要找到一个列表,其中返回所有重叠的矩形。例如,在一个包含7个矩形的列表中,如果4个矩形重叠,其余矩形分开,则列表的列表应如下所示: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
[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不包含正确的链列表。请参阅我对示例的原始帖子。谢谢我不明白:让我们