Search code examples
javaraytracing

Ray-sphere intersection method not working


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;
}

It should return -1 when there is no intersection.

There is a sphere at (5,0,0) with a radius of 2. When I pass a ray with origin (0,0,0) and direction (5,0,0).unit, it returns 3 as it should. When I pass a ray with origin (0,0,0) and direction (5,2,0).unit, it returns 3.9 as it should. When I pass a ray with origin (0,0,0) and direction (5,0,1).unit, it returns -1, even though the ray intersects. When the direction is (5,0,-1).unit, it returns 2.73, even though it is not possible for t to be less than 3 and it should return the same thing as (5,0,1).unit returns.


Solution

  • When I run that code with your "ray with origin (0,0,0) and direction (5,0,1).unit" example, it returns 3.15979 for me. From what I can tell all the code you posted is correct. I imagine it's one of your other implementations that's causing the failure. It could be your unit vector calculation, your Vector.sub() method, Vector.dot() method, etc.

    Try adding print statements throughout to see where it goes wrong. That's how I usually debug something like this.

    Also I did a quick translation of your code into C++ (because I don't know java) that you can compare with if you like. It seems to function fine, which means that it's likely not your intersection function that is the problem.

    My code is here: http://codepad.org/xldbJRKo

    I hope this helps a little bit!