Deteksi tabrakan: banyak kasus khusus?

8

Saya sedang menulis mesin fisika sederhana dalam 2D. Tujuan pertama saya adalah agar deteksi tabrakan berfungsi. Saya tahu bahwa objek saya pada akhirnya akan dibuat dari bentuk primitif, tetapi saya bertanya-tanya - apakah perpustakaan pendeteksian tabrakan terdiri dari banyak fungsi kasus khusus, seperti "rayAndLine", "rectangleRectangle", "rectangleCircle" dll, atau apakah ada kerangka dasar yang mendasari untuk deteksi tabrakan yang berfungsi terlepas dari primitif mana yang digunakan untuk membuat bentuk?

Michael Stachowsky
sumber
Anda bertanya tentang kerangka kerja yang mendasarinya, tetapi secara khusus nyatakan bahwa Anda ingin membangun bagian ini sendiri. Dapatkah Anda menjernihkan kalimat terakhir di mana pertanyaan Anda yang sebenarnya terjadi, agar lebih spesifik memisahkan kekhawatiran Anda tentang membangunnya sendiri, dari menggunakan kerangka kerja orang lain yang telah mereka bangun. Saya akan memberikan jawaban juga.
Joshua Hedges
Titik adil. Maksudku teori yang mendasari dari mana semua pendeteksian tabrakan berasal. Dengan kata lain, jika saya menulis subsistem pendeteksian tabrakan, apakah saya perlu menulis satu fungsi untuk setiap jenis tumbukan primitif / primitif, atau adakah fungsi generik tunggal yang berfungsi tidak peduli apa pun primitifnya?
Michael Stachowsky
Semacam. Saya baru saja menjawabnya. Ada beberapa yang menggeneralisasikan solusi dengan sangat baik, seperti SAT bekerja untuk semua poligon cembung, dan setiap poligon cekung dapat dipecah menjadi poligon cembung, yang membuatnya bekerja untuk setiap poligon dengan beberapa pekerjaan. Setelah itu Anda harus berspesialisasi terhadap kurva, bola, dan oval. Saya sudah menguraikannya di bawah ini. Ini adalah topik besar untuk dibahas, jadi ini panjang. Beri tahu saya jika Anda memiliki pertanyaan tentang hal spesifik atau apa pun
Joshua Hedges
2
Ini pertanyaan sebelumnya pada abstrak jenis bentuk yang berbeda mungkin juga berguna.
DMGregory
1
Semakin banyak kode bersama, semakin baik. Jika Anda menemukan diri Anda menggunakan salin dan tempel, periksa diri Anda dengan serius!
corsiKa

Jawaban:

9

Mendapatkan deteksi tabrakan bekerja adalah tujuan pertama yang bagus untuk mesin fisika 2D Anda. Ada baiknya Anda memutuskan bahwa untuk saat ini Anda secara khusus bekerja dalam 2D, karena tidak setiap aturan dalam 2D ​​bekerja dalam 3D, terlepas dari jumlah algoritma terkait n-dimensi, pada titik tertentu Anda harus mengkhususkannya (lakukan lebih varian spesifik seperti bagaimana produk silang hanya memenuhi identitas Jacobi dalam 3D).

Pertanyaan Anda secara inheren tentang arsitektur dan desain kerangka kerja bukan tentang fisika 2D, jadi kekhawatiran tentang apa yang harus dipisahkan oleh bangunan Anda dalam pikiran Anda tentang bagaimana potongan-potongan itu digunakan. Pada dasarnya, Anda perlu memisahkan mentalitas membangun mesin / perpustakaan / kerangka kerja dari penggunaannya di proyek lain.

Menyusun mesin pemecahan: Dengan mesin matematika apa pun, kami pada dasarnya ingin memasukkan nilai ke dalam beberapa fungsi, dan kami berharap nilai yang keluar akan berguna untuk membuat simulasi yang menarik.

Elemen inti dari proses ini harus seabstrak mungkin, sedangkan elemen atom (bagian / data terkecil yang berguna) harus spesifik untuk keperluan individu dan berguna untuk menyusun bersama. Dalam kasus kami, hampir satu-satunya atom yang berguna adalah vektor 2D, yang seharusnya berupa kelas objek tunggal yang memungkinkan ekspresi struktur (x, y), dan memiliki metode untuk semua operasi matematika dasar yang berguna untuk perhitungan vektor dalam 2D. Penambahan, pengurangan, normalisasi, normal (tegak lurus), produk silang, produk titik, besaran / panjang, dan apa pun yang Anda temui yang secara khusus melekat pada vektor -> operasi vektor atau vektor -> operasi bilangan real. Jika Anda menggunakan bahasa berbasis kelas, sederhana class Vectordengan masing-masing sebagai fungsi anggota atau kelebihan operator akan sangat baik.

Setelah semua jenis atom dikonstruksi, maka Anda akan menyusun algoritme mereka menjadi lapisan lain di atas jenis atom kami Vector. Tujuan saya adalah a Linedan a Curve. Kami akan memutuskan di sini bahwa a Curveberada di luar cakupan untuk ini dan memerlukan banyak spesialisasi (konsep yang Anda rujuk di atas sebagai menciptakan banyak fungsi kasus khusus). Dari Vectorsaya juga akan menulis Rectanglesebagai 4 Vectorprimitif, menulis Circledari vektor menggunakan a Vectordan a radius, dan kemudian saya akan menulis Polygondari Vectorjuga. Polygonharus dibuat dari Vectordan bukan di Linesini karena setiap baris akan berbagi titik duplikat dengan baris terakhir dalam poligon.

Sekarang Anda memiliki bentuk, tetapi kami tidak tahu apa yang harus dilakukan dengan mereka.

Deteksi Tumbukan Deteksi tumbukan bukan ilmu pasti dan tidak ada satu algoritma sempurna tunggal (atau apa pun). Ada banyak metode yang dapat digunakan untuk mencapai berbagai kualitas efek atau bahkan memiliki akurasi lebih dari yang lain. Pada dasarnya, ini dapat dipisahkan menjadi beberapa tingkat perhatian yang berbeda dan dengan demikian beberapa proses yang berbeda.

Deteksi tabrakan fase luas adalah tindakan membagi area tempat kita peduli tentang apa yang mungkin / bisa / tidak bertabrakan, dan memisahkannya untuk proses fase sempit. Dalam 2D ​​saya biasanya akan merekomendasikan menggunakan pohon quad untuk ini. Untuk itu kita akan membutuhkan yang Rectanglekita bangun sebelumnya dan untuk menyediakannya dengan deteksi tabrakan AABB. Ini adalah singkatan dari Axis Aligned Bounding Box dan kami akan menggunakannya untuk menentukan bahwa untuk kotak non-rotasi Ayang tidak ada bagian dari kotak Bada di dalamnya A. Ini mengikuti dari asumsi bahwa tidak ada bagian dari yang Bbisa ada dalam Atabrakan itu ada jika mereka berpotongan.

Quad tree adalah proses rekursif di mana Anda menentukan kedalaman maksimum, atau membiarkan kuantitas objek Anda untuk mencegah kedalaman rekursi yang tak terbatas. Ini mengelompokkan benda-benda fisika menjadi 4 wilayah (karena itu namanya) dan harus memungkinkan Anda untuk mengakses setiap quad secara terpisah. Anda kemudian akan masuk ke dalam masing-masing empat paha depan, dan melakukan proses yang sama yang saya tidak akan gariskan di sini untuk singkatnya tetapi tersedia di sini: https://gamedevelopment.tutsplus.com/tutorials/quick-tip-use-quadtrees- untuk mendeteksi kemungkinan tabrakan-di-ruang 2d - gamedev-374

Tabrakan fase sempitadalah proses melalui kelompok bentuk Anda yang telah kami tentukan akan / mungkin / lakukan bertabrakan dan melakukan pemeriksaan tabrakan yang lebih diskrit, pada saat ini, kami mulai peduli apakah benda-benda itu berputar atau tidak (saya menang ' cover tutupi ini, ketika Anda melewati fase-fase tabrakan ini, Anda akan melihat pendeteksian tabrakan dengan momentum sudut) dan apa bentuk tubuh tabrakan mereka sebenarnya. Untuk melakukan bagian tabrakan ini, Anda akan mengkhususkan metode Anda seperti yang telah Anda jelaskan di atas (membuat fungsi spesifik untuk AABBvsCircle, OBBvsCircle, CirclevsCircle, PolygonvsCircle, PolygonvsCircle, PointvsCircle, dll.) Namun, metode ini sendiri juga dapat dilakukan dengan cara berlapis seperti di atas.

Cek pemisahan primitif Anda adalah diskrit, metode deteksi tabrakan khusus atau yang umum seperti SAT tergantung pada kasus penggunaan dan harus semua hanya kembali baik true / false, atau kembali objek relasional seperti Manifold, Joint, CollisionObjectdll, yang akan memiliki sambungan dengan dua bentuk yang ditemukan bertabrakan, dan informasi apa pun tentang mereka yang diperlukan untuk menyelesaikan tabrakan, seperti seberapa dalam mereka bertabrakan atau pada kecepatan berapa (data apa yang Anda butuhkan dalam manifold Anda bergantung pada metode resolusi yang Anda gunakan). Objek yang kemudian Anda lewati ke suatu Solveryang seharusnya menghilangkan perbedaan antara semua bentuk berbeda yang dapat bertabrakan, dengan hanya menerima Manifolddan tidak menerima informasi tertentu tentang bentuk.

Ringkasan The Solverakan mengambil Manifolddiproduksi dengan bertabrakan beberapa primitif Adengan beberapa primitif B, menggunakan pengelompokan fase luas pertama (semua vs dunia) dan kemudian deteksi fase sempit (A vs B) dan jika bentuk non-poligon harus khusus, Solvermaka menghasilkan baik baru Vectors untuk posisi bertabrakan bentuk dan kecepatan, atau benda yang PhysicsEnvironmentatau Worldkemudian dapat digunakan untuk tabrakan tekad pada anak-anak itu, lalu akhirnya memperbarui QuadTreedan ulangi proses ini pada frame berikutnya. Jika kedua bentuk bertabrakan adalah poligon maka spesialisasi hanya boleh dilakukan dengan memperhatikan peningkatan kinerja, jika tidak cukup menggunakan Teorema Sumbu Pemisah

Joshua Hedges
sumber
1
Jawaban yang bagus, terima kasih. Saya penasaran, meskipun: Saya awalnya mempertimbangkan mendasarkan objek paling primitif saya pada titik, kemudian membangun vektor dari sana. Saya melihat dari jawaban Anda bahwa ini belum tentu pilihan terbaik. Mengapa demikian?
Michael Stachowsky
1
Alasannya adalah karena dalam 2 dimensi vektor dan sebuah titik sebenarnya memiliki definisi yang sama. a Vector direction,Magnitudedapat dianggap sebagai Point x,yjika Anda mengabaikan beberapa operasi yang Vectordisediakan. Bagian terbaik dari melakukan ini, adalah hanya karena Anda dapat mengabaikan operasi itu sekarang, ketika Anda ingin menentukan hal-hal seperti momentum sudut Anda tidak mengubah jenis objek. Itu hampir merupakan masalah selera, karena apa yang para pengembang game sebut sebagai "Point" ahli matematika memang menyebut "Vektor". Jadi sebut saja apa yang Anda inginkan, yang penting adalah apa yang ditawarkannya.
Joshua Hedges
1
Dalam bahasa gaya C, jika saya ingin menggunakan definisi "Point" untuk mudah dibaca sebenarnya saya akan cukup typedefdari Vector, atau alias istilah "Point" berarti hal yang sama dengan "Vector".
Joshua Hedges