Math.atan2() is very convenient, yet very slow.
A lookup table will be roughly 8x faster.
You lose accuracy, but heck, that's obvious.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| public static final float atan2Deg(float y, float x) { return FastMath.atan2(y, x) * DEG; }
public static final float atan2DegStrict(float y, float x) { return (float) Math.atan2(y, x) * DEG; }
public static final float atan2(float y, float x) { float add, mul;
if (x < 0.0f) { if (y < 0.0f) { x = -x; y = -y;
mul = 1.0f; } else { x = -x; mul = -1.0f; }
add = -3.141592653f; } else { if (y < 0.0f) { y = -y; mul = -1.0f; } else { mul = 1.0f; }
add = 0.0f; }
float invDiv = ATAN2_DIM_MINUS_1 / ((x < y) ? y : x);
int xi = (int) (x * invDiv); int yi = (int) (y * invDiv);
return (atan2[yi * ATAN2_DIM + xi] + add) * mul; }
private static final int ATAN2_BITS = 7;
private static final int ATAN2_BITS2 = ATAN2_BITS << 1; private static final int ATAN2_MASK = ~(-1 << ATAN2_BITS2); private static final int ATAN2_COUNT = ATAN2_MASK + 1; private static final int ATAN2_DIM = (int) Math.sqrt(ATAN2_COUNT);
private static final float ATAN2_DIM_MINUS_1 = (ATAN2_DIM - 1);
private static final float[] atan2 = new float[ATAN2_COUNT];
static { for (int i = 0; i < ATAN2_DIM; i++) { for (int j = 0; j < ATAN2_DIM; j++) { float x0 = (float) i / ATAN2_DIM; float y0 = (float) j / ATAN2_DIM;
atan2[j * ATAN2_DIM + i] = (float) Math.atan2(y0, x0); } } } |