/// <summary> /// Нахождение всех пересечений двух полилиний /// </summary> /// <param name="bound">Прямоугольник в котором находятся возможные пересечения</param> /// <param name="p1">Первая полилиния</param> /// <param name="p2">Вторая полилиния</param> /// <returns>Список пересечений</returns> public static List<Intersection> PolylineInters(Rect bound, Polyline p1, Polyline p2) { var intersections = new List<Intersection>(); for (int i = 0; i < p1.Points.Count - 1; i++) if(LineInRect(new []{p1.Points[i], p1.Points[i + 1]}, bound )) for (int j = 0; j < p2.Points.Count - 1; j++) { if (LineInRect(new[] { p2.Points[j], p2.Points[j + 1] }, bound)) { Intersection inter = LineIntersectionPoint(p1.Points[i], p1.Points[i + 1], p2.Points[j], p2.Points[j + 1]); if ((inter.Point.X != 0 || inter.Point.Y != 0) && intersections.FindIndex( x => Math.Abs(x.Point.X - inter.Point.X) < 1 && Math.Abs(x.Point.Y - inter.Point.Y) < 1) == -1) { inter.Section1 = i; inter.Section2 = j; intersections.Add(inter); } } } return intersections; }
public Edge(int speed, int width, Polyline shape, List<int> links) { Speed = speed; Width = width; Shape = shape; Links = links; Length = GeometryWork.PolylineLength(shape); }
/// <summary> /// Определение длины полилинии /// </summary> /// <param name="polyline">Полилиния</param> /// <returns>Длина полилинии</returns> public static double PolylineLength(Polyline polyline) { double length = 0; for (int i = 0; i < polyline.Points.Count - 1; i++) { length += PointsDistance(polyline.Points[i], polyline.Points[i + 1]); } return length; }
/// <summary> /// Метод разбирающий строку и строящий полилинию /// </summary> /// <param name="s">Строка</param> /// <returns></returns> public static Polyline PolylineParse(string s) { Polyline p = new Polyline(); s = s.Remove(0, s.IndexOf('(')); s = s.Replace("(", ""); s = s.Replace(")", ""); string[] strings = s.Split(','); foreach (string s1 in strings) { string s2 = s1.Replace('.', ',').Trim(); string[] point = s2.Split(' '); p.Points.Add(new Point(double.Parse(point[0]), double.Parse(point[1]))); } return p; }
/// <summary> /// Построение прямоугольника в котором находится полилиния /// </summary> /// <param name="polyline">Полилиния</param> /// <returns>Прямоугольник</returns> public static Rect PolylineToRectangle(Polyline polyline) { Point p1 = new Point(polyline.Points[0].X, polyline.Points[0].Y); Point p2 = new Point(polyline.Points[0].X, polyline.Points[0].Y); foreach (Point point in polyline.Points) { if (point.X < p1.X) p1.X = point.X; else if (point.X > p2.X) p2.X = point.X; if (point.Y < p1.Y) p1.Y = point.Y; else if (point.Y > p2.Y) p2.Y = point.Y; } Rect rectangle = new Rect(p1, p2); return rectangle; }
/// <summary> /// Разбиение дороги на отрезке в местах пересечений с другими дорогами /// </summary> /// <param name="links">Список связей с другими дорогами</param> /// <param name="road">Дорога</param> /// <returns>Список всех отрезков дороги и их связей с другими отрезками</returns> private static List<BuildEdge> RoadFragmentation(List<Link2> links, Road road) { var edges = new List<BuildEdge>(); int section = 0; double t = 0; var edgelinks = new List<int>(); Point p = road.Shape.Points[0]; edges.Add(new BuildEdge()); foreach (Link2 t1 in links) { if (!(t1.Section == section && Math.Abs(t - t1.T) < 0.01)) { var polyline = new Polyline(); polyline.Points.Add(p); if (section != t1.Section) { if (!(Math.Abs(1 - t) < 0.01)) polyline.Points.Add(road.Shape.Points[section + 1]); for (int j = section + 1; j < t1.Section - 1; j++) polyline.Points.Add(road.Shape.Points[j + 1]); section = t1.Section; } if (Math.Abs(1 - t1.T) < 0.01) { polyline.Points.Add(road.Shape.Points[section + 1]); p = road.Shape.Points[section + 1]; t = 1; } else { double dif = road.Shape.Points[section + 1].X - road.Shape.Points[section].X; p.X = road.Shape.Points[section].X + dif*t1.T; p.Y = road.Shape.Points[section].Y + dif*t1.T; t = t1.T; polyline.Points.Add(p); } edgelinks.Add(t1.Edge); var edge = new Edge(road.Speed, road.Width, polyline, edgelinks); edges[edges.Count - 1].Edge = edge; edges.Add(new BuildEdge()); edgelinks = new List<int>(); } edgelinks.Add(t1.Edge); if (edges.Count > 1 && edgelinks.Count > 1) { edges[edges.Count - 2].Edge.Links.Add(t1.Edge); edges[edges.Count - 1].Newedges.Add(t1.Edge); } else if (edges.Count > 1) { edges[edges.Count - 1].Newedges = new List<int> {t1.Edge}; } } if (section != road.Shape.Points.Count - 2 || Math.Abs(t - 1) > 0.01) { var polyline = new Polyline(); polyline.Points.Add(p); if (!(Math.Abs(1 - t) < 0.01)) polyline.Points.Add(road.Shape.Points[section + 1]); for (int j = section + 1; j < road.Shape.Points.Count - 1; j++) polyline.Points.Add(road.Shape.Points[j + 1]); var edge = new Edge(road.Speed, road.Width, polyline, edgelinks); edges[edges.Count - 1].Edge = edge; } if (edges[edges.Count - 1].Edge == null) edges.RemoveAt(edges.Count - 1); return edges; }