【问题标题】:Optimized Sphere-Line Check Only?仅优化球线检查?
【发布时间】:2014-08-29 06:27:15
【问题描述】:

是否有用于计算球体和线是否相交的优化方程,我知道最近的点解,但我想知道是否还有另一个。还有二次方程,但它需要大量计算,而且我不确定所有可能的早期输出。我知道两个(我认为)...

Vec3 d = lineEnd - lineStart; // the ray
Vec3 f = lineStart - sphereCenter; // center -> lineStart


float c = dot(f, f) - radius * radius;

if(c <= 0)
{
    // first out
    // sphere is touching the vertex
    // hit !
}

float b = dot(f, d);

if(b >= 0)
{
    // second out
    // line ray and center -> start, are going same direction
    // if the start point didn't intersect above
    // then there's no way for the segment or other point to
    // miss
}

float a = dot(d, d);

// ... any other optimizations

if(b*b - a*c < 0)
{
    // miss
}

【问题讨论】:

  • 注意,b 实际上应该是 dot(f, d) * 2。 (或者,如果你真的想把 2 因素排除在外,判别检查中的 2*b*b 应该是 4*b*b。)
  • @Wyzard 很好,我现在可以删除这两个 4,但我不能吗?

标签: c++ algorithm math optimization


【解决方案1】:

我不认为你真的可以变得更好。您也许可以消除一些简单的情况。如果说直线的起点和终点的 x 坐标小于球心减去半径,并且高于球心的坐标和低于球心的坐标,那么这是不可能的。您可以考虑围绕球体的立方体。如果一条线不与框相交,则它不能与球体相交。这可能更容易计算。

二次算法还不错。点积是三乘三加。我认为整个事情可以用十二次乘法来完成(不包括乘以 2 和 4)。您有机会消除其中的一些。请注意,您不需要计算真正昂贵的平方根,只需在代码中检查判别式的符号即可。

【讨论】:

    【解决方案2】:

    看这里ray and ellipsoid intersection accuracy improvement

    • 只需将r[3] 设置为(1/R*R,1/R*R,1/R*R)
    • 或将方程更新为奇异半径(稍后可以将整个方程乘以 1/(R*R))
    • 在当前状态下,它需要 3 x 三点、1 x sqrt、2 x div 和一些小的操作,如 +、-、*

    【讨论】:

    • 虽然我不需要交叉点,我只是在测试是否存在交叉点。
    猜你喜欢
    • 1970-01-01
    • 2013-07-27
    • 1970-01-01
    • 1970-01-01
    • 2017-06-10
    • 2013-06-20
    • 2012-02-03
    • 1970-01-01
    • 2020-11-22
    相关资源
    最近更新 更多