Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve MathUtils.asin(), acos() #6332

Merged
merged 1 commit into from Dec 27, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
40 changes: 32 additions & 8 deletions gdx/src/com/badlogic/gdx/math/MathUtils.java
Expand Up @@ -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);
}
}

// ---
Expand Down