В даний час у мене є острови, які виглядають так:
І я хочу процедурно поділити його на такі регіони:
Який алгоритм робить те, що я шукаю? Чи є у вас пропозиції щодо створення узгоджених регіонів, як на нижньому малюнку. Ваша допомога вдячна.
В даний час у мене є острови, які виглядають так:
І я хочу процедурно поділити його на такі регіони:
Який алгоритм робить те, що я шукаю? Чи є у вас пропозиції щодо створення узгоджених регіонів, як на нижньому малюнку. Ваша допомога вдячна.
Відповіді:
У реальному світі ці провінційні кордони часто дотримуються таких геологічних особливостей, як річки.
То, може, вдалим підходом було б моделювати геологію острова і не допустити до цього меж?
Red Blob Games має кілька хороших статей на цю тему, з приємними результатами.
Схоже, його підхід передбачає використання тесселяції Вороного та визначення річок як меж між осередками.
Перегляньте інші статті на його сайті, він багато написав на тему генерування карт .
Я вирішив би цю проблему двома проходами діаграм Вороного:
Перший прохід використовує дещо рідкий розподіл балів (тобто відстань між точками має бути відносно великим), щоб приблизно розділити острів на регіони (див. Примітку нижче щодо генерації точок). Далі створіть діаграму Вороного на основі цих пунктів. Це розділить острів на полігональні регіони навколо кожної точки, як показано нижче:
Тепер, коли острів був розділений на регіони, наступним кроком є «розчленування» меж між ними. Для цього створіть новий шар точок, використовуючи більш компактний розподіл точок (тобто відстань між точками має бути невеликим) і знову використовуйте ці точки для створення ще однієї діаграми Вороного. Далі для кожної меншої області призначте її для більшої області, перевіривши її "насіннєву" точку. Це призведе до більш чітких меж між більшими підрозділами. Ось докладний опис того, як це виглядає з обома діаграмами Вороного:
І ось ця сама область показує лише остаточні межі:
Щодо генерації точок, мені подобається використовувати розподіл дисків Пуассона , щоб отримати порівняно хороший і рівномірний розподіл очок. Інший поширений варіант - отримати аналогічний рівномірний розподіл - це використовувати алгоритм Ллойда на наборі "регулярних" випадкових точок. LLoyd's простіше кодувати, але може спробувати кілька помилок і визначити, скільки пропусків потрібно для отримання бажаного результату.
Одна з потенційних проблем такого підходу полягає в тому, що розділення першого проходу може генерувати деякі дуже малі регіони. Якщо ви не хочете, щоб вони були у вашому кінцевому результаті, я б просто об'єднав їх із випадковим сусіднім регіоном.
Надані нами ілюстрації бувають растровими зображеннями, але ця методика також працює з полігональними / векторними поданнями.
MineCraft робить це чудово, і його алгоритм світового покоління був ретельно проаналізований та задокументований.
Існують різні описи алгоритму, один з них тут: https://github.com/UnknownShadow200/ClassiCube/wiki/Minecraft-Classic-map-generation-algorithm
Ядро алгоритму - генератор шуму Перліна . Це контролює висоту безпосередньо (більш-менш, оскільки наступний крок по висіченню печер може також змінити поверхню), а також генерацію біома. Щось подібне до генератора біома, мабуть, те, що ви хочете використовувати для створення своїх областей.
(Стара версія його) задокументована , в основному вона працює за допомогою двох різних генераторів шуму Perlin, одного для "температури", одного для "опадів", а потім вибору біома з цих двох. Самі змінні (температура та опади) пізніше насправді не використовуються в грі; наприклад, у пустелях немає дощу, але гра визначає це з властивості "пустеля", а не від вихідного значення опадів.
Існують різні онлайн-інструменти для генерування карти біома з випадкового насіння, один з них - mineatlas.com . Я здогадуюсь, що внутрішньо вони використовують сервер java, який використовує внутрішні класи самого MineCraft; Я не знаю, чи доступний якийсь їх вихідний код.
Типовий алгоритм, який використовується, наприклад, Azgaar ( вихідний код) ). Приблизно так:
Якщо вам цікаво робити це у векторіальному форматі, а не на основі растрових підходів, я недавно написав допис у блозі про майже саме це.
http://blog.particracy.com/worlds-and-their-geography/
Ідея полягає в тому, що ви починаєте з сітки (зазвичай на основі Вороного) і вирощуєте регіони концентрично з випадково засіяних точок, достатньо розташованих один від одного.
Що цікаве питання :) Цей підхід начебто базується на клітинах Vornoi, але метрика відстані не зовсім євклідова (я використав потужність 1,5 замість 2,0) і в неї вбудована деяка випадковість. Він може перестрибнути через воду, що не ідеально.
Близькі регіони можна об'єднати разом, щоб отримати більш цікаві форми, тут я начебто використовував N найближчих сусідів для визначення цього.
Якщо ви зацікавлені, я можу розібратися в деталях та поділитися кодом Python.