Tutoriel Raycasting / Question mathématique vectorielle

8

Je vérifie ce joli tutoriel de raycasting sur http://lodev.org/cgtutor/raycasting.html et j'ai une question mathématique probablement très simple.

Dans l'algorithme DDA, j'ai du mal à comprendre le calcul des variables deltaDistX et deltaDistY, qui sont les distances que le rayon doit parcourir de 1 côté x au côté x suivant, ou de 1 côté y au suivant côté y, dans la grille carrée qui compose la carte du monde (voir capture d'écran ci-dessous).

entrez la description de l'image ici

Dans le tutoriel, ils sont calculés comme suit, mais sans trop d'explications:

//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 et rayDirX sont la direction d'un rayon qui a été lancé.

Comment obtenez-vous ces formules? Il semble que le théorème de Pythagore en fasse partie, mais d'une manière ou d'une autre, la division est impliquée ici. Quelqu'un peut-il me donner des informations sur les connaissances mathématiques qui me manquent ici, ou «prouver» la formule en montrant comment elle est dérivée?

mattboy
la source
Vous aimeriez probablement aussi vérifier scratchapixel.com/lessons/3d-basic-lessons/… qui a une très belle et détaillée explication de DDA.
Grieverheart

Réponses:

8

Ahh oui. J'ai jeté mes maths dessus et je pense que je l'ai frappé. Vous avez raison, cela implique le théorème de Pythagore et une certaine mise à l'échelle.

Vous commencez avec votre vecteur normalisé qui représente votre rayon.

entrez la description de l'image ici

Il a un xcomposant et un ycomposant. Nous voulons d'abord voir combien de temps il est quand il voyage d'une unité dans la xdirection. Alors que faisons-nous? Nous voulons mettre le vecteur entier à l'échelle de sorte que la xcomposante soit égale 1. Pour savoir par quoi le mettre à l'échelle, nous procédons comme suit:

scaleFactor = 1/rayDirX;

Écrire cela en mathématiques c'est vraiment juste

scaledX = rayDirX * (1/rayDirX) = 1

Nous pouvons donc simplement appeler cela 1.

Ensuite pour le ycomposant:

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

Alors maintenant, nous avons nos composants mis à l'échelle comme (1, rayDirY/rayDirX)

Maintenant, nous voulons connaître la longueur. Maintenant, Pythagore entre en jeu. Lequel est

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

Ainsi, en connectant nos composants à l'échelle, nous obtenons:

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

Appliquez une algèbre et simplifiez et nous obtenons:

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

Il en va de même pour la longueur lorsque le ycomposant parcourt une unité, sauf que nous aurons (rayDirX/rayDirY, 1)ce qui se traduira par

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

Nous avons là vos deux équations de votre question. Génial. Merci pour l'exercice d'algèbre.

MichaelHouse
la source
ahh tu m'as battu dessus! Très agréable!
Philip
Ha, j'ai continué à vérifier s'il y avait de nouvelles réponses! Je me sentais comme si je courais quelqu'un :)
MichaelHouse
Très gentil merci! C'était beaucoup moins évident que ce à quoi je m'attendais.
mattboy
Je n'ai trouvé la réponse que lorsque j'ai renoncé à la désosser et à trouver comment j'obtiendrais cette valeur si je le faisais. Je pensais que peut-être mettre à l'échelle le vecteur serait une sorte de raccourci, mais il s'avère que c'est la même façon qu'ils le font :)
MichaelHouse
1

En supposant que la longueur unitaire de chaque distance de grille est de 1.

Le triangle (Triangle 1) dans le diagramme affiché (question OP) consistant deltaDistXen l'hypoténuse, a la même valeur de cosinus de son angle que la valeur de cosinus de l'angle formé dans le triangle formé par les constituants du rayDir# Vector(Triangle 2)

Ainsi, les éléments suivants peuvent être assimilés ( magnitudes vectorielles ci-dessous ) et simplifiés (1-3)

Rappelez-vous: 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)

De même, l'équation pour deltaDistYpeut être dérivée.

espace métrique
la source