using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using NetTopologySuite.Geometries; namespace FortAnalysis { public class PolygonSplit { // 找到自相交多边形的交点 private static List> FindIntersectionPoints(List> coordinates) { List> intersectionPoints = new List>(); for (int i = 0; i < coordinates.Count; i++) { var edge1Start = coordinates[i]; var edge1End = coordinates[(i + 1) % coordinates.Count]; for (int j = i + 2; j < coordinates.Count + i - 1; j++) { var edge2Start = coordinates[j % coordinates.Count]; var edge2End = coordinates[(j + 1) % coordinates.Count]; var intersection = FindIntersection(edge1Start, edge1End, edge2Start, edge2End); if (intersection != null) { intersectionPoints.Add(intersection); } } } return intersectionPoints; } // 找到两条边的交点 private static Tuple FindIntersection(Tuple p1, Tuple p2, Tuple p3, Tuple p4) { double x1 = p1.Item1; double y1 = p1.Item2; double x2 = p2.Item1; double y2 = p2.Item2; double x3 = p3.Item1; double y3 = p3.Item2; double x4 = p4.Item1; double y4 = p4.Item2; double denominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4); if (Math.Abs(denominator) < double.Epsilon) { return null; // 平行或共线,无交点 } double x = ((x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4)) / denominator; double y = ((x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4)) / denominator; return new Tuple(x, y); } // 根据交点分割多边形集合 public static List> SplitPolygons(List> polygons, List intersectionPoints) { List> splittedPolygons = new List>(); foreach (var polygon in polygons) { List splittedPolygon = new List(polygon); foreach (var intersectionPoint in intersectionPoints) { if (IsInsidePolygon(intersectionPoint, polygon)) { splittedPolygon.Add(intersectionPoint); } } splittedPolygon = splittedPolygon.OrderBy(p => Math.Atan2(p.Y - intersectionPoints[0].Y, p.X - intersectionPoints[0].X)).ToList(); splittedPolygons.Add(splittedPolygon); } return splittedPolygons; } // 判断点是否在多边形内部 private static bool IsInsidePolygon(Coordinate point, List polygon) { int count = 0; int n = polygon.Count; for (int i = 0; i < n; i++) { var p1 = polygon[i]; var p2 = polygon[(i + 1) % n]; if (IsPointOnSegment(point, p1, p2)) { return true; // 点在多边形的边上 } if (point.Y > Math.Min(p1.Y, p2.Y) && point.Y <= Math.Max(p1.Y, p2.Y) && point.X <= Math.Max(p1.X, p2.X) && p1.Y != p2.Y) { double xIntersection = (point.Y - p1.Y) * (p2.X - p1.X) / (p2.Y - p1.Y) + p1.X; if (p1.X == p2.X || point.X <= xIntersection) { count++; } } } return count % 2 == 1; } // 判断点是否在线段上 private static bool IsPointOnSegment(Coordinate point, Coordinate p1, Coordinate p2) { return Math.Abs(Distance(point, p1) + Distance(point, p2) - Distance(p1, p2)) < double.Epsilon; } // 计算两个点之间的距离 private static double Distance(Coordinate p1, Coordinate p2) { double dx = p1.X - p2.X; double dy = p1.Y - p2.Y; return Math.Sqrt(dx * dx + dy * dy); } } }