我有一张地图上有一些DeadZones(无法到达的区域)。
我的应用程序流程中有一点需要检查此地图上是否可以访问某行。
现在,我的线路交叉口代码非常可靠,但我无法弄清楚如何限制需要检查的死区数量,因为其中一些将是地图的另一侧。
现在死区只是一个List<Point>
,其中Point
是x和y,类型double
和我的行只是2个单独的点描述了开头和结束了。
所以,在我调用它并处理所有死区的地方,这就是我正在做的事情:
DeadZones.All(dz => !FastPolygons.DoesLineIntersectPolygon(point1, point2, dz.Polygon));
首先,我想我可以使用来自死区的MaxX和MaxY来消除远处的那些,但是如果两个点都位于死区之外,那么所有这些点仍将被处理并且它将需要线路每端的一个点实际上位于死区,以便消除死区。
我写了一个方法,我可以在我的linq语句中的Where
中使用它来尝试这个,然后才意识到这不起作用。这就是我的尝试
private static bool ZoneCouldNotOverlap(Point point, Zone zone)
{
return (zone.MaxX < point.X || zone.MaxY < point.Y) || (zone.MinX > point.X || zone.MinY > point.Y);
}
然后Linq声明变成了这个:
DeadZones.Where(x=> ZoneCouldNotOverlap(point1,x) || ZoneCouldNotOverlap(point2,x)).All(dz => !FastPolygons.DoesLineIntersectPolygon(point1, point2, dz.Polygon));
所以我已经到了这一点,我可以消除地图的大部分,因此不会处理我不感兴趣的地图部分的死区,但我似乎无法意识到在我的Linq声明中这样做。任何帮助都非常受欢迎。
编辑:我也非常欢迎有关如何在这里应用parellelization的最佳建议
答案 0 :(得分:0)
因此,这使得通过5000次迭代处理所需的时间减少了约30秒,因此这似乎是一个充分的答案。
我所做的是创建一个struct
被调用的行来代替这对点。
看起来像这样:
public struct Line
{
public List<Point> Points { get; private set; }
public double MaxX { get; private set; }
public double MinX { get; private set; }
public double MinY { get; private set; }
public double MaxY { get; private set; }
public Line(Point start, Point end) : this()
{
Points = new List<Point>();
Points.AddRange(new[] {start, end});
var xs = Points.Select(p => p.X);
var ys = Points.Select(p => p.Y);
MaxX = xs.Max();
MinX = xs.Min();
MaxY = ys.Max();
MinY = ys.Min();
}
}
然后我在名为ZoneCouldNotOverlapLine()
的新方法中使用了它,看起来像这样:
private static bool ZoneCouldNotOverlapLine(Line line, Zone zone)
{
return (line.MinX > zone.MaxX || line.MaxX < zone.MinX) && (line.MaxY < zone.MinY || line.MinY > zone.MaxY);
}
反过来,我在我的Linq声明中使用了这样的话:
DeadZones.Where(z=> !ZoneCouldNotOverlapLine(line,z))
.All(dz => !FastPolygons.DoesLineIntersectPolygon(point1, point2, dz.Polygon));
这是有效的说法,只看看整个线路不在区域一侧的死区。在我的代码中还有一些地方,这样的优化会很有用,通过这些工作将帮助我解决这些问题。