A bug when use Acos() to 2 normalized vector
SteveCruise opened this issue · 2 comments
SteveCruise commented
It throw out exception "Must between -FP.One and FP.One"
The demo is as follow:
FP x1 = FP.FromRaw(3492999344);
FP y1 = FP.FromRaw(2499139782);
FP x2 = FP.FromRaw(-3492914803);
FP y2 = FP.FromRaw(-2499256617);
Debug.Log("x1: " + x1 + " y1: " + y1 + " x2: " + x2 + " y2: " + y2);
// x1: 0.8132773 y1: 0.5818763 x2: -0.8132576 y2: -0.5819035
FP x1_normalized = x1 / FP.Sqrt(x1 * x1 + y1 * y1);
FP y1_normalized = y1 / FP.Sqrt(x1 * x1 + y1 * y1);
Debug.Log("normalized vector1 x: " + x1_normalized + " y: " + y1_normalized);
// normalized vector1 x: 0.8132773 y: 0.5818763
FP x2_normalized = x2 / FP.Sqrt(x2 * x2 + y2 * y2);
FP y2_normalized = y2 / FP.Sqrt(x2 * x2 + y2 * y2);
Debug.Log("normalized vector2 x: " + x2_normalized + " y: " + y2_normalized);
// normalized vector2 x: -0.8132578 y: -0.5819036
FP dot = x1_normalized * x2_normalized + y1_normalized * y2_normalized;
Debug.Log("Dot of vector1 and vector2: " + dot);
// Dot of vector1 and vector2: -1
FP.Acos(dot);
// ArgumentOutOfRangeException: x
// Parameter name: Must between -FP.One and FP.One
The code of Fix64:
/// <summary>
/// Returns the arccos of of the specified number, calculated using Atan and Sqrt
/// This function has at least 7 decimals of accuracy.
/// </summary>
public static FP Acos(FP x)
{
if (x < -One || x > One)
{
throw new ArgumentOutOfRangeException("Must between -FP.One and FP.One", "x");
}
if (x.RawValue == 0) return PiOver2;
var result = Atan(Sqrt(One - x * x) / x);
return x.RawValue < 0 ? result + Pi : result;
}
SteveCruise commented
Dot RawValue: -4294967297
FP.One RawValue: 4294967296
SteveCruise commented
May be it's just not so accurate