/**
* Copyright (c) Lambda Innovation, 2013-2015
* 本作品版权由Lambda Innovation所有。
* http://www.li-dev.cn/
*
* This project is open-source, and it is distributed under
* the terms of GNU General Public License. You can modify
* and distribute freely as long as you follow the license.
* 本项目是一个开源项目,且遵循GNU通用公共授权协议。
* 在遵照该协议的情况下,您可以自由传播和修改。
* http://www.gnu.org/licenses/gpl.html
*/
package cn.liutils.util.generic;
import net.minecraft.util.Vec3;
/**
* @author WeAthFolD
*
*/
public class MathUtils {
public static final float PI_F = (float) Math.PI;
public static float wrapYawAngle(float a) {
float ret = a % 360f;
return ret < 0 ? ret + 360f : ret;
}
public static double toRadians(double angle) {
return angle * Math.PI / 180;
}
public static float toRadians(float angle) {
return angle * PI_F / 180;
}
public static double toAngle(double rad) {
return rad * 180 / Math.PI;
}
public static float toAngle(float rad) {
return rad * 180 / PI_F;
}
/**
* Return whether a -180~180 wrapped yaw angle is in the range denoted by [start, end].
* Note that this is not a simple range comparison. If the arc of the angle is in the
* range sweeped from start to end clockwisely, then the result is true.
*/
public static boolean angleYawinRange(float start, float end, float angle) {
if(end < start)
return false;
if(end - start >= 360f)
return true;
float ss = wrapYawAngle(start), se = wrapYawAngle(end), sa = wrapYawAngle(angle);
if(ss > se) {
return ss <= sa || sa <= se;
}
//System.out.println(ss + " " + se + " " + sa);
return ss <= sa && sa <= se;
}
/**
* Perform a simple linear lerp between a and b
* @param a
* @param b
* @param lambda The weight of b
* @return The lerp value
*/
public static double lerp(double a, double b, double lambda) {
return a * (1 - lambda) + b * lambda;
}
public static float lerpf(float a, float b, float lambda) {
return a * (1 - lambda) + b * lambda;
}
public static int wrapi(int min, int max, int val) {
return Math.max(min, Math.min(max, val));
}
public static double wrapd(double min, double max, double val) {
if(val > max)
return max;
if(val < min)
return min;
return val;
}
public static float wrapf(float min, float max, float val) {
if(val > max)
return max;
if(val < min)
return min;
return val;
}
public static double distanceSq(double[] vec1, double[] vec2) {
if(vec1.length != vec2.length) {
throw new RuntimeException("Inconsistent length");
}
double ret = 0.0;
for(int i = 0; i < vec1.length; ++i) {
double d = vec2[i] - vec1[i];
ret += d * d;
}
return ret;
}
public static double distance(double x0, double y0, double z0, double x1, double y1, double z1) {
return Math.sqrt(distanceSq(x0, y0, z0, x1, y1, z1));
}
public static double distanceSq(double x0, double y0, double z0, double x1, double y1, double z1) {
return distanceSq(new double[] { x0, y0, z0 }, new double[] { x1, y1, z1 });
}
public static double distance(double[] vec1, double[] vec2) {
return Math.sqrt(distanceSq(vec1, vec2));
}
public static Vec3 multiply(Vec3 vec, double factor) {
return Vec3.createVectorHelper(vec.xCoord * factor, vec.yCoord * factor, vec.zCoord * factor);
}
public static double length(double dx, double dy, double dz) {
return Math.sqrt(dx * dx + dy * dy + dz * dz);
}
public static double lengthSq(double dx, double dy, double dz) {
return dx * dx + dy * dy + dz * dz;
}
}