- Home /
Getting NaN values out of a function. Need help to solve the problem.,Getting NaN values out of a function, and I do not understand why.
Made a orbit script, it uses degrees / radians to calculate the orbiting bodys next position based on its speed. From what i can tell the function works flawlessly for 1 second at the most then outputs a NaN value. This is a reversed version of a elliptical arch length equation. (to find angle A insted of arch length)
double x = Math.Abs(Math.Sqrt(Math.Acos((Math.Pow(
Math.Sqrt((_Orbit.SemiMajorAxis - b) / _Orbit.SemiMajorAxis), (v + _Orbit.SemiMajorAxis *
Math.Log((Distance * (_Orbit.OrbitPosition * (Math.PI / 180)) * Math.Cos(_Orbit.OrbitPosition * (Math.PI / 180))) / _Orbit.SemiMajorAxis, Math.Sqrt((_Orbit.SemiMajorAxis - b) / _Orbit.SemiMajorAxis)))
/ _Orbit.SemiMajorAxis)) * _Orbit.SemiMajorAxis) / Distance));
This function takes in _OrbitPosition (always between 0 and 360) and v (velocity, constantly changeing always above 0)
double v = Math.Sqrt((mass * 0.00000000006674f) * ((2 / Distance) - (1 / _Orbit.SemiMajorAxis)));
Distance, SemiMajorAxsis, and b (semiminoraxsis) are always grater then 0;
Like I said in the second it works, the orbiting bodys move the distance the should move in that second, but it will always seam to break with a NaN value. I know its this part of the code becuase this dose not happen if i change double x to somthing like:
double x =(((c / 360) * _Orbit.OrbitPosition + (v*Time.deltaTime)) / c) * 360;
Any help would be much appreciated!!!
Answer by TreyH · Dec 10, 2018 at 03:35 PM
Variable assignments like that are pretty hard to read, so let's try and decompose that a bit. Quickly and probably erroneously breaking it out with dummy names, your assignment looks like this:
var deg2rad = Math.PI / 180;
var a = (_Orbit.SemiMajorAxis - b) / _Orbit.SemiMajorAxis;
var b = Distance * (_Orbit.OrbitPosition * deg2rad) * Math.Cos(_Orbit.OrbitPosition * deg2rad);
var log = Math.Log(b / _Orbit.SemiMajorAxis, Math.Sqrt(a));
var sqrt = Math.Sqrt((_Orbit.SemiMajorAxis - b) / _Orbit.SemiMajorAxis);
var pow = (v + _Orbit.SemiMajorAxis * log) / _Orbit.SemiMajorAxis;
var c = Math.Pow(sqrt, pow);
var acos = Math.Acos(c * _Orbit.SemiMajorAxis) / Distance;
double x = Math.Abs(Math.Sqrt(acos));
The only way you could be getting NaN's here would be if your Math.Log
took a non-positive argument, one of your Math.Sqrt
calls took a negative argument, if your Math.Acos
call's argument exceeded the inclusive unit interval [-1,1], or if you divided by 0 somewhere (your Distance
value). You should check for these cases, which can be sort of tedious. We'll cover the Math.Acos
situation:
var c = Math.Pow(sqrt, pow);
var d = (c * _Orbit.SemiMajorAxis) / Distance;
var e = (d < -1) ? -1 : (d > 1) ? 1 : d;
var acos = Math.Acos(e);
double x = Math.Abs(Math.Sqrt(acos));
if (d != e)
Debug.LogFormat("{0} != {1}", d, e);
As this isn't really a Unity question, this question may end up being removed.
Thanks for the answer Trey. $$anonymous$$ost Unity devs are challenged by math and C#, and this question is relevant.
Thanks for the feedback, I'll rephrase the body to be less repellent.
Your answer
