-1.#IND00000 when normalising a vector (0,0,0)

Started by
6 comments, last by Endar 14 years, 1 month ago
So i get a Vector and in some cases it is (0,0,0). This gets normalised by double vector_length = this->length(); this->x /= vector_length; this->y /= vector_length; this->z /= vector_length; so should be 0/0. so im getting a divide by 0 returning that value. Can i just say if the length is 0 then divide by 1 so it will return 0 in this case?
Advertisement
If the length is zero you don't have to do anything at all, giving you a zero vector.

+-1.#IND00000 is correct answer for floating point division by zero.

You'll need to compare the vector length for zero or some really small value in order to avoid problems with normalization.

Best regards!
Sound. Thanks.
You're missing the point, though. The big question is, why are you trying to normalize a vector that could be zero?

The entire purpose of normalizing a vector is to extract its direction.

The entire point of a zero vector is that it doesn't have a direction.

If the 'zero' data is getting into the part of the code where you normalize the vector, maybe there is something wrong with the other parts of the process?
It's wise practice to assert that the vector length is non zero in your normalize function. That way you catch any silly mistakes during debugging and the assert can be compiled out in release builds leaving you fairly certain you're not accidentally doing it.

That being said you should always know exactly what you are normalizing. You should either know the length is non zero or check the length (usually the squared length is good enough for a zero length check) before you call normalize.

It's also common to have a safe normalize function which internally checks the length and allows the user to supply an alternate value in case the vector length is zero. This is kind of the lazy alternative to the above mentality. But it gets the job done in exactly the same manor.

bool Vector::IsZeroLength( ) const { return EpsilonEquals( SquaredLength( ), 0.0f, small_epsilon );}Vector& Vector::NormalizeSafe( const Vector& fallbackValue ){ if( IsZeroLength( ) ) *this = fallbackValue; else Normalize( ); return *this;}
Not sure what API you are using, but in XNA you have to check Vector.Length() > 0 before normalizing or an exception is thrown. I ran into this a lot when doing collision and boids navigation for a lot of npc units.

So you should check if the vector is 0,0,0 (or very close) before normalizing, and make a special case to handle it. For example, what to do about collision if 2 NPC spawn in exactly the same spot?.
Quote:Original post by EJH
So you should check if the vector is 0,0,0 (or very close) before normalizing, and make a special case to handle it.

You could, but it's probably not a good idea. You should never have a vector that you want to normalise (assuming the vector represents a direction), that has a length of 0.

Unless you're doing something specialised, you should simply assert that the length is not 0 or almost 0 (within a certain value, often 0.0001 or similar is used), and then when it hits the assert and fails, find out why you're trying to normalise a 0 length vector and fix it.

You really don't want to be messing around with special case code in a case a vector is 0, 0, 0. You should just be initialising it with something sensible, even if it is just a default of 0, 0, -1 (pointing straight down the z-axis).

Edit:
Quote:Original post by EJH
For example, what to do about collision if 2 NPC spawn in exactly the same spot?

Oh, and I guess I'm being somewhat pedantic, but you really shouldn't be normalising a position unless you're trying to find the direction of the position from the origin (I can't think of a reason why you would need to). If you're normalising something, you'd want it to be a vector that indicates a direction in some way, such as the offset from one position to another to find the direction from the first position to the next.
[size="2"][size=2]Mort, Duke of Sto Helit: NON TIMETIS MESSOR -- Don't Fear The Reaper

This topic is closed to new replies.

Advertisement