射线球交叉法不起作用

时间:2014-04-16 00:22:00

标签: java raytracing

public double intersect(Ray r)
{
    double t;

    Vector L = r.origin.sub(pos);

    double a = r.direction.dot(r.direction);
    double b = 2*(r.direction.dot(L));
    double c = (L.dot(L)) - (radius*radius);

    double disc = b*b - 4*a*c;

    if (disc < 0)
        return -1;

    double distSqrt = Math.sqrt(disc);
    double q;

    if (b < 0)
        q = (-b - distSqrt)/2;
    else
        q = (-b + distSqrt)/2;

    double t0 = q/a;
    double t1 = c/q;

    if (t0 > t1)
    {
        double temp = t0;
        t0 = t1;
        t1 = temp;
    }

    if (t1 < 0)
        return -1;

    if (t0 < 0)
        t = t1;
    else
        t = t0;

    return t;
}

没有交叉时应该返回-1。

在(5,0,0)处有一个半径为2的球体。 当我传递一条带有原点(0,0,0)和方向(5,0,0).unit的光线时,它会返回3。 当我传递一条带有原点(0,0,0)和方向(5,2,0).unit的光线时,它会返回3.9。 当我传入具有原点(0,0,0)和方向(5,0,1).unit的光线时,即使光线相交,它也会返回-1。 当方向是(5,0,-1).unit时,它返回2.73,即使t不可能小于3并且它应该返回与(5,0,1)相同的东西.unit返回

2 个答案:

答案 0 :(得分:1)

我认为用于计算q的条件不正确:

if (b < 0)
    q = (-b - distSqrt)/2;
else
    q = (-b + distSqrt)/2;

在这里,你决定b的标志。你应该计算两个值。很明显,第一个(-b - distSqrt)/2总是会给出较小的q值,因为distSqrt始终是非负的。仅当(-b - distSqrt)/2为否定时,您应该检查(-b + distSqrt)/2,在某些情况下可能是肯定的。当光线的原点位于球体内时,将出现这种情况。

t1 = c/q是必要的吗?当您使用q的正值较小时,您就完成了(因为a必须为正数,如果方向是单位向量,则为1。)

在我的实现中,我以这种方式进行了计算:

double Sphere::getIntersection(Ray ray)
{
    Vector v = ray.origin - center;
    double b = 2 * dot(ray.dir, v);
    double c = dot(v, v) - radius * radius;
    double d = b * b - 4 * c;
    if(d > 0)
    {
        double x1 = (-b - sqrt(d)) / 2;
        double x2 = (-b + sqrt(d)) / 2;
        if(x1 >= 0 && x2 >= 0) return x1;
        if(x1 < 0 && x2 >= 0) return x2;
    }
    return -1;
}

并且运作良好。

答案 1 :(得分:0)

当我使用&#34; ray with origin(0,0,0)和direction(5,0,1).unit&#34;运行该代码时例如,它为我返回3.15979。据我所知,您发布的所有代码都是正确的。我认为这是导致失败的其他实现之一。它可能是你的单位向量计算,你的Vector.sub()方法,Vector.dot()方法等等。

尝试在整个过程中添加打印语句以查看出错的位置。这就是我经常调试这样的事情。

此外,我还将您的代码快速翻译成C ++(因为我不懂Java),如果您愿意,可以将其与之进行比较。它似乎运行良好,这意味着它可能不是你的交叉函数是问题。

我的代码在这里:http://codepad.org/xldbJRKo

我希望这有点帮助!

相关问题