我正在研究光线跟踪器的数学运算,但我并没有按照我在这个主题上阅读的每篇文章进行过渡。这就是我所拥有的:
球体公式:
(X - Cx)^ 2 +(Y - Cy)^ 2 +(Z - Cz)^ 2 - R ^ 2 = 0
其中R是半径,C是中心,X,Y,Z是球体中的所有点。
一条线的公式:
X + DxT,Y + DyT,Z + DzT
其中D是线的标准化方向向量,X,Y,Z是线上的所有点,T是线上某点的参数。
通过将线的分量代入球面方程,我们得到:
(X + DxT - Cx)^ 2 +(Y + DyT - Cy)^ 2 +(Z + DzT - Cz)^ 2 - R ^ 2 = 0
我遵循一切到目前为止(至少我认为我这样做),但是我读过的每个教程都会从那里跳到二次方程而不解释它(这是从其中一个网站复制的,所以这些术语与我的例子略有不同):
A = Xd ^ 2 + Yd ^ 2 + Zd ^ 2
B = 2 *(Xd *(X0-Xc)+ Yd *(Y0-Yc)+ Zd *(Z0-Zc))
C =(X0-Xc)^ 2 +(Y0-Yc)^ 2 +(Z0-Zc)^ 2-Sr ^ 2
我得到了如何使用二次公式求解T,但我不明白他们如何从上面的公式得到二次方程。我假设这只是我早已忘记的一些常见数学知识,但谷歌搜索“如何设置二次方程式”并没有真正产生任何东西。
我真的很想在继续之前了解如何进入这一步,因为我不喜欢编写我不完全掌握的代码。
答案 0 :(得分:14)
这是每个步骤的详细演练;希望这会使事情变得清晰。三维球的方程是:
(x-a)^2 + (y-b)^2 + (z-c)^2 = r^2
以<a, b, c>
为球体的中心,r
为半径。如果满足这个等式,则<x, y, z>
点在球体上。
射线的参数方程是:
X = xo + xd*t
Y = yo + yd*t
Z = zo + zd*t
其中<xo, yo, zo>
是光线的原点,而<xd,yd,yd>
是相机光线的方向。
要找到交点,我们希望看到光线上的哪些点与球体上的点相同。因此,我们将射线方程代入球面方程:
(xo + xd*t - a)^2 + (yo + yd*t - b)^2 + (zo + zd*t - c)^2 = r^2
扩展为:
(xd^2 + yd^2 + zd^2) * t^2 +
[2[xd * (xo - a) + yd * (yo - b) + zd *(zo - c)]] * t +
[(xo - a)^2 + (yo - b)^2 + (zo - c^)2 - r^2] * 1
= 0
请注意,这是At^2 + Bt + C = 0
形式的二次方程式,其中包含:
A = (xd^2 + yd^2 + zd^2)
B = [2[xd * (xo - a) + yd * (yo - b) + zd *(zo - c)]]
C = [(xo - a)^2 + (yo - b)^2 + (zo - c^)2 - r^2]
我们可以将一般二次公式应用于未知变量,即:
t = [-B +- sqrt(B^2 - 4AC)] / 2A
B^2 - 4AC
部分称为“判别式”。根据判别式的值,我们将得到这个等式的零个,一个或两个解:
如果它小于零,则解是一个虚数,并且光线和球体不会在实际平面上相交。
如果它等于零,那么光线恰好与球体相交1点(它与球体正好相切)。
如果它大于零,那么光线恰好在2点与球体相交。
如果判别式表明没有解决方案,那么你已经完成了!光线不与球体相交。如果判别式指示至少一个解,则可以求解t
以确定交点。这两种解决方案是:
t_1 = [-B + sqrt(B^2 - 4AC)] / 2A
t_2 = [-B - sqrt(B^2 - 4AC)] / 2A
较小的解决方案是射线首先击中球体的点。
答案 1 :(得分:8)
从这里开始:
(X + DxT - Cx)^2 + (Y + DyT - Cy)^2 + (Z + DzT - Cz)^2 - R^2 = 0
扩展三个平方项,所以你有一个长表达式:
X^2 + Dx^2T^2 + Cx^2 + 2XDxT - 2XCx - 2DxTCx + ...... = 0
(这是由于使用公式(x+y+z)^2 = x^2 + y^2 + z^2 + 2xy + 2xz + 2yz
)
然后分组,这样你就有了T ^ 2,T和1的因子:
(....)T^2 + (....)T + .... = 0
这些因素是上面给出的A,B,C。这是T的二次方程,可以使用二次公式求解。