Подтвердить что ты не робот

Как создать случайный выпуклый многоугольник?

Я пытаюсь разработать метод генерации случайных 2D выпуклых многоугольников. Он должен иметь следующие свойства:

  • координаты должны быть целыми числами;
  • многоугольник должен лежать внутри квадрата с углами (0, 0) и (C, C), где C задано:
  • многоугольник должен иметь число вершин, близких к заданному числу N.

Например, генерируем случайные полигоны, которые имеют 10 вершин и лежат внутри квадрата [0..100] x [0..100].

Что затрудняет эту задачу, так это то, что координаты должны быть целыми числами.

Подход, который я пытался, заключался в том, чтобы создать случайный набор точек в данном квадрате и вычислить выпуклую оболочку этих точек. Но результирующая выпуклая оболочка имеет очень мало вершин по сравнению с N.

Любые идеи?

4b9b3361

Ответ 1

Это не совсем полно, но это может дать вам некоторые идеи.

Выйдите, если N < 3. Создайте единичный круг с N вершинами и поверните его в произвольном порядке [0..90] градусов.

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

После настройки ваших вершин найдите вершину с наибольшей величиной от начала координат. Разделите каждую вершину на эту величину, чтобы нормализовать многоугольник, а затем масштабируйте его (C/2). Переведите на (C/2, C/2) и верните целое число.

Ответ 2

Простым алгоритмом будет:

  • Начните со случайной строки (две вершины и два многогранника)
  • Возьмем случайное ребро E многоугольника
  • Сделать новую случайную точку P на этом краю
  • Возьмем прямую L, перпендикулярную E, проходящую через точку P. Вычисляя пересечение между линией T и строками, определяемыми двумя ребрами, смежными с E, вычислите максимальное смещение P, когда выпуклость не сломана.
  • Случайное смещение точки P в этом диапазоне.
  • Если недостаточно точек, повторите с 2.

Ответ 3

Ваш первоначальный подход правильный - вычисление выпуклой оболочки - это единственный способ удовлетворить случайность, выпуклость и целостность.

Единственный способ, которым я могу думать об оптимизации вашего алгоритма, чтобы получить "больше очков", - это организовать их вокруг круга, а не полностью случайным образом. Ваши точки, скорее всего, будут находиться рядом с "краями" вашего квадрата, чем возле центра. В центре вероятность должна быть равна ~ 0, так как многоугольник должен быть выпуклым.

Один простой вариант - установить минимальный радиус для ваших точек - возможно, C/2 или C * 0.75. Вычислите центр квадрата C, и если точка слишком близко, отведите его от центра до достижения минимального расстояния.

Ответ 4

Вот самый быстрый алгоритм, который я знаю, который генерирует каждый выпуклый многоугольник с равной вероятностью. Выход имеет ровно N вершин, а время выполнения - O (N log N), поэтому он может генерировать даже большие многоугольники очень быстро.

  • Создайте два списка X и Y из N случайных чисел от 0 до C. Убедитесь, что дубликатов нет.
  • Сортировка X и Y и сохранение их максимального и минимального элементов.
  • Случайно разделите остальные (не max или min) элементы на две группы: X1 и X2, и Y1 и Y2.
  • Повторно вставьте минимальный и максимальный элементы в начале и конце этих списков (minX в начале X1 и X2, maxX в конце и т.д.).
  • Найдите последовательные разности (X1[i + 1] - X1[i]), изменив порядок для второй группы (X2[i] - X2[i + 1]). Сохраните их в списках XVec и YVec.
  • Randomize (shuffle) YVec и обрабатывать каждую пару XVec[i] и YVec[i] как 2D-вектор.
  • Сортируйте эти векторы по углу, а затем отложите их от конца до конца, чтобы сформировать многоугольник.
  • Переместите многоугольник в исходные минимальные и максимальные координаты.

Анимация и реализация Java доступны здесь: Генерация случайных выпуклых многоугольников.

Этот алгоритм основан на статье Павла Вальтра: " Вероятность того, что n случайных точек находятся в выпуклой позиции". Дискретная и вычислительная геометрия 13.1 (1995): 637-643.