|
-
October 4th, 2008, 01:04 AM
#1
float point rounding error problems
hello guys,
in my program, i need to check if an arbitrary 3D line segment intersects with any edge of a 3D triangle (but they are actually in the same plane).
my approach is to solve the equations that are consisted of the line function of the line segment and the line functions of the triangle edges.
once i have a result, i then check if the intersection point is actually on the line segment and one of the triangle edges.
however, i got float point rounding error problems, because the equation solving part involves some subtractions, especially when the triangle and the line segment are very small.
the actual problem happens at where i need to check if a denominator is 0. sometimes, the denominator should be 0, but because of the rounding error, it is not but a very small value.
i thought about using barycentric coordinates method, instead of directly solving the equations, but in my program, i need not only checking if they intersect with each other but also finding out the intersection point. with barycentric coordinates, it is easy to tell if a line segment intersects a triangle edge by checking if one of it's endpoint is outside the triangle, but i don't know how to get the intersection point.
i have two ideas to solve this problem, either transforming the line segment and the triangle into a 2D coordinate system, as there are a lot of intersection solutions in 2D. but why don't those 2D intersection methods have the float point rounding error problem?
or maybe i can use a small value instead of 0 in my equation solving function to check the denominator. is this reasonable? because i did see someone's code doing this trick.
thank you.
or is there any better way to solve linear equations? say using matrix?
-
October 4th, 2008, 03:35 AM
#2
Re: float point rounding error problems
for floating point, you can never check whether a value is equal to 0.0 in order to check if it's zero. You have to fix an epsilon which is a small value and if your value is under that, consider it zero.
Code:
const double epsilon = 0.00000001; // arbitrary, depends on the range of values you work with
bool is_zero(double d)
{
return (fabs(d) < epsilon);
}
You might also want to read this excellent FAQ
Last edited by Yves M; October 4th, 2008 at 03:38 AM.
Get this small utility to do basic syntax highlighting in vBulletin forums (like Codeguru) easily.
Supports C++ and VB out of the box, but can be configured for other languages.
-
October 4th, 2008, 01:47 PM
#3
Re: float point rounding error problems
 Originally Posted by Yves M
for floating point, you can never check whether a value is equal to 0.0 in order to check if it's zero. You have to fix an epsilon which is a small value and if your value is under that, consider it zero.
100% correct (although I do not use a fixed constant for epsilon, but that is a different story.
There are also two different geometric issues (that transcent programming).
The first is intersect (cross) and abut (touch). Note that this distinction only applies if one of the shapes is not a straight line.
In the real world there is always measurement error. You may look with the naked eye and say that two objects are touching. Magnification may proves this to be false. At the atomic level, the whole concept gets "wierd" with electrons, clouds, etc....
Intersection is much easier to detect, and find an approximation of the intersection point. One mental technique is to imagine the line, to be a two dimensional object (ie one that has a width, and any non-theoretical line must have. The intersection then does not become a point but rather is a polygon (having area).
When dealing with floating point numbers, the limited precision effectively becomes the width.
TheCPUWizard is a registered trademark, all rights reserved. (If this post was helpful, please RATE it!)
2008, 2009,2010
In theory, there is no difference between theory and practice; in practice there is.
* Join the fight, refuse to respond to posts that contain code outside of [code] ... [/code] tags. See here for instructions 
* How NOT to post a question here
* Of course you read this carefully before you posted
* Need homework help? Read this first
-
October 5th, 2008, 09:17 AM
#4
Re: float point rounding error problems
 Originally Posted by Yves M
for floating point, you can never check whether a value is equal to 0.0 in order to check if it's zero. You have to fix an epsilon which is a small value and if your value is under that, consider it zero.
Code:
const double epsilon = 0.00000001; // arbitrary, depends on the range of values you work with
bool is_zero(double d)
{
return (fabs(d) < epsilon);
}
You might also want to read this excellent FAQ
I have follow up question on this. Let suppose I'd like to check if 20 milliseconds has elapsed. So now the pseduo source:
Code:
double const duration = .020;
while ( 1 ) {
if ( time_expired ( start_time, duration ) ) {
break ;
}
}
Now given, the issue surrounding comparing floating point values for equality, if you were to write the code for the method time_expired what would that look like?
-
October 5th, 2008, 01:02 PM
#5
Re: float point rounding error problems
Calculate in units of milliseconds, and then you can use simple integer arithmetic.
More fundamentally, however, your program is polling for an event (i.e., expiration of 20 msec), which is a terrible waste of CPU resources. Rewrite the code so that your program receives a notification of the event, and simpley waits (without use of CPU) for the event to arrive. In windows, and with your desired behavior of waiting for expriation of 20 msecs, you can use waitable timers, a simple sleep (maybe), inter-thread signalling, etc
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|