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.