private void add_intersection_points() { if (polygon1.Count == 0 || polygon2.Count == 0) { return; } PolygonNode[] pol1 = new PolygonNode[polygon1.Count + 1]; polygon1.CopyTo(pol1, 0); pol1[pol1.Length - 1] = pol1[0]; PolygonNode[] pol2 = new PolygonNode[polygon2.Count + 1]; polygon2.CopyTo(pol2, 0); pol2[pol2.Length - 1] = pol2[0]; for (int i = 0; i < pol1.Length - 1; ++i) { for (int j = 0; j < pol2.Length - 1; ++j) { PointF intersection = find_intersection_point(pol1[i].p, pol1[i + 1].p, pol2[j].p, pol2[j + 1].p); if (intersection.X != -1) { //узел в первом полигоне, после которого нужно вставить точку пересечения LinkedListNode <PolygonNode> previous_node1 = polygon1.Find(pol1[i]); //если для текущего ребра уже вставлено одно пересечение, //то проверяется - до или после предыдущего пересечения должно быть вставлено новое if (previous_node1.Next != null && previous_node1.Next.Value.isIntersection && distance_between_points(previous_node1.Value.p, intersection) > distance_between_points(previous_node1.Value.p, previous_node1.Next.Value.p)) { previous_node1 = previous_node1.Next; } LinkedListNode <PolygonNode> intersectionNode1 = polygon1.AddAfter(previous_node1, new PolygonNode(intersection, true)); LinkedListNode <PolygonNode> previous_node2 = polygon2.Find(pol2[j]); if (previous_node2.Next != null && previous_node2.Next.Value.isIntersection && distance_between_points(previous_node2.Value.p, intersection) > distance_between_points(previous_node2.Value.p, previous_node2.Next.Value.p)) { previous_node2 = previous_node2.Next; } LinkedListNode <PolygonNode> intersectionNode2 = polygon2.AddAfter(previous_node2, new PolygonNode(intersection, true)); intersectionNode1.Value.intersectionInOtherPolygon = intersectionNode2; intersectionNode2.Value.intersectionInOtherPolygon = intersectionNode1; } } } }
private void find_polygon_intersection() { if (polygon1.Count == 0 || polygon2.Count == 0) { return; } LinkedListNode <PolygonNode> curNode = polygon1.First; bool isInside = is_point_inside(polygon2.Where(i => !i.isIntersection).Select(i => i.p).ToList(), curNode.Value.p); while (curNode.Next != null && !curNode.Value.isIntersection) { curNode = curNode.Next; } if (curNode.Value.isIntersection) { polygonIntersection.AddLast(curNode.Value); PolygonNode start = curNode.Value; if (isInside) { curNode = curNode.Value.intersectionInOtherPolygon; } curNode = curNode.Next; while (curNode.Value.p != start.p) { polygonIntersection.AddLast(curNode.Value); if (curNode.Value.isIntersection) { curNode = curNode.Value.intersectionInOtherPolygon; } curNode = curNode.Next == null ? curNode.List.First : curNode.Next; } label1.Text = "Есть пересечение"; } else //если обошли весь полигон и точки пересечения не нашлось { List <PointF> pol1 = polygon1.Where(i => !i.isIntersection).Select(i => i.p).ToList(); List <PointF> pol2 = polygon2.Where(i => !i.isIntersection).Select(i => i.p).ToList(); bool polygonInsideOtherPolygon = false; //все вершины второго полигона внутри первого полигона? foreach (PointF p in pol2) { polygonInsideOtherPolygon = is_point_inside(pol1, p); if (!polygonInsideOtherPolygon) { break; } } //да => пересечение = полигон2 if (polygonInsideOtherPolygon) { label1.Text = "Полигоны пересекаются"; polygonIntersection = polygon2; return; } //нет => все вершины первого полигона внутри второго полигона? foreach (PointF p in pol1) { polygonInsideOtherPolygon = is_point_inside(pol2, p); if (!polygonInsideOtherPolygon) { break; } } //да => пересечение = полигон1 if (polygonInsideOtherPolygon) { label1.Text = "Полигоны пересекаются"; polygonIntersection = polygon1; return; } //нет => не пересекаются label1.Text = "Полигоны не пересекаются"; } }