Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 球面与直线相交的参数方程与代数方程的区别_C_Graphics_Raytracing_Polynomial Math - Fatal编程技术网

C 球面与直线相交的参数方程与代数方程的区别

C 球面与直线相交的参数方程与代数方程的区别,c,graphics,raytracing,polynomial-math,C,Graphics,Raytracing,Polynomial Math,我正在用C写一个光线跟踪器,为了画一个球体,我使用笛卡尔方程: x^2 + y^2 + z^2 = R^2. 我有我的眼睛位置(x_眼睛,y_眼睛,z_眼睛)和我的眼睛向量(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

我正在用C写一个光线跟踪器,为了画一个球体,我使用笛卡尔方程:

x^2 + y^2 + z^2 = R^2.
我有我的眼睛位置(x_眼睛,y_眼睛,z_眼睛)和我的眼睛向量(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 = 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)  
解决这个系统

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
的方程是一样的


但总的来说,这可能不是一个切实可行的方法。因为您正在尝试编写光线跟踪器,所以不希望手动求解每个方程。相反,使用一些系统求解算法。一个好的起点可能是查找一些关于牛顿法和割线法的信息。任何关于数值分析的入门教材都应该包含大量的信息,让你开始学习

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

  • 它是分析性的,即不需要数值迭代
  • 要计算球体是否被击中,您不必调用任何
    math.h
    函数,也就是说,您可以使用b^2-4.a.c>=0计算交点的判别式(如您所指出的)
  • 如果您需要进一步计算交点,那么只需进行一次
    sqrt()
    函数调用。我预计这将比多次调用trig.functions加上Newton-Raphson更快,而且代码也会少得多(总是一件好事!)

  • 使用球体的参数方程会使你必须求解的方程复杂化,因为你引入了额外的变量
    u
    v
    。你想这样做有什么特别的原因吗?我试图理解它是如何工作的,以便绘制其他更复杂的对象,如迪尼的曲面、男孩的曲面或莫比曲面美国环。我想知道一些光线跟踪器是如何绘制复杂对象的,我认为它们使用参数方程。引入新变量并不是一个真正的问题,因为变量
    u
    v
    实际上取代了
    x
    y
    z
    。事实上,原始系统有4个变量(
    x
    y
    z
    k
    )而新版本只有3个。真正的困难在于引入触发功能。
    (x_eye + k * Vx)^2 + (y_eye + k * Vy)^2 + (z_eye + k * Vz)^2 = R2