Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ray Sphere Intersections in OpenGL

I'm trying to use ray-sphere intersections to perform mouse picking in OpenGL. I found a few formulae online, and the last one I tried was one suggested by a user on Stack Exchange:

Ray-Sphere intersection

From what I've understood of this answer, I'm checking if the quadratic equation has positive roots. I don't really care where the intersection takes place, just if the ray intersects the sphere at all. My code is as follows, but doesn't seem to work.

bool Mesh::useObject(vec3 camera, vec3 direction) {

    // a = (xB-xA)²+(yB-yA)²+(zB-zA)²
    float a = ((direction.v[0] - camera.v[0])*(direction.v[0] - camera.v[0])
        + (direction.v[1] - camera.v[1])*(direction.v[1] - camera.v[1])
        + (direction.v[2] - camera.v[2])*(direction.v[2] - camera.v[2]));

    // b = 2*((xB-xA)(xA-xC)+(yB-yA)(yA-yC)+(zB-zA)(zA-zC))
    float b = 2 * ((direction.v[0] - camera.v[0])*(camera.v[0] - mOrigin.v[0])
        + (direction.v[1] - camera.v[1])*(camera.v[1] - mOrigin.v[1])
        + (direction.v[2] - camera.v[2])*(camera.v[2] - mOrigin.v[2]));

    // c = (xA-xC)²+(yA-yC)²+(zA-zC)²-r²
    float c = ((camera.v[0] - mOrigin.v[0])*(camera.v[0] - mOrigin.v[0])
        + (camera.v[1] - mOrigin.v[1])*(camera.v[1] - mOrigin.v[1])
        + (camera.v[2] - mOrigin.v[2])*(camera.v[2] - mOrigin.v[2])
        - (mRadius)*(mRadius));

    float delta = (b*b) - (4 * a*c);

    if (delta < 0)
        return false;

    else {
        std::cout << "Object " << mMesh << " is at postion (" <<
            mOrigin.v[0] << ", " <<
            mOrigin.v[1] << ", " <<
            mOrigin.v[2] << ")\n" <<
            "Size: " << mRadius << std::endl;
        return true;
    }
}

My C++ skills are pretty rusty, so I apologise if this is a horrible way of doing this. This method takes two vectors of three floats, the position of the camera, and the coordinates of a point in my scene 1 unit in front of the camera (I've called this direction).

I want to get the position of the object and it's radius when I face an object and press a key, but instead I get output only when I'm standing on one of the objects in my scene, or if I stand close to another large object. Clearly there's something wrong with my calculations (or worse, my code) but I cannot figure out what that is. :(

Let me know if you need any more code, or if anything is unclear. This is my first question with SO, so if this question is badly phrased, I'm sorry.

EDIT: I shouldn't have been using mouse coordinates as a point on my ray. Edited my question slightly.

like image 785
eihe Avatar asked Nov 09 '22 23:11

eihe


1 Answers

That code looks pretty messy. The general formula for checking the intersection of a line (direction, origin) with a sphere (center, radius) should be:

length(cross(direction, center-origin)) / length(direction) < radius

Check if you implemented that correctly, maybe factor out some operations into seperate functions.

like image 197
Tau Avatar answered Nov 14 '22 22:11

Tau