[quote name='Mybowlcut' timestamp='1320652023' post='4881304']
...Ok, so basically clamp to 0 if it's an acceptable margin of error?
It depends on the circumstances:
The value you're computing is a distance. If it is measured in meters and express the distance between 2 atoms then you shouldn't clamp it. But if it is a distance in meters between 2 people meeting at the streets a resolution of 0.001 is good enough.
You actually do a comparison by invoking assertEquals(0.0f, distance). For this you should use an Epsilon expression. For sub-sequent uses as transformation parameter you'll usually need not clamp the distance but use it as is.
Notice that small errors may become a problem when being accumulated. E.g. concatenating many rotations will yield in a non-uniform scaling deformation because the small errors summed up will leave you with a non-pure rotation. If you have a situation like that you need to be up against it. Another situation is where precision plays a role, e.g. at marginal cases in point in polygon tests. In such cases you need to use precise data types and functions.
[/quote]
Hmm. I've been doing a bit of reading (I appreciate the links given, but I'm not mathematically minded and so opted for something with simpler examples) and it seems that my idea of using a fixed value for the epsilon wouldn't be a good idea. I'd like to use something like
AlmostEqual2sComplement, but am not sure about two things:
- How to do the same thing in Java (in terms of the dereferencing etc.)
- What to use for maxUlps
Here is the [font="Courier New"]AlmostEqual2sComplement[/font] mentioned in the article:
bool AlmostEqual2sComplement(float A, float B, int maxUlps)
{
// Make sure maxUlps is non-negative and small enough that the
// default NAN won't compare as equal to anything.
assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024);
int aInt = *(int*)&A;
// Make aInt lexicographically ordered as a twos-complement int
if (aInt < 0)
aInt = 0x80000000 - aInt;
// Make bInt lexicographically ordered as a twos-complement int
int bInt = *(int*)&B;
if (bInt < 0)
bInt = 0x80000000 - bInt;
int intDiff = abs(aInt - bInt);
if (intDiff <= maxUlps)
return true;
return false;
}