Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vector2 normalize (division with zero) #44

Open
bQvle opened this issue Oct 21, 2017 · 4 comments
Open

Vector2 normalize (division with zero) #44

bQvle opened this issue Oct 21, 2017 · 4 comments

Comments

@bQvle
Copy link

bQvle commented Oct 21, 2017

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;
            }
        }
@experdot
Copy link

experdot commented Oct 21, 2017

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

@bQvle
Copy link
Author

bQvle commented Oct 21, 2017

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 :)

@louis-langholtz
Copy link

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

@bQvle
Copy link
Author

bQvle commented Oct 21, 2017

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants