【发布时间】:2011-01-04 23:01:06
【问题描述】:
我正在尝试确定线段(即两点之间)是否与球体相交。我对交叉点的位置不感兴趣,只关心线段是否与球面相交。有人对最有效的算法有什么建议吗? (我想知道是否有比通常的射线球相交算法更简单的算法,因为我对相交位置不感兴趣)
【问题讨论】:
-
你的意思是线段还是无限线?所有答案均指无限线。
标签: algorithm intersection raytracing
我正在尝试确定线段(即两点之间)是否与球体相交。我对交叉点的位置不感兴趣,只关心线段是否与球面相交。有人对最有效的算法有什么建议吗? (我想知道是否有比通常的射线球相交算法更简单的算法,因为我对相交位置不感兴趣)
【问题讨论】:
标签: algorithm intersection raytracing
如果您只对知道它是否相交感兴趣,那么您的基本算法将如下所示...
假设您有射线线的矢量,A -> B。
你知道这个向量和球心之间的最短距离发生在你的光线向量和一个与它成 90 度角的向量的交点处。
因此,您有两个向量,其方程完全定义。您可以使用线性代数计算向量的交点,从而计算线的长度(或更有效地计算线长度的平方)并测试它是否小于半径(或半径的平方) ) 你的领域。
【讨论】:
我不知道标准的做法是什么,但如果你只想知道它是否相交,我会这样做。
一般规则...避免执行 sqrt() 或其他昂贵的操作。如果可能,处理半径的平方。
从这里开始,你的起点在球体之外。
从这里开始,您将处于更复杂的阶段。你的起点在想象的盒子和球体之间。您可以使用微积分和几何得到简化的表达式。
您要做的事情的要点是确定您的射线和球体之间的最短距离是否小于球体的半径。
让你的射线用 (x0 + it, y0 + jt, z0 + kt) 表示,球体的中心在 (xS, yS, zS )。因此,我们希望找到 t,使其给出最短的 (xS - x0 - it, yS - y0 - jt, zS - z0 - kt)。
令 x = xS - x0, y = yX - y0, z = zS - z0, D = 向量平方的大小
D = x^2 -2*xit + (i*t)^2 + y^2 - 2*yjt + (j* t)^2 + z^2 - 2*zkt + (k*t)^2
D = (i^2 + j^2 + k^2)t^2 - (xi + yj + zk)*2*t + (x^2 + y^2 + z^2)
dD/dt = 0 = 2*t*(i^2 + j^2 + k^2) - 2*(xi + yj + z*k)
t = (xi + yj + z*k) / (i^2 + j^2 + k^2)
将 t 插入 D = ... 的方程。如果结果小于或等于球体半径的平方,则有一个交点。如果大于,则没有交集。
【讨论】:
This page 对这个问题有一个精确的解决方案。本质上,您是将直线方程代入球体方程,然后计算所得二次方的判别式。判别式的值表示交集。
【讨论】:
如果你想要准确的话,无论如何你都必须在这个位置上工作。从算法上提高速度的唯一方法是从光线-球体相交切换到光线-边界框相交。
或者您可以更深入地尝试改进 sqrt 和其他内部函数调用
【讨论】: