Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Game Development
  2. Programming
Gamedevelopment

Cara Mencipta Enjin Fizik 2D Kustom: Badan Terarah Berorientasikan

by
Difficulty:IntermediateLength:LongLanguages:
This post is part of a series called How to Create a Custom Physics Engine.
How to Create a Custom 2D Physics Engine: Friction, Scene and Jump Table

Malay (Melayu) translation by Aisyah Arrafah (you can also view the original English article)

Setakat ini, kami telah melengkapkan resolusi impuls, seni bina teras, dan geseran. Di sini, tutorial akhir dalam siri ini, kami akan membincangkan topik yang sangat menarik: orientasi.

Dalam artikel ini kita akan membincangkan topik berikut:

  • Matematik putaran
  • Bentuk berorientasikan
  • Pengesanan perlanggaran
  • Resolusi perlanggaran

Saya sangat disyorkan membaca pada tiga artikel sebelumnya dalam siri ini sebelum cuba mengatasi masalah ini. Banyak maklumat penting dalam artikel sebelumnya adalah prasyarat untuk melengkapkan artikel ini.


Kod Sampel

Saya telah mencipta enjin sampel yang kecil di C++, dan saya cadangkan anda melayari dan merujuk kepada kod sumber sepanjang bacaan artikel ini, kerana banyak butiran pelaksanaan praktikal tidak dapat dimasukkan ke dalam artikel itu sendiri.


Repo GitHub ini mengandungi enjin sampel itu sendiri, bersama dengan projek Visual Studio 2010. GitHub membolehkan anda melihat sumber tanpa perlu memuat turun sumber itu sendiri, untuk kemudahan.


Matematik Orientasi

Matematik yang melibatkan putaran dalam 2D ​​agak mudah, walaupun penguasaan subjek akan diperlukan untuk membuat sesuatu yang bernilai dalam enjin fizik. Undang-undang kedua Newton menyatakan:

\[Persamaan \: 1:\\
F = ma\]

Terdapat persamaan yang sama yang berkaitan dengan kekuatan sudut dan pecutan sudut. Walau bagaimanapun, sebelum persamaan ini dapat ditunjukkan, penerangan pantas produk salib dalam 2D ​​diperlukan.

Produk Silang

Produk silang dalam 3D adalah operasi yang terkenal. Walau bagaimanapun, produk salib dalam 2D ​​boleh agak mengelirukan, kerana tidak benar-benar interpretasi geometri pepejal.

Produk salib 2D, tidak seperti versi 3D, tidak mengembalikan vektor tetapi skalar. Nilai skalar ini sebenarnya mewakili magnitud vektor ortogonal di sepanjang paksi z, jika produk salib benar-benar dilakukan dalam 3D. Dengan cara ini, produk salib 2D hanya merupakan versi mudah dari produk salib 3D, kerana ia adalah lanjutan matematik vektor 3D.

Jika ini membingungkan, jangan bimbang: pemahaman yang menyeluruh mengenai produk salib 2D bukanlah semua yang diperlukan. Hanya tahu dengan tepat bagaimana melaksanakan operasi, dan ketahuilah bahawa urutan operasi adalah penting: \(a \times b\ ) tidak sama dengan \(b \kali a\). Artikel ini akan memanfaatkan produk salib yang berat untuk mengubah halaju sudut ke dalam halaju linear.

Walau bagaimanapun, mengetahui bagaimana untuk melaksanakan produk salib dalam 2D ​​adalah sangat penting. Dua vektor boleh dipalang, skalar boleh dilintang dengan vektor, dan vektor boleh dilangkau dengan skalar. Inilah operasi:

Kelajuan Torque dan Angular

Seperti yang kita semua tahu dari artikel sebelumnya, persamaan ini mewakili hubungan antara daya yang bertindak ke atas badan dengan massa dan pecutan badan itu. Terdapat analog untuk putaran:

\[Persamaan \: 2:\\
T = r \: times \: \omega\]

\(T\) bermaksud tork. Tork adalah daya putaran.

\(r\) adalah vektor dari pusat jisim (COM) ke titik tertentu pada sesuatu objek. \(r\) boleh dianggap sebagai merujuk kepada ''radius'' dari COM ke satu titik. Setiap titik unik tunggal pada objek akan memerlukan nilai \(r\) yang berbeza yang akan diwakili dalam Persamaan 2.

\(\omega\ ) dipanggil ''omega'', dan merujuk kepada halaju putaran. Hubungan ini akan digunakan untuk mengintegrasikan halaju sudut badan yang tegar.

Adalah penting untuk memahami bahawa halaju linear adalah halaju COM dari suatu badan yang tegar. Dalam artikel sebelumnya, semua objek tidak mempunyai komponen putaran, maka halaju linear COM adalah halaju yang sama untuk semua titik pada badan. Apabila orientasi diperkenalkan, mata lebih jauh dari COM berputar lebih cepat daripada yang berdekatan dengan COM. Ini bermakna kita memerlukan persamaan baru untuk mencari halaju titik pada badan, kerana badan kini boleh berputar dan diterjemahkan pada masa yang sama.

Gunakan persamaan berikut untuk memahami hubungan antara titik pada badan dan halaju titik itu:

\[Persamaan \: 3:\\
\omega = r \: \times v \]

\(v\) mewakili halaju linear. Untuk mengubah halaju linear ke halaju sudut, salib radius \(r\) dengan \(v\).

Begitu juga, kita boleh menyusun semula Persamaan 3 untuk membentuk versi lain:

\[Persamaan \: 4:\\
v = \omega \: \times r \]

Persamaan-persamaan dari bahagian terakhir agak kuat hanya jika badan tegar mempunyai ketumpatan seragam. Ketumpatan yang tidak seragam membuat matematik terlibat dalam mengira apa-apa yang diperlukan putaran dan tingkah laku badan tegar yang terlalu rumit. Tambahan lagi, jika titik yang mewakili badan yang tegar tidak berada di COM, maka pengiraan mengenai  \(r\) akan menjadi benar-benar berjaya.

Inertia

Dalam dua dimensi objek berputar mengenai paksi z khayalan. Putaran ini boleh agak sukar bergantung kepada berapa jisim objek yang ada, dan sejauh mana dari jisim objek COM itu. Satu bulatan dengan jisim sama dengan batang panjang nipis akan lebih mudah berputar daripada batang. Ini ''sukar untuk berputar'' faktor boleh dianggap sebagai momen inersia sesuatu objek.

Dalam erti kata lain, inersia adalah jisim putaran objek. Semakin banyak sesuatu yang inersia, semakin sukar untuk mendapatkannya berputar.

Mengetahui ini, seseorang boleh menyimpan inersia objek di dalam tubuh sebagai format yang sama dengan massa. Adalah lebih baik untuk menyimpan nilai songsangan ini, berhati-hati untuk tidak melakukan pembahagian dengan sifar. Sila lihat artikel sebelumnya dalam siri ini untuk maklumat lanjut mengenai jisim massa dan songsang.

Integrasi

Setiap badan yang tegar memerlukan lebih banyak medan untuk menyimpan maklumat putaran. Berikut adalah contoh cepat struktur untuk memegang beberapa data tambahan:

Mengintegrasikan halaju sudut dan orientasi badan sangat serupa dengan integrasi halaju dan percepatan. Berikut adalah contoh kod cepat untuk menunjukkan bagaimana ia dilakukan (nota: butiran mengenai integrasi telah diliputi dalam artikel sebelumnya):

Dengan sedikit maklumat yang diberikan setakat ini, anda sepatutnya dapat mula memutar pelbagai perkara pada skrin tanpa sebarang masalah. Dengan hanya beberapa baris kod, sesuatu yang agak mengagumkan dapat dibina, mungkin dengan melemparkan bentuk ke udara semasa berputar tentang COM apabila graviti menariknya ke bawah untuk membentuk jalan arakan.

Mat22

Orientasi harus disimpan sebagai nilai radian tunggal, seperti yang terlihat di atas, walaupun sering kali penggunaan matriks putaran kecil dapat menjadi pilihan yang jauh lebih baik untuk bentuk tertentu.

Satu contoh hebat ialah Kotak Bounding Berorientasi (OBB). OBB terdiri daripada lebar dan ketinggian, kedua-duanya boleh diwakili oleh vektor. Kedua-dua takat vektor ini boleh diputar oleh matriks putaran dua demi dua untuk mewakili paksi OBB.

Saya mencadangkan penciptaan a Mat22 kelas matriks akan ditambah ke perpustakaan matematik apa sahaja yang anda gunakan. Saya sendiri menggunakan perpustakaan matematik kecil yang dikemas dalam demo sumber terbuka. Berikut ini contoh contoh objek seperti:

Beberapa operasi yang berguna termasuk: pembinaan dari sudut, pembinaan dari vektor lajur, transpose, darab dengan Vec2, darab dengan Mat22, nilai mutlak yang lain.

Fungsi berguna terakhir adalah untuk dapat mengambil sama ada ruang x atau y dari vektor. Fungsi lajur akan kelihatan seperti:

Teknik ini berguna untuk mendapatkan vektor unit sepanjang paksi putaran, sama ada paksi x atau y. Di samping itu, matriks dua demi dua boleh dibina dari dua vektor unit ortogonal, kerana setiap vektor boleh dimasukkan secara langsung ke dalam baris. Walaupun kaedah pembinaan ini agak jarang berlaku untuk enjin fizik 2D, masih boleh sangat berguna untuk memahami bagaimana putaran dan matriks berfungsi secara umum.

Pembina ini mungkin kelihatan seperti:

Oleh kerana operasi yang paling penting bagi matriks putaran adalah untuk melakukan putaran berdasarkan sudut, penting untuk dapat membina matriks dari sudut dan membiak vektor oleh matriks ini (untuk memutar vektor dari sudut arah jam dengan sudut matriks dibina dengan):

Demi ketimpangan saya tidak akan dapatkan mengapa matriks putaran mengikut arah jam mengikut bentuk:

Walau bagaimanapun, penting untuk mengetahui bahawa ini adalah bentuk matriks putaran. Untuk maklumat lanjut mengenai matriks penggiliran sila lihat halaman Wikipedia.


Mengubah kepada Asas

Adalah penting untuk memahami perbezaan antara model dan ruang dunia. Ruang model ialah sistem koordinat setempat kepada bentuk fizik. Asal adalah di COM, dan orientasi sistem koordinat sejajar dengan paksi bentuk itu sendiri.

Untuk mengubah bentuk ke dalam ruang dunia, ia mesti diputar dan diterjemahkan. Putaran mesti berlaku terlebih dahulu, kerana putaran selalu dilakukan mengenai asal usul. Oleh kerana objek berada dalam ruang model (asal COM), putaran akan berputar mengenai COM bentuknya. Putaran akan berlaku dengan matrik Mat22. Dalam kod sampel, matriks orientasi adalah nama u.

Selepas putaran dilakukan, objek itu kemudiannya akan diterjemahkan ke kedudukannya di dunia dengan tambahan vektor.

Sekali objek di dalam ruang dunia, ia kemudian boleh diterjemahkan ke ruang model objek yang sama sekali berbeza dengan menggunakan transformasi songsang. Putaran songsang diikuti oleh terjemahan songsang digunakan untuk berbuat demikian. Ini adalah berapa banyak matematik dipermudahkan semasa pengesanan perlanggaran!

Inverse transformation from world space to model space of the red polygon.
Transformasi songsang (kiri ke kanan) dari ruang dunia ke ruang model poligon merah.

Seperti yang dilihat pada imej di atas, jika transformasi songsang dari objek merah digunakan pada kedua poligon merah dan biru, maka ujian pengesanan perlanggaran boleh dikurangkan ke bentuk ujian AABB vs OBB, bukannya mengira matematik kompleks antara dua bentuk berorientasikan.

Dalam kebanyakan kod sumber sampel, simpul sentiasa berubah dari model ke dunia dan kembali ke model, untuk pelbagai sebab. Anda harus mempunyai pemahaman yang jelas tentang apa yang dimaksudkan untuk memahami kod pengesanan perlanggaran sampel.


Pengesanan Perlanggaran dan Generasi Manifold

Dalam bahagian ini, saya akan membentangkan garis besar poligon dan perlanggaran bulatan. Sila lihat kod sumber sampel untuk butiran pelaksanaan lebih mendalam.

Poligon ke poligon

Mari bermula dengan rutin pengesanan pelanggaran yang paling kompleks dalam siri artikel keseluruhan ini. Idea untuk memeriksa perlanggaran di antara dua poligon sebaiknya dilakukan (pada pendapat saya) dengan Teorema Axis Pemisahan (SAT).

Walau bagaimanapun, bukannya memperlihatkan setiap segi poligon pada satu sama lain, terdapat kaedah yang lebih baru dan lebih efisien, seperti yang digariskan oleh Dirk Gregorius dalam Kuliah 2013 GDC (slaid yang tersedia di sini secara percuma).

Perkara pertama yang mesti dipelajari adalah konsep titik sokongan.

Mata Sokongan

Titik sokongan poligon ialah puncak yang paling jauh sepanjang arah yang diberikan. Jika dua titik mempunyai jarak yang sama sepanjang arah yang diberikan, salah satu boleh diterima.

Untuk mengira titik sokongan, produk titik mesti digunakan untuk mencari jarak yang ditandatangani di sepanjang arah yang diberikan. Oleh kerana ini sangat mudah, saya akan menunjukkan contoh cepat dalam artikel ini:

Produk titik digunakan pada setiap puncak. Produk dot mewakili jarak yang ditandatangani dalam arah yang diberikan, sehingga puncak dengan jarak yang diproyeksikan yang paling besar akan menjadi titik belakang untuk kembali. Operasi ini dilakukan dalam ruang model poligon yang diberikan dalam enjin sampel.

Mencari Axis Pemisahan

Dengan menggunakan konsep titik sokongan, pencarian paksi pemisahan boleh dilakukan di antara dua poligon (poligon A dan poligon B). Idea pencarian ini adalah untuk melengkung bersama semua wajah poligon A dan dapatkan titik sokongan dalam keadaan negatif yang normal.

SupportPoints

Dalam imej di atas, dua titik sokongan ditunjukkan: satu pada setiap objek. Normal biru akan sesuai dengan titik sokongan pada poligon yang lain sebagai puncak paling jauh sepanjang arah yang bertentangan normal biru. Begitu juga, warna merah akan digunakan untuk mencari titik sokongan yang terletak di hujung anak panah merah.

Jarak dari setiap titik sokongan ke muka semasa adalah penembusan yang ditandatangani. Dengan menyimpan jarak paling jauh, kemungkinan penembusan minimum boleh direkodkan.

Berikut adalah contoh fungsi dari kod sumber sampel yang mendapati kemungkinan penetrasi minimum menggunakan fungsi GetSupport:

Oleh kerana fungsi ini mengembalikan penembusan terbesar, jika penembusan ini adalah positif, bermakna kedua-dua bentuk tidak bertindih (penembusan negatif akan menandakan tiada paksi pemisahan).

Fungsi ini perlu dipanggil dua kali, membalikkan objek A dan B setiap panggilan.

Keratan Penyebab dan Rujukan

Dari sini, kejadian dan muka rujukan perlu dikenalpasti, dan muka kejadian perlu dipotong daripada pesawat sisi muka rujukan. Ini adalah operasi yang agak tidak penting, walaupun Erin Catto (pencipta Box2D, dan semua fizik yang digunakan oleh Blizzard) telah mencipta beberapa slaid hebat yang meliputi topik ini secara terperinci.

Kliping ini akan menghasilkan dua titik hubungan berpotensi. Semua titik hubungan di belakang muka rujukan boleh dianggap sebagai titik hubungan.

Di luar slaid Erin Catto, enjin sampel juga mempunyai rutin kliping yang dilaksanakan sebagai contoh.

Lingkaran ke Polygon

Lingkaran vs rutin tabrakan poligon agak sedikit lebih mudah daripada pengesanan berlanggar polygon vs poligon. Pertama, muka yang paling dekat pada poligon ke pusat bulatan dikira dengan cara yang sama untuk menggunakan mata sokongan dari bahagian sebelumnya: dengan menggelung setiap muka normal poligon dan mencari jarak dari pusat bulatan ke wajah.

Jika pusat bulatan berada di belakang wajah yang paling dekat ini, maklumat hubungan tertentu boleh dijana dan rutin boleh segera berakhir.

Selepas wajah yang paling dekat dikenal pasti, ujian akan menjadi segmen garis vs. ujian bulatan. Segmen garisan mempunyai tiga kawasan menarik yang dipanggil wilayah Voronoi. Perhatikan rajah berikut:

Voronoi regions of a line segment.
Kawasan Voronoi segmen garisan.

Secara intuitif, bergantung kepada di mana pusat bulatan terletak maklumat hubungan yang berbeza boleh diperolehi. Bayangkan pusat bulatan terletak pada rantau vertex. Ini bermakna bahawa titik terdekat ke pusat bulatan akan menjadi pinggir kelebihan, dan perlanggaran yang betul akan menjadi vektor dari puncak ini ke pusat bulatan.

Sekiranya bulatan berada di kawasan muka maka titik terdekat dari segmen ke pusat bulatan akan menjadi projek pusat bulatan ke segmen. Perlanggaran normal hanya akan menjadi muka normal.

Untuk mengira rantau Voronoi mana lingkaran terletak di dalam, kami menggunakan produk dot antara beberapa simpang. Idea ini adalah untuk membuat segitiga khayalan dan ujian untuk melihat sama ada sudut sudut yang dibina dengan puncak segmen adalah di atas atau di bawah 90 darjah. Satu segitiga dibuat untuk setiap bahagian atas segmen garisan.

Projecting vector from edge vertex to circle center onto the edge.
Menunjukkan vektor dari pinggir tepi ke pusat bulatan ke tepi.

Nilai di atas 90 darjah akan bermakna wilayah pinggir telah dikenalpasti. Sekiranya sudut sudut tepi segitiga tidak melebihi 90 darjah, maka pusat bulatan perlu diunjurkan ke segmen itu sendiri untuk menghasilkan maklumat manifold. Seperti yang dilihat pada imej di atas, jika vektor dari pinggir tepi ke pusat bulatan dihiasi dengan vektor pinggir itu sendiri adalah negatif, maka wilayah Voronoi lingkaran terletak di dalam diketahui.

Nasib baik, produk titik boleh digunakan untuk mengira unjuran yang ditandatangani, dan tanda ini akan negatif jika di atas 90 darjah dan positif jika di bawah.


Resolusi Perlanggaran

Ia adalah masa itu lagi: kami akan kembali ke kod resolusi impuls kami untuk masa ketiga dan terakhir. Sekarang, anda harus selesa menulis kod resolusi mereka sendiri yang mengira impuls resolusi, bersama-sama dengan impuls geseran, dan juga boleh boleh membuat unjuran linier untuk menyelesaikan penembusan yang sisa.

Komponen putaran perlu ditambah kepada kedua-dua geseran dan resolusi penembusan. Sesetengah tenaga akan diletakkan ke dalam halaju sudut.

Inilah resolusi impuls kami apabila kami meninggalkannya dari artikel sebelumnya tentang geseran:

\[Persamaan 5: \\
j = \frac{-(1 + e)((V^{A} - V^{B}) * t)}{\frac{1}{mass^{A}} + \frac{1}{mass^{B}}}
\]

Jika kita membuang komponen putaran, persamaan akhir kelihatan seperti ini:

\[ Persamaan 6: \\
j=\frac{-(1+e)((V^{A}-V^{B})*t)}{\frac1}{mass^{A}}+\frac{1}{mass^{B}}+\frac{(r^{A} \times t)^{2}}{I^{A}}+\frac{(r^{B} \times t)^{2}}{I^{B}}}
\]

Dalam persamaan di atas, \(r\) sekali lagi merupakan "radius", seperti dalam vektor dari COM objek ke titik hubungan. Penurunan yang lebih mendalam tentang persamaan ini boleh didapati di laman Chris Hecker.

Adalah penting untuk menyedari bahawa halaju titik tertentu pada sesuatu objek adalah:

\[ Persamaan 7: \\
V'= V + \omega  \times r
\]

Penerapan impuls sedikit berubah untuk menjelaskan istilah putaran:


Kesimpulannya

Ini menyimpulkan artikel akhir siri ini. Sehingga kini, beberapa topik telah diliputi, termasuk resolusi berdasarkan impuls, generasi manifold, geseran, dan orientasi, semuanya dalam dua dimensi.

Jika anda telah membuatnya sejauh ini, saya mesti mengucapkan tahniah kepada anda! Pengaturcaraan enjin fizik untuk permainan adalah bidang pengajian yang amat sukar. Saya ingin semua nasib pembaca, dan jangan ragu untuk mengulas atau bertanya di bawah.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.