[英]Grouping Arbitrary Number of Polygons by Intersection - C#
I have multiple lists of polygons that each represent an physical object. 我有多个多边形列表,每个多边形表示一个物理对象。 For example: 例如:
List<CurveLoop> A
could represent a rectangle with a hole in it. List<CurveLoop> A
可以表示其中带有孔的矩形。 One curve within this list would be the outline of the rectangle, and another curve would be the hole. 此列表中的一条曲线将是矩形的轮廓,而另一条曲线将是孔。
I want a method that will return a list of lists, where each list contains all the objects that intersect. 我想要一个将返回列表列表的方法,其中每个列表包含所有相交的对象。
I already have a method that will return whether two of the objects intersect: 我已经有一个方法,该方法将返回两个对象是否相交:
bool _CurveLoopsIntersect(List<CurveLoop> curveLoopsA, List<CurveLoop> curveLoopsB) {...}
will return true if any any two curves within the two lists touch. 如果两个列表中的任何两条曲线接触,将返回true。
Below is the code I have so far, but it just gives me a single pass. 下面是我到目前为止的代码,但这只给了我一次机会。 I think I need multiple passes, so that if object A and B intersect, and B and C intersect, then they would form set { A, B, C }. 我认为我需要多次通过,以便如果对象A和B相交,而对象B和C相交,则它们将形成集合{A,B,C}。 I need an arbitrary number of passes though, and sometimes the objects won't intersect at all, or be part of different sets, such as {A, B, C} and {D, E} and {F}. 但是,我需要任意次数的传递,有时对象根本不会相交,或者成为不同集合的一部分,例如{A,B,C}和{D,E}和{F}。
public List<CurveLoop> _MergeCurveLoops(List<List<CurveLoop>> elementCurveLoops, View view)
{
// ...
// Preprocessing
var listOfLists = new List<List<CurveLoop>>();
foreach (var elementCurveLoop in elementCurveLoops)
{
var newList = elementCurveLoops.FindAll(x => _CurveLoopsIntersect(x, elementCurveLoop));
listOfLists.Add(newList);
}
}
private bool _CurveLoopsIntersect(List<CurveLoop> curveLoopsA, List<CurveLoop> curveLoopsB)
{
foreach (var curveLoopA in curveLoopsA)
{
foreach (var curveA in curveLoopA)
{
foreach (var curveLoopB in curveLoopsB)
{
foreach (var curveB in curveLoopB)
{
var result = curveA.Intersect(curveB);
if (result == SetComparisonResult.Overlap ||
result == SetComparisonResult.Subset ||
result == SetComparisonResult.Superset ||
result == SetComparisonResult.Equal)
{
return true;
}
}
}
}
}
return false;
}
This can be implemented using some code like this psuedu 可以使用类似psuedu的代码来实现
set = a,b,c, ...
While(set not empty) {
Create newSet
Add set.first to new list
Remove set.first from set // this line isnt necessary if a curve doesnt intersect with self
For (i = 0 , i < newset.length , i++)
{
newSet.add(set.FindAll(x => _CurveLoopsIntersect(x, newSet[i]));
set.removeRange(newSet); // this line may have error that the first element doesnt exist in set
}
Add newSet to set of sets
} }
Thanks, you put me in the right direction. 谢谢,您让我朝正确的方向前进。 You were right, using a Set was the right approach. 您是对的,使用Set是正确的方法。 I used a set in combination with a recursive function (similar to your while loop). 我将集合与递归函数结合使用(类似于while循环)。
The code I wrote is below: 我写的代码如下:
static List<Polygon> _RecursiveMergePolygons(List<Polygon> polygons, View view)
{
HashSet<Polygon> initialSet = new HashSet<Polygon>(polygons);
HashSet<Polygon> finalSet = new HashSet<Polygon>(polygons);
foreach (var polygon in initialSet)
{
// Should always return at least 1 instance
var polys = polygons.FindAll(x => _PolygonsIntersect(x, polygon));
// if it's greater than 1, then merge them and restart the recursion, otherwise continue
if (polys.Count > 1)
{
foreach (var poly in polys)
{
finalSet.Remove(poly);
}
var mergedPolygon = new Polygon(polys, view);
finalSet.Add(mergedPolygon);
break;
}
}
if (finalSet.Count == initialSet.Count)
{
return finalSet.ToList();
}
return _RecursiveMergePolygons(finalSet.ToList(), view);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.