Vector3.CalculateAngle can return NaN when it shouldn't
The static method in Vector3.cs
public static float CalculateAngle(Vector3 first, Vector3 second)
{
return (float)System.Math.Acos((Vector3.Dot(first, second)) / (first.Length * second.Length));
}
can return NaN if the value passed to Acos is outside the range 1 -1 because (Vector3.Dot(first, second)) / (first.Length * second.Length) returns a float number and when it is casted to double the value can go outside the range
To solve this issue it seems sufficient to change the method as
public static float CalculateAngle(Vector3 first, Vector3 second)
{
float temp = (Vector3.Dot(first, second)) / (first.Length * second.Length);
return (float)System.Math.Acos(temp);
}
Wow - this is a first. I do not quite understand how a double within [-1..1] can go outside that range when cast to a float, can you show me what reproduces this?
It's not the double casted to float but the float casted to double. Granted that the 2 Vectors have lenght > 0, it should always be possible to calculate the angle between them. You can try this code:
Urho.Vector3 v = new Urho.Vector3(0.11008f, 0, 0);
Urho.Vector3 v1 = new Urho.Vector3(0.6184301f, 0, 0);
float cosFloat = Urho.Vector3.Dot(v, v1) / (v.Length * v1.Length);
double cosDouble = Urho.Vector3.Dot(v, v1) / (v.Length * v1.Length);
double angleF = Math.Acos(cosFloat);
double angleD = Math.Acos(cosDouble);
float a = Urho.Vector3.CalculateAngle(v, v1);
You will see that cosDouble > 1 and a = angleD = NaN