Menghindari tabrakan 3D: menemukan vektor kecepatan yang diperbarui (di luar kerucut "kecepatan tabrakan")

8

Saya mencoba memahami dan menerapkan mekanisme penghindaran tabrakan 3D sepenuhnya (perilaku kemudi) untuk pergerakan penerbangan (enam derajat kebebasan), saat ini berfokus pada menghindari rintangan statis (semua dengan bentuk bola).

Namun, saya tidak begitu mengerti bagaimana cara mengetahui vektor kecepatan baru dari agen yang bergerak. Gambar di bawah menggambarkan pemandangan. Agen yang bergerak (hijau) harus mengarahkan tiga objek statis (biru). Garis merah mewakili vektor kecepatan awal ke depan.

masukkan deskripsi gambar di sini

Perhatikan bahwa ada juga tiga kerucut putih / semi-transparan. Ini mewakili "vektor kecepatan terlarang" tentang setiap hambatan. Ini berarti, himpunan vektor kecepatan yang, jika digunakan sebagai vektor depan baru dari agen, akan membuat agen bertabrakan dengan satu atau lebih hambatan (juga perhatikan bahwa jari-jari setiap kerucut sama dengan jari-jari dari rintangan yang diberikan ditambah jari-jari agen, sehingga memungkinkan offset bagi pemain untuk bermanuver di sekitar).

Untuk mengetahui vektor baru di depan dari agen yang bergerak dalam lingkungan 3D tersebut, dengan mempertimbangkan tiga kendala, pendekatan naif adalah dengan hanya melakukan porting ke 3D, solusi klasik yang dijelaskan dalam artikel yang sering dikutip ini dan dicontohkan dengan gambar 2D berikut:

masukkan deskripsi gambar di sini

Di sana, kecepatan baru (panah oranye) hanya dihitung dengan menormalkan jarak minimum (panah hitam) antara kecepatan asli dan pusat hambatan dan kemudian mengalikan normal tersebut dengan jumlah antara jari-jari rintangan dan jari-jari agen bergerak. Kemudian, rata-rata kecepatan baru yang dihitung untuk masing-masing rintangan akan memberikan total kecepatan akhir.

Dalam banyak kasus, itu sudah cukup. Namun, lihat kasus-kasus di bawah ini (dicontohkan dalam 2D ​​untuk memudahkan visualisasi):

masukkan deskripsi gambar di sini

Pada semuanya, pendekatan naif akan menghasilkan tabrakan. Dalam a dan b, kecepatan baru akhir akan bertepatan dengan kecepatan asli (panah merah) dan agen bergerak akan bergerak maju meskipun sebagian atau sepenuhnya diblokir. Di c) dan d), kecepatan baru (panah oranye) masih akan menghasilkan konsekuensi yang sama.

Jadi, pertanyaan saya adalah: apa cara yang paling efisien secara komputasi untuk mengetahui vektor baru bergerak dari agen bergerak dalam lingkungan 3D seperti itu, dengan mempertimbangkan tiga hambatan, dengan cara yang menghindari tabrakan? Atau, dengan kata lain, vektor depan baru yang:

1) tidak ada di dalam salah satu kerucut;

2) adalah yang paling dekat dengan vektor depan asli (garis merah pada gambar).

PS: Lebih disukai saya tidak mencari perpustakaan, saya ingin belajar bagaimana caranya.

Louis15
sumber

Jawaban:

1

Saya tidak berpikir ada cara yang efisien untuk menyelesaikan masalah dengan tepat, tetapi inilah cara saya mencoba mengatasinya.

Pertama, saya akan menggunakan volume pembatas di sekitar setiap objek, bukan objek itu sendiri. Setiap objek dapat diperkirakan dengan penyatuan lebih dari satu volume yang terikat.

Solusi paling sederhana adalah menghitung volume penjilidan tunggal yang berisi semua objek yang perlu Anda hindari dan menghitung kerucut dari volume itu.

Ini mungkin tidak cukup baik jika objek tidak relatif dekat satu sama lain. Anda mungkin ingin melakukan beberapa pengelompokan dengan cara dua objek milik cluster yang sama jika itu tidak mungkin, atau setidaknya tidak sepele untuk lewat di antara mereka. Hitung kelompok objek dengan mempertimbangkan volume pembatasnya ditambah ukuran volume pembatas pemain ditambah margin tambahan. Anda mungkin menggunakan sesuatu seperti ini:

http://lab.polygonal.de/?p=120

Setelah Anda memiliki kelompok, temukan yang terdekat dan hitung kerucut untuk menghindari bertabrakan dengannya. Karena cara cluster dibuat, jika Anda mengarahkan cukup untuk menghindari memukul satu cluster, Anda tidak akan menekan yang lain.

Selanjutnya, Anda dapat membuat struktur rekursif saat menghitung cluster yang akan membantu Anda menemukan cluster terdekat.

Ada beberapa hal yang bisa Anda mainkan. Misalnya, alih-alih memilih gugus terdekat, pilih dua kelompok terdekat dan hitung satu kerucut tunggal yang menghindari keduanya. Juga, Anda bisa mencoba volume pembatas lain selain bola.

Gato
sumber
0

Ada dua cara untuk menjawab pertanyaan ini yang bisa saya lihat. Pertama, jika Anda hanya ingin menemukan cara untuk mengarahkan, maka Anda hanya perlu menerapkan pathfinding ( saya menemukan ini cukup membantu ). Itu akan menjadi akhir dari itu (dan merupakan jawaban praktis yang benar untuk pertanyaan ini), tetapi saya pikir Anda lebih penasaran dengan solusi matematika untuk masalah Anda.

Untuk mengatasinya, mari kita lihat masalah yang setara. Ambil irisan 2D adegan Anda "di depan" pilot Anda dari sebuah pesawat yang normal dengan vektor asli. Apa yang akan Anda dapatkan adalah titik yang mewakili vektor asli Anda dan serangkaian elips yang merupakan proyeksi 2D dari kerucut oklusi Anda. Sekarang yang ingin Anda lakukan adalah menemukan titik terdekat dengan titik awal Anda (sebut saja P) yang terletak di bagian luar elips yang tidak tumpang tindih. Ternyata ini adalah masalah yang cukup sulit untuk dipecahkan. Ada 3 langkah:

  • Cari tahu titik persimpangan semua elips Anda
  • Temukan lubang di persatuan semua elips Anda
  • Cari tahu titik terdekat untuk Psemua elips Anda di luar serikat (yang bisa berada di dalam lubang)

Oke, semua ini membutuhkan pengganda Lagrange dan pengecekan sudut dan beberapa hal rumit lainnya untuk dipecahkan. Mari kita lihat opsi lain. Jika kita mengubah masalah kita menjadi ruang sudut, kita melihat bahwa apa yang sebenarnya ingin kita lakukan adalah menemukan jarak minumum antara titik dan beberapa lingkaran yang diproyeksikan ke permukaan bola. Dalam geometri diferensial, ini sering disebut bola-2 dan berguna di sini. Jadi pertama-tama, kita perlu menemukan jarak antara dua titik di permukaan bola, yang akan kita gunakan metrik 2-bola untuk menemukan. Untungnya, ini cukup mudah:, di ds^2 = (R^2)*(dth^2) + (R^2)*(sin(th)^2)*(dph^2)mana kita memegang Rkonstan ketika jari-jari 2-bola kita diproyeksikan menjadi 3-ruang. Berasal dari fisika, saya mengambil thsudut dari positif zdan phmenjadi sudut dari positif xdengansmenjadi jarak.

Apa yang dilakukan dengan melakukan ini? Hal ini memungkinkan kita untuk menghapus penggunaan pengganda Lagrange untuk meminimalkan jarak, dan memungkinkan kita untuk bekerja dalam koordinat "asli" (karena kita mendefinisikan kerucut kita dalam hal sudut oklusi). Jadi sekarang kita perlu menemukan radius proyeksi kerucut kita. Mari kita ambil satu kerucut untuk saat ini, dan memanggil sudut yang mendefinisikannya a. Jari-jari proyeksi kemudian sederhana R*a. Itu cukup mudah - kuantitas apa lagi yang perlu kita ketahui tentang kerucut? Kita perlu mengetahui pusat proyeksi, yang ditentukan oleh vektor tampilan dari aktor. Pertama-tama kita mengkonversi x,, ydan zmenjadi koordinat bola di mana kita tahu kita berada jauh R, dan menyelesaikannya untuk thdan ph, yang dapat kita lakukan dengan hanya memasukkan ke rumus konversi kita:th = acos(z/R)dan ph = atan2(y/x)(gunakan di atan2sini untuk menjelaskan ambigitas kuadran arctangent). Prosesnya sama untuk menemukan posisi vektor asli Anda dalam koordinat bola.

Jadi masalahnya sudah disederhanakan. Namun, masalahnya masih cukup sulit untuk dipecahkan, tetapi sekarang Anda hanya perlu khawatir tentang lingkaran dan titik, bukan elips dan titik atau sudut dan vektor. Sisa prosesnya agak prosedural. Anda pada dasarnya perlu menemukan area pembatas yang dibentuk oleh lingkaran Anda, dan ada beberapa solusi. Saya akan menyajikan satu metode yang mungkin bukan yang terbaik, tetapi akan berhasil.

Pertama-tama saya akan membandingkan jumlah jari-jari semua pasangan lingkaran dan jarak antara pusat, dan kemudian jika jumlah mereka lebih besar dari jarak pusat, setel sama dan pecahkan untuk thdanphuntuk menemukan persimpangan. Anda tahu bahwa setiap pasangan persimpangan menggambarkan "sudut terlarang" untuk lingkaran yang dimaksud, yang akan Anda simpan sebagai array sudut titik persimpangan (dari pusat lingkaran) untuk setiap lingkaran yang memotong yang ini - yang penting Anda harus " gabungkan "rentang apa pun yang tumpang tindih saat Anda menambahkannya ke array agar bagian selanjutnya berfungsi dengan benar. Kemudian Anda menemukan titik terdekat di tepi lingkaran ke titik asli (yang sesederhana menggambar garis melalui titik pusat lingkaran dan titik asli, lalu menemukan lokasi pada garis di jari-jari lingkaran) jauh dari pusat). Kemudian loop melalui array yang tersimpan dan uji apakah sudut itu dalam kisaran masing-masing sudut terlarang. Jika demikian, maka pilih tepi terdekat. Itu adalah titik terdekat ke luar yang dijelaskan di dalam lingkaran ini. Ulangi proses untuk semua lingkaran (beberapa optimasi dapat dilakukan dalam proses pemilihan - Anda sebenarnya tidak perlu menghitung ini untuk setiap lingkaran). Sekarang bandingkan semua jarak terpendek Anda, temukan yang terkecil, dan itulah jawaban Anda, dijelaskan dalam sudut pandangthdan ph. Ingatlah bahwa jarak dijelaskan dengan metrik 2-bola saat melakukan perhitungan ini. Karena Anda tidak peduli dengan bola tempat semua ini aktif, hanya sudutnya, Anda dapat mengatur R=1dan melakukan perhitungan ini pada unit bola.

Ini adalah cara paling sederhana yang dapat saya pikirkan untuk melakukan ini. Saya tidak yakin itu cara termudah mutlak, tetapi itu akan bekerja dengan cukup baik. Secara praktis untuk sebuah game, Anda hanya ingin mengimplementasikan pathfinding.

dannuic
sumber