Saya sedang mengkode seorang mekanik yang memungkinkan pengguna untuk bergerak di sekitar permukaan bola. Posisi pada bola saat ini disimpan sebagai theta
dan phi
, di mana theta
sudut antara sumbu z dan proyeksi xz dari posisi saat ini (yaitu rotasi sekitar sumbu y), dan phi
merupakan sudut dari sumbu y ke posisi. Saya menjelaskannya dengan buruk, tetapi pada dasarnya theta = yaw
,phi = pitch
Vector3 position = new Vector3(0,0,1);
position.X = (float)Math.Sin(phi) * (float)Math.Sin(theta);
position.Y = (float)Math.Sin(phi) * (float)Math.Cos(theta);
position.Z = (float)Math.Cos(phi);
position *= r;
Saya percaya ini akurat, namun saya bisa saja salah. Saya harus bisa bergerak dalam arah dua dimensi semu yang semena-mena di sekitar permukaan bola pada titik asal ruang dunia dengan jari-jari r
. Misalnya, memegang Wharus bergerak di sekitar bola dalam arah ke atas relatif terhadap orientasi pemain.
Saya percaya saya harus menggunakan Quaternion untuk mewakili posisi / orientasi pada bola, tetapi saya tidak bisa memikirkan cara yang tepat untuk melakukannya. Geometri bulat bukan setelan kuat saya.
Intinya, saya perlu mengisi blok berikut:
public void Move(Direction dir)
{
switch (dir)
{
case Direction.Left:
// update quaternion to rotate left
break;
case Direction.Right:
// update quaternion to rotate right
break;
case Direction.Up:
// update quaternion to rotate upward
break;
case Direction.Down:
// update quaternion to rotate downward
break;
}
}
(1,1,1)
memegang kiri akan berputar di sekitar bola, melewati(~1.2,0,~-1.2)
, lalu(-1,-1,-1)
, lalu(~-1.2,0,~1.2)
dan kembali ke(1,1,1)
.theta
danphi
ketika posisi Anda diperbarui, Anda membuat masalah Anda menjadi tidak perlu. Jauh lebih mudah untuk hanya menghitung 2 sumbu rotasi setiap frame (salah satunya (yaw) tidak pernah berubah) dan diVector3.Transorm
sekitar bola. Ini akan menyederhanakan masalah Anda tetapi akan menyebabkan Anda memutuskan koneksi denganphi
&theta
.Jawaban:
Sebenarnya, ternyata Anda tidak bisa memilikinya 'dua arah': jika niat Anda adalah untuk tidak memiliki rasa 'orientasi absolut' di bola (yaitu, jika para pemain tidak selalu eg menghadap ke arah kutub ), maka Anda harus memiliki gagasan tentang orientasi pemain. Ini karena, bertentangan dengan apa yang mungkin dikatakan oleh intuisi, gerakan di bola tidak persis seperti gerakan di pesawat, bahkan tidak secara lokal (cukup); lengkungan intrinsik bola berarti bahwa pemain dapat mengambil tindakan yang akan memutar diri mereka sendiri!
Untuk contoh paling ekstrim dari apa yang saya bicarakan, bayangkan bahwa pemain mulai pada titik di khatulistiwa (untuk kenyamanan kita akan membayangkan wajah jam dipetakan ke khatulistiwa dari atas, dan menempatkan pemain pada jam 6 ), menghadap 'atas' - yaitu, menuju Kutub Utara. Misalkan pemain berjalan sampai ke Kutub Utara; maka mereka akan menghadap langsung ke titik 12:00. Sekarang, biarkan pemain bergerak langsung ke kanan, dari Kutub Utara kembali ke khatulistiwa; mereka akan berakhir pada titik jam 3 - tetapi karena wajah mereka tidak berubah ketika mereka bergerak ke kanan(Idenya adalah bahwa wajah mereka tidak berubah tidak peduli bagaimana mereka bergerak), mereka masih akan menghadapi titik jam 12 - mereka sekarang menghadapi sepanjang garis katulistiwa! Sekarang, biarkan mereka bergerak 'mundur' kembali ke titik awal (jam 6); maka mereka masih akan menghadap ke garis khatulistiwa, jadi mereka akan menghadap ke arah jam 3 - hanya bergerak di sepanjang bola tanpa pernah mengubah orientasi 'pribadi' mereka telah menyebabkan mereka berputar dari menghadap ke arah kutub utara ke menghadap ke garis khatulistiwa! Dalam arti tertentu, ini adalah penjabaran dari yang lama 'seorang pemburu bergerak satu mil ke selatan, satu mil ke barat dan kemudian satu mil ke utara' lelucon - tetapi di sini kita mengambil keuntungan dari lengkungan bola untuk menghasilkan perubahan arah. Perhatikan bahwa efek yang sama masih terjadi bahkan pada skala yang jauh lebih kecil;
Untungnya, angka empat melakukan (seperti yang Anda catat sendiri) menangani situasi ini; karena angka empat mewakili rotasi sewenang-wenang, itu secara efektif mewakili 'titik plus orientasi' sewenang-wenang di bola: bayangkan mulai dengan 'triaksi' di titik asal dan berikan beberapa rotasi acak, lalu gerakkan satu unit ke arah mana pun sumbu diputar ' Titik sumbu Z; sedikit pemikiran akan meyakinkan Anda bahwa ini membawa Anda ke titik di unit bola dengan beberapa 'orientasi' (yaitu, beberapa pengaturan sumbu X dan Y dari triaksi Anda), dan bahwa Anda bisa mendapatkan setiap titik + orientasi pada unit sphere dengan cara ini (cukup tetapkan sumbu Z Anda untuk menunjuk sepanjang garis dari titik asal melalui titik Anda pada bola, lalu bawa triaksi Anda kembali ke titik asal di sepanjang garis itu). Apalagi, karena penggandaan angka empat sesuai dengan komposisi rotasi, setiap operasi yang Anda gambarkan dapat diwakili dengan mengalikan 'orientasi Anda saat ini' dengan angka empat yang dipilih secara tepat: khususnya, karena angka empat (unit) angka empat (qx, qy, qz, qw) berarti 'memutar tentang sumbu (qx, qy, qz) oleh arccos (qw)', lalu (tergantung pada pilihan spesifik sistem koordinat Anda, dan membiarkan c_a menjadi cos (alpha) dan s_a menjadi sin (alpha)) dua dari tiga angka empat M_x = (s_a, 0, 0, c_a), M_y = (0, s_a, 0, c_a), dan M_z = (0, 0, s_a, c_a) akan mewakili 'rotate (yaitu bergerak) ke arah I 'Saya saat ini dihadapkan oleh alpha' dan 'putar ke arah orthogonal dengan yang saya sedang hadapi oleh alpha'. (Yang ketiga dari empat angka tersebut akan mewakili 'putar karakter saya tentang porosnya sendiri'
Cur_q = M_x * Cur_q
jika pemain telah menekan ke atas, atauCur_q = M_y * Cur_q
jika pemain menekan ke kanan (atau mungkin sesuatu sepertiCur_q = M_yinv * Cur_q
jika pemain menekan ke kiri, di mana M_yinv adalah 'kebalikan' dari angka empat M_y, mewakili rotasi dengan cara lain). Perhatikan bahwa Anda harus berhati-hati di 'sisi' mana Anda menerapkan rotasi, apakah untuk pra-kelahiran atau pascamultiply; sejujurnya, mungkin paling mudah untuk menyelesaikannya dengan coba-coba, mencoba penggandaan dan melihat mana yang berhasil.Beralih dari angka empat yang diperbarui ke titik di bola (dan ke orientasi karakter Anda) juga relatif mudah: dengan korespondensi paragraf terakhir, yang harus Anda lakukan adalah menggunakan angka empat Anda berdasarkan vektor (1, 0,0), (0,1,0) dan (0,0,1) dari frame Anda melalui operasi 'rotate vector by quaternion' v → qvq -1 (di mana perkalian di sini adalah angka empat dikalikan dan kami mengidentifikasi vektor v = (x, y, z) dengan 'angka empat yang merosot' (x, y, z, 0)). Misalnya, posisi pada unit sphere didapat dengan hanya mentransformasikan vektor z: pos = (qx, qy, qz, qw) * (0, 0, 1, 0) * (-qx, -qy, -qz, qw) = (qx, qy, qz, qw) * (qy, -qx, qw, qz) = (2 (qy * qw + qz * qx), 2 (qz * qy-qw * qx), (qz ^ 2 + qw ^ 2) - (qx ^ 2 + qy ^ 2), 0), jadi
(2(qy*qw+qz*qx), 2(qz*qy-qw*qx), (qz^2+qw^2)-(qx^2+qy^2))
akan menjadi koordinat dari pengguna yang 'ditransformasikan' pada unit sphere (dan untuk mendapatkan koordinat pada sphere yang sewenang-wenang, tentu saja, Anda hanya akan mengalikannya dengan radius sphere); perhitungan serupa bekerja untuk sumbu lainnya, untuk menentukan misalnya arah menghadap pengguna.sumber
Move()
prosedur, tetapi untuk mendapatkan sumbu yang dinormalisasi (yaitu posisi saya), apakah saya akan mengambilnya(sin(qx),sin(qy),sin(qw)) * r
?Saya pikir Anda menginginkan sesuatu yang mirip dengan http://www.youtube.com/watch?v=L2YRZbRSD1k ini
Saya mengembangkannya untuk gamejam 48jam ... Anda dapat memuat kode di sini ... http://archive.globalgamejam.org/2011/evil-god
Saya menggunakan sesuatu yang mirip dengan kode Anda untuk mendapatkan 3D coords ... tapi saya memutar planet ini dan pemain berada di posisi yang sama, saya pikir Anda tertarik pada gerakan makhluk, apakah ini:
sumber