Разделить сетку (2D массив) в части случайной формы?

Проблема
Я хочу разделить сетку (2D массив) в части случайной формы (думайте тектонические плиты земли).

Критерии:

  • Размер сетки вводов данных пользователем (программа должна масштабироваться, потому что это могло быть очень большим).
  • Фактор подразделения сетки вводов данных пользователем (сколько частей).
  • Сетка является шестнадцатеричной сеткой прямоугольной формы и ограничивается вершина и нижняя часть, повторитесь левый и правый.
  • Никакая фрагментация частей.
  • Никакие части в других частях.
  • Никакие крошечные или суперзначительные части.
  • Части случайной формы, которые не являются идеальными кругами или ослабевшими ползущими формами.

Мое решение:

  • Создайте метод, который может получать доступ/управлять к смежным ячейкам.
  • Случайным образом определите размер каждой части (сумма всех частей равняются размеру целого 2D массива).
  • Заполните весь 2D массив идентификационным номером последней части.
  • Для каждой части кроме последнего:
  • Отберите текущий идентификационный номер части в случайной ячейке 2D массива.
  • Выполните итерации по целому массиву и сохраните адрес каждой ячейки, смежной с любыми ячейками, уже отобранными с текущим идентификационным номером части.
  • Извлеките один из сохраненных адресов и заливки, что ячейка с текущим идентификационным номером пластины (и таким образом, часть начинает формироваться).
  • Повторитесь, пока размер части не будет достигнут.

Обратите внимание, что для предотвращения частей с длинным растянуло "руки" или большие дыры в них, я создал два массива хранения данных: один для ячеек, смежных со всего одной ячейкой с текущим идентификационным номером части и другим для ячеек, смежных больше чем с одним, затем, я исчерпываю последнего перед первым.

Выполнение моего решения дает следующее:
Размер сетки: 200
ширина: 20
высота: 10
Части: 7

66633333111114444466
00033331111114444466
00003331111114444466
00003331111144444660
00000333111164444660
00000336111664422600
00000336615522222200
00006655555522222200
00006655555552222220
00066655555552222220

Номер детали: 0
Размер части: 47

Номер детали: 1
Размер части: 30

Номер детали: 2
Размер части: 26

Номер детали: 3
Размер части: 22

Номер детали: 4
Размер части: 26

Номер детали: 5
Размер части: 22

Номер детали: 6
Размер части: 27

Проблемы с моим решением:

  • Последняя часть всегда фрагментируется - в случае выше существует три отдельных группы шестерок.
  • Алгоритм остановится, когда форма частей в тупиках и не будет иметь пространство для роста до их полного размера (алгоритм не позволяет являться частями по другим частям, если это не последняя часть, которая установлена по всему 2D массиву в запуске).
  • Если я не указываю размеры части прежде, чем сформировать 2-й массив и просто умею обойтись определением количества частей и случайным образом генерации размеров части на лету, это оставляет открытым возможность крошечных частей сформированный, который не мог бы также быть там вообще, особенно когда 2D массив является очень большим. Мой текущий метод размера части ограничивает размеры частей между 10% и 40% общего размера 2D массива. Я могу быть хорошо с не определением размеров частей, если существует некоторый суперизящный способ сделать это - единственный контроль, который будет иметь пользователь, 2-й размер массива и количество частей.

Другие идеи:

  • Явитесь частями в отлично выровненных квадратах, затем работайте на основе 2D массива и случайным образом позвольте каждой части посягать на другие части, деформировав их в случайные формы.
  • Проведите ползущие линии через сетку и заполните созданные пространства, возможно, с помощью некоторой математики как это: http://mathworld.wolfram.com/PlaneDivisionbyLines.html

Заключение:
Таким образом, вот протирание: Я - программист новичка, который не уверен, если я занимаюсь этой проблемой правильным способом. Я могу создать еще многие, "исправляют" методы, тот сдвиг фрагментированные части вместе, и позволяют являться частями для "выскакивания" тупиков, если они застревают в них, но это чувствует себя грязным.

Как Вы приблизились бы к этой проблеме? Есть ли некоторая сексуальная математика, которую я мог использовать для упрощения вещей, возможно?

Спасибо

8
задан denis 1 October 2010 в 11:12
поделиться

2 ответа

Несколько месяцев назад я сделал нечто подобное для игры, но это была прямоугольная сетка, а не шестигранная. Тем не менее, теория та же самая, и в результате были получены красивые смежные области примерно одинакового размера - некоторые были больше, некоторые меньше, но ни одна из них не была слишком маленькой или слишком большой. YMMV.

  1. Создайте массив указателей на все пробелы в вашей сетке. Перемешайте массив.
  2. Присвойте первым N из них идентификаторы - 1, 2, 3 и т. Д.
  3. Пока в массиве не будет указано ни одного пробела, у которого нет идентификатора,
  4. Перебрать массив в поисках пробелов, в которых нет ID
  5. Если у пространства есть соседи в сетке, у которых ДЕЙСТВИТЕЛЬНО есть идентификаторы, назначьте пространство идентификатор из взвешенного случайного выбора идентификаторов его соседей.
  6. Если у него нет соседей с идентификаторами, переходите к следующему.
  7. Когда нет непустых мест, у вас есть карта с достаточным количеством пятен.
5
ответ дан 5 December 2019 в 18:55
поделиться

Вот что я бы сделал: использовал алгоритм Вороного. Сначала разместите несколько случайных точек, а затем позвольте алгоритму Вороного сгенерировать части. Чтобы получить представление о том, как это выглядит, обратитесь: к этому приложению .

3
ответ дан 5 December 2019 в 18:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: