Saat ini saya sedang menulis simulasi AI 2D, tetapi saya tidak sepenuhnya yakin bagaimana memeriksa apakah posisi agen berada dalam bidang pandang orang lain.
Saat ini, partisi dunia saya adalah partisi ruang-sel sederhana (kotak). Saya ingin menggunakan segitiga untuk mewakili bidang pandang, tetapi bagaimana saya bisa menghitung sel yang bersinggungan dengan segitiga?
Mirip dengan gambar ini:
Area merah adalah sel yang ingin saya hitung, dengan memeriksa apakah segitiga memotong sel-sel itu.
Terima kasih sebelumnya.
EDIT:
Hanya untuk menambah kebingungan (atau bahkan membuatnya lebih mudah). Setiap sel memiliki vektor min dan maks di mana min adalah sudut kiri bawah dan maks adalah sudut kanan atas.
collision-detection
intersection
Ray Dey
sumber
sumber
Jawaban:
Hitung tiga sudut segitiga fov Anda, putar agar menghadap ke arah yang benar dan semacamnya, lalu lakukan salah satu dari:
1) melakukan tes point-in-triangle untuk semua target potensial
2) menghitung kotak pembatas dari segitiga ini, dan lakukan tes point-in-triangle untuk semua target potensial dalam sel dalam kotak pembatas ini - ini akan menjadi kode yang sangat mudah untuk di-debug
Pendekatan serupa adalah dengan menggunakan quadtree daripada grid dan melakukan persimpangan itu. Jika akses ubin O (1) mempercepat Anda, maka hanya menguji semua sel dalam batas segitiga fov untuk segitiga-in seharusnya sangat cepat untuk menjadi instan. Ketika Anda melihat opsi lain, saya anggap tidak dan bahwa O (1) sebenarnya mengambil biaya kehilangan cache yang besar saat Anda merobohkan cache Anda. Anda tentu saja mungkin dapat melihat instruksi pengambilan awal untuk memberi anotasi berjalan kotak terikat Anda dengan ...
3) 'rasterise' segitiga ini dan periksa sel yang 'dicat' - kemungkinan kode yang paling efisien, tapi mungkin hanya sedikit karena saya berspekulasi semuanya didominasi oleh cache miss times dan tergantung pada seberapa kompleks sel Anda dan seberapa sibuknya mereka.
Pendekatan alternatif adalah membuat FOV menjadi bitmap di luar layar dan kemudian membaca nilai piksel untuk masing-masing objek Anda; Anda tidak dapat 'mencampur cat' tetapi dengan sejumlah objek dan dengan hati-hati memilih cat, Anda dapat menyimpulkan siapa yang melihat siapa. Pendekatan ini mirip dengan berapa banyak permainan yang berhasil diklik pengguna - mereka menarik adegan di luar layar menggunakan warna solid untuk area hit. GPU sangat cepat pada pengisian segitiga ...
sumber
Solusi kanonik dalam renderers perangkat lunak (yang harus melakukan algoritma ini tepat setiap kali mereka meraster segitiga) adalah, saya percaya, untuk memindai segitiga satu baris piksel pada satu waktu. Tepi kiri dan kanan dari setiap baris dan dihitung dengan berjalan menyusuri sisi segitiga menggunakan Bresenham , dan kemudian Anda mengisi baris di antara mereka.
Saya membahas banyak detail, tetapi itulah ide dasarnya. Jika Anda mencari-cari "render perangkat lunak" dan "rasterisasi segitiga", Anda mungkin akan menemukan lebih banyak detail. Ini adalah masalah yang terpecahkan. Kartu grafis Anda melakukan ini jutaan kali dalam satu bingkai.
Jika Anda menginginkan solusi yang lebih spesifik untuk roguelike, inilah cara saya menerapkan FOV di tambang. Tampaknya bekerja cukup cepat. Ini pada dasarnya bayangan kastor sederhana, bekerja pada oktan pada suatu waktu, memindai keluar dari pemain.
sumber
Saya menggunakan variasi dari algoritma scanline untuk menyelesaikan masalah yang sama persis. Saya mulai dengan menyortir tiga titik segitiga berdasarkan tinggi mereka. Saya kemudian pada dasarnya memeriksa apakah dua tepi berada di sebelah kiri atau di sebelah kanan. Untuk sisi dengan dua sisi, Anda harus menandai baris di mana Anda mengubah sisi mana yang membatasi baris Anda. Untuk sisi dengan satu sisi, Anda selalu dapat menggunakannya.
Jadi untuk setiap baris, saya tahu dua sisi mana yang membatasi itu, dan saya bisa menghitung batas atas dan bawah dalam arah x. Kedengarannya cukup rumit, tetapi hanya mengembun menjadi beberapa baris kode. Pastikan Anda menangani kasing khusus di mana satu ujungnya benar-benar horizontal!
sumber
Bagaimana dengan mempertahankan rentang kolom untuk setiap baris yang ada dalam segitiga? Apa yang dapat Anda lakukan adalah mengatur kolom min dan maks untuk setiap baris di mana setiap titik berada, dan di mana setiap garis segitiga melintasi garis pemisah baris horizontal.
Keluaran:
sumber
Ada beberapa pekerjaan algoritma yang dilakukan di komunitas roguelike yang berhubungan dengan FOV / LOS / pencahayaan di dunia berbasis ubin.
Mungkin Anda dapat menemukan sesuatu di halaman ini yang dapat digunakan untuk membantu menyelesaikan masalah Anda: http://roguebasin.roguelikedevelopment.org/index.php?title=Field_of_Vision
Secara khusus "FOV Permisif" mungkin yang paling berlaku untuk situasi Anda.
sumber