How to solve some math inaccuracies ??

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
cederron
Posts: 53
Joined: Thu Jul 13, 2006 11:35 pm

How to solve some math inaccuracies ??

Post by cederron »

Hello all,

Im using irrlicht 0.14 and Im converting a vertex in world space back to model space, what i do is :

Code: Select all

//We get the collided triangle and store it in triCollided, also collision point
irrScene->getSceneCollisionManager()->getCollisionPoint( line,                s, *collisionPoint, *triCollided );

// create a matrix that is inverse of the current transformation
matrix4 irrmat;
irrmat = node->getAbsoluteTransformation();
irrmat.makeInverse();

//Transform vectors of triCollided so they are in model space now
irrmat.transformVect(triCollided->pointA);
irrmat.transformVect(triCollided->pointB);
irrmat.transformVect(triCollided->pointC);


/* Now I do a check to see what model vertex matches with the triangle     collided, in the following code meshVertices is a pointer to the mesh vertex buffer   */
for ( int i = 0; i < numVertices; i++ )
          if( triCollided.PointA == meshVertices[i].Pos )
                     bFound = true;
The problem is that bFound is never true because after transforming triCollided it seems there is some math inaccuracy and there is never a mesh vertex equal to the transformed triangle vertex. For example, in my app after transforming the vertex to model space i get a x value of 2.236578 but the vertex in the mesh has x coord of 2.236580. So it never matches.

Is It a normal behavior? Is it a bug? What can I do to solve this?

Thank you!
Baal Cadar
Posts: 377
Joined: Fri Oct 28, 2005 10:28 am
Contact:

Post by Baal Cadar »

Thats normal behaviour and implicit to the way floating point values are handled. *Never* try to directly compare two floats/doubles using ==, instead check, whether one float is in some epsilon range/environment(?) of the other.

Code: Select all

float EPSILON = 0.00001f // values that are less distant than this are considered equal..
float v1, v2;
..
if (abs(v1-v2) < EPSILON)
{
   // values are equal
}
else
{
   // they aren't
}
The actual epsilon value is up to you, the 0.00001 is just an example.
No offense :)
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

I can think of two things.
  1. Use an epsilon value when comparing the positions.
  2. Convert the vertex pos into world space, then do the comparison.
The first works by allowing a tolerance, but the problem is that you need to pick a good tolerance. The problem is that the tolerance will depend on the distance to the origin.

Code: Select all

inline bool epsilon_equals(const core::vector3df& a, const core::vector3df& b, f32 e)
{
   return fabs(a.X - b.X) < e && fabs(a.Y - b.Y) < e && fabs(a.Z - b.Z) < e;
}
The second works by assuming that the vertices are transformed using the same matrix. If they are, then the results will be the same.

Travis
cederron
Posts: 53
Joined: Thu Jul 13, 2006 11:35 pm

Post by cederron »

Thanks, I have done the comparison with a tolerance and it's working, since i won't be doing big scenes i think it won't be a problem, but i will try also to transform the vertex to model position.

Thank you both, really!
Post Reply