Tutorial de Raycasting / questão matemática vetorial


8

Estou consultando este bom tutorial sobre raycasting em http://lodev.org/cgtutor/raycasting.html e tenho uma pergunta matemática provavelmente muito simples.

No algoritmo DDA, estou tendo problemas para entender a calibração das variáveis ​​deltaDistX e deltaDistY, que são as distâncias que o raio deve percorrer de 1 lado x para o próximo lado x, ou de 1 lado y para o próximo lado y, na grade quadrada que compõe o mapa do mundo (veja a captura de tela abaixo).

insira a descrição da imagem aqui

No tutorial, eles são calculados da seguinte forma, mas sem muita explicação:

//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 e rayDirX são a direção de um raio que foi lançado.

Como você obtém essas fórmulas? Parece que o teorema de Pitágoras faz parte dele, mas de alguma forma há divisão envolvida aqui. Alguém pode me informar sobre o conhecimento matemático que estou perdendo aqui ou "provar" a fórmula, mostrando como ela é derivada?


Você provavelmente também gostaria de verificar scratchapixel.com/lessons/3d-basic-lessons/…, que tem uma explicação muito agradável e detalhada do DDA.
Grieverheart 5/12/12

Respostas:


8

Ah sim. Joguei minha matemática e acho que acertou. Você está correto, pois envolve o teorema de Pitágoras e algumas escalas.

Você começa com seu vetor normalizado que representa seu raio.

insira a descrição da imagem aqui

Tem um xcomponente e um ycomponente. Primeiro, queremos ver quanto tempo demora quando ele viaja uma unidade na xdireção. Então, o que fazemos? Queremos escalar o vetor inteiro para que o xcomponente seja igual 1. Para descobrir em que escala, fazemos o seguinte:

scaleFactor = 1/rayDirX;

Escrevendo isso em matemática é realmente apenas

scaledX = rayDirX * (1/rayDirX) = 1

Então podemos chamar assim 1.

Depois, para o ycomponente:

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

Então agora temos nossos componentes dimensionados como (1, rayDirY/rayDirX)

Agora, queremos saber o comprimento. Agora Pitágoras entra em jogo. Qual é

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

Então, conectando nossos componentes em escala, obtemos:

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

Aplique alguma álgebra e simplifique e obtemos:

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

O mesmo vale para o comprimento quando o ycomponente viaja uma unidade, exceto que teremos (rayDirX/rayDirY, 1)quais resultados em

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

Aí temos suas duas equações da sua pergunta. Muito arrumado. Obrigado pelo exercício de álgebra.


ahh você me venceu! Muito agradável!
Philip

Ha, eu ficava checando para ver se havia novas respostas! Eu senti como se estivesse correndo alguém :)
Michaelhouse

Muito bom, obrigado! Era muito menos óbvio do que eu esperava.
mattboy

Eu só encontrei a resposta quando desisti de tentar fazer engenharia reversa e tentei descobrir como obter esse valor se estivesse fazendo isso. Eu pensei que talvez escalar o vector seria algum tipo de atalho, mas acontece que é da mesma forma que eles estão fazendo isso :)
Michaelhouse

1

Supondo que o comprimento da unidade de cada distância da grade seja 1.

O triângulo (Triângulo 1) no diagrama publicado (questão OP), que consiste deltaDistXna hipotenusa, tem o mesmo valor de cosseno de seu ângulo que o valor de cosseno de ângulo formado no triângulo formado pelos constituintes do rayDir# Vector(Triângulo 2)

Portanto, o seguinte pode ser equacionado ( magnitudes do vetor abaixo ) e simplificado (1-3)

Lembre-se: 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)

Da mesma forma, a equação para deltaDistYpode ser derivada.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.