Saya ingin menghasilkan urutan angka untuk menghasilkan planet secara prosedural di sektor galaksi. Setiap planet harus ditempatkan secara acak, namun sangat kecil kemungkinannya bahwa dua planet secara langsung bersebelahan. Bagaimana saya bisa mencapainya?
Saya tahu bahwa Anda dapat memodifikasi peluang dengan menerapkan fungsi distribusi, tetapi bagaimana saya bisa mengendalikannya untuk membuat nilai tertentu lebih / kurang mungkin?
mathematics
procedural-generation
random
API-Beast
sumber
sumber
Jawaban:
Jika Anda tahu distribusi yang Anda inginkan, Anda dapat menggunakan sampel penolakan .
Cara termudah: Pada grafik di atas, pilih titik secara acak hingga Anda menemukan satu di bawah kurva. Maka gunakan saja
x
-coordinate.Untuk distribusi aktual, ada berbagai pendekatan yang masuk akal. Misalnya, untuk nomor planet
i
di lokasip
, dan beberapa parameter kekuatank
(misalnya0.5
), tentukan fungsif_i(x)=abs(p-x)^k
, lalu gunakan fungsi distribusig(x)=f_1(x)*f_2(x)*...*f_n(x)
.Dalam praktiknya, hitung dan simpan hasil
g(x)
to arrayt
(t[x]=g(x)
); ingat nilai tertinggi yang terlihath
juga. Pilih posisi acakx
dit
, memilih nilai acaky
antara0
danh
, ulangiif y>t[x]
; jika tidak nilai pengembaliannya adalahx
.sumber
Saya tidak yakin masalahnya ditentukan sepenuhnya oleh pertanyaan, tetapi saya dapat memberikan beberapa ide sederhana, yang kedua ini akan memberikan angka kira-kira sesuai dengan apa yang ditunjukkan gambar yang Anda inginkan.
Apa pun cara Anda menyadari fungsi distribusi berubah setelah setiap angka yang dihasilkan, dan memiliki memori (yaitu: itu non-Markovian ) dan salah satu dari metode ini terbukti tidak praktis ketika 'memori' (jumlah angka yang diambil sebelumnya) mendapat sangat besar.
Sederhana:
Hasilkan angka acak dari distribusi datar, bandingkan dengan angka sebelumnya yang ditarik, ulangi jika 'terlalu dekat'
Jawaban ini lebih seperti sosok Anda (dengan asumsi kami ingin menggambar dari 0..1):
tempat sampah endpoint adalah kasus khusus, tetapi harus cukup sederhana bagi Anda untuk melihat cara menanganinya.
sumber
Pikirkan perbedaan antara 1 dadu dan 3 dadu . 1 Dadu memberi Anda probabilitas genap untuk semua nilai, sedangkan 3 dadu cenderung memiliki probabilitas lebih tinggi untuk nilai-nilai ke arah tengah.
Semakin banyak "dadu" dalam persamaan Anda, semakin kuat peluang Anda untuk mendapatkan sesuatu ke tengah. Jadi mari kita mendefinisikan fungsi yang dapat menangani angka apa pun secara merata :
Sekarang kita dapat mendefinisikan fungsi contoh untuk menggunakan ini:
Sekarang yang pertama dicatat adalah bahwa kode ini benar-benar tidak memeriksa apakah pemilih sudah cocok dengan salah satu poin. Jika ya maka itu tidak akan menghasilkan poin, mungkin sesuatu yang mungkin Anda sukai.
Untuk menjelaskan apa yang terjadi di sini adalah bahwa CenterRandom menghasilkan semacam kurva lonceng. Fungsi ini memecah pesawat menjadi beberapa kurva lonceng, satu per pasang poin yang ada. Pemetik memberi tahu kami kurva lonceng mana yang akan dihasilkan. Karena kami memilih secara linear, kami dapat memastikan bahwa pasangan dengan celah yang lebih besar di antara mereka akan dipilih lebih sering, tetapi kami masih membiarkannya sepenuhnya acak.
Semoga ini menunjukkan Anda ke arah yang benar.
sumber
Saya tahu Anda bertanya tentang urutan posisi acak, tetapi jika Anda tidak dibatasi untuk menghasilkan set secara berurutan, ada pendekatan lain: menghasilkan serangkaian poin yang memiliki jarak yang diinginkan.
Apa yang saya pikir Anda inginkan adalah seperangkat planet yang cukup masuk akal dengan beberapa keacakan. Alih-alih menghasilkan posisi planet dengan generator angka acak, buat spasi planet dengan generator angka acak. Ini akan memungkinkan Anda mengontrol distribusi jarak secara langsung, dengan menggunakan generator angka acak yang mengambil dari distribusi tersebut. Ini mudah dalam 1 dimensi.
Dalam 2 dimensi, saya telah melihat beberapa pendekatan yang menghasilkan "noise biru" tapi saya tidak tahu cara menghasilkan spasi dengan distribusi sewenang-wenang. Artikel ini membahas pendekatan standar "cobalah menempatkannya dan tolak jika terlalu dekat", tetapi Anda dapat menghasilkan semuanya sekaligus, dengan solusi "lebih lunak" dengan menempatkan semua poin Anda, kemudian menggunakan Lloyd Relaxation untuk memindahkan semua planet ke lebih banyak posisi yang diinginkan. Ini akan memindahkan planet yang terlalu dekat lebih jauh. Ubin Wang Rekursif adalah pendekatan lain yang bisa berguna. Kertas inimemperluas masalah untuk menghasilkan planet dengan satu kerapatan dan beberapa objek lain seperti asteroid dengan kerapatan lain. Anda mungkin juga dapat menghasilkan noise biru dengan menggunakan seri Fourier; Saya tidak yakin. Pendekatan seri Fourier juga akan memungkinkan Anda menggunakan distribusi sewenang-wenang alih-alih hanya noise biru.
sumber