Sebagaimana Nathan Reed dan teodron terpapar, resep untuk memutar vektor v oleh q angka empat satuan panjang adalah:
1) Buat p angka empat murni dari v . Ini berarti menambahkan koordinat keempat dari 0:
p = ( vx, vy, vz, 0 ) ⇔ p = ( v , 0 )
2) Pra-gandakan dengan q dan gandakan dengan konjugat q * :
hal′= q× p × q∗
3) Ini akan menghasilkan angka empat murni lain yang dapat dikembalikan ke vektor:
v′= ( hal′x,p′y,p′z)
Vektor ini adalah diputar oleh .v′vq
Ini bekerja tetapi jauh dari optimal . Penggandaan Quaternion berarti berton-ton operasi. Saya ingin tahu tentang berbagai implementasi seperti ini , dan memutuskan untuk mencari dari mana mereka datang. Inilah temuan saya.
Kami juga bisa menggambarkan q sebagai kombinasi dari vektor 3-dimensi u dan skalar s :
q=(ux,uy,uz,s)⇔q= ( kamu , s )
Dengan aturan perkalian angka empat , dan sebagai konjugasi dari angka empat satuan hanya kebalikannya, kita mendapatkan:
hal′= qp q∗= ( u , s ) ( v , 0 ) ( - u , s )= ( s v + u × v , - u ⋅ v ) ( - u , s )= ( ( - u ⋅ v ) ( - u ) + s ( s v + u × v ) + ( s v + u × v ) × ( - u ) , ... ) = ( ( u ⋅ v ) u + s2v + s ( u × v ) + s v × ( - u ) + ( u × v ) × ( - u ) , ... )
Bagian skalar (elips) menghasilkan nol, seperti yang dijelaskan di sini . Yang menarik adalah bagian vektor, AKA vektor diputar kami v ' . Ini dapat disederhanakan menggunakan beberapa identitas vektor dasar :
v′= ( u ⋅ v ) u + s2v + s ( u × v ) + s ( u × v ) + u × ( u × v )= ( u ⋅ v ) u + s2v + 2 s ( u × v ) + ( u ⋅ v ) u - ( u ⋅ u ) v= 2 ( u ⋅ v ) u + ( s2- u ⋅ u ) v + 2 s ( u × v )
Ini sekarang jauh lebih optimal ; produk dua titik, produk silang dan beberapa tambahan: sekitar setengah operasi. Yang akan memberikan sesuatu seperti itu dalam kode sumber (dengan asumsi beberapa perpustakaan matematika vektor generik):
void rotate_vector_by_quaternion(const Vector3& v, const Quaternion& q, Vector3& vprime)
{
// Extract the vector part of the quaternion
Vector3 u(q.x, q.y, q.z);
// Extract the scalar part of the quaternion
float s = q.w;
// Do the math
vprime = 2.0f * dot(u, v) * u
+ (s*s - dot(u, u)) * v
+ 2.0f * s * cross(u, v);
}
vprime = v + ((cross(u, v) * s) + cross(u, cross(u, v)) * 2.0f
Apakah ini optimasi yang sama? Itu terlihat agak mirip, tetapi tidak sama - hanya menggunakan produk silang, tidak ada produk titik. Kode sumber asli dapat ditemukan di berkas type_quat.inl resmi GLM repositori dalamoperator*
yang membutuhkan angka empat dan vektor (vec<3, T, Q> operator*(qua<T, Q> const& q, vec<3, T, Q> const& v)
)Pertama-tama, q ^ (- 1) bukan -q / magnitude (q); itu q * / (magnitude (q)) ^ 2 (q * adalah konjugat; yang meniadakan semua komponen kecuali yang asli). Tentu saja, Anda dapat meninggalkan divisi dengan besarnya jika semua angka empat Anda sudah dinormalisasi, yang biasanya akan berada dalam sistem rotasi.
Sedangkan untuk perkalian dengan vektor, Anda hanya perlu memperpanjang vektor ke angka empat dengan mengatur komponen real quat menjadi nol dan komponen ijk ke xyz vektor. Kemudian Anda melakukan perkalian angka empat untuk mendapatkan v ', dan kemudian ekstrak komponen ijk lagi. (Bagian nyata dari v 'harus selalu keluar nol, plus atau minus beberapa kesalahan floating-point.)
sumber
Pengamatan pertama: Kebalikan dari
q
tidak-q/magnitude(q)
, itu sepenuhnya salah. Rotasi dengan angka empat menyiratkan bahwa bilangan setara 4D kompleks ini memiliki norma kesatuan, karenanya terletak pada bidang unit S3 dalam ruang 4D itu. Fakta bahwa quat adalah kesatuan berarti norma itu adalahnorm(q)^2=q*conjugate(q)=1
dan itu berarti bahwa kebalikan quat adalah konjugatnya.Jika unit angka empat ditulis sebagai
q=(w,x,y,z)
= (cos (t), sin (t) v ), maka konjugatnya adalahconjugate(q)=(w,-x,-y,-z)
= (cos (t), - sin (t) v ), di mana t adalah setengah dari sudut rotasi dan v adalah sumbu rotasi (sebagai vektor satuan, tentu saja).Ketika pria Hamilton itu memutuskan untuk bermain-main dengan angka-angka ekuivalen kompleks dalam dimensi yang lebih tinggi, ia juga menemukan beberapa properti bagus. Misalnya, jika Anda mempekerjakan angka empat benar-benar murni
q=(0,x,y,z)
(tidak ada bagian skalar w !), Anda dapat mempertimbangkan omong kosong bahwa sebagai vektor (itu sebenarnya quat pada apa yang orang sebut ekuator lingkup S3, yang merupakan lingkup S2! ! - keberatan membengkokkan barang jika kita mempertimbangkan bagaimana gangguan teknis orang-orang di abad ke-19 tampaknya bagi kita koboi EyePhone saat ini). Maka Hamilton mengambil vektor itu dalam bentuk quat-nya:v=(0,x,y,z)
dan melakukan serangkaian eksperimen dengan mempertimbangkan sifat-sifat geometris quat .. Singkatnya:dimana
Pengamatan: q * (0, v) * conj (q) harus quat lain dari bentuk (0, v '). Saya tidak akan membahas semua penjelasan yang kelihatannya rumit tentang mengapa ini terjadi, tetapi jika Anda memutar angka empat imajiner murni (atau vektor dalam kasus kami!) Melalui metode ini, Anda harus mendapatkan jenis objek yang serupa: quat imajiner murni. dan Anda mengambil bagian imajinernya sebagai hasil Anda. Itu dia, dunia rotasi yang indah dengan angka empat dalam cangkang kacang.
CATATAN : kepada siapa pun yang melompat dengan frasa yang terlalu sering digunakan: quat baik karena mereka menghindari 'kunci gimbal .. harus membuka imajinasi mereka terlebih dahulu !! Quat hanyalah alat matematika "elegan" dan dapat dihindari sama sekali dengan menggunakan pendekatan lain, yang saya temukan benar-benar setara secara geometris menjadi pendekatan sudut sumbu.
KODE : pustaka C ++ yang saya suka agak sederhana, tetapi memiliki semua operasi matriks, vektor dan quat yang harus dibutuhkan oleh seorang pencoba grafis 3D tanpa harus menghabiskan lebih dari 15 menit untuk mempelajarinya .. Anda dapat menguji hal-hal yang saya tulis di sini menggunakan itu dalam 15 menit jika Anda bukan seorang pemula C ++. Semoga berhasil!
sumber
Berikut adalah cara alternatif untuk mengubah vektor oleh angka empat. Ini adalah cara MS melakukannya dalam kerangka xna. http://pastebin.com/fAFp6NnN
sumber
Saya mencoba menyelesaikannya dengan tangan, dan menghasilkan persamaan / metode berikut:
Saya akan sangat menghargai jika seseorang akan melihat mt deriviation saya menggunakan http://pastebin.com/8QHQqGbv Saya akan menyarankan untuk menyalin ke editor teks yang mendukung pengguliran samping
dalam notasi saya, saya menggunakan q ^ (- 1) berarti konjugasi, dan bukan invers, dan pengidentifikasi yang berbeda, tapi saya berharap itu bisa diikuti. Saya pikir mayoritas benar terutama ketika membuktikan bagian nyata dari vektor akan hilang.
sumber