@antonwx

Как отсортировать произвольные точки так, чтобы при проведении линии через них последовательно получился многоугольник?

Есть несколько точек в двухмерном пространстве, совершенно произвольные могут быть (но не могут совпадать).
Нужно отсортировать их так, чтобы при последовательном проведении линии через все эти точки получился - не самопересекающийся многоугольник.
Как это сделать? Существует ли вообще алгоритм, который способен на подобное?
Ну или подойдёт какая-нибудь библиотека на C# или C++, которая просто возьмёт и сделает это.
  • Вопрос задан
  • 422 просмотра
Решения вопроса 5
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Точки, соединённые в любом порядке, дадут многоугольник. Он может быть самопересекающимся или невыпуклым, но у вас в задаче никаких ограничений нет.
Ответ написан
Adamos
@Adamos
Банально-наколенный вариант: находим среднюю арифметическую координату, пересчитываем координаты всех точек в радиальные относительно этой средней, сортируем по углу (а при равенстве углов - по удаленности) - и соединяем в этом самом порядке.
Ответ написан
Alexandroppolus
@Alexandroppolus
кодир
Если надобно без самопересечений, то подойдет упрощенная версия алгоритма выпуклой оболочки - просто сортируешь по углу относительно самой левой точки, и всё.
Ответ написан
Комментировать
@Akina
Сетевой и системный админ, SQL-программист.
Возможный алгоритм.

Этап 1.

Строим выпуклую оболочку. Использованные точки отбрасываем. По оставшимся опять строим выпуклую оболочку... В итоге получаем несколько вложенных непересекающихся оболочек и, возможно, 1-2 точки внутри самой внутренней из них.

Этап 2.

Соединяем каждую из оболочек с ближайшей внешней. Для чего ищем две пары соседних вершин, по одной на каждой из оболочек, таких, чтобы образованный ими четырёхугольник не пересекался ни с одной из этих оболочек, и соответственно заменяем образуемые этими парами рёбра на рёбра, являющиеся другой парой сторон четырёхугольника. Если на первом этапе остались 1-2 внутренние точки, то просто присоединяем их к внутренней оболочке так, чтобы не получить самопересечения.

В итоге получаем несамопересекающийся многоугольник. Обходим его в любом направлении от любой из вершин - полученный список и есть требуемый ответ.
Ответ написан
Комментировать
ThunderCat
@ThunderCat
{PHP, MySql, HTML, JS, CSS} developer
Самый правильный путь - найти геометрический центр скопления, и от него перейти в радиальные координаты, двигаясь по кругу соединить все точки.
Второй, и как мне кажется на порядок более простой вариант - находим геометрический центр скопления, делим область на 4 части осями х и у, далее сверху вниз проходим каждую из них, соединяя каждую нижележащую с предыдущей (полинейное сканирование). Крайние точки областей соединяем - профит.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы