Saya seorang Pengembang Game dan tidak belajar Matematika. Jadi saya hanya ingin menggunakan Quaternions sebagai alat. Dan untuk dapat bekerja dengan rotasi 3D, perlu menggunakan Quaternions (Atau Matriks, tapi mari kita tetap di Quaternions di sini di Pertanyaan ini). Saya pikir penting bagi banyak pengembang untuk menggunakannya. Itu sebabnya saya ingin berbagi pengetahuan dan mudah-mudahan mengisi lubang yang saya miliki. Sekarang....
Sejauh yang saya mengerti:
Quaternion dapat menggambarkan 2 hal:
- Orientasi objek 3d saat ini.
- Transformasi rotasi Obyek bisa dilakukan. (perubahan rotasi)
Anda dapat melakukannya dengan Quaternion:
Perkalian:
Quaternion endOrientation = Rotasi Quaternion Ubah * Quaternion currentOrientation;
Jadi misalnya: Objek 3D saya diputar 90 ° ke kiri - dan rotasi saya, saya kalikan adalah rotasi 180 ° ke kanan, pada akhirnya Obyek 3D 90 ° saya diputar ke kanan.
Rotasi QuaternionChange = Quaternion endRotation * Quaternion.Inverse (startRotation);
Dengan ini, Anda mendapatkan perubahan rotasi, yang dapat diterapkan ke Orientasi lain.
Vector3 endPostion = Rotasi kuarter mengubah * Vector3 currentPosition;
Jadi misalnya: Objek 3D saya ada di Posisi (0,0,0) dan rotasi saya, saya kalikan adalah rotasi 180 ° ke kanan, endosisi saya kira-kira seperti (0, -50,0). Di dalam Quaternion ada Axis - dan rotasi di sekitar sumbu itu. Anda mengubah titik Anda di sekitar sumbu Y Derajat itu.
Vector3 rotatedOffsetVector = Rotasi QuaternionChange * Vector3 currentOffsetVector;
Sebagai contoh: Arah awal saya menunjukkan UP - (0,1,0), dan rotasi saya I adalah rotasi 180 ° ke kanan, arah akhir saya ditampilkan ke bawah. (0, -1,0)
Blending (Lerp dan Slerp):
Quaternion currentOrientation = Quaternion.Slerp (startOrientation, endOrientation, interpolator)
jika interpolator adalah 1: currentOrientation = endOrientation
jika interpolatornya adalah 0: currentOrientation = startOrientation
Slerp interpolasi lebih tepat, Lerp interpolasi lebih banyak performan.
Pertanyaan saya):
Apakah semua yang saya jelaskan sampai sekarang benar?
Apakah itu "semua" yang dapat Anda lakukan dengan Quaternions? (obv. not)
Apa lagi yang bisa Anda lakukan dengan mereka?
Apa gunanya produk Dot dan produk Cross antara 2 Quaternions?
Edit:
Pertanyaan yang Diperbarui dengan beberapa jawaban
sumber
n
orientasi yang berbeda (sikap, pose, dll). Kemudian Anda dapat rata-rata menggunakan bobot, secara efektif menggeneralisasi slerp / lerp. Anda juga dapat mengubah angka empat menjadi rotor, yang setara dengan menerapkan kecepatan sudut untuk jumlah waktu tertentu ke benda tegar. Karenanya Anda dapat menggambarkan integrasi kecepatan sudut dengan angka empat juga. Anda juga dapat memperkirakan seberapa berbeda dua orientasi itu (menghitung panjang busur yang direntang oleh dua angka empat pada hypersphere).Jawaban:
Perkalian
Paling tidak dalam hal implementasi Quaternions dari Unity, urutan multiplikasi yang dijelaskan dalam pertanyaan itu tidak benar. Ini penting karena rotasi 3D tidak komutatif .
Jadi, jika saya ingin memutar objek dengan
rotationChange
memulainya,currentOrientation
saya akan menulisnya seperti ini:(mis. Transformasi menumpuk ke kiri - sama dengan konvensi matriks Unity. Rotasi paling kanan diterapkan pertama / pada ujung "paling lokal")
Dan jika saya ingin mengubah arah atau mengimbangi vektor dengan rotasi, saya akan menulis seperti ini:
(Unity akan menghasilkan kesalahan kompilasi jika Anda melakukan yang sebaliknya)
Memadukan
Untuk sebagian besar kasus, Anda dapat menggunakan rotasi Lerping. Itu karena sudut yang digunakan "di bawah tenda" dalam angka empat adalah setengah sudut rotasi, membuatnya jauh lebih dekat dengan perkiraan linier Lerp daripada sesuatu seperti Matriks (yang secara umum tidak akan Lerp dengan baik!). Lihat sekitar 40 menit dalam video ini untuk penjelasan lebih lanjut .
Satu-satunya kasus ketika Anda benar-benar membutuhkan Slerp adalah ketika Anda membutuhkan kecepatan yang konsisten dari waktu ke waktu, seperti menginterpolasi antar kerangka kunci pada timeline animasi. Untuk kasus-kasus di mana Anda hanya peduli bahwa output adalah perantara antara dua input (seperti memadukan lapisan animasi) maka biasanya Lerp berfungsi dengan cukup baik.
Apa lagi?
Produk titik dari dua unit angka empat memberikan cosinus sudut di antara mereka, sehingga Anda dapat menggunakan produk titik sebagai ukuran kesamaan jika Anda perlu membandingkan rotasi. Ini sedikit tidak jelas, jadi untuk kode yang lebih mudah dibaca, saya sering menggunakan Quaternion.Angle (a, b) sebagai gantinya, yang lebih jelas menyatakan bahwa kami membandingkan sudut, dalam satuan yang dikenal (derajat).
Jenis metode kenyamanan yang disediakan Unity untuk Quaternions sangat berguna. Di hampir setiap proyek saya menggunakan yang ini setidaknya beberapa kali :
Ini membangun angka empat yang:
forward
argumen vektorup
argumen vektor, jika disediakan, atau ke(0, 1, 0)
jika dihilangkanAlasan "naik" hanya "sedekat mungkin" adalah karena sistemnya terlalu ditentukan. Menghadapi z + untuk
forward
menggunakan dua derajat kebebasan (mis. Yaw dan pitch) sehingga kita hanya memiliki satu derajat kebebasan tersisa (roll).Saya menemukan cukup sering saya menginginkan sesuatu dengan sifat ketepatan yang berlawanan: Saya ingin y + lokal untuk menunjukkan tepat bersama
up
, dan z + lokal untuk sedekat mungkinforward
dengan kebebasan yang tersisa.Ini muncul misalnya ketika mencoba untuk membentuk kerangka koordinat relatif kamera untuk input gerakan: Saya ingin arah naik lokal saya tetap tegak lurus dengan lantai atau permukaan yang cenderung normal, jadi input saya tidak mencoba untuk memasukkan karakter ke medan. atau mengangkat mereka dari itu.
Anda juga bisa mendapatkan ini jika Anda ingin rumah menara dari sebuah tank untuk menghadapi target, tanpa terkelupas dari tubuh tangki ketika membidik atas / bawah.
Kita dapat membangun fungsi kenyamanan kita sendiri untuk melakukan ini, menggunakan
LookRotation
untuk mengangkat berat:Di sini kita pertama-tama memutar lokal y + ke z +, dan lokal z + ke y-.
Kemudian kami memutar z + baru ke arah atas kami (jadi hasil bersihnya adalah titik lokal y + langsung di sepanjang
exactUp
), dan y + baru sedekat mungkin dengan arah maju yang dinegasikan (jadi hasil bersihnya adalah titik z + lokal sedekat mungkin sepanjangapproximateForward
)Metode kenyamanan praktis lainnya adalah
Quaternion.RotateTowards
, yang sering saya gunakan seperti ini:Ini memungkinkan kita mendekat pada
targetRotation
kecepatan yang konsisten dan terkendali terlepas dari framerate - penting untuk rotasi yang mempengaruhi hasil / keadilan mekanisme permainan (seperti memutar gerakan karakter, atau memiliki track-in turret pada pemain). Lerping / Slerping secara naif dalam situasi ini dapat dengan mudah menyebabkan kasus di mana gerakan menjadi lebih cepat pada framerate tinggi, yang berdampak pada keseimbangan game. (Itu tidak berarti metode ini salah - ada cara untuk menggunakannya dengan benar tanpa mengubah keadilan, itu hanya membutuhkan perawatan.RotateTowards
Memberikan jalan pintas yang nyaman yang menangani ini untuk kita)sumber
Di mana produk titik digunakan?
Di Unity, salah satu pengguna paling umum dari produk titik adalah setiap kali Anda memeriksa apakah angka empat sama dengan
==
atau!=
. Unity menghitung titik produk untuk memeriksa kesamaan daripada secara langsung membandingkan nilai x, y, z, w internal. Sebaiknya ingat yang satu ini karena membuat panggilan lebih mahal dari yang Anda perkirakan.Kami juga menggunakannya dalam use case yang menarik juga ..
Bersenang-senang dengan produk titik empat angka - Dunia bola dan orbital
Simulasi seluruh planet dan bahkan seluruh tata surya menjadi semakin umum. Untuk melakukan ini secara realtime, kita memerlukan produk dot angka empat juga. Banyak dari mereka. Produk quaternion dot sangat kurang digunakan tetapi pasti memiliki kegunaannya - Mari kita lihat!
Pertama, kami memiliki serangkaian rotasi untuk dipertimbangkan:
Kombinasikan semuanya dan Anda berakhir dengan banyak kerumitan (dan banyak sekali!). Ketika pemirsa berdiri di permukaan planet ini, kami tidak ingin mereka meluncur dengan kecepatan gila melalui ruang gameworld kami. Kami sebenarnya lebih suka mereka diam dan di suatu tempat dekat asal - pindahkan alam semesta di sekitar pemain sebagai gantinya.
Yang penting, agar kita bisa mendapatkan putaran dan kemiringan planet yang benar dalam skenario ini, kita perlu mengunci poros tiang sehingga hanya bisa mengayun ke atas / ke bawah pada gambar di atas (yaitu mengayunkan "ke atas" saat pemain bergerak utara). Di situlah produk dot angka empat masuk. Jika kami tidak menggunakan produk dot di sini dan sebagai gantinya hanya mengalikan kemiringan juga, ini akan terjadi:
Perhatikan bagaimana kutub 'planet' kita yang mengorbit selalu miring ke arah bintang. Ini bukan yang terjadi dalam kenyataan - kemiringannya berada pada arah yang tetap .
Tanpa membahas topik yang terlalu jauh, berikut ringkasan singkatnya:
Dengan hanya memperoleh sudut, kita menjatuhkan beberapa rotasi yang tidak diinginkan . Pada saat yang sama kami juga berakhir dengan pengukuran bujur yang berguna untuk navigasi serta iklim lokal.
* Planet dibangun dari banyak sel jaringan . Hanya yang terdekat yang benar-benar ditampilkan.
sumber
dot(a, b) = a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w
sebagai lawan dari komposisi angka empat yang akan kita gunakan untuk rantai bersama-sama rotasi) akan membantu kami menyelesaikan masalah ini. Saya dengan senang hati akan mendukung jika Anda dapat menguraikan hal ini sedikit kemudian (saya tidak bermaksud menjauhkan Anda dari slerp Anda ... maksud saya tidur!)