Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gtx/intersect(Ray/Line)Sphere math error #8

Closed
boromisp opened this issue Nov 11, 2012 · 1 comment
Closed

gtx/intersect(Ray/Line)Sphere math error #8

boromisp opened this issue Nov 11, 2012 · 1 comment
Assignees
Labels
Milestone

Comments

@boromisp
Copy link

If I understood correctly the purpose of the intersectRay function, it contains a few errors.

Edit: The intersectLineSphere function is also incorrect.

1.) The function has a sphere center parameter, but ignores it and assumes that the sphere is in the origo.
2.) It calculates the length of the ray direction vector, but later on uses this vector as a unit vector.
3.) The position calculation is simply wrong. It multiplies the direction vector with the radius of the sphere instead of the calculated intersection distance.

Here is a corrected implementation with "floating-point safeguards" on the quadratic equation solving too.
The quadratic equation implementation is based on this pdf: http://www.scilab.org/content/download/1106/10848/file/scilabisnotnaive.pdf

template <typename genType>
    GLM_FUNC_QUALIFIER bool intersectRaySphere
    (
        genType const & rayStarting, genType const & rayDirection,
        genType const & sphereCenter, typename genType::value_type sphereRadius,
        genType & position, genType & normal
    )
    {
        genType unitRayDirection = normalize(rayDirection);
        genType diff = rayStarting - sphereCenter;
        typename genType::value_type Epsilon = std::numeric_limits<typename genType::value_type>::epsilon();
        typename genType::value_type b = dot(diff, unitRayDirection);
        typename genType::value_type c = dot(diff, diff) - sphereRadius * sphereRadius;
        typename genType::value_type d = b * b - c;
        if( d < 0 )
        {
            return false;
        }
        typename genType::value_type q = -(b + sign(b) * sqrt(d));
        if( q <= Epslion)
        {
            return false;
        }
        typename genType::value_type x = c / q;
        if(x <= Epsilon)
        {
            x = q;
        }
        position = rayStarting + rayDirection * x;
        normal = (position - sphereCenter) / sphereRadius;
        return true;
    }

And I would also like to add, that for most of the applications of this function simply returning (or assigning) the intersection distance (x) would be more useful. The rest can be calculated by the user if necessary.

@Groovounet
Copy link
Member

This should be fixed by the pull request.

Thanks for contributing!
Christophe

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants