Sign in to follow this  
discodowney

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

Recommended Posts

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?

Share this post


Link to post
Share on other sites

+-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!

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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;
}

Share this post


Link to post
Share on other sites
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?.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this