我正在尝试确定线段(即两点之间)是否与球体相交。我对交点的位置不感兴趣,而对线段是否与球体表面相交不感兴趣。有没有人建议最有效的算法是什么? (我想知道是否有比通常的射线球相交算法更简单的算法,因为我对相交的位置不感兴趣)

最佳答案

我不知道它的标准方法是什么,但是如果您只想知道它相交,这就是我会做的。

一般规则...避免执行sqrt()或其他昂贵的操作。尽可能处理半径的平方。

  • 确定起点是否在球体的半径内。如果您知道永远不会这样,请跳过此步骤。如果您在内部,则射线将与球体相交。

  • 从这里开始,您的起点不在范围内。
  • 现在,想象一下适合球形的小盒子。如果您在该框外,请检查射线的x方向,y方向和z方向,以查看它是否与射线开始的框的侧面相交。这应该是一个简单的符号检查,或与零的比较。如果您在外面并远离它,则您将永远不会与它相交。

  • 从这里开始,您将处于更复杂的阶段。您的起点在假想盒子和球体之间。您可以使用微积分和几何获得简化的表达式。

    您要做的要点是确定射线与球之间的最短距离是否小于球的半径。

    让您的射线由(x0 + it,y0 + jt,z0 + kt)表示,球体的中心位于(xS,yS,zS)。因此,我们希望找到t,使其给出最短的值(xS-x0-它,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 = ...的方程中。如果结果小于或等于球体半径的平方,则您有一个相交。如果更大,则没有交集。

    关于algorithm - 测试线段是否与球体相交,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/2062286/

    10-12 14:13