Удаление озер с алмазной квадратной карты

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

пример карты высот

Это изображение показывает неокрашенную карту высот введите описание изображения здесь

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

Я исследовал простую функцию размывания прямоугольника (устанавливая каждый пиксель в среднем для своих соседей), но это вызывает странные артефакты, возможно, из-за шага квадрата алмазного квадрата.

Подойдет ли другое (возможно, гауссовское) размытие, или это проблема с моей реализацией? Эта ссылка говорит, что у алмазного квадрата есть некоторые присущие ему проблемы, но, похоже, они не являются регулярно расположенными артефактами, и моя карта высот заполнена 16 (а не 4) значениями.

1 ответ

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

Чтобы это исправить, нужно по существу определить размеры областей воды и разрешить только большие площади.

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

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

Так что лучше сделать еще один шаг и считать ширину и длину отдельно.

например, чтобы обнаружить простой одиночный пиксель

если map[i,j] <порог && (карта [i-1, j-1]> порог && ... && map[i+1,j+1] > порог), тогда Area = 1

обнаружит изолированные пиксели.

Вы можете изменить это, чтобы обнаружить большие группы и написать общий алгоритм для измерения любого размера потенциальных "океанов"... тогда должно быть просто получить генерирование любой карты высот с любым океаном минимального (и максимального) размера, который вы хотите. Следующим шагом является "исправление" (или использование растрового изображения) частей карты, которые могут быть ниже уровня моря, но не преобразованы в реальную воду. то есть, поскольку мы обычно ожидаем, что вещи ниже уровня моря будут содержать воду. Используя растровое изображение, вы можете учесть воду в воде или воду в земле и т. Д.

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

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

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

Другие вопросы по тегам