Sign in to follow this  
Jiia

Intersecting a plane, precision problems

Recommended Posts

This has really got me stuck. This is for moving sphere collision response, and the problem happens when the sphere is moving almost parallel with the triangle's plane (brushing against it). This is how I determine where the sphere will intersect the triangle plane:
FLOAT plane_dot = DOT( TriangleNormal, MovingDirection );
// plane_dot is now -0.000017070566

// Only concerned if moving toward triangle facing
if( plane_dot is > 0.0f )
  return NoCollsion;

// do something else if moving completely parallel with plane
if( plane_dot > -0.000001f )
  DoSomethingElse(); // I'm not worried about this situation yet

// Get the distance from sphere start point to triangle plane (it's negative)
FLOAT dist_to_plane = DOT( TriangleNormal, VertexA - SphereStart );

// Add radius (really subtracting radius, since distance is neg)
dist_to_plane += SphereRadius; // in the situation I'm testing, dist_to_plane is now -0.0000038146973

// Convert this to the distance on the sphere moving line where it intersects the plane
FLOAT dist_on_sphere_line = dist_to_plane / plane_dot;

// dist_on_sphere_line is now 0.22346635, which is too high



Just a tiny bit of precision error before the dist_to_plane / plane_dot will cause massive differences in the final distance, because the numbers are so tiny. If I move the sphere from the sphere start point through the movement direction multiplied by dist_on_sphere_line, it is inside of the triangle plane. This is really bad. How low of a number (on plane_dot) should I consider parallel? If I use too high of a number, assuming the movement is exactly parallel may allow the sphere to move inside of the triangle, especially moving over a large distance on the plane of the triangle. Does anyone know of a better way to do this? Perhaps another way to compute the intersect point if plane_dot is so close to zero? Or just another way entirely? That final divide by the tiny numbers is what is screwing me, but I don't know another way to do this. Thanks for any help [smile] [Edited by - Jiia on November 24, 2004 6:33:29 PM]

Share this post


Link to post
Share on other sites
You have a precision problem. Single precision floats have only about 7 digits of precision. So when operating in the range of [-1,1], almost all of the bits in a number as small as 0.000001 are going to be garbage.

You have several choices (some better than others):
1. Use double precision.
2. Use a much larger cutoff value.
3. Reorder calculations to avoid multiplyig or dividing by the difference of two nearly-identical numbers.
4. Rather than determining where/when the intersection will happen, check each frame to see if the intersection happens in that frame.

Try a cutoff value of .001 instead. That will give you many more bits to work with and the sphere's direction is still very close to parallel at that value.

[Edited by - JohnBolton on November 25, 2004 2:36:07 AM]

Share this post


Link to post
Share on other sites
if you have a known timestep, you can use that as the basis for the comparison, instead of solving for t explicitly.

instead of:
t = some_constant / DOT( TriangleNormal, MovingDirection );
if (t > dt)...

you could say:
if (dt * DOT( TriangleNormal, MovingDirection ) > some_constant)
...

this works for things like collision detection, but not for ray tracers.

Share this post


Link to post
Share on other sites
Well, I am only checking every frame. But if the framerate is low, time between frames is high. And the distance of movement increases.

lonesock: I need the distance to the plane in the movement direction. Is there a way to get it another way?

I ended up using a cutoff of -0.0001. I then pull the intersect point back by about 0.005, which so far has eliminated the problems.

I appreciate the help [smile]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this