Asumsikan Anda sedang menulis kode matriks yang menangani rotasi, terjemahan dll untuk ruang 3d.
Sekarang matriks transformasi harus 4x4 agar sesuai dengan komponen terjemahan.
Namun, Anda sebenarnya tidak perlu menyimpan w
komponen dalam vektor bukan?
Bahkan dalam pembagian perspektif, Anda cukup menghitung dan menyimpan di w
luar vektor, dan membagi perspektif sebelum kembali dari metode.
Sebagai contoh:
// post multiply vec2=matrix*vector
Vector operator*( const Matrix & a, const Vector& v )
{
Vector r ;
// do matrix mult
r.x = a._11*v.x + a._12*v.y ...
real w = a._41*v.x + a._42*v.y ...
// perspective divide
r /= w ;
return r ;
}
Apakah ada gunanya menyimpan w
di kelas Vector?
mathematics
vector
projection
bobobobo
sumber
sumber
r.x = ... + a._14*v.w;
r.y = ... + a._24*v.w;
r.z = ... + a._34*v.w;
r.w = ... + a._44*v.w;
lihat jawaban saya untuk perincianJawaban:
Penyangkalan EDIT : Untuk kenyamanan dalam jawaban ini, vektor dengan w == 0 disebut vektor dan dengan w == 1 disebut poin. Meskipun seperti yang ditunjukkan oleh FxIII, itu bukan terminologi yang benar secara matematis. Namun, karena titik jawabannya bukanlah terminologi, tetapi kebutuhan untuk membedakan kedua jenis vektor, saya akan menaatinya. Untuk alasan praktis, konvensi ini banyak digunakan dalam pengembangan game.
Tidak mungkin membedakan antara vektor dan titik tanpa komponen 'w'. Ini adalah 1 untuk poin dan 0 untuk vektor.
Jika vektor dikalikan dengan matriks transformasi affine 4x4 yang memiliki terjemahan pada baris / kolom terakhir, vektor juga akan diterjemahkan, yang salah, hanya titik yang harus diterjemahkan. Nol dalam komponen 'w' dari vektor menangani hal itu.
Menyoroti bagian ini dari perkalian matriks-vektor membuatnya lebih jelas:
Yaitu akan salah untuk menerjemahkan vektor, misalnya sumbu rotasi, hasilnya hanya salah, Dengan memiliki komponen ke-4 Anda masih dapat menggunakan matriks yang sama yang mengubah titik untuk mengubah sumbu rotasi dan hasilnya akan valid dan panjangnya dipertahankan selama tidak ada skala dalam matriks. Itu adalah perilaku yang Anda inginkan untuk vektor. Tanpa komponen ke-4 Anda harus membuat 2 matriks (atau 2 fungsi perkalian yang berbeda dengan parameter ke-4 yang tersirat. Dan membuat 2 pemanggilan fungsi yang berbeda untuk titik dan vektor.
Untuk menggunakan register vektor CPU modern (SSE, Altivec, SPU), Anda harus tetap mengapung 4x 32 bit (register 128 bit), ditambah Anda harus menjaga perataan, biasanya 16 byte. Jadi, Anda tidak memiliki kesempatan untuk mengamankan ruang untuk komponen ke-4.
EDIT: Jawaban atas pertanyaan pada dasarnya
Seseorang harus memilih salah satunya, tidak mungkin menyimpan hanya {x, y, z} dan masih menggunakan hanya satu fungsi penggandaan matriks-vektor. XNA misalnya menggunakan pendekatan yang terakhir dengan memiliki 2 fungsi Transform di kelas Vector3 , yang disebut
Transform
danTransformNormal
Berikut adalah contoh kode yang menunjukkan kedua pendekatan dan menunjukkan kebutuhan untuk membedakan kedua jenis vektor dalam 1 dari 2 cara yang mungkin. Kami akan memindahkan entitas permainan dengan posisi dan arah pandang di dunia dengan mengubahnya dengan sebuah matriks. Jika kita tidak menggunakan komponen 'w', kita tidak bisa menggunakan perkalian matriks-vektor yang sama lagi, seperti ditunjukkan contoh ini. Jika kita tetap melakukannya, kita akan mendapatkan jawaban yang salah untuk
look_dir
vektor yang diubah :Status Entitas Awal:
Sekarang transformasi dengan terjemahan x + 5 dan rotasi 90 derajat di sekitar sumbu y akan diterapkan pada entitas ini. Jawaban yang benar setelah tranformasi adalah:
Kami hanya akan mendapatkan jawaban yang benar jika kami membedakan vektor dengan w == 0 dan posisi dengan w == 1 dalam salah satu cara yang disajikan di atas.
sumber
Jika Anda membuat kelas vektor, maka saya kira kelas akan menyimpan deskripsi vektor 3D. Vektor 3D memiliki besaran x, y, dan z. Jadi kecuali jika vektor Anda membutuhkan besaran arbitrer, tidak, Anda tidak akan menyimpannya di kelas.
Ada perbedaan besar antara vektor dan matriks transformasi. Karena DirectX dan OpenGL menangani matriks untuk Anda, saya biasanya tidak menyimpan matriks 4x4 dalam kode saya; alih-alih, saya menyimpan rotasi Euler (atau Quaternions jika Anda mau - yang kebetulan memiliki komponen aw) dan terjemahan x, y, z. Terjemahan adalah vektor jika Anda mau, dan rotasi secara teknis akan cocok dengan vektor juga, di mana setiap komponen akan menyimpan jumlah rotasi di sekitar porosnya.
Jika Anda ingin menyelami sedikit lebih dalam matematika dari suatu vektor, vektor Euclidean hanyalah arah dan besarnya. Jadi biasanya ini diwakili oleh triplet angka, di mana setiap angka adalah besarnya sepanjang sumbu; arahnya tersirat oleh kombinasi dari tiga magnitudo ini, dan magnitudo dapat ditemukan dengan rumus jarak Euclidean . Atau, kadang-kadang itu benar-benar disimpan sebagai arah (vektor dengan panjang = 1) dan besarnya (float), jika itu yang nyaman (misalnya jika besarnya berubah lebih sering daripada arah, mungkin lebih nyaman untuk hanya ubah angka magnitudo dari pada mengambil vektor, normalkan , dan gandakan komponen dengan magnitudo baru).
sumber
Dimensi keempat dalam vektor 3D digunakan untuk menghitung transformasi affine yang tidak mungkin untuk dihitung menggunakan matriks saja. Ruang tetap tiga dimensi sehingga ini berarti bahwa keempat dipetakan dalam ruang 3d dalam beberapa cara.
Memetakan dimensi berarti bahwa vektor 4D yang berbeda menunjukkan titik 3D yang sama. Peta itu adalah jika A = [x ', y', z'.w '] dan B = [x ", y", z ", w"] mereka mewakili titik yang sama jika x' / x "= y ' / y "= z '/ z" = w' / w "= α yaitu komponen proporsional untuk koefisien α yang sama.
Mengatakan bahwa Anda dapat mengekspresikan suatu titik - katakanlah (1,3,7) - dalam perilaku tak terbatas seperti (1,3,7,1) atau (2,6,14,2) atau (131,393,917,131) atau secara umum (α · 1, α · 3, α · 7, α).
Ini berarti bahwa Anda dapat skala vektor 4D ke yang lain yang mewakili titik 3D yang sama sehingga w = 1: formulir (x, y, z, 1) adalah bentuk kanonik.
Saat Anda menerapkan matriks ke vektor ini, Anda dapat memperoleh vektor yang tidak memiliki w = 1, tetapi Anda selalu dapat menskalakan hasil untuk menyimpannya dalam bentuk kanonik. Jadi jawabannya tampaknya "Anda harus menggunakan vektor 4D saat melakukan matematika tetapi jangan menyimpan komponen keempat" .
Ini cukup benar tetapi ada beberapa poin yang tidak dapat Anda masukkan ke dalam bentuk kanonik: poin seperti (4,2,5,0). Poin-poin itu adalah yang spesial, mereka mewakili titik tak terhingga yang diarahkan dan dapat dinormalisasi ke satuan vektor secara konsisten: Anda dapat dengan aman pergi ke yang tak terbatas dan kembali (bahkan dua kali) tanpa menjadi Chuck Norris. Anda akan mendapatkan pembagian yang menyedihkan dengan nol jika Anda mencoba untuk memaksa vektor-vektor itu dalam bentuk kanonik.
Sekarang Anda tahu, jadi pilihan ada di tangan Anda!
sumber
Ya, benar. Transformasi Anda salah untuk beberapa jenis vektor. Anda dapat melihat ini di perpustakaan matematika D3DX - mereka memiliki dua fungsi multiplikasi matriks-vektor yang berbeda, satu untuk w = 0 dan satu untuk w = 1.
sumber
Tergantung pada apa yang Anda inginkan dan butuhkan. :)
Saya akan menyimpannya, b / c itu diperlukan untuk transformasi dan semacamnya (Anda tidak dapat melipatgandakan vektor 3 dengan matriks 4x4), meskipun jika Anda selalu memiliki aw of 1, saya kira Anda bisa memalsukannya.
sumber