Алгоритм генерування країв і вершин назовні від початку з максимальною кратністю 3


11

Я створюю 2-грі для веб-сайту, де Всесвіт може зростати надзвичайно великим (в основному нескінченно великим). Спочатку Всесвіт складається з 6 зірок, що знаходяться на рівній відстані від походження (0, 0). Моє завдання - вміти генерувати більше зірок, які матимуть «доріжки» (краї), які з'єднуються між собою. Як я можу створити алгоритм, який відповідає цим обмеженням:

  1. Зірки випадковим чином породжуються назовні. (наприклад (x, y) координати для нових зірок повільно будуть виходити назовні від (0, 0) у всіх напрямках, бажано у спіральному форматі)
  2. Краї НЕ перетинаються.
  3. Хоча має бути певна дисперсія, нові зірки не повинні бути занадто далеко або занадто близько до інших зірок. (Наприклад, має бути мінімальний радіус)
  4. Жодна зірка / точка не повинна мати кратність більше 3.
  5. Зважаючи на те, що все це буде зберігатися в базі даних, алгоритм не може бути надто дорогим. Іншими словами, я хотів би досягти чогось із (n) складності (не знаю, чи це можливо).

По суті, те, за що я йду, - це спіралеподібна галактика, де зорі - точки на графіку, а подорож між зірками зображено ребрами між цими зірками.

Конкретні кроки, які мені потрібно вирішити:

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

Я намагався шукати рішення, але мої математичні навички (та знання з теорії графіків) потребують багато роботи. Також будь-які ресурси / посилання з цього питання були б вдячні.

Ось якийсь псевдо-код, про який я думав, але я не впевнений, чи це навіть спрацює, і я впевнений, що він не буде дуже добре після кількох 10000 зірок тощо.

newStar = randomly generated (x, y) within radius of last star from origin
while(newStar has not been connected):
    for (star in the known universe):
        if(distance between newStar and star > x units):
            if(star has < 3 multiplicity):
                if(path from newStar to star does not intersect another path):
                    connect the star to the other star
                    break;

    newStar = new random (x, y) coordinate

Крім того, якщо хтось має поради щодо того, як я повинен зберігати це в базі даних MySQL, я також вдячний за це.

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


1
Мандрівник по цьому Всесвіту, ймовірно, рухатиметься в одному напрямку, тобто якщо у вас не буде зірок, вам доведеться генерувати зірки в усіх напрямках від початку. Один нудний користувач може зламати вашу базу даних, іншими словами. Ви розглядали таку можливість (припускаючи, що це може бути проблемою)?
Ніл

2
Також інша думка, розміщення зірок не потрібно пам’ятати. Якщо ви використовуєте відтворене покоління зірок, ви можете створити зірки, які користувач міг би бачити таким чином, що ці зірки будуть генеруватися таким же чином у майбутньому. Значить, у вашій базі даних потрібно зберігати інформацію лише про зірки. Її позиція - це її ідентичність.
Ніл

1
Що ви будете робити, якщо кожна згенерована зірка має точно кратність 3, тому крок 1 провалиться? Будь-чому, чому на вашому малюнку одна точка з кратністю 4, це помилка?
Док Браун

1
Ні. Якщо ви зможете генерувати зірки передбачуваним способом, тоді це буде так, як ніби вони завжди були там, якщо ви підете, а потім повернетесь. Лише алгоритм і насіння не змінюються.
Ніл

2
@JF Не бачимо нікого чоловічого неба . Хлопець буквально породжує всесвіт. Він зберігає лише планети, які відвідали гравці, і все ж існуючі планети залишаються на своїх відповідних місцях. Все засноване на використанні належного насіння, яке використовується для отримання випадкових чисел.
Ніл

Відповіді:


2

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

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

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

Як це зробити: Знайдіть фрактальні генератори місцевості. Для цього є безліч безкоштовних та відкритих кодів. Вам потрібен лише базовий код, який генерує значення висоти для кожної точки на карті. Ми будемо використовувати його по-іншому. Використовуйте цей код для створення ДВА незалежних карт висоти місцевості. Почніть зі справжнього положення X, Y зірки, перегляньте це місце на кожній карті, використовуйте одне значення карти для компенсації положення відображення X зірки та використовуйте інше значення карти для компенсації положення Y-зірки Y зірки. Вам доведеться пограти з деякими коефіцієнтами масштабування, але це може дати вам ефект випадково викривленого гумового листа. Великі варіації положення зірки повинні повністю приховувати основні упорядковані положення. Фрактальний характер випадковості дасть дуже природний вигляд,

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