简体   繁体   English

按交叉点将任意多边形数量分组-C#

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM