Tutorial de Raycasting / pregunta matemática vectorial

8

Estoy revisando este bonito tutorial de Raycasting en http://lodev.org/cgtutor/raycasting.html y tengo una pregunta matemática probablemente muy simple.

En el algoritmo DDA, tengo problemas para comprender el cálculo de las variables deltaDistX y deltaDistY, que son las distancias que tiene que recorrer el rayo desde el lado x al siguiente lado x, o desde el lado y al siguiente lado y, en la cuadrícula cuadrada que forma el mapa mundial (ver la captura de pantalla a continuación).

ingrese la descripción de la imagen aquí

En el tutorial se calculan de la siguiente manera, pero sin mucha explicación:

//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 y rayDirX son la dirección de un rayo que se ha emitido.

¿Cómo se obtienen estas fórmulas? Parece que el teorema de Pitágoras es parte de él, pero de alguna manera hay división involucrada aquí. ¿Alguien puede darme una idea de qué conocimiento matemático me estoy perdiendo aquí, o "probar" la fórmula mostrando cómo se deriva?

Mattboy
fuente
Probablemente también le gustaría consultar scratchapixel.com/lessons/3d-basic-lessons/… que tiene una explicación muy agradable y detallada de DDA.
Grieverheart

Respuestas:

8

Ahh si. Le lancé mis cálculos y creo que lo acerté. Estás en lo cierto, implica el teorema de Pitágoras y algo de escala.

Comienzas con tu vector normalizado que representa tu rayo.

ingrese la descripción de la imagen aquí

Tiene un xcomponente y un ycomponente. Primero, queremos ver cuánto dura cuando viaja una unidad en la xdirección. ¿Asi que que hacemos? Queremos escalar todo el vector para que el xcomponente sea igual 1. Para averiguar por qué escalarlo, hacemos lo siguiente:

scaleFactor = 1/rayDirX;

Escribir eso en matemáticas es realmente solo

scaledX = rayDirX * (1/rayDirX) = 1

Entonces podemos llamarlo así 1.

Luego para el ycomponente:

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

Así que ahora tenemos nuestros componentes escalados como (1, rayDirY/rayDirX)

Ahora, queremos saber la longitud. Ahora entra en juego Pitágoras. Cual es

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

Al conectar nuestros componentes escalados obtenemos:

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

Aplica un poco de álgebra y simplifica y obtenemos:

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

Lo mismo ocurre con la longitud cuando el ycomponente viaja una unidad, excepto que tendremos (rayDirX/rayDirY, 1)qué resultados en

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

Ahí tenemos sus dos ecuaciones de su pregunta. Con buena pinta. Gracias por el ejercicio de álgebra.

MichaelHouse
fuente
ahh me ganaste! ¡Muy agradable!
Philip
¡Ja, seguí comprobando si había nuevas respuestas! Sentí que estaba corriendo contra alguien :)
MichaelHouse
¡Muy bien, gracias! Era mucho menos obvio de lo que esperaba.
Mattboy
Solo encontré la respuesta cuando dejé de intentar hacer ingeniería inversa e intenté encontrar cómo obtendría ese valor si lo estuviera haciendo. Pensé que tal vez escalar el vector sería algún tipo de atajo, pero resulta que es de la misma manera que lo están haciendo :)
MichaelHouse
1

Suponiendo que la unidad de longitud de cada distancia de cuadrícula es 1.

El triángulo (Triángulo 1) en el diagrama publicado (pregunta OP) que consiste deltaDistXen la hipotenusa, tiene el mismo valor coseno de su ángulo que el valor coseno del ángulo formado en el triángulo formado por los constituyentes del rayDir# Vector(Triángulo 2)

Entonces lo siguiente puede ser equiparado ( magnitudes vectoriales a continuación ) y simplificar (1-3)

Recuerde: cos = Base / Hipotenusa

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)

De manera similar, deltaDistYse puede derivar la ecuación para .

espacio métrico
fuente