Pertanyaan tutorial / vektor matematika raycasting


8

Saya memeriksa tutorial raycasting yang bagus ini di http://lodev.org/cgtutor/raycasting.html dan memiliki pertanyaan matematika yang mungkin sangat sederhana.

Dalam algoritma DDA, saya mengalami kesulitan memahami perhitungan variabel deltaDistX dan deltaDistY, yang merupakan jarak yang harus ditempuh oleh sinar dari 1 sisi x ke sisi x sisi berikutnya, atau dari sisi 1 y ke sisi berikutnya sisi y, di kotak persegi yang membentuk peta dunia (lihat screenshot di bawah).

masukkan deskripsi gambar di sini

Dalam tutorial mereka dihitung sebagai berikut, tetapi tanpa banyak penjelasan:

//length of ray from one x or y-side to next x or y-side
double deltaDistX = sqrt(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX));
double deltaDistY = sqrt(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY));

rayDirY dan rayDirX adalah arah dari sinar yang telah dilemparkan.

Bagaimana Anda mendapatkan formula ini? Sepertinya teorema pythagoras adalah bagian darinya, tetapi entah bagaimana ada pembagian yang terlibat di sini. Adakah yang bisa memberi saya petunjuk tentang pengetahuan matematika apa yang saya lewatkan di sini, atau "buktikan" rumus dengan menunjukkan bagaimana itu diturunkan?


Anda mungkin juga ingin memeriksa scratchapixel.com/lessons/3d-basic-lessons/… yang memiliki penjelasan DDA yang sangat bagus dan terperinci.
Grieverheart

Jawaban:


8

Ahh ya. Saya melempar matematika saya dan saya pikir saya memukulnya. Anda benar itu memang melibatkan teorema Pythagoras dan beberapa penskalaan.

Anda mulai dengan vektor Anda yang dinormalisasi yang mewakili sinar Anda.

masukkan deskripsi gambar di sini

Ini memiliki xkomponen dan ykomponen. Pertama-tama kita ingin melihat berapa lama ketika ia berjalan satu unit ke xarah itu. Jadi apa yang kita lakukan? Kami ingin skala seluruh vektor sehingga xkomponennya sama 1. Untuk mengetahui skala apa yang harus diukur, kami melakukan hal berikut:

scaleFactor = 1/rayDirX;

Menuliskannya dalam matematika itu benar-benar adil

scaledX = rayDirX * (1/rayDirX) = 1

Jadi kita bisa menyebutnya begitu 1.

Kemudian untuk ykomponen:

scaledY = rayDirY * (1/rayDirX) = rayDirY/rayDirX

Jadi sekarang kita memiliki komponen skala kita sebagai (1, rayDirY/rayDirX)

Sekarang, kami ingin tahu panjangnya. Sekarang Pythagoras ikut bermain. Yang mana

length = sqrt((x * x) + (y * y))

Jadi, memasukkan komponen berskala kami dapatkan:

length = sqrt((1 * 1 ) + (rayDirY / rayDirX) * (rayDirY / rayDirX))

Terapkan beberapa aljabar dan sederhanakan dan kita dapatkan:

length = sqrt(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX))

Sama berlaku untuk panjang ketika ykomponen bergerak satu unit, kecuali kita akan memiliki (rayDirX/rayDirY, 1)yang menghasilkan

length = sqrt(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY))

Di sana kami memiliki dua persamaan Anda dari pertanyaan Anda. Cukup rapi. Terima kasih untuk latihan aljabar.


ahh kau mengalahkanku untuk itu! Sangat bagus!
Philip

Ha, saya terus memeriksa untuk melihat apakah ada jawaban baru! Saya merasa seperti sedang membalap seseorang :)
MichaelHouse

Bagus sekali, terima kasih! Jauh lebih jelas daripada yang kuharapkan.
mattboy

Saya hanya menemukan jawabannya ketika saya menyerah mencoba untuk merekayasa balik dan mencoba menemukan bagaimana saya akan mendapatkan nilai itu jika saya melakukannya. Saya pikir mungkin skala vektor akan menjadi semacam jalan pintas, tetapi ternyata itu cara yang sama mereka melakukannya :)
MichaelHouse

1

Dengan asumsi panjang satuan dari setiap jarak kisi adalah 1.

Segitiga (Segitiga 1) dalam diagram yang diposting (pertanyaan OP) yang terdiri dari deltaDistXsebagai sisi miring, memiliki nilai kosinus yang sama dari sudutnya sebagaimana nilai kosinus sudut yang dibentuk dalam segitiga yang dibentuk oleh konstituen dari rayDir# Vector(Segitiga 2)

Jadi yang berikut ini bisa disamakan ( besaran vektor di bawah ), dan disederhanakan (1-3)

Ingat: cos = Base / Hypotenuse

0. cosine_triangle_2                   = cosine_triangle_1
1. rayDirX/sqrt(rayDirX^2 + rayDirY^2) = 1/deltaDistX
2. (rayDirX*deltaDistX)^2              = rayDirX^2 + rayDirY^2
3. deltaDistX                          = sqrt(1+ rayDirY^2/rayDirX^2)

Demikian pula persamaan untuk deltaDistYdapat diturunkan.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.