VelcroPhysics icon indicating copy to clipboard operation
VelcroPhysics copied to clipboard

Vector2 normalize (division with zero)

Open bQvle opened this issue 7 years ago • 4 comments

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;
            }
        }

bQvle avatar Oct 21 '17 12:10 bQvle

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

experdot avatar Oct 21 '17 12:10 experdot

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 avatar Oct 21 '17 14:10 bQvle

@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.

louis-langholtz avatar Oct 21 '17 19:10 louis-langholtz

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;
        }

bQvle avatar Oct 21 '17 20:10 bQvle