我有多个多边形列表,每个多边形代表一个物理对象。例如:
List<CurveLoop> A
可以代表一个带孔的矩形。此列表中的一条曲线是矩形的轮廓,另一条曲线是孔。
我想要一个返回列表列表的方法,其中每个列表包含所有相交的对象。
我已经有一个方法可以返回两个对象是否相交:
bool _CurveLoopsIntersect(List<CurveLoop> curveLoopsA, List<CurveLoop> curveLoopsB) {...}
将返回true。
以下是我到目前为止的代码,但它只给了我一次通过。我想我需要多次传递,所以如果对象A和B相交,而B和C相交,那么它们将形成集合{A,B,C}。我需要任意数量的通道,有时对象根本不会相交,或者是不同集合的一部分,例如{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;
}
答案 0 :(得分:2)
这可以使用像这个psuedu
这样的代码来实现import scalaz._
import Scalaz._
type EitherTH[F[_], A] = EitherT[F, Throwable,A]
type StateTH[F[_], A] = StateT[F, String, A]
type StateTList[A] = StateTH[List, A]
type EitherTStateTList[A] = EitherTH[StateTList, A]
val lst = List(1,2,3,4)
def checkNum(x:Int)(implicit ms:MonadState[EitherTStateTList, Int]) = if ((x%2)==0) {
put(s"Error: $x")
-\/(new Throwable())
} else {
put("")
\/-(x)
}
val prg = for {
x <- lst.liftM[StateTH].liftM[EitherTH]
// y <- checkNum(x).liftM[EitherTH]
} yield y
prg.run("")
}
答案 1 :(得分:0)
谢谢,你让我朝着正确的方向前进。你是对的,使用Set是正确的方法。我将一个集合与递归函数结合使用(类似于你的while循环)。
我写的代码如下:
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);
}