Raycasting учебник / вопрос векторной математики


8

Я проверяю этот хороший учебник по лучевой трансляции по адресу http://lodev.org/cgtutor/raycasting.html и у меня, вероятно, очень простой математический вопрос.

В алгоритме DDA у меня возникают проблемы с пониманием вычисления переменных deltaDistX и deltaDistY, которые представляют собой расстояния, которые должен пройти луч от 1 стороны x до следующей стороны x, или от 1 стороны y до следующей у, в квадратной сетке, которая составляет карту мира (см. скриншот ниже).

введите описание изображения здесь

В учебнике они рассчитываются следующим образом, но без особых пояснений:

//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 и rayDirX - это направление луча.

Как вы получаете эти формулы? Похоже, теорема Пифагора является ее частью, но каким-то образом здесь происходит деление. Может кто-нибудь подсказать мне, какие математические знания мне здесь не хватает, или «доказать» формулу, показав, как она получается?


Вы, вероятно, также хотели бы проверить scratchapixel.com/lessons/3d-basic-lessons/…, где есть очень хорошее и подробное объяснение DDA.
Grieverheart

Ответы:


8

Ааа да Я бросил свою математику в это, и я думаю, что ударил это. Вы правы, это включает в себя теорему Пифагора и некоторое масштабирование.

Вы начинаете с вашего нормализованного вектора, который представляет ваш луч.

введите описание изображения здесь

Он имеет xкомпонент и yкомпонент. Во-первых, мы хотим увидеть, сколько времени проходит одна единица в xнаправлении. Так что же нам делать? Мы хотим масштабировать весь вектор так, чтобы xкомпонент был равен 1. Чтобы выяснить, что его масштабировать, мы делаем следующее:

scaleFactor = 1/rayDirX;

Записать это в математике это действительно просто

scaledX = rayDirX * (1/rayDirX) = 1

Так что мы можем просто назвать это 1.

Тогда для yкомпонента:

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

Так что теперь у нас есть наши масштабированные компоненты как (1, rayDirY/rayDirX)

Теперь мы хотим знать длину. Теперь пифагорейец вступает в игру. Который

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

Итак, подключив наши масштабированные компоненты, мы получим:

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

Применим некоторую алгебру и упростим, и мы получим:

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

То же самое касается длины, когда yкомпонент перемещается на одну единицу, за исключением того, что мы получим, (rayDirX/rayDirY, 1)что приводит к

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

Там у нас есть два уравнения из вашего вопроса. Довольно аккуратно. Спасибо за упражнение алгебры.


ааа, ты побил меня к этому! Очень хорошо!
Филипп

Ха, я продолжал проверять, есть ли новые ответы! Я чувствовал, что я
гоняю

Очень мило спасибо! Было намного менее очевидно, чем я ожидал.
Mattboy

Я нашел ответ только тогда, когда бросил попытки перепроектировать его и попытался найти способ получить это значение, если бы делал это. Я подумал, что, возможно, масштабирование вектора будет чем-то вроде ярлыка, но оказывается, что они делают то же самое :)
MichaelHouse

1

Предполагая, что единичная длина каждого расстояния сетки равна 1.

Треугольник (Треугольник 1) в размещенной диаграмме (вопрос ОП), состоящий из deltaDistXгипотенузы, имеет то же значение косинуса своего угла, что и значение косинуса угла, образованного в треугольнике, образованном составляющими rayDir# Vector(Треугольник 2)

Таким образом, следующее может быть приравнено ( векторные величины ниже ) и упрощено (1-3)

Помните: 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)

Аналогичным образом deltaDistYможно вывести уравнение для .

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.