Я хочу создать последовательность чисел для процедурно генерирующих планет в галактическом секторе. Каждая планета должна располагаться случайным образом, однако очень маловероятно, что две планеты находятся непосредственно рядом друг с другом. Как я могу этого достичь?
Я знаю, что вы можете изменить шансы, применяя функцию распределения, но как я могу управлять ими, чтобы повысить вероятность определенных значений?
mathematics
procedural-generation
random
API-Beast
источник
источник
Ответы:
Если вы знаете, какое распределение вы хотите, вы можете использовать выборку отклонения .
Самый простой способ: на графике выше выбирайте точки случайным образом, пока не найдете точку ниже кривой. Тогда просто используйте
x
-координату.Для фактического распространения существуют различные вероятные подходы. Например, для номера планеты
i
в местоположенииp
и некоторого параметра прочностиk
(например0.5
), определите функциюf_i(x)=abs(p-x)^k
, затем используйте функцию распределенияg(x)=f_1(x)*f_2(x)*...*f_n(x)
.На практике вычислить и сохранить результаты
g(x)
для arrayt
(t[x]=g(x)
); помните также самое высокое значениеh
. Выберите случайное положениеx
вt
, выбрать случайное значениеy
между0
иh
повторитеif y>t[x]
; в противном случае возвращается значениеx
.источник
Я не уверен, что проблема полностью указана в этом вопросе, но я могу дать несколько простых идей, вторая из них будет содержать цифры примерно в соответствии с тем, что ваша картинка указывает на то, что вы хотите.
В любом случае, как вы понимаете, функция распределения меняется после каждого сгенерированного числа и имеет память (то есть: она не является марковской ), и любой из этих методов может оказаться непрактичным, когда «память» (число ранее нарисованных чисел) получает очень большой.
Просто:
генерируйте случайное число из плоского распределения, сравните с ранее нарисованными числами, повторите, если «слишком близко»
Этот ответ больше похож на вашу фигуру (при условии, что мы хотим извлечь из 0..1):
Контейнеры конечных точек - это особый случай, но он должен быть достаточно простым, чтобы вы могли понять, как с ними работать.
источник
Подумайте о разнице между 1 кубиком и 3 кубиками . 1 кубик дает вам равную вероятность для всех значений, в то время как 3 кубика будут иметь более высокую вероятность для значений ближе к середине.
Чем больше «кубиков» в вашем уравнении, тем больше у вас шансов получить что-то к центру. Итак, давайте определим функцию, которая может обрабатывать любое число равномерно :
Теперь мы можем определить пример функции, чтобы использовать это:
Теперь первое, что следует отметить, - этот код действительно не проверяет, соответствует ли сборщик одному из пунктов. Если это произойдет, то просто не будет генерировать точку, возможно, то, что вам может понравиться.
Чтобы объяснить, что здесь происходит, это то, что CenterRandom создает своего рода кривую колокола. Эта функция разбивает плоскость на несколько кривых колокольчиков, по одной на пару существующих точек. Сборщик говорит нам, из какой кривой колокола генерировать. Поскольку мы выбираем линейно, мы можем гарантировать, что пары с большими промежутками между ними будут выбираться чаще, но мы все равно оставляем их совершенно случайными.
Надеюсь, что это указывает вам в правильном направлении.
источник
Я знаю, что вы спрашиваете о последовательности случайных положений, но если вы не ограничены последовательным генерированием набора, есть другой подход: создать набор точек с желаемым интервалом.
Я думаю, что вы хотите, чтобы набор планет, которые разумно разнесены с некоторой случайностью. Вместо того, чтобы генерировать положения планет с помощью генератора случайных чисел, генерируйте расстояние между планетами с помощью генератора случайных чисел. Это позволит вам напрямую контролировать распределение интервалов, используя генератор случайных чисел, который выбирает из этого распределения. Это просто в одном измерении.
В двух измерениях я видел несколько подходов, которые генерируют «синий шум», но я не знаю, как создать интервал с произвольным распределением. В этой статье описывается стандартный подход «попробуйте разместить его и отклонить, если он слишком близок», но вы можете сгенерировать их все сразу, с помощью «более мягкого» решения, разместив все свои точки, а затем с помощью Lloyd Relaxation переместить все планеты к более желательные позиции. Это раздвинет слишком близкие планеты дальше друг от друга. Рекурсивные плитки Ван - еще один подход, который может оказаться полезным. Эта бумагарасширяет задачу создания планет с одной плотностью и некоторых других объектов, таких как астероиды с другой плотностью. Вы также можете генерировать синий шум, используя ряды Фурье; Я не уверен. Подход ряда Фурье также позволил бы вам использовать произвольные распределения вместо только синего шума.
источник