Проблема
Я хочу разделить сетку (двумерный массив) на части произвольной формы (например, тектонические плиты Земли ).
Критерии:
- Пользователь вводит размер сетки (программа должна масштабироваться, поскольку она может быть очень большой).
- Пользователь вводит коэффициент деления сетки (сколько частей).
- Сетка представляет собой шестигранную решетку прямоугольной формы, которая закрывается сверху и снизу, оборачивается вокруг слева и справа.
- Нет фрагментации частей.
- Нет частей внутри других частей.
- Никаких крошечных или сверхбольших частей.
- Части произвольной формы, которые не являются идеальными кругами или вытянутыми змеиными формами.
Мое решение:
- Создать метод, который может получить доступ / манипулировать соседними ячейками.
- Произвольно определить размер каждой части (сумма всех частей равна размеру всего двумерного массива).
- Заполните весь двумерный массив идентификатором последней части.
- Для каждой части, кроме последней:
- Поместить текущий номер детали в случайную ячейку двумерного массива.
- Выполните итерацию по всему массиву и сохраните адрес каждой ячейки рядом с любыми ячейками, которые уже заполнены текущим номером детали.
- Извлеките один из сохраненных адресов и заполните эту ячейку текущим идентификационным номером пластины (и, таким образом, деталь начнет формироваться).
- Повторяйте, пока не будет достигнут размер детали.
Обратите внимание: чтобы избежать частей с длинными вытянутыми "руками" или большими отверстиями внутри них, я создал два массива хранения: один для соседних ячеек
только одну ячейку с текущим номером идентификатора детали, а другую - для ячеек, смежных с более чем одной, тогда я исчерпываю последнюю перед первой.
Запуск моего решения дает следующее:
Размер сетки: 200
ширина: 20
высота: 10
Запчасти: 7
66633333111114444466
00033331111114444466
00003331111114444466
00003331111144444660
00000333111164444660
00000336111664422600
00000336615522222200
00006655555522222200
00006655555552222220
00066655555552222220
Номер детали: 0
Размер части: 47
Номер детали: 1
Размер детали: 30
Номер детали: 2
Размер части: 26
Номер детали: 3
Размер части: 22 * 1079 *
Номер детали: 4
Размер части: 26
Номер детали: 5
Размер части: 22 * 1085 *
Номер детали: 6
Размер части: 27
Проблемы с моим решением:
- Последняя часть всегда фрагментирована - в приведенном выше случае есть три отдельные группы по шесть человек.
- Алгоритм остановится, когда детали образуются в тупиках, и у них нет места для увеличения до их полного размера (алгоритм не позволяет формировать детали поверх других деталей, если это не последняя деталь, которая установлена по всему массиву 2D в начале).
- Если я не укажу размеры деталей перед формированием массива 2d, а просто укажу количество деталей и случайное генерирование размеров деталей на лету, это оставляет возможность формирования крошечных деталей, что может даже не быть там вообще, особенно когда двумерный массив очень большой. Мой текущий метод определения размера деталей ограничивает размеры деталей до 10-40% от общего размера двумерного массива. Я могу согласиться с тем, чтобы не указывать размеры частей, если есть какой-то супер-элегантный способ сделать это - единственный элемент управления, который будет у пользователя, - это размер двухмерного массива и количество частей.
Другие идеи:
- Сформируйте части в идеально выровненные квадраты, затем обведите 2D-массив и случайным образом разрешите каждой части вторгаться в другие части, деформируя их в случайные формы.
- Нарисуйте змеевидные линии по сетке и заполните созданные места, возможно, используя некоторую математику, подобную этой: http://mathworld.wolfram.com/PlaneDivisionbyLines.html
Вывод:
Так вот в чем суть: я начинающий программист, который не уверен, правильно ли я решаю эту проблему.Я могу создать еще несколько методов «исправления», которые сдвигают фрагментированные части вместе и позволяют формирующимся частям «выпрыгивать» из тупиков, если они застряли в них, но это кажется грязным.1118 * Как бы вы подошли к этой проблеме?Есть ли какая-нибудь сексуальная математика, которую я мог бы использовать, чтобы упростить вещи возможно?
Thx