Code sometimes returns Vector3 (NaN, NaN, NaN)

I can’t figure out why it gets (NaN, NaN, NaN) sometimes. There isn’t any logic, syntax, or mathematical errors that I can find.

        M = (2 * Mathf.PI * t) / period;
        E = M;
        E = M - eccentricity * Mathf.Sin(E);
        c = M - eccentricity * Mathf.Sin(E);

        while (Mathf.Approximately(E, c) == true)
        {
            E = c;
            c = M + eccentricity * Mathf.Sin(E);
        }

        v = 2 * Mathf.Atan(Mathf.Sqrt(((1 + eccentricity) / (1 - eccentricity)) * Mathf.Tan((c / 2))));

        r = (major_axis * (1 - Mathf.Pow(eccentricity, 2))) / (1 + eccentricity * Mathf.Cos(v));

        x = r * (Mathf.Cos(ascending_node) * Mathf.Cos((perihelion + v)) - Mathf.Sin(ascending_node) *
            Mathf.Sin((perihelion + v)) * Mathf.Cos(inclination));

        y = r * (Mathf.Sin(ascending_node) * Mathf.Cos((perihelion + v)) - Mathf.Cos(ascending_node) *
            Mathf.Sin((perihelion + v)) * Mathf.Cos(inclination));

        z = r * Mathf.Sin((perihelion + v)) * Mathf.Sin(inclination);

        X = x;

        Y = (y * Mathf.Cos(inclination) - z * Mathf.Sin(inclination));

        Z = (y * Mathf.Sin(inclination) + z * Mathf.Cos(inclination));
     
        Vector3 coords = new Vector3(X, Y, Z);

        return coords;

Here is the info for two planets and their output, one worked and one didn’t. I can provide more if needed.

Planet 1:

Coords: NaN, NaN, NaN

Period: 1.368065
Major Axis: 1.232361
Eccentricity: 0.9859662
Perihelion: 161
Ascending Node: 97
Inclination: 0

Planet 2:

Coords: -1.885116, 0.665647, 0

Period: 4.694033
Major Axis: 2.80348
Eccentricity: 0.93421
Perihelion: 266
Ascending Node: 284
Inclination: 0

NaN normally comes if you have gone too big for the size of a float. You can do this by dividing by zero, or by repeatedly multiplying big numbers.

Try trending the relavant values with something like Trend Me and see under what conditions things go wrong.

https://bitbucket.org/BoredMormon/trend.me

Edit: Going to big results in infinity. NaN is for dividing by zero. See clarifications below.

I have no idea what that trend me thing is or how to use it. Also if the numbers get too big to store in a float shouldn’t it throw an error?

1 Like

It’s one of his freely available assets. The readme is simply buried.

https://bitbucket.org/BoredMormon/trend.me/src/bd10b392daa8a35ce720960c21a0ac2457698d29/Assets/TrendMe/Readme.txt?at=master&fileviewer=file-view-default

I really should go fix that.

Import the tool into your project. Then attach the Trender component to an empty GameObject in the scene. Direct the exposed field towards the Vector that is going nuts. Then hit play.

The animation curve on the trender will show you what the float is doing over time. You should then be able to pick what goes to NaN first. And work you way through to what caused that. You will probably need several Trenders to track the various floats.

The other way is to pick through your math with a fine tooth comb. You have some complex things happening there, and its difficult to solve without knowing exactly what is supposed to happen.

1 Like

Use a debugger or a bunch of log statements to find out what the intermediate numbers are, most importantly, the denominators of your divisions. It’s probably v og r that turns out to be NaN, which causes all other values to be NaN.

2 Likes

Pretty sure these operations result in Positive and Negative Infinity. I could be wrong, though.

https://msdn.microsoft.com/en-us/library/system.single.nan(v=vs.110).aspx

Float overflows simply result in ± infinity. He was correct for the second part.

https://csharp.2000things.com/2014/05/16/1098-floating-point-overflow/

Trend.me is pretty cool. Thanks for sharing.

1 Like

You are welcome. I built it for an almost identical problem to the OP. I had an economic simulation that was randomly becoming unstable and going crazy. Using a Debug.Log on a dozen variables was too difficult to trace. Setting a watch was also impractical. So I built Trend Me to be able to track variables frame by frame in the inspector.

The csv output is also useful, I frequently dump a bunch of variables out to excel or modelling software.

It’s come in handy in a bunch of other ways too. I have one app that uses the technique to record data for playback later. Another that uses the technique for generic decoupled UI. And another that uses it to track the users physical location and plot it on a map.

It took me a week to figure out that math not including the time it took to code it correctly. The math behind calculating celestial bodies is just plain painful to deal with, doesn’t help half the stuff has vague names. Doesn’t help that I’m seriously considering having the player use polar coordinates to navigate. Thanks for the tool I hope I’m able to figure it out without too much trouble.

If anyone wants I can put up the notes I took when figure this stuff out.

2 Likes

Yeah, sure. Upload it if you can, sounds pretty cool and I’m sure someone would find it critically useful for a project.

I think I can do you one better and put up the function properly commented once I have it working 100% correctly.

Ok so I have found where and why it breaks, but I’m not sure how to fix it. I broke down the equation for v.

        w = c / 2;

        a = Mathf.Tan(w);

        s = 1 + eccentricity;

        d = 1 - eccentricity;

        g = s / d;

        h = g * a;

        f = Mathf.Sqrt(h);

        b = Mathf.Atan(f);

        v = 2 * Mathf.Atan(b);

So problem is the Mathf functions returns the answer in radians. Unfortunately I was unable to take trig in high school and haven’t gotten to in yet in college so I don’t know how to fix it.

You can use these to convert back and forth between degrees and radians. The formulas for doing it are there too.

https://docs.unity3d.com/ScriptReference/Mathf.Deg2Rad.html
https://docs.unity3d.com/ScriptReference/Mathf.Rad2Deg.html

The thing is I’m not sure if degrees is the units in the equation. I think I’m way past the point of this being worth the effort for a game; I’ve already spent well over a month hung up on this. There is way more to this stuff than I thought and way more than I need. All I’m really trying to do is calculate an objects position on a 3d ellipse with a non-origin center which is way easier than having to figure out which way the star is moving. I mean I wanted to fake the universe being more complicated than it actually was in the first place; unless your Dwarf Fortress that is what you do. Thanks for the help though I would have likely wasted more time without it.