Hi,

On Monday 26 February 2007 09:23, Anders Backman wrote:
> I just got stuck on something I been worried about for quite some time
> regarding the Math library in osg:
>
>         bool Matrix::isIdentity() const
>         {
>             return _mat[0][0]==1.0f && _mat[0][1]==0.0f &&
> _mat[0][2]==0.0f&&  _mat[0][3]==
> 0.0f &&
>                    _mat[1][0]==0.0f && _mat[1][1]==1.0f &&
> _mat[1][2]==0.0f&&  _mat[1][3]==
> 0.0f &&
>                    _mat[2][0]==0.0f && _mat[2][1]==0.0f &&
> _mat[2][2]==1.0f&&  _mat[2][3]==
> 0.0f &&
>                    _mat[3][0]==0.0f && _mat[3][1]==0.0f &&
> _mat[3][2]==0.0f&&  _mat[3][3]==
> 1.0f;
>         }
>
> Is there a specific reason for not using epsilon tests for a float? I can
> think of quite a few situations when this would fail.
> I guess, there is only one situation when this would succeed for sure, and
> that is after a call to makeIdentity().
>
>
> This also goes for quite some of the Vec3, Vec4, Quat code too.
> All comparisons such as:
>
> inline bool operator == (const Vec3f& v) const { return _v[0]==v._v[0] &&
> _v[1]==v._v[1] && _v[2]==v._v[2]; }
>
> Would effectively fail in most situations, as comparing floats directly is
> something that is not recomended.
>
>
> Instead something like the following should be used:
>
>
> #define EPSILON 1E-16
> #define EQUAL(A,B) (abs((A)-(B)) < EPSILON)
>
> inline bool operator == (const Vec3f& v) const { return
> EQUAL(_v[0]-v._v[0]) && EQUAL(_v[1]-v._v[1]) && EQUAL(_v[2]-v._v[2]); }'
Well, that is wrong too.

In effect you are making fixed point arithmethic from floating point 
arithmethic.
Somehow more correct would be:
#define EQUAL(A,B) (abs((A)-(B)) <= 
std::numeric_limits<double>::epsilon()*max(abs(a), abs(b)))
But even that is not the real trueth...
See Goldbergs excelent paper 'what every sceintist should know about floating 
point arithmetics' (just google for that).
Doing that right is highly dependent on the application you need.
Due to error accumulation your proposed bound is too hard, since this test 
only checks for roundoff in the representation, not roundoff that happens 
when operating on such numbers.

I cannot speak for osg, but from my point of view the implemented method is 
perfect. If you want to have an 'equal up to floating point precision' test I 
would prefer having a new set of methods that do not test for exact equality.
From my experience with that kind of stuff, you should not hard code that 
EPSILON here - may be provide a sensible default value but no hardcoding ...

   Greetings

        Mathias

-- 
Dr. Mathias Fröhlich, science + computing ag, Software Solutions
Hagellocher Weg 71-75, D-72070 Tuebingen, Germany
Phone: +49 7071 9457-268, Fax: +49 7071 9457-511
_______________________________________________
osg-users mailing list
[email protected]
http://openscenegraph.net/mailman/listinfo/osg-users
http://www.openscenegraph.org/

Reply via email to