球与线相交的参数方程和代数方程之间的区别
我正在用 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.ac >= 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)
I'm writing a Raytracer in C, and to draw a sphere I'm using the Cartesian equation:
x^2 + y^2 + z^2 = R^2.
I have my eye position (x_eye, y_eye, z_eye) and my eye vector (Vx, Vy, Vz).
The parametric equation of my line is:
x = x_eye + k * Vx
y = y_eye + k * Vy
z = z_eye + k * Vz
I put the parametric equation of my line in the Cartesian equation of the sphere in order to solve it
(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
I got now an equation like ax^2 + bx + c = 0 and define a, b, c with:
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)
then i can find k for each pixel if there is intersection (b^2 - 4.a.c >= 0).
But is there any other way to find k using these parametric equation of line and sphere
line :
x = x_eye + k * Vx
y = y_eye + k * Vy
z = z_eye + k * Vz
and for sphere:
x = R.cos(u).cos(v)
y = R.sin(u).cos(v)
z = R.sin(v)
how could i find k with these two parametric equation?
should I do
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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
要求解系统,
首先对每个方程两边求平方,然后将所有三个方程加在一起。然后使用三角恒等式简化右侧,直到得到
与之前的
k
相同的方程。但总的来说,这可能不是一个实用的方法。由于您正在尝试编写光线追踪器,因此您不想手动求解每个方程。相反,使用一些系统求解算法。一个好的起点可能是查找有关多个变量的牛顿法和割线法的一些信息。任何关于数值分析的入门教科书都应该包含大量可以帮助您入门的信息。
To solve the system
start by squaring both sides of each equation, and then add all three equations together. Then simplify the right hand side using trigonometric identities until you get
which is the same equation for
k
that you had before.In general, though, this may not be practical approach. Since you are trying to write a raytracer, you don't want to solve every equation by hand. Instead, use some system solving algorithms. A good starting point may be looking up some information on Newton's method and secant method for several variables. Any introductory textbook on numerical analysis should contain plenty of information that will get you started.
所以你的问题基本上是“解决球体射线相交的最佳方法是什么”。我认为从编码的角度来看,您已经在使用最好的方法,即求解二次方程(这正是我在光线跟踪项目中所做的pvtrace。我认为这是最好的方法有几个原因:
>math.h
函数,即您可以仅使用 b^2 - 4.ac >= 0 来计算交集的判别式(正如您所指出的)。So your question basically 'what is the best way to solve the sphere ray intersection'. I think you already are using the best way from a coding point of view i.e. solving the quadratic equation (this is exactly what I do in my ray-tracing project pvtrace. There are few reason I think this is the best approach:
math.h
function i.e. you can calculate the discriminant for intersection (as you pointed out) just using b^2 - 4.a.c >= 0.sqrt()
function call. I anticipate this will be faster then multiple calls to trig. functions coupled with a Newton-Raphson, plus it will be much less code (always a good thing!).