Закрепите сегмент линии на многоугольник в C#
В этом примере найдены фрагменты сегмента линии, которые лежат внутри и снаружи многоугольника. Он рисует части сегмента, которые лежат вне многоугольника с розовым фоном, и он рисует части сегмента внутри полигона желтым цветом.
Основная идея состоит в том, чтобы найти все точки пересечения между отрезком линии и краями многоугольника. Метод FindIntersection, используемый в этом примере, вычисляет значение t между 0.0 и 1.0, которое указывает положение точки пересечения вдоль сегмента линии. Значение 0.0 означает, что пересечение находится в первой конечной точке сегмента, 1.0 означает, что пересечение находится во второй конечной точке сегмента, а значения между 0.0 и 1.0 означают, что пересечение находится между ними.
После вычисления точек пересечения между отрезком и краями многоугольника программа сортирует эти пересечения по их значениям t. Сортированные точки пересечения - это места, где сегмент поочередно входит и покидает многоугольник.
В следующем коде показан метод ClipLineWithPolygon, который находит точки пересечения.
// Возвращаем точки, в которых сегмент входит и выходит из многоугольника. private PointF[] ClipLineWithPolygon( out bool starts_outside_polygon, PointF point1, PointF point2, Listpolygon_points) { // Создание списков для хранения точек // пересечение и их значения t. List intersections = new List (); List t_values = new List (); // Добавить начальную точку сегмента. intersections.Add(point1); t_values.Add(0f); starts_outside_polygon = !PointIsInPolygon(point1.X, point1.Y, polygon_points.ToArray()); // Исследуем края многоугольника. for (int i1 = 0; i1 < polygon_points.Count; i1++) { // Получим конечные точки для этого ребра. int i2 = (i1 + 1) % polygon_points.Count; // Смотрите, где край пересекает сегмент. bool lines_intersect, segments_intersect; PointF intersection, close_p1, close_p2; float t1, t2; FindIntersection(point1, point2, polygon_points[i1], polygon_points[i2], out lines_intersect, out segments_intersect, out intersection, out close_p1, out close_p2, out t1, out t2); // Смотрите, пересекает ли отрезок ребро. if (segments_intersect) { // Смотрите, нужно ли записывать это пересечение. // Записываем это пересечение. intersections.Add(intersection); t_values.Add(t1); } } // Добавить конечную точку сегмента. intersections.Add(point2); t_values.Add(1f); // Сортируем точки пересечения по значению t. PointF[] intersections_array = intersections.ToArray(); float[] t_array = t_values.ToArray(); Array.Sort(t_array, intersections_array); // Вернем пересечения. return intersections_array; }
Этот метод достаточно понятен.
Информацию о методе PointIsInPolygon см. в сообщении Определить, находится ли точка внутри многоугольника в C# .
Информацию о методе FindIntersection см. в сообщении Определить, где две строки пересекаются в C# .