разница между параметрическим и алгебраическим уравнением пересечения сферы с линией

Я пишу Raytracer на C, и для рисования сферы я использую декартово уравнение:

x^2 + y^2 + z^2 = R^2.

У меня есть положение моего глаза (x_eye, y_eye, z_eye) и вектор моего глаза (Vx, Vy, Vz). Параметрическое уравнение моей линии:

x = x_eye + k * Vx  
y = y_eye + k * Vy  
z = z_eye + k * Vz

Я подставляю параметрическое уравнение моей линии в декартово уравнение сферы, чтобы решить его

(x_eye + k * Vx)^2 + (y_eye + k * Vy)^2 + (z_eye + k * Vz)^2 = R^2  

(Vx^2 + Vy^2 + Vz^2) * k^2 + 2 * (x_eye*Vx + y_eye*Vy + z_eye*Vz) * k + (x_eye^2 + y_eye^2 + z_eye^2 - R^2) = 0  

Теперь я получил уравнение вида ax^2 + bx + c = 0 и определяю a, b, c с помощью:

a = (Vx^2 + Vy^2 + Vz^2) * k^2  
b = 2 * (x_eye * Vx + y_eye * Vy + z_eye * Vz) * k  
c = (x_eye^2 + y_eye^2 + z_eye^2 - R^2)  

тогда я могу найти k для каждого пикселя, если есть пересечение (b ^ 2 - 4.a.c >= 0).

Но есть ли другой способ найти k, используя эти параметрические уравнения линии и сферической линии
:

x = x_eye + k * Vx  
y = y_eye + k * Vy  
z = z_eye + k * Vz  

и для сферы:

x = R.cos(u).cos(v)  
y = R.sin(u).cos(v)  
z = R.sin(v)  

как я могу найти k с помощью этих двух параметрических уравнений?
что мне делать

x_eye + k * Vx  = R.cos(u).cos(v)  
y_eye + k * Vy  = R.sin(u).cos(v)  
z_eye + k * Vz  = R.sin(v)  

person Mickael Ciocca    schedule 12.03.2011    source источник
comment
Использование параметрического уравнения для сферы усложняет уравнение, которое необходимо решить, поскольку вы ввели дополнительные переменные u и v. Есть ли особая причина, по которой вы хотите сделать это таким образом?   -  person    schedule 12.03.2011
comment
Я пытаюсь понять, как это работает, чтобы нарисовать другой объект, более сложный, например поверхность Дини, поверхность мальчика или кольцо Мебиуса. Мне интересно, как некоторые трассировщики лучей могут рисовать сложные объекты, и я думаю, что они используют параметрическое уравнение.   -  person Mickael Ciocca    schedule 12.03.2011
comment
Введение новых переменных на самом деле не проблема, так как переменные u и v фактически заменяют x, y и z. На самом деле в исходной системе было 4 переменные (x, y, z и k), а в новой всего 3. Настоящая трудность заключается во введении триггерных функций.   -  person    schedule 12.03.2011


Ответы (2)


Чтобы решить систему

x_eye + k * Vx  = R.cos(u).cos(v)  
y_eye + k * Vy  = R.sin(u).cos(v)  
z_eye + k * Vz  = R.sin(v)

начните с возведения в квадрат обеих частей каждого уравнения, а затем сложите все три уравнения вместе. Затем упростите правую часть, используя тригонометрические тождества, пока не получите

(x_eye + k * Vx)^2 + (y_eye + k * Vy)^2 + (z_eye + k * Vz)^2 = R2  

это то же самое уравнение для k, которое у вас было раньше.

В целом, однако, это не может быть практичным подходом. Поскольку вы пытаетесь написать трассировщик лучей, вы не хотите решать каждое уравнение вручную. Вместо этого используйте некоторые алгоритмы решения системы. Хорошей отправной точкой может быть поиск некоторой информации о методе Ньютона и методе секущих для нескольких переменных. Любой вводный учебник по численному анализу должен содержать много информации, которая поможет вам начать работу.

person Community    schedule 12.03.2011

Итак, ваш вопрос в основном «как лучше всего решить пересечение сферических лучей». Я думаю, что вы уже используете лучший способ с точки зрения кодирования, т.е. решаете квадратное уравнение (это именно то, что я делаю в своем проекте трассировки лучей pvtrace. Есть несколько причин, по которым я считаю, что это лучший подход:

  1. Он аналитический, т.е. не требует численной итерации!
  2. Чтобы определить, попала ли сфера, вам не нужно вызывать какую-либо функцию math.h, т.е. вы можете вычислить дискриминант для пересечения (как вы указали), просто используя b^2 - 4.a.c >= 0.
  3. Если вам нужно сделать еще один шаг и вычислить точку пересечения, вы просто делаете один вызов функции sqrt(). Я ожидаю, что это будет быстрее, чем несколько вызовов триггера. функций в сочетании с Newton-Raphson, плюс будет гораздо меньше кода (всегда хорошо!).
person danieljfarrell    schedule 13.03.2011