Если какой-либо компонент любого из ваших вычислений равен NaN
, тогда весь результат также будет NaN
.
NaN
не связано с число становится большим (это может вызвать либо исключение, либо непредвиденное поведение - например, переключение на отрицательные значения). Это скорее намекает на то, что в какой-то момент ваших вычислений вы создаете математически неопределенное значение.
Метод или оператор возвращает NaN, если результат операции не определен. Например, результат деления нуля на ноль равен NaN, как показано в следующем примере. (Но обратите внимание, что деление ненулевого числа на ноль возвращает либо PositiveInfinity, либо NegativeInfinity, в зависимости от знака делителя.)
Кроме того, 3 Billion * 3 Billion
будет 9E+24
, максимальное значение из float
равно 3.40282347E+38
, так что это в любом случае не будет проблемой.
Вероятно, вы делите на / 0
где-то
Места, где это может произойти, например:
при прохождении radius = 0
Потому что во многих случаях вы делите на / radius
при прохождении radius = 2
, потому что позже вы делаете
vertRadius = radius / 2;
=> равно 1, а затем вы делаете / vertRadius - 1
, например, для C
так vertRadius - 1
будет 0
если A = 0
если objectDot.x - lightDot.x = 0
потому что тогда A
, B
и C
- это 0
, если B*B - 4*A*C = 0
, потому что также квадрат- root отрицательных чисел не определен, и вы делаете
System.Math.Sqrt(B*B - 4*A*C)
Вы с Он может разделить ваши вычисления и добавить проверки, чтобы упростить отладку, чтение и обслуживание, например, вроде
public static Vector2 GetEllipseOuterIntersection(Vector2 ellipseCentre, float radius, Vector2 lightDot, Vector2 objectDot)
{
if(Mathf.Approximately(radius, 0))
{
Debug.LogError("radius may not be 0");
return default;
}
if(Mathf.Approximately(radius, 2))
{
Debug.LogError("radius may not be 2");
return default;
}
lightDot.x -= ellipseCentre.x;
lightDot.y -= ellipseCentre.y;
objectDot.x -= ellipseCentre.x;
objectDot.y -= ellipseCentre.y;
// Get the semiminor axis.
float vertRadius = radius/2;
var difX = objectDot.x - lightDot.x;
var difY = objectDot.y - lightDot.y;
if(Mathf.Approximately(difX, 0))
{
Debug.LogError("objectDot.x - lightDot.x may not be 0!");
return default;
}
if(Mathf.Approximately(difY, 0))
{
Debug.LogError("objectDot.y - lightDot.y may not be 0!");
return default;
}
var difXSqr = difX * difX;
var difYSqr = difY * difY;
var radiusSqr = radius * radius;
var vertRadiusSqr = vertRadius * vertRadius;
var lightDotXSqr = lightDot.x * lightDot.x;
var lightDotYSqr = lightDot.y * lightDot.y;
// Calculate the quadratic parameters.
float A = difXSqr / radiusSqrInverse + difYSqr / vertRadiusSqr;
float B = 2 * lightDot.x * difX / radiusSqr + 2 * lightDot.y * difY / vertRadiusSqr;
float C = lightDotXSqr / radiusSqr + lightDotYSqr / vertRadiusSqr - 1;
if(Mathf.Approximately(A, 0))
{
Debug.LogError("A may not be 0!");
return default;
}
double BSquare = B*B;
double AC4 = 4*A*C;
double DIF = BSquare - AC4;
if(DIF < 0)
{
Debug.LogError("DIF may not be negative!");
return default;
}
double t = (-B + System.Math.Sqrt(DIF)) / 2 / A;
print(t);
float x = (float) (lightDot.x + difX * t + ellipseCentre.x);
float y = (float) (lightDot.y + difY * t + ellipseCentre.y);
return new Vector2(x, y);
}