float returning "NaN"

So I’m trying to calculate resultant vectors (not vectors as C# and Monogame know them, but physical vectors as in two or more forces acting on an object.). This is all for getting the physics right in my dumb asteroids project. I’m sure my code looks goofy as all get out, but I’m really only concerned with what’s written below in the /**/ comments.

I tried to adapt the math in a line of code from here: http://www.fatihtan.net/en/Blog/Post/c-sharp-form-application--calculating-resultant-force-3 into my own project. If I’m doing this all wrong and this class need to be burned with fire, please tell me also, but I feel like I’m very close.

Text formatting here is acting a little goofy as well, but I think it can be deciphered. please go easy on me, I’m a massive noob.

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AvoidTheStroids
{
    class Sprite
    {
        private Texture2D _texture;
        private float _rotation;
        private float _dirThrust;
        private float _lastThrust = 0f;
        private float _thrust;
        int butt = 0;

        public Vector2 Position;
        public Vector2 Origin;

        public float RotationVelocity = 3f;
        public float LinearVelocity = 0f;

        //the data below is only meant to be monitored by Game1.cs and displayed to the console
        public float rotation;
        public float dirThrust;
        public float lastThrust;
        public float thrust;
        public Vector2 position;
        public float linearVelocity;


        public Sprite(Texture2D texture)
        {
            _texture = texture;
        }

        public void Update()
        {
            if (Keyboard.GetState().IsKeyDown(Keys.A))
                _rotation -= MathHelper.ToRadians(RotationVelocity);
            if (Keyboard.GetState().IsKeyDown(Keys.D))
                _rotation += MathHelper.ToRadians(RotationVelocity);

            rotation = _rotation;
            dirThrust = _dirThrust;
            lastThrust= _lastThrust;
            thrust = _thrust;
            position = Position;
            linearVelocity = LinearVelocity;

            _dirThrust = 0f;
            if (Keyboard.GetState().IsKeyDown(Keys.W))
            {
                _thrust = .4f;
                _dirThrust = _rotation;
                if (_lastThrust == 0f) _lastThrust = _dirThrust;
            }
            else
            {
                _thrust = 0f;
            }
            //if (Keyboard.GetState().IsKeyDown(Keys.S) && LinearVelocity >= 0)
            //{
            //    LinearVelocity -= .2f;
            //}

            var oneX = (float)Math.Cos(_dirThrust) * _thrust;
            var oneY = (float)Math.Sin(_dirThrust) * _thrust;
            var twoX = (float)Math.Cos(_lastThrust) * LinearVelocity;
            var twoY = (float)Math.Sin(_lastThrust) * LinearVelocity;
            
            if (butt < 2)
            {
                Console.WriteLine(oneX);
                Console.WriteLine(oneY);
                Console.WriteLine(twoX);
                Console.WriteLine(twoY);
            }
            ++butt;

            _lastThrust = (float)Math.Tan((oneX + twoX) / (oneY + twoY));
            LinearVelocity = (float)(Math.Sqrt(Math.Pow((oneX + twoX), 2) + Math.Pow((oneY + twoY), 2)));

           /*
           I'm 100% sure its the line above that is returning "NaN" I found it out through writing the values to the console.
           LinearVelocity initially returns "0" before this line of code happens. I would love to know why.
          */

            if (LinearVelocity > 2f)
            {
                LinearVelocity = 2f;
            }

            var direction = new Vector2((float)Math.Cos(MathHelper.ToRadians(90) - _lastThrust), -(float)Math.Sin(MathHelper.ToRadians(90) - _lastThrust));

            Position += direction * LinearVelocity;
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(
                _texture,
                Position,
                null,
                Color.White,
                _rotation,
                Origin,
                1,
                SpriteEffects.None,
                0f);
        }
    }
}

You can format code with 3 ` before and after :wink:

What’s the exact exception + stacktrace ?

NaN is what you get when an operation returns undefined / impossible value (like division by zero).

You probably just have a division by zero somewhere in there. I suggest debugging and checking the values in all the operations that are not sub / add in your code.

I appreciate the response. Please forgive me in advance for the stupid questions. What’s a stacktrace? There are no real exceptions. I wrote the values of onex, oneY, twoX and twoY to the console twice. The first time they ran zeroes. The second time (after passing LinearVelocity through the resultant velocity equation), twoX and twoY came out as NaN. twoX and twoY are calculated with LinearVelocity and _lastThrust. LinearVelocity is initialized as zero and that’s why it works the first time.

The end result, LinearVelocity can’t be used to calculate Position… and Position can’t be passed on to spriteBatch.Draw(); Thus… no sprite.

I might be finding the square root of a negative… would that do it?

Don’t ask me, ask the debugger! :slight_smile:
Whenever faced with questions like these simple write a minimal code to test the condition and see what you get.

1 Like

I was indeed dividing by zero. Thanks again… Code still doesn’t work… but my sprite is on the screen now.

You can get a nan if your result is below a minimum value. aka Not A Number.

Which means dividing a very small number by a very large number can also cause a nan. In a chain of operations were you do things like square root you need to take care.