diff --git a/gdx/src/com/badlogic/gdx/math/MathUtils.java b/gdx/src/com/badlogic/gdx/math/MathUtils.java index 4d9b662c7dc..43c57e5f494 100644 --- a/gdx/src/com/badlogic/gdx/math/MathUtils.java +++ b/gdx/src/com/badlogic/gdx/math/MathUtils.java @@ -108,16 +108,40 @@ static public float atan2 (float y, float x) { return y < 0f ? atan - PI : atan; } - /** Returns acos in radians, less accurate than Math.acos but may be faster. */ - static public float acos (float a) { - return 1.5707963267948966f - (a * (1f + (a *= a) * (-0.141514171442891431f + a * -0.719110791477959357f))) - / (1f + a * (-0.439110389941411144f + a * -0.471306172023844527f)); + /** Returns acos in radians; less accurate than Math.acos but may be faster. Average error of 0.00002845 radians + * (0.0016300649 degrees), largest error of 0.000067548 radians (0.0038702153 degrees). This implementation does not + * return NaN if given an out-of-range input (Math.acos does return NaN), unless the input is NaN. + * @param a acos is defined only when a is between -1f and 1f, inclusive + * @return between {@code 0} and {@code PI} when a is in the defined range */ + static public float acos(float a) { + float a2 = a * a; // a squared + float a3 = a * a2; // a cubed + if (a >= 0f) { + return (float) Math.sqrt(1f - a) * + (1.5707288f - 0.2121144f * a + 0.0742610f * a2 - 0.0187293f * a3); + } + else { + return 3.14159265358979323846f - (float) Math.sqrt(1f + a) * + (1.5707288f + 0.2121144f * a + 0.0742610f * a2 + 0.0187293f * a3); + } } - /** Returns asin in radians, less accurate than Math.asin but may be faster. */ - static public float asin (float a) { - return (a * (1f + (a *= a) * (-0.141514171442891431f + a * -0.719110791477959357f))) - / (1f + a * (-0.439110389941411144f + a * -0.471306172023844527f)); + /** Returns asin in radians; less accurate than Math.asin but may be faster. Average error of 0.000028447 radians + * (0.0016298931 degrees), largest error of 0.000067592 radians (0.0038727364 degrees). This implementation does not + * return NaN if given an out-of-range input (Math.asin does return NaN), unless the input is NaN. + * @param a asin is defined only when a is between -1f and 1f, inclusive + * @return between {@code -HALF_PI} and {@code HALF_PI} when a is in the defined range */ + static public float asin(float a) { + float a2 = a * a; // a squared + float a3 = a * a2; // a cubed + if (a >= 0f) { + return 1.5707963267948966f - (float) Math.sqrt(1f - a) * + (1.5707288f - 0.2121144f * a + 0.0742610f * a2 - 0.0187293f * a3); + } + else { + return -1.5707963267948966f + (float) Math.sqrt(1f + a) * + (1.5707288f + 0.2121144f * a + 0.0742610f * a2 + 0.0187293f * a3); + } } // ---