VelcroPhysics
VelcroPhysics copied to clipboard
Vector2 normalize (division with zero)
public static void Normalize(ref Vector2 value, out Vector2 result)
{
float factor;
DistanceSquared(ref value, ref zeroVector, out factor);
factor = 1f / (float)Math.Sqrt(factor);
result.X = value.X * factor;
result.Y = value.Y * factor;
}
I'm currently using Farseer and had some issues with contact solving. I figured the issue might still be with Velcro.
Normalize return a Vector2(X=NaN, Y=NaN) if you try to normalize a zero vector.
because factor will be zero so 1f / (float)Math.Sqrt(factor)
will result in Infinity
the solver does something like Normalize(Position1 - Position2) so if the two positions is identical we get the NaN vector which crashes the physics.
Hopes this helps :)
I solved it this way
public static void Normalize(ref Vector2 value, out Vector2 result) {
if (value == zeroVector)
result = zeroVector;
else {
float factor;
DistanceSquared(ref value, ref zeroVector, out factor);
factor = 1f / (float)Math.Sqrt(factor);
result.x = value.x * factor;
result.y = value.y * factor;
}
}
Solution
My partner and I have changed to use System.Numerics
in Farseer,and I found the same problem in Systerm.Numerics
but not SharpDx
,maybe it helps you.
See Also
System.Numerics doesn't check for zero too, SharpDx does. I solved it within the Vector2 class in farseer. just wanted to let @Genbox know, in case he wants to fix it for Velcro :)
@bQvle I don't mean this as a statement but as a sincere question: instead of comparing value
to the zero vector, would it be better to check if factor
(value
's magnitude) is not normal?
I ask because if factor
is not normal, then the result won't be much more meaningful than if it's zero. OTOH, checking for normal in C# may be less performant than checking for two zeroes. I don't know but I'd like to hear people's thoughts on this.
Actually I have no idea. But since zero is the only Vector that will result in zero "length/distanceSquare" I just wanted to "return" before even calculating the length. But I think that no matter how you do it, it shouldn't change much in the big scope, performance wise.
Edit: Since trying to normalize a zero vector is a 0.001% thing. your right, theres no reason optimizing for that. however instead of checking for a normal factor, I just check the factor for 0 (while it still represents the length)
public static void Normalize(ref Vector2 value, out Vector2 result) {
float factor;
DistanceSquared(ref value, ref zeroVector, out factor);
if (factor != 0)
factor = 1f / Mathf.Sqrt(factor);
result.x = value.x * factor;
result.y = value.y * factor;
}