我试图确定线段(即两点之间)是否与球体相交。我对交点的位置不感兴趣,只是该段是否与球体表面相交。有没有人对这个最有效的算法是什么有任何建议? (我想知道是否有任何算法比通常的射线球交叉算法更简单,因为我对交叉位置不感兴趣)
答案 0 :(得分:9)
如果你只是想知道它是否相交,那么你的基本算法将会是这样......
考虑你有光线的矢量,A - >乙
你知道这个矢量和球体中心之间的最短距离发生在你的射线矢量和一个与球体中心成90度的矢量的交点处。
因此,您有两个向量,其方程完全完全定义。您可以使用线性代数计算向量的交点,从而计算线的长度(或者更有效地计算线的长度的平方)并测试它是否小于半径(或半径的平方)你的球体。
答案 1 :(得分:6)
我不知道这样做的标准方法是什么,但是如果你只是想知道它是否相交,这就是我要做的。
一般规则......避免执行sqrt()或其他昂贵的操作。如果可能,处理半径的平方。
从现在开始,你的出发点就在球体之外。
从现在开始,你处于更复杂的阶段。你的起点在假想的盒子和球体之间。您可以使用微积分和几何来获得简化的表达式。
您要做的事情的要点是确定光线与球体之间的最短距离是否小于球体的半径。
让你的光线由(x0 + i t,y0 + j t,z0 + k t)表示,并且球体的中心位于(xS,yS,zS) )。因此,我们希望找到这样的最小值(xS - x0 - i t,yS - y0 - j t,zS - z0 - k t)。 / p>
设x = xS - x0,y = yX - y0,z = zS - z0,D =矢量平方的幅度
D = x ^ 2 -2 * x i t +(i * t)^ 2 + y ^ 2 - 2 * y j t +(j * t)^ 2 + z ^ 2 - 2 * z k t +(k * t)^ 2
D =(i ^ 2 + j ^ 2 + k ^ 2) t ^ 2 - (x i + y j + z k)* 2 * t +(x ^ 2 + y ^ 2 + z ^ 2)
dD / dt = 0 = 2 * t *(i ^ 2 + j ^ 2 + k ^ 2) - 2 *(x i + y j + z * k)
t =(x i + y j + z * k)/(i ^ 2 + j ^ 2 + k ^ 2)
将D插回D =的等式中....如果结果小于或等于球体半径的平方,则表示您有一个交点。如果它更大,则没有交集。
答案 2 :(得分:4)
This page可以解决此问题。基本上,您将线的等式代入球体的等式,然后计算得到的二次曲线的判别式。判别式的值表示交集。
答案 3 :(得分:-1)
或者你可以更深入地尝试改进sqrt和其他内部函数调用