285 lines
8.1 KiB
Java
285 lines
8.1 KiB
Java
package eu.univento.commons.utils;
|
|
|
|
import java.util.Calendar;
|
|
import java.util.GregorianCalendar;
|
|
import java.util.Random;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
/**
|
|
* @author joethei
|
|
* @version 1.5
|
|
*/
|
|
|
|
final class Maths {
|
|
public static final float nanoToSec = 1.0E-009F;
|
|
public static final float FLOAT_ROUNDING_ERROR = 1.0E-006F;
|
|
public static final float PI = 3.141593F;
|
|
public static final float PI2 = 6.283186F;
|
|
public static final float SQRT_3 = 1.73205F;
|
|
public static final float E = 2.718282F;
|
|
public static final float radiansToDegrees = 57.295776F;
|
|
public static final float radDeg = 57.295776F;
|
|
public static final float degreesToRadians = 0.01745329F;
|
|
public static final float degRad = 0.01745329F;
|
|
private static final int ATAN2_DIM = (int)Math.sqrt(16384.0D);
|
|
private static final float INV_ATAN2_DIM_MINUS_1 = 1.0F / (ATAN2_DIM - 1);
|
|
|
|
private static final Random random = new Random();
|
|
|
|
public static float sin(float radians) {
|
|
return Sin.table[((int)(radians * 2607.5945F) & 0x3FFF)];
|
|
}
|
|
|
|
public static float cos(float radians)
|
|
{
|
|
return Sin.table[((int)((radians + 1.570796F) * 2607.5945F) & 0x3FFF)];
|
|
}
|
|
|
|
public static float sinDeg(float degrees)
|
|
{
|
|
return Sin.table[((int)(degrees * 45.511112F) & 0x3FFF)];
|
|
}
|
|
|
|
public static float cosDeg(float degrees)
|
|
{
|
|
return Sin.table[((int)((degrees + 90.0F) * 45.511112F) & 0x3FFF)];
|
|
}
|
|
|
|
public static float atan2(float y, float x)
|
|
{
|
|
float mul;
|
|
float add;
|
|
if (x < 0.0F)
|
|
{
|
|
if (y < 0.0F) {
|
|
y = -y;
|
|
mul = 1.0F;
|
|
} else {
|
|
mul = -1.0F;
|
|
}x = -x;
|
|
add = -3.141593F;
|
|
}
|
|
else
|
|
{
|
|
if (y < 0.0F) {
|
|
y = -y;
|
|
mul = -1.0F;
|
|
} else {
|
|
mul = 1.0F;
|
|
}add = 0.0F;
|
|
}
|
|
float invDiv = 1.0F / ((x < y ? y : x) * INV_ATAN2_DIM_MINUS_1);
|
|
|
|
if (invDiv == 1.0F) return ((float)Math.atan2(y, x) + add) * mul;
|
|
|
|
int xi = (int)(x * invDiv);
|
|
int yi = (int)(y * invDiv);
|
|
return (Atan2.table[(yi * ATAN2_DIM + xi)] + add) * mul;
|
|
}
|
|
|
|
public static int random(int range)
|
|
{
|
|
return random.nextInt(range + 1);
|
|
}
|
|
|
|
public static int random(int start, int end)
|
|
{
|
|
return start + random.nextInt(end - start + 1);
|
|
}
|
|
|
|
public static boolean randomBoolean()
|
|
{
|
|
return random.nextBoolean();
|
|
}
|
|
|
|
public static boolean randomBoolean(float chance)
|
|
{
|
|
return random() < chance;
|
|
}
|
|
|
|
private static float random()
|
|
{
|
|
return random.nextFloat();
|
|
}
|
|
|
|
public static float random(float range)
|
|
{
|
|
return random.nextFloat() * range;
|
|
}
|
|
|
|
public static float random(float start, float end)
|
|
{
|
|
return start + random.nextFloat() * (end - start);
|
|
}
|
|
|
|
public static int nextPowerOfTwo(int value)
|
|
{
|
|
if (value == 0) return 1;
|
|
value--;
|
|
value |= value >> 1;
|
|
value |= value >> 2;
|
|
value |= value >> 4;
|
|
value |= value >> 8;
|
|
value |= value >> 16;
|
|
return value + 1;
|
|
}
|
|
|
|
public static boolean isPowerOfTwo(int value) {
|
|
return (value != 0) && ((value & value - 1) == 0);
|
|
}
|
|
|
|
public static int clamp(int value, int min, int max)
|
|
{
|
|
if (value < min) return min;
|
|
if (value > max) return max;
|
|
return value;
|
|
}
|
|
|
|
public static short clamp(short value, short min, short max) {
|
|
if (value < min) return min;
|
|
if (value > max) return max;
|
|
return value;
|
|
}
|
|
|
|
public static float clamp(float value, float min, float max) {
|
|
if (value < min) return min;
|
|
if (value > max) return max;
|
|
return value;
|
|
}
|
|
|
|
public static int floor(float x)
|
|
{
|
|
return (int)(x + 16384.0D) - 16384;
|
|
}
|
|
|
|
public static int floorPositive(float x)
|
|
{
|
|
return (int)x;
|
|
}
|
|
|
|
public static int ceil(float x)
|
|
{
|
|
return (int)(x + 16384.999999999996D) - 16384;
|
|
}
|
|
|
|
public static int ceilPositive(float x)
|
|
{
|
|
return (int)(x + 0.9999999000000001D);
|
|
}
|
|
|
|
public static int round(float x)
|
|
{
|
|
return (int)(x + 16384.5D) - 16384;
|
|
}
|
|
|
|
public static int roundPositive(float x)
|
|
{
|
|
return (int)(x + 0.5F);
|
|
}
|
|
|
|
public static boolean isZero(float value)
|
|
{
|
|
return Math.abs(value) <= 1.0E-006F;
|
|
}
|
|
|
|
public static boolean isZero(float value, float tolerance)
|
|
{
|
|
return Math.abs(value) <= tolerance;
|
|
}
|
|
|
|
public static boolean isEqual(float a, float b)
|
|
{
|
|
return Math.abs(a - b) <= 1.0E-006F;
|
|
}
|
|
|
|
public static boolean isEqual(float a, float b, float tolerance)
|
|
{
|
|
return Math.abs(a - b) <= tolerance;
|
|
}
|
|
|
|
public static long parseDateDiff(String time, boolean future)
|
|
throws Exception
|
|
{
|
|
Pattern timePattern = Pattern.compile("(?:([0-9]+)\\s*y[a-z]*[,\\s]*)?(?:([0-9]+)\\s*mo[a-z]*[,\\s]*)?(?:([0-9]+)\\s*w[a-z]*[,\\s]*)?(?:([0-9]+)\\s*d[a-z]*[,\\s]*)?(?:([0-9]+)\\s*h[a-z]*[,\\s]*)?(?:([0-9]+)\\s*m[a-z]*[,\\s]*)?(?:([0-9]+)\\s*(?:s[a-z]*)?)?", 2);
|
|
Matcher m = timePattern.matcher(time);
|
|
int years = 0;
|
|
int months = 0;
|
|
int weeks = 0;
|
|
int days = 0;
|
|
int hours = 0;
|
|
int minutes = 0;
|
|
int seconds = 0;
|
|
boolean found = false;
|
|
while (m.find()) {
|
|
if ((m.group() == null) || (m.group().isEmpty())) {
|
|
continue;
|
|
}
|
|
for (int i = 0; i < m.groupCount(); i++) {
|
|
if ((m.group(i) != null) && (!m.group(i).isEmpty())) {
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (found) {
|
|
if ((m.group(1) != null) && (!m.group(1).isEmpty()))
|
|
years = Integer.parseInt(m.group(1));
|
|
if ((m.group(2) != null) && (!m.group(2).isEmpty()))
|
|
months = Integer.parseInt(m.group(2));
|
|
if ((m.group(3) != null) && (!m.group(3).isEmpty()))
|
|
weeks = Integer.parseInt(m.group(3));
|
|
if ((m.group(4) != null) && (!m.group(4).isEmpty()))
|
|
days = Integer.parseInt(m.group(4));
|
|
if ((m.group(5) != null) && (!m.group(5).isEmpty()))
|
|
hours = Integer.parseInt(m.group(5));
|
|
if ((m.group(6) != null) && (!m.group(6).isEmpty()))
|
|
minutes = Integer.parseInt(m.group(6));
|
|
if ((m.group(7) == null) || (m.group(7).isEmpty())) break;
|
|
seconds = Integer.parseInt(m.group(7));
|
|
break;
|
|
}
|
|
}
|
|
if (!found)
|
|
throw new Exception("Illegal Date");
|
|
Calendar c = new GregorianCalendar();
|
|
if (years > 0)
|
|
c.add(1, years * (future ? 1 : -1));
|
|
if (months > 0)
|
|
c.add(2, months * (future ? 1 : -1));
|
|
if (weeks > 0)
|
|
c.add(3, weeks * (future ? 1 : -1));
|
|
if (days > 0)
|
|
c.add(5, days * (future ? 1 : -1));
|
|
if (hours > 0)
|
|
c.add(11, hours * (future ? 1 : -1));
|
|
if (minutes > 0)
|
|
c.add(12, minutes * (future ? 1 : -1));
|
|
if (seconds > 0)
|
|
c.add(13, seconds * (future ? 1 : -1));
|
|
return c.getTimeInMillis();
|
|
}
|
|
|
|
private static class Atan2
|
|
{
|
|
static final float[] table = new float[16384];
|
|
|
|
static { for (int i = 0; i < Maths.ATAN2_DIM; i++)
|
|
for (int j = 0; j < Maths.ATAN2_DIM; j++) {
|
|
float x0 = i / Maths.ATAN2_DIM;
|
|
float y0 = j / Maths.ATAN2_DIM;
|
|
table[(j * Maths.ATAN2_DIM + i)] = (float)Math.atan2(y0, x0);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static class Sin
|
|
{
|
|
static final float[] table = new float[16384];
|
|
|
|
static { for (int i = 0; i < 16384; i++)
|
|
table[i] = (float)Math.sin((i + 0.5F) / 16384.0F * 6.283186F);
|
|
for (int i = 0; i < 360; i += 90)
|
|
table[((int)(i * 45.511112F) & 0x3FFF)] = (float)Math.sin(i * 0.01745329F);
|
|
}
|
|
}
|
|
} |