Algoritme apa yang baik untuk menghasilkan batas / wilayah negara pada peta bintang 2d?

9

Saya mencoba untuk menghasilkan peta bintang dua dimensi yang cukup besar yang menunjukkan faksi / negara yang berbeda, masing-masing memiliki satu atau lebih sistem bintang. Saya ingin secara otomatis membuat batas / area untuk fraksi.

Idenya adalah untuk dasarnya pergi dari sesuatu seperti ini (titik-titik mewakili sistem bintang pada pesawat 2d, warna adalah afiliasi faksi)

Sistem bintang dan afiliasi fraksinya

untuk ini

Sistem bintang dengan area fraksi

Membuat peta seperti ini sepertinya persyaratan yang cukup umum, jadi pertanyaan saya yang sebenarnya adalah ini: Apakah ada algoritma standar untuk menghasilkan area keadaan seperti yang ditunjukkan? Jika demikian, dapatkah Anda menunjukkannya kepada saya? Jika tidak, dapatkah Anda memikirkan algoritma yang baik (ide dasar atau kode semu baik-baik saja)?

Kinerja algoritma bukan masalah utama bagi saya, jadi saya lebih suka memiliki peta "lebih cantik" daripada yang lebih cepat untuk menghasilkan. Pertanyaan serupa ini menawarkan pendekatan yang mungkin berlaku untuk masalah saya, meskipun dengan beberapa "prettification" diperlukan: Cara membuat peta dari grafik

Biarkan saya menjelaskan apa yang saya maksud ketika saya mengatakan lebih cantik: Di bagian bawah pertanyaan terkait, penanya menyajikan hasil akhirnya setelah menerapkan jawaban yang diterima. Masalah pertama saya di sini: Area untuk node # 6, # 9 dan # 12 sangat kecil dan berbentuk aneh. Selain itu, daripada tepi yang tajam, saya lebih suka tampilan yang lebih halus dan melengkung.

Sejauh ini ide saya sendiri, termasuk kelemahan / pertanyaan yang saya lihat bersama mereka:

  • Hasilkan poligon "convex hull" untuk setiap faksi, lalu perluas sedikit. Masalah: Tidak ada fitur cekung. Juga, bagaimana Anda menangani tumpang tindih?
  • Hasilkan grafik voronoi untuk titik-titik, kemudian gunakan tepi poligon voronoi antara sistem tetangga dari faksi yang berbeda sebagai batas. Masalah: Poligon besar di tepi peta - bagaimana cara mengidentifikasi dan memperbaikinya?
  • Hasilkan poligon ukuran tetap untuk setiap titik, satukan semua poligon untuk satu faksi tunggal (menghasilkan satu "faksi poligon" besar yang berpotensi kompleks). Kemudian lakukan sesuatu untuk merekonsiliasi area yang tumpang tindih antara dua faksi. Masalah: Bagaimana tepatnya saya melakukan ini? Bukan proses yang sepele. Bagaimana jika ada tumpang tindih antara lebih dari dua faksi?

Bantuan Anda dihargai.


Tambahan: Setelah memikirkan dua jawaban pertama dan pendekatan masing-masing untuk menyelesaikan masalah, saya menyadari bahwa persyaratan saya di atas tidak lengkap.

Saya harus menambahkan bahwa peta dapat memiliki daerah berpenduduk jarang, artinya mungkin ada bintang atau gugusan bintang yang terisolasi. Saya ingin menampilkan masing-masing cluster dengan area berwarna yang berdekatan. Sesuatu seperti ini:

Sistem bintang dengan area fraksi, cluster berbeda

Saya menyadari bahwa ini mungkin memerlukan langkah pertama yang mengidentifikasi cluster, dan kemudian menjalankan algoritma yang sebenarnya untuk masing-masing cluster.

Grüse
sumber
(brainstorming) Anda mungkin dapat mengisi sisa ruangan dengan noise biru (mis. poisson disc) dan kemudian jalankan voronoi untuk mendapatkan tugas warna. Poin yang ditambahkan akan diberikan wilayah latar belakang putih.
amitp
@amitp Hai Amit, suatu kehormatan untuk Anda berkomentar di sini! Saya telah mengambil banyak inspirasi dan pengetahuan praktis dari membaca artikel Red Blob Games Anda. Lebih banyak tentang topik: Gagasan untuk menghasilkan titik-titik tambahan masuk akal, ada alasan khusus mengapa Anda menyebutkan noise biru secara spesifik?
Grüse
... Saya kira karena itu terlihat seperti distribusi yang lebih alami daripada rasa kebisingan lainnya.
Grüse

Jawaban:

16

Saya pikir ide Voronoi bagus. Setiap bintang menjadi titik benih bagi Voronoi, dan kemudian wilayah Voronoi menunjukkan area yang dimiliki oleh setiap faksi. Namun, ada beberapa perubahan yang akan membuatnya bekerja lebih baik:

  1. Seperti yang Anda sebutkan, ada area kosong yang tidak boleh ditugaskan ke faksi. Voronoi akan membuat poligon besar yang menjangkau area di mana faksi tidak boleh mencapai. Untuk memperbaikinya, gunakan algoritma derau biru seperti cakram poisson untuk mengisi ruang kosong dengan bintang "milik siapa pun". Kebisingan biru adalah acak tetapi terdistribusi secara merata (mungkin juga bermanfaat untuk menghasilkan lokasi bintang Anda).
  2. Voronoi menghasilkan daerah kuning. Untuk menghasilkan sel yang lebih bulat, ganti perhitungan sirkumenter Voronoi dengan perhitungan centroid. Saya telah menulis sedikit tentang ini di sini dengan beberapa gambar perbandingan.
  3. Voronoi menghasilkan poligon, tetapi Anda menginginkan area bundar. Di setiap sudut, ada tiga poligon. Ketika ketiganya adalah faksi yang sama, Anda bisa membiarkannya sendiri. Ketika keduanya adalah faksi yang sama, perkenalkan kurva bezier kuadrat yang menggeser batas menuju faksi lainnya. Ketika ketiga faksi berbeda, Anda dapat meninggalkan sudut sendirian, atau Anda dapat memperkenalkan tiga kurva bezier untuk memindahkan semua batas satu sama lain. Saya tidak yakin mana yang terlihat lebih baik.

Inilah hasilnya:

Peta goblok

Saya juga menulis halaman yang memungkinkan Anda mengecat daerah untuk melihat seperti apa mereka.

amitp
sumber
Ini sangat cocok untuk saya, terima kasih banyak! Saya harus mengatakan itu sama mengesankan dan menyedihkan bahwa Anda dapat membuat contoh interaktif begitu cepat, sementara itu mungkin akan membawa saya setidaknya beberapa hari untuk mereproduksi apa yang Anda sajikan di sini :) Menantikan artikel tutorial itu.
Grüse
4

Salah satu dari banyak metode adalah peta pengaruh . Anda dapat mencari implementasi kode tertentu, tetapi algoritma dasarnya cukup sederhana.

Untuk setiap objek faksi (misalnya sistem bintang), tetapkan nilai positif (panas). Untuk semua objek faksi lain memberikan nilai negatif (dingin). Besarnya panas atau dingin harus didasarkan pada seberapa besar pengaruh Anda terhadap objek pada lingkungan dan tetangga. Nilai-nilai ini tidak harus proporsional jika Anda ingin mempertahankan "dmz" di antara faksi-faksi.

Gunakan detail ini untuk membuat kisi sementara (misalnya larik) yang mendekati piksel peta Anda. Anda dapat membangun kotak seperti itu untuk resolusi yang Anda inginkan termasuk 1: 1.

Selanjutnya, gunakan persamaan transfer panas / bidang untuk beralih dan menyebarkan kekuatan objek faksi (panas) terhadap kekuatan 'objek' musuh (dingin) untuk setiap sel tetangga di grid.

Bilas dan ulangi untuk setiap Fraksi di peta Anda dengan membuat kisi faksi terpisah untuk masing-masing.

Akhirnya, interpolasi kisi faksi bersama untuk menghasilkan kontur pengaruh untuk masing-masing faksi. Kemudian transfer kisi itu kembali ke peta piksel Anda dengan resolusi yang Anda gunakan untuk kisi (menambahkan warna khusus faksi, dll.).

Seni dalam proses ini adalah untuk menentukan seberapa besar pengaruh masing-masing objek dan elemen permainan apa yang Anda gunakan untuk mengukur nilai itu.

Selain itu, produk dari metode ini dapat digunakan untuk semua jenis hal lainnya, seperti pengambilan keputusan Anda.


Referensi tambahan: utas diskusi tentang asal-usul pemetaan pengaruh .

JEE
sumber
Pendekatan ini harus jelas, tetapi tidak pernah terpikir oleh saya. Terima kasih telah membawanya ke perhatian saya! Suatu pemikiran: Peta saya bisa jarang di daerah tertentu, sementara daerah lain padat dengan bintang-bintang dari afiliasi yang berbeda tepat di sebelah satu sama lain. Apakah ada cara untuk menggunakan ukuran sel sel yang berbeda untuk area yang berbeda? Berpikir sepanjang garis quadtree atau serupa.
Grüse
2

Anda harus melihat diagram Voronoi. Berikut ini definisi wikipedia:

Dalam matematika, diagram Voronoi adalah partisi pesawat ke dalam wilayah berdasarkan jarak ke titik dalam subset tertentu dari pesawat.

Poin dasar biasanya dihasilkan secara acak dan sering disebut node. Dalam kasus Anda, setiap node bisa menjadi bintang Anda. Dengan begitu, faksi yang terkait dengan bintang-bintang dapat dikaitkan dengan sel voronoi yang mengelilingi bintang dan ketika setiap sel telah dihitung, Anda bergabung dengan mereka yang memiliki faksi yang sama bersama-sama dan Anda harus memiliki perbatasan yang cukup rapi di sekitar bintang Anda.

Pustaka FastNoise memiliki dukungan untuk Diagram Voronoi, jadi mungkin Anda harus melihatnya.

Menghaluskan daerah

Simpan bintang-bintang Anda di «array aman» dan gunakan salinannya di tempat Anda benar-benar menambahkan lebih banyak poin melalui interpolasi tetangga terdekat dan hasilkan diagram dari titik-titik itu. Ini akan memberi Anda daerah yang lebih halus.

Gagasan lain Algoritme keberuntungan didasarkan pada garis lurus yang menyapu bidang kartesius. Ide yang menarik adalah menggunakan lingkaran untuk menyapu pesawat dari pusat galaksi / ruang Anda, mungkin itu bisa mengarah pada beberapa bentuk menarik juga.

Manipulasi geometri

Gagasan terakhir Anda untuk menggabungkan poligon yang lebih kecil menjadi yang lebih besar dan kemudian memperbaiki tepinya akan membutuhkan algoritma spline canggih untuk memodifikasi bentuk. Tidak yakin apakah itu akan membuatnya efisien atau tampan. Saya cukup yakin bahwa diagram voronoi dengan tessellation ekstra adalah cara untuk pergi karena memperbaiki masalah tepi dengan sendirinya dan bahkan dapat menawarkan beberapa data tambahan dengan sendirinya seperti jarak dari perbatasan (yang dapat digunakan untuk menentukan zona konflik antara faksi yang berbeda, kemungkinan bertemu berbagai jenis kapal, dll.)

BadgerBadger
sumber
Perhatikan bahwa OP sudah merujuk ke jawaban menggunakan diagram Voronoi, jadi mereka mengetahui tekniknya, tetapi telah meminta modifikasi khusus untuk mengubah tampilan perbatasan. Bisakah Anda memperluas jawaban Anda untuk menjawab permintaan khusus itu?
DMGregory
Maaf, salah membaca kiriman
BadgerBadger
Terima kasih telah mengubah jawaban Anda! Ide perataan itu menarik. Saya memiliki dua masalah dengan pendekatan Voronoi: Satu: Bagaimana cara mendeteksi dan membatasi titik "luar" sehingga perbatasan tidak merentang sampai ke tepi layar (lihat gambar kedua pertanyaan saya). Dua: Di daerah yang jarang penduduknya, Voronoi tidak memberikan hasil yang bagus karena poligonnya menjadi besar. Mungkin ada solusi yang jelas untuk mereka yang gagal saya lihat?
Grüse
Apakah itu menjadi opsi untuk menambahkan poin Anda sendiri untuk membingkai area? Kemudian, ketika Anda membuat grafik, jika garis mencapai tepi gambar yang sebenarnya, Anda tidak perlu menggambarnya karena tidak akan menjadi bagian dari area permainan. Masalah kedua harus diperbaiki dengan smoothing. Anda bisa menambahkan lebih banyak poin ketika mereka menambahkan lebih lanjut sehingga Anda menjaga semacam «ukuran kotak» yang konsisten.
BadgerBadger
@BadgerBadger ya, saya sedang bereksperimen dengan menambahkan poin sekarang
Grüse