Процедурно генерувати регіони на острові


29

В даний час у мене є острови, які виглядають так:

острів

І я хочу процедурно поділити його на такі регіони:

острів з регіонами

Який алгоритм робить те, що я шукаю? Чи є у вас пропозиції щодо створення узгоджених регіонів, як на нижньому малюнку. Ваша допомога вдячна.


Як ти вперше отримав цей образ острова? Ви її генерували, і якщо так, то як ви цього домоглися?
Vaillancourt

Я отримав це від онлайн-генератора карт.
domisum

Вибачте за затримку в оновленні моєї відповіді - повернутися додому потрібно довше, ніж спочатку планувалося. Я додав ілюстрацій та посилань.
Пікалек

Якщо ви отримали це від онлайн-генератора, вам слід подивитися на генератор фантазійних карт Azgaar . Він має регіони та назви з налаштованими параметрами, і WB.SE вітається. Це github, тому ви, можливо, зможете перевірити їх код.
Anoplexian

Відповіді:


40

У реальному світі ці провінційні кордони часто дотримуються таких геологічних особливостей, як річки.

То, може, вдалим підходом було б моделювати геологію острова і не допустити до цього меж?

Red Blob Games має кілька хороших статей на цю тему, з приємними результатами.

Схоже, його підхід передбачає використання тесселяції Вороного та визначення річок як меж між осередками.

Перегляньте інші статті на його сайті, він багато написав на тему генерування карт .

острів


3
Зауважте, що в реальному світі політичні чи адміністративні поділи також іноді мають довільні поділи, як правило, прямі (наприклад, уздовж широтних / поздовжніх ліній, ліній між гірськими вершинами тощо).
Пабло Н

2
@PabloH Добре, хоча прямі кордони здаються явищем колоніальної епохи після посередництва. Але оскільки ми не знаємо про встановлення проблеми ОП, це може бути актуальним
Sentry

27

Я вирішив би цю проблему двома проходами діаграм Вороного:

Перший прохід: Розбиття регіону

Перший прохід використовує дещо рідкий розподіл балів (тобто відстань між точками має бути відносно великим), щоб приблизно розділити острів на регіони (див. Примітку нижче щодо генерації точок). Далі створіть діаграму Вороного на основі цих пунктів. Це розділить острів на полігональні регіони навколо кожної точки, як показано нижче:

введіть тут опис зображення

Другий прохід: Рандомізація кордону

Тепер, коли острів був розділений на регіони, наступним кроком є ​​«розчленування» меж між ними. Для цього створіть новий шар точок, використовуючи більш компактний розподіл точок (тобто відстань між точками має бути невеликим) і знову використовуйте ці точки для створення ще однієї діаграми Вороного. Далі для кожної меншої області призначте її для більшої області, перевіривши її "насіннєву" точку. Це призведе до більш чітких меж між більшими підрозділами. Ось докладний опис того, як це виглядає з обома діаграмами Вороного:

введіть тут опис зображення

І ось ця сама область показує лише остаточні межі:

введіть тут опис зображення

Коментарі щодо покоління точок

Щодо генерації точок, мені подобається використовувати розподіл дисків Пуассона , щоб отримати порівняно хороший і рівномірний розподіл очок. Інший поширений варіант - отримати аналогічний рівномірний розподіл - це використовувати алгоритм Ллойда на наборі "регулярних" випадкових точок. LLoyd's простіше кодувати, але може спробувати кілька помилок і визначити, скільки пропусків потрібно для отримання бажаного результату.

Одна з потенційних проблем такого підходу полягає в тому, що розділення першого проходу може генерувати деякі дуже малі регіони. Якщо ви не хочете, щоб вони були у вашому кінцевому результаті, я б просто об'єднав їх із випадковим сусіднім регіоном.

Заключні ноти

Надані нами ілюстрації бувають растровими зображеннями, але ця методика також працює з полігональними / векторними поданнями.


1
Для процедурних планів це те, що я роблю, робимо діаграму Вороного з точок всередині регіону (острова), будую сітку (вона не повинна бути прямокутною, для вашого випадку деформованою сіткою), яка охоплює той самий регіон, потім обчисліть булеві перетини сітки та Voronoi, обчисліть площі та призначте дерево даних (список списку, нерівний масив тощо), будь-яку структуру даних ви віддаєте перевагу) відповідно до 0,6 відсотка найменшої комірки сітки, ви отримаєте кілька відсутніх комірок, але ви можете порівняти свою сітку з оригіналом, щоб знайти та присвоїти вашому дереву.
Феліпе Гутьєррес

Ви додали зображення! Це саме те, що я роблю з іншою метою
Феліпе Гутьєррес

4

MineCraft робить це чудово, і його алгоритм світового покоління був ретельно проаналізований та задокументований.

Існують різні описи алгоритму, один з них тут: https://github.com/UnknownShadow200/ClassiCube/wiki/Minecraft-Classic-map-generation-algorithm

Ядро алгоритму - генератор шуму Перліна . Це контролює висоту безпосередньо (більш-менш, оскільки наступний крок по висіченню печер може також змінити поверхню), а також генерацію біома. Щось подібне до генератора біома, мабуть, те, що ви хочете використовувати для створення своїх областей.

(Стара версія його) задокументована , в основному вона працює за допомогою двох різних генераторів шуму Perlin, одного для "температури", одного для "опадів", а потім вибору біома з цих двох. Самі змінні (температура та опади) пізніше насправді не використовуються в грі; наприклад, у пустелях немає дощу, але гра визначає це з властивості "пустеля", а не від вихідного значення опадів.

Існують різні онлайн-інструменти для генерування карти біома з випадкового насіння, один з них - mineatlas.com . Я здогадуюсь, що внутрішньо вони використовують сервер java, який використовує внутрішні класи самого MineCraft; Я не знаю, чи доступний якийсь їх вихідний код.


4

Типовий алгоритм, який використовується, наприклад, Azgaar ( вихідний код) ). Приблизно так:

  1. розділіть свою земельну ділянку на менші площі, наприклад, через затримку триангуляції або вороної клітини.
  2. визначте (випадковим чином чи іншим чином) "вихідні" місця для ваших культур, царств, релігій та іншого, що ви хочете імітувати.
  3. визначити (випадковим чи іншим чином) "коефіцієнт росту" для кожного з них. Чим більше різниці у факторах росту, тим менш рівномірна ваша кінцева карта.
  4. Тепер перегляньте свої сфери (тощо) і, залежно від коефіцієнта росту, змусьте їх розповсюджуватись на навколишні, порожні плитки, поки вся карта не заповниться.
  5. Ви, мабуть, хочете трохи закінчити випрямлення меж, перемикаючи клітини, які мають лише одного сусіда у своєму кольорі і в іншому випадку оточені іншим кольором.

3

Якщо вам цікаво робити це у векторіальному форматі, а не на основі растрових підходів, я недавно написав допис у блозі про майже саме це.

http://blog.particracy.com/worlds-and-their-geography/

Ідея полягає в тому, що ви починаєте з сітки (зазвичай на основі Вороного) і вирощуєте регіони концентрично з випадково засіяних точок, достатньо розташованих один від одного.


2

Що цікаве питання :) Цей підхід начебто базується на клітинах Vornoi, але метрика відстані не зовсім євклідова (я використав потужність 1,5 замість 2,0) і в неї вбудована деяка випадковість. Він може перестрибнути через воду, що не ідеально.

Близькі регіони можна об'єднати разом, щоб отримати більш цікаві форми, тут я начебто використовував N найближчих сусідів для визначення цього.

Якщо ви зацікавлені, я можу розібратися в деталях та поділитися кодом Python.

карта 1 карта 2

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.