/**
* Copyright (c) 25/feb/2015 Davide Cossu & Matthew Albrecht.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 3 of the License, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, see <http://www.gnu.org/licenses>.
*/
package com.minestellar.utils;
import java.util.Random;
/**
* Contains various math-related helper functions. Often faster than conventional implementations.
*
* @author King Lemming
*
*/
public final class MathHelper {
private MathHelper() {
}
public static final Random RANDOM = new Random();
public static final double PHI = 1.618034;
public static final double[] SIN_TABLE = new double[65536];
static {
for (int i = 0; i < 65536; i++) {
SIN_TABLE[i] = Math.sin(i / 65536D * 2 * Math.PI);
}
SIN_TABLE[0] = 0;
SIN_TABLE[16384] = 1;
SIN_TABLE[32768] = 0;
SIN_TABLE[49152] = 1;
}
public static double sin(double d) {
return SIN_TABLE[(int) ((float) d * 10430.378F) & 65535];
}
public static double cos(double d) {
return SIN_TABLE[(int) ((float) d * 10430.378F + 16384.0F) & 65535];
}
public static int clampI(int a, int min, int max) {
return a < min ? min : (a > max ? max : a);
}
public static float clampF(float a, float min, float max) {
return a < min ? min : (a > max ? max : a);
}
public static float approachLinear(float a, float b, float max) {
return a > b ? a - b < max ? b : a - max : b - a < max ? b : a + max;
}
public static double approachLinear(double a, double b, double max) {
return a > b ? a - b < max ? b : a - max : b - a < max ? b : a + max;
}
public static float interpolate(float a, float b, float d) {
return a + (b - a) * d;
}
public static double interpolate(double a, double b, double d) {
return a + (b - a) * d;
}
public static double approachExp(double a, double b, double ratio) {
return a + (b - a) * ratio;
}
public static double approachExp(double a, double b, double ratio, double cap) {
double d = (b - a) * ratio;
if (Math.abs(d) > cap) {
d = Math.signum(d) * cap;
}
return a + d;
}
public static double retreatExp(double a, double b, double c, double ratio, double kick) {
double d = (Math.abs(c - a) + kick) * ratio;
if (d > Math.abs(b - a)) {
return b;
}
return a + Math.signum(b - a) * d;
}
public static double clip(double value, double min, double max) {
if (value > max) {
value = max;
} else if (value < min) {
value = min;
}
return value;
}
public static boolean between(double a, double x, double b) {
return a <= x && x <= b;
}
public static int approachExpI(int a, int b, double ratio) {
int r = (int) Math.round(approachExp(a, b, ratio));
return r == a ? b : r;
}
public static int retreatExpI(int a, int b, int c, double ratio, int kick) {
int r = (int) Math.round(retreatExp(a, b, c, ratio, kick));
return r == a ? b : r;
}
/**
* Unchecked implementation to round a number. Parameter should be known to be valid in advance.
*/
public static int round(double d) {
return (int) (d + 0.5D);
}
/**
* Unchecked implementation to round a number up. Parameter should be known to be valid in advance.
*/
public static int ceil(double d) {
return (int) (d + 0.9999D);
}
/**
* Unchecked implementation to round a number down. Parameter should be known to be valid in advance.
*/
public static int floor(double d) {
int i = (int) d;
return d < i ? i - 1 : i;
}
/**
* Unchecked implementation to determine the smaller of two Floats. Parameters should be known to be valid in advance.
*/
public static float minF(float a, float b) {
return a < b ? a : b;
}
public static float minF(int a, float b) {
return a < b ? a : b;
}
public static float minF(float a, int b) {
return a < b ? a : b;
}
/**
* Unchecked implementation to determine the larger of two Floats. Parameters should be known to be valid in advance.
*/
public static float maxF(float a, float b) {
return a > b ? a : b;
}
public static float maxF(int a, float b) {
return a > b ? a : b;
}
public static float maxF(float a, int b) {
return a > b ? a : b;
}
public static double maxAbs(double a, double b) {
if (a < 0.0D) {
a = -a;
}
if (b < 0.0D) {
b = -b;
}
return a > b ? a : b;
}
public static int setBit(int mask, int bit, boolean value) {
mask |= (value ? 1 : 0) << bit;
return mask;
}
public static boolean isBitSet(int mask, int bit) {
return (mask & 1 << bit) != 0;
}
}