球与线相交的参数方程和代数方程之间的区别

发布于 2024-10-21 18:14:52 字数 1141 浏览 8 评论 0原文

我正在用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

心意如水 2024-10-28 18:14:52

要求解系统,

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 相同的方程。

但总的来说,这可能不是一个实用的方法。由于您正在尝试编写光线追踪器,因此您不想手动求解每个方程。相反,使用一些系统求解算法。一个好的起点可能是查找有关多个变量的牛顿法和割线法的一些信息。任何关于数值分析的入门教科书都应该包含大量可以帮助您入门的信息。

To solve the system

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)

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

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

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.

幻想少年梦 2024-10-28 18:14:52

所以你的问题基本上是“解决球体射线相交的最佳方法是什么”。我认为从编码的角度来看,您已经在使用最好的方法,即求解二次方程(这正是我在光线跟踪项目中所做的pvtrace。我认为这是最好的方法有几个原因:

  1. 它是分析性的,即不需要数值迭代!
  2. 要计算球体是否被击中,您不必调用任何>math.h 函数,即您可以仅使用 b^2 - 4.ac >= 0 来计算交集的判别式(正如您所指出的)。
  3. 如果您需要更进一步并计算交点然后您只需进行一次 sqrt() 函数调用,我预计这会比多次调用 trig. 函数与 Newton-Raphson 相结合更快,而且代码量也会少得多(这总是一件好事) !)。

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:

  1. It's analytical i.e. no numerical iteration required!
  2. To work out if the sphere is hit you don't have to call any math.h function i.e. you can calculate the discriminant for intersection (as you pointed out) just using b^2 - 4.a.c >= 0.
  3. If you need to go one step further and calculate the intersection point then you simply make one 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!).
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文