Генерація випадкових карт - стратегії розсіювання / кластеризації випадкових вузлів


10

Я роблю просту стратегію 4X стратегії в просторі, де кожен вузол є цікавою точкою (планета, астероїд тощо).

Щоб довільно генерувати карту, я б виконував наведені нижче дії

  1. Визначте, який тип кожного вузла матиме карта (можливо, скажімо, 5 планет, подібних до Землі, 10 безплідних планет тощо)

  2. Розмістіть на карті кожен тип вузла.

На кроці 2 я хотів би мати рівномірне поширення кожного типу вузлів. Так, наприклад, я би почав з розміщення всіх планет, подібних до Землі. Якщо я просто виконаю рейд (map.width, map.height), щоб визначити позицію, я можу в кінцевому підсумку всі землеподібні планети згрупуватися разом, що дасть перевагу гравцеві, який починає в цій області.

Чи існують якісь методи, такі як використання різних графічних функцій або функція шуму, які могли б генерувати послідовність координат (x, y), які розкидані одна від одної. Так само, чи існують способи створення координат, близьких один до одного?


1
Будь ласка, позначте відповідь як прийняту, будь то моя чи чужа. Дякую.
Інженер

Відповіді:


8

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

  1. Розділіть свій простір на сектори (наприклад, якщо у вас площа 100 на 100, і вам потрібно генерувати 100 цих сонячних систем, а потім розділіть свою область на 10 на 10 сітки секторів)

  2. Проведіть цикл через кожен сектор і повторіть крок 3 (який, у свою чергу, повторить крок 4 кілька разів)

  3. Випадково визначте кількість планет для поточної сонячної системи (наприклад, для діапазону від 3 до 7 планет, просто придбайте випадкове число, що становить від 0 до 4, і додайте 3) у поточному секторі (якщо у вас є більше однієї сонячної енергії система в секторі, саме тут ви встановите інший цикл)

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

Ви також можете визначити зону "поза межами" біля краю кожного сектора, щоб запобігти прямим контактам планет із сусідніх секторів (на випадок, якщо вони фактично були випадковим чином розташовані поруч), або. ..

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


Ласкаво просимо! І +1, щоб розмістити деяку інформацію про те, що вирішило вашу проблему. =)
Рандольф Річардсон

8

Найкращий спосіб забезпечити рівномірний розподіл - це трактувати кожен вузол як якусь фізичну частинку. Спочатку зробіть випадковий розподіл по неперервній площині xy. Застосовуючи сили відштовхування між кожною окремою парою окремих частинок на площині, ви виявите, що вони повільно поширюються. У певному сенсі це як дозвіл на зіткнення, тільки про фактичний контакт не можна говорити. Тоді це просто перетворити цю площину ("розпарити її") назад в цілочисельну індексовану сітку. Ви можете просто зробити це з цілочисельної індексованої сітки для початку, але може бути дещо складніше отримати речі "приємними" - це залежить від того, наскільки висока роздільна здатність вашої сітки ... чим вище, тим краще , в цьому випадку.

Очевидно, що ви можете також застосувати якісь сили з країв квадратної площини, інакше ви можете виявити безліч частинок, що "миються на березі". Крім того, ви можете створити поле набагато більше, ніж потрібно, а потім зробіть знімок невеликої площі, що уникне вищезгаданої проблеми.

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


1
Ви також можете отримати кластерну поведінку за допомогою моделі "фізики", вам просто доведеться використовувати інший набір правил, можливо, використовуючи поєднання тяжіння та відштовхування. Варіантів нескінченно, все, що потрібно зробити - це знайти правильну модель.
aaaaaaaaaaaa

6

Для отримання розподілу "синього шуму" ви можете використовувати простий алгоритм розподілу Пуассона на диску . Це призводить до того, що в площині точки розташовані приблизно однаково один від одного. Це працює не лише у вашому 2D прикладі, але і в 3D, а також у неевклідових просторах, але обчислення можуть швидко стати непростими.

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

Швидкий та елегантний альтернативний алгоритм для генерування 2D такого шуму, а також коротке обговорення їх властивостей можна знайти у " Просторовій структурі даних для швидкого генерування проби Пуассона-Диска " Деніела Данбара та Грега Хамфріса з університету Вірджинії.


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