У меня есть процедурно сгенерированная карта с использованием ячеек Вороного, с определенным уровнем моря и правдоподобной картой высот.
До сих пор мне удавалось маркировать определенные географические особенности: суша, океан, озера, реки, лиманы, слияния, горы и биомы. Биомы включают тундру, бореальный лес, луга и умеренный лес. Там также есть пара других биомов, но для моих целей они сейчас не важны.
Я хотел бы обозначить заливы и проливы рядом, но я не знаю, как это сделать правильно. Залив - это утопленный прибрежный водоем, который напрямую соединяется с океаном.
Пролив - это естественный узкий водный путь, соединяющий две части океана. В основном, где два клочка земли почти соприкасаются, и с обеих сторон есть океан. Также называется "каналом".
Для определения функций я могу просмотреть любую функцию по типу:
for each (var feature:Object in geography.getFeaturesByType(Geography.LAND))
// loop through lands
for each (var cell:Cell in feature.cells)
// loop through cells
for each (var neighbor:Cell in cell.neighbors)
// loop through a cell's neighbors
trace(neighbor.hasFeatureType(Geography.LAND));
источник
Ответы:
Способ, которым Dragons Abound идентифицирует заливы, состоит в том, чтобы пройти вдоль береговой линии и найти две точки на береговой линии, где прямое расстояние между точками меньше, чем расстояние вдоль береговой линии между точками. Это извилистость береговой линии между двумя точками. Выбрав предел извилистости и пределы для прямой линии между пятнами, вы можете определить узкие глубокие заливы, широкие неглубокие заливы и т. Д.
На этом рисунке красные и фиолетовые точки показывают две точки-кандидата, а зеленая линия является береговой линией между точками. Извилистость - это отношение этих двух длин:
Кроме того, вы можете выбрать две точки на побережье и создать многоугольник, соединив две точки и береговую линию между двумя точками (то есть, соедините зеленую линию выше от красной точки до фиолетовой точки). Измерьте площадь этого многоугольника. Залив будет иметь большую площадь, чем не-залив.
По моему опыту, комбинация этих двух мер была лучшей для надежной идентификации того, что люди видят как отсеки.
Обратите внимание, что это также обнаружит точки. Чтобы найти только бухты, вам нужно проверить, что «внутри» бухты содержится вода, а не земля. Быстрый и простой способ сделать это - проверить среднюю точку линии между двумя точками, чтобы убедиться, что это вода. (Это можно одурачить, но, как правило, достаточно.)
Связанная проблема заключается в определении «устья» бухты, т. Е. Наилучшего выбора для двух точек, обозначающих отверстие в бухте. Как правило, у вас будет куча кандидатов на «рот». На приведенном выше примере карты вы можете расположить устье этого залива дальше или дальше. Вообще говоря, это, вероятно, не имеет большого значения, но одна эвристика, которая работает достаточно хорошо, это минимизировать прямолинейное расстояние через рот.
Я еще не пролил проливы, но моя интуиция заключается в том, чтобы проверять точки вдоль береговой линии, чтобы найти ближайшую точку на любой другой береговой линии; если это ниже определенного предела, это пролив.
источник
Вот примерная идея, использующая преобразования обработки изображений для выделения интересующих функций:
Примените заливку из океанской клетки, чтобы создать маску из всех океанских клеток. В зависимости от того, как настроены ваши реки, вам может понадобиться дополнительный критерий высоты или клиренса, чтобы не допустить смещения океанской маски внутрь страны. ;)
Примените локальное сглаживание к краю этой маски, сохраняя неизменность связности / топологии, но сглаживая небольшие шумные элементы береговой линии, которые могут отвлекать. Это позволяет нам сосредоточиться на больших бухтах над крошечными входами. Вы можете использовать ширину ядра фильтра / количество итераций, чтобы точно контролировать масштаб сохраняемых вами функций.
Здесь я применил медианный фильтр несколько раз. Клеточные автоматы - еще один популярный способ размывать плавные формы из-за шумного ввода.
Превратите маску в поле расстояния, где каждая ячейка хранит свое расстояние от сглаженной береговой линии.
Теперь мы видим некоторые многообещающие особенности. В поле с обозначенными расстояниями заливы и проливы отображаются в виде острых выступов, причем расстояние уменьшается в стороны. Мы можем использовать фильтр обнаружения края, чтобы вытащить эти гребни:
Затем вы можете различить заливы и проливы, следуя по гребню, чтобы определить его связность. Залив - это горный хребет, который бежит к побережью, становясь все более и более мелким (на расстоянии от земли), пока не заканчивается в точке. Пролив - это горный хребет, который соединяет область большого расстояния с другой областью большого расстояния, проходя через область меньшего расстояния по пути.
Или другой способ - назначить каждому острову идентификатор (поиск связанного компонента), а затем, когда вы создаете поле расстояния, распространяйте «идентификатор ближайшего острова» вдоль границы расстояния. Бухта или залив - это гребень в воде, примыкающий к одной и той же суше с обеих сторон, а канал - это гребень, который разделяет воду, примыкающую к двум разным массам суши.
Вы можете установить минимальные и максимальные ограничения расстояния до берега или длины хребта, чтобы контролировать, какие объекты маркировать, например, если вам необходимо исключить чрезмерно узкие / широкие проливы.
источник
По сути, вам нужно подумать о том, что именно вы подразумеваете под заливом или проливом, и почему вы хотите их дифференцировать (это для расчетов ИИ, или для обозначения ориентиров, или для чего-то еще?). Поиграйте с несколькими определениями, чтобы найти то, которое вам больше всего подходит. Затем сформулируйте условия для проверки ваших клеток Вороного. Несколько предложений:
залив
Пролив
источник