Geometry 光线-球体相交:处理角点情况

Geometry 光线-球体相交:处理角点情况,geometry,intersection,raytracing,Geometry,Intersection,Raytracing,我正在努力在2d中实现一个健壮的光线-球体相交例程。我将一个相当拥挤的函数拼凑在一起,由于它在GPU上运行,所以无法正确调试。我的灵感来自: 和。我不知道应该在哪里查找错误。我错过了什么明显的东西吗?由于我对实际的圆段碰撞感兴趣,所以我检查圆是否包围直线的情况作为交点返回 以下是相关的代码片段: bool CircleSegmentIntersection2d(float2 x0, float2 x1, float2 center, float r) { float2 d = x1-x0; f

我正在努力在2d中实现一个健壮的光线-球体相交例程。我将一个相当拥挤的函数拼凑在一起,由于它在GPU上运行,所以无法正确调试。我的灵感来自: 和。我不知道应该在哪里查找错误。我错过了什么明显的东西吗?由于我对实际的圆段碰撞感兴趣,所以我检查圆是否包围直线的情况作为交点返回

以下是相关的代码片段:

bool CircleSegmentIntersection2d(float2 x0, float2 x1, float2 center, float r) {

float2 d = x1-x0;
float2 f = x0-center;

float a = dot2d(d,d);
float b = 2*dot2d(f,d);
float c = dot2d(f,f)-r*r;

float discriminant = b*b-4*a*c;

if( discriminant < 0 ) {
      // no intersection
      return false;
} else {
    discriminant = sqrt(discriminant);
    // either solution may be on or off the ray so need to test both
    float sol1 = (-b + discriminant)/(2*a);
    float sol2 = (-b - discriminant)/(2*a);

    float t0 = min(sol1, sol2);
    float t1 = max(sol1, sol2);

    if (t1 < 0)
        return false;

    // Line segment doesn't intersect and on outside of sphere, in which case both values of t will either be less than 0 or greater than 1.
    if (0 < t0 && 0 < t1 || t0 > 1 && t1 > 1)
        return false;

    // Line segment doesn't intersect and is inside sphere, in which case one value of t will be negative and the other greater than 1.
    if (t0 < 0 && t1 > 1) {
        return true;
    }

    // Line segment intersects at one point, in which case one value of t will be between 0 and 1 and the other not.
    if (t0 < 0 && 0 <= t1 && t1 <= 1) {
        return true;
    }

    // Line segment intersects at two points, in which case both values of t will be between 0 and 1.
    if (0 <= t1 && t1 <= 1 && 0 <= t0 && t0 <= 1) {
        return true;
    }

    // Line segment is tangential to the sphere, in which case both values of t will be the same and between 0 and 1.
    if (length(t0-t1) < 0.005f) {
        return true;
    }
}

return false;

}

谢谢你的时间

你知道哪个角点的情况不成功吗?我想我忘记了一个例子,它说:
//线段在一个点相交,在这种情况下,t的一个值将在0和1之间,而另一个值不在0和1之间。
我添加了
if((t1>1&&0这似乎会导致问题:
if((01&&t1>1))
它实际上应该是:
if((0>t0&&0>t1)|(t0>1&&t1>1))
float dot2d(float2 a, float2 b) {
return a.x*b.x+a.y*b.y;
}