Как отделить внутренний многоугольник и внешний многоугольник от списка точек в С#

Предположим, что многоугольник, как показано ниже

многоугольник, нарисованный по списку точек

У меня есть форма, как указано выше, и список точек любого порядка.

Point[] polygon = { A(x,y), B (x,y) ..... L(x,y) }

Мне нужно разделить точки внешнего многоугольника и внутреннего многоугольника.

Point[] outerpoly = { A(x,y), B(x,y), C(x,y)... H(x,y) }

Point[] innerpoly = { I(x,y), J(x,y), K(x,y), L(x,y) }

Для целей алгоритма мы можем предположить, что Point может быть в System.Windows.Point или System.Drawing.Point.

Пожалуйста, помогите мне найти алгоритм для получения списка точек внутреннего и внешнего многоугольника.


person Revanth    schedule 04.08.2020    source источник
comment
Если у вас есть только список точек в любом порядке, будет несколько способов отсортировать их по двум кольцам. Как и в вашем примере, есть много комбинаций.   -  person TimTim Wong    schedule 04.08.2020
comment
@ ТимТим Вонг, правда. Это проблема. Я надеюсь, что смогу разделить их как замкнутые многоугольники, в случае примера 2 замкнутых многоугольника.   -  person Revanth    schedule 04.08.2020
comment
Полигоны конечно закрытые. Я имею в виду, что это могут быть ABCFGHLI и DEKJ или другие комбинации.   -  person TimTim Wong    schedule 04.08.2020
comment
Так нельзя тогда??   -  person Revanth    schedule 04.08.2020
comment
Да, никакого детерминированного решения.   -  person TimTim Wong    schedule 04.08.2020
comment
Спасибо @TimTim Wong   -  person Revanth    schedule 04.08.2020
comment
Насколько точно полигоны будут напоминать ваш рисунок? Можете ли вы предоставить некоторые образцы точек?   -  person NetMage    schedule 05.08.2020
comment
@NetMage, у многоугольников будут углы и края. Внутренние и внешние полигоны будут иметь углы и ребра. В идеале... Может быть любой формы с краями и углами.   -  person Revanth    schedule 05.08.2020
comment
Я бы начал с уменьшения количества точек-кандидатов. Самые внешние - самые большие и самые маленькие для x и y. Затем вы можете что-то сделать с линиями, пересекающими две пары точек. Линии между соединенными точками каждой фигуры не будут пересекать линии между любыми другими.   -  person Andy    schedule 05.08.2020


Ответы (1)


Используя систему координат, в которой возрастающие значения идут вниз и вправо, вы можете просто отсортировать и выбрать точки для каждого полигона.

Создайте List<Point>s для хранения результатов:

var outerpoly = new List<Point>();
var innerpoly = new List<Point>();

Теперь отсортируйте точки по вертикали для начальных выборок:

var vertical = polygon.OrderByDescending(p => p.Y).ToList();

Затем для каждого раздела отсортируйте их по горизонтали и извлеките то, что вам нужно.

Во-первых, внешний полигон:

var outerBottom = vertical.Take(2).OrderBy(p => p.X);    
outerpoly.AddRange(outerBottom);

var outerRightBottomIn = vertical.Skip(2).Take(4).OrderByDescending(p => p.X).Take(2);
outerpoly.AddRange(outerRightBottomIn);

var outerRightTopOut = vertical.Skip(8).Take(2).OrderBy(p => p.X);
outerpoly.AddRange(outerRightTopOut);

var outerTop = vertical.Skip(10).OrderByDescending(p => p.X);
outerpoly.AddRange(outerTop);

Затем внутренний многоугольник:

var innerBottom = vertical.Skip(2).Take(4).OrderBy(p => p.X).Take(2);
innerpoly.AddRange(innerBottom);

var innerTop = vertical.Skip(6).Take(2).OrderByDescending(p => p.X);
innerpoly.AddRange(innerTop);
person NetMage    schedule 04.08.2020
comment
Позвольте мне подтвердить @NetMage - person Revanth; 05.08.2020
comment
Я провел тест, но результат не такой, как ожидалось. Пожалуйста, дайте мне знать, если вам нужна дополнительная информация. - person Revanth; 05.08.2020