115 lines
3.8 KiB
Java
115 lines
3.8 KiB
Java
package com.hypixel.hytale.math.util;
|
|
|
|
import javax.annotation.Nonnull;
|
|
|
|
public class TrigMathUtil {
|
|
public static final float PI = (float) Math.PI;
|
|
public static final float PI_HALF = (float) (Math.PI / 2);
|
|
public static final float PI_QUARTER = (float) (Math.PI / 4);
|
|
public static final float PI2 = (float) (Math.PI * 2);
|
|
public static final float PI4 = (float) (Math.PI * 4);
|
|
public static final float radToDeg = 180.0F / (float)Math.PI;
|
|
public static final float degToRad = (float) (Math.PI / 180.0);
|
|
|
|
public static float sin(float radians) {
|
|
return TrigMathUtil.Riven.sin(radians);
|
|
}
|
|
|
|
public static float cos(float radians) {
|
|
return TrigMathUtil.Riven.cos(radians);
|
|
}
|
|
|
|
public static float sin(double radians) {
|
|
return TrigMathUtil.Riven.sin((float)radians);
|
|
}
|
|
|
|
public static float cos(double radians) {
|
|
return TrigMathUtil.Riven.cos((float)radians);
|
|
}
|
|
|
|
public static float atan2(float y, float x) {
|
|
return TrigMathUtil.Icecore.atan2(y, x);
|
|
}
|
|
|
|
public static float atan2(double y, double x) {
|
|
return TrigMathUtil.Icecore.atan2((float)y, (float)x);
|
|
}
|
|
|
|
public static float atan(double d) {
|
|
return (float)Math.atan(d);
|
|
}
|
|
|
|
public static float asin(double d) {
|
|
return (float)Math.asin(d);
|
|
}
|
|
|
|
private TrigMathUtil() {
|
|
}
|
|
|
|
private static final class Icecore {
|
|
private static final int SIZE_AC = 100000;
|
|
private static final int SIZE_AR = 100001;
|
|
private static final float[] ATAN2 = new float[100001];
|
|
|
|
public static float atan2(float y, float x) {
|
|
if (y < 0.0F) {
|
|
if (x < 0.0F) {
|
|
return y < x ? -ATAN2[(int)(x / y * 100000.0F)] - (float) (Math.PI / 2) : ATAN2[(int)(y / x * 100000.0F)] - (float) Math.PI;
|
|
} else {
|
|
y = -y;
|
|
return y > x ? ATAN2[(int)(x / y * 100000.0F)] - (float) (Math.PI / 2) : -ATAN2[(int)(y / x * 100000.0F)];
|
|
}
|
|
} else if (x < 0.0F) {
|
|
x = -x;
|
|
return y > x ? ATAN2[(int)(x / y * 100000.0F)] + (float) (Math.PI / 2) : -ATAN2[(int)(y / x * 100000.0F)] + (float) Math.PI;
|
|
} else {
|
|
return y > x ? -ATAN2[(int)(x / y * 100000.0F)] + (float) (Math.PI / 2) : ATAN2[(int)(y / x * 100000.0F)];
|
|
}
|
|
}
|
|
|
|
static {
|
|
for (int i = 0; i <= 100000; i++) {
|
|
double d = i / 100000.0;
|
|
double x = 1.0;
|
|
double y = x * d;
|
|
float v = (float)Math.atan2(y, x);
|
|
ATAN2[i] = v;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static final class Riven {
|
|
private static final int SIN_BITS = 12;
|
|
private static final int SIN_MASK = ~(-1 << SIN_BITS);
|
|
private static final int SIN_COUNT = SIN_MASK + 1;
|
|
private static final float radFull = (float) (Math.PI * 2);
|
|
private static final float radToIndex = SIN_COUNT / radFull;
|
|
private static final float degFull = 360.0F;
|
|
private static final float degToIndex = SIN_COUNT / degFull;
|
|
@Nonnull
|
|
private static final float[] SIN = new float[SIN_COUNT];
|
|
@Nonnull
|
|
private static final float[] COS = new float[SIN_COUNT];
|
|
|
|
public static float sin(float rad) {
|
|
return SIN[(int)(rad * radToIndex) & SIN_MASK];
|
|
}
|
|
|
|
public static float cos(float rad) {
|
|
return COS[(int)(rad * radToIndex) & SIN_MASK];
|
|
}
|
|
|
|
static {
|
|
for (int i = 0; i < SIN_COUNT; i++) {
|
|
SIN[i] = (float)Math.sin((i + 0.5F) / SIN_COUNT * radFull);
|
|
COS[i] = (float)Math.cos((i + 0.5F) / SIN_COUNT * radFull);
|
|
}
|
|
|
|
for (int i = 0; i < 360; i += 90) {
|
|
SIN[(int)(i * degToIndex) & SIN_MASK] = (float)Math.sin(i * Math.PI / 180.0);
|
|
COS[(int)(i * degToIndex) & SIN_MASK] = (float)Math.cos(i * Math.PI / 180.0);
|
|
}
|
|
}
|
|
}
|
|
}
|