com.brashmonkey.spriter.Calculator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of overlap2d-runtime-libgdx Show documentation
Show all versions of overlap2d-runtime-libgdx Show documentation
overlap2d-runtime-libgdx provides functionality to load, manipulate and render scenes generated by Overlap2D.
package com.brashmonkey.spriter;
import static java.lang.Math.*;
/**
* A utility class which provides methods to calculate Spriter specific issues,
* like linear interpolation and rotation around a parent object.
* Other interpolation types are coming with the next releases of Spriter.
*
* @author Trixt0r
*
*/
public class Calculator {
public final static float PI = (float)Math.PI;
/**
* Calculates the smallest difference between angle a and b.
* @param a first angle (in degrees)
* @param b second angle (in degrees)
* @return Smallest difference between a and b (between 180? and -180?).
*/
public static float angleDifference(float a, float b){
return ((((a - b) % 360) + 540) % 360) - 180;
}
/**
* @param x1 x coordinate of first point.
* @param y1 y coordinate of first point.
* @param x2 x coordinate of second point.
* @param y2 y coordinate of second point.
* @return Angle between the two given points.
*/
public static float angleBetween(float x1, float y1, float x2, float y2){
return (float)toDegrees(atan2(y2-y1,x2-x1));
}
/**
* @param x1 x coordinate of first point.
* @param y1 y coordinate of first point.
* @param x2 x coordinate of second point.
* @param y2 y coordinate of second point.
* @return Distance between the two given points.
*/
public static float distanceBetween(float x1, float y1, float x2, float y2){
float xDiff = x2-x1;
float yDiff = y2-y1;
return (float)sqrt(xDiff*xDiff+yDiff*yDiff);
}
/**
* Solves the equation a*x^3 + b*x^2 + c*x +d = 0.
* @param a
* @param b
* @param c
* @param d
* @return the solution of the cubic function
*/
public static Float solveCubic(float a, float b, float c, float d) {
if (a == 0) return solveQuadratic(b, c, d);
if (d == 0) return 0f;
b /= a;
c /= a;
d /= a;
float squaredB = squared(b);
float q = (3f * c - squaredB) / 9f;
float r = (-27f * d + b * (9f * c - 2f * squaredB)) / 54f;
float disc = cubed(q) + squared(r);
float term1 = b / 3f;
if (disc > 0) {
float s = r + sqrt(disc);
s = (s < 0) ? -cubicRoot(-s) : cubicRoot(s);
float t = r - sqrt(disc);
t = (t < 0) ? -cubicRoot(-t) : cubicRoot(t);
float result = -term1 + s + t;
if (result >= 0 && result <= 1) return result;
} else if (disc == 0) {
float r13 = (r < 0) ? -cubicRoot(-r) : cubicRoot(r);
float result = -term1 + 2f * r13;
if (result >= 0 && result <= 1) return result;
result = -(r13 + term1);
if (result >= 0 && result <= 1) return result;
} else {
q = -q;
float dum1 = q * q * q;
dum1 = acos(r / sqrt(dum1));
float r13 = 2f * sqrt(q);
float result = -term1 + r13 * cos(dum1 / 3f);
if (result >= 0 && result <= 1) return result;
result = -term1 + r13 * cos((dum1 + 2f * PI) / 3f);
if (result >= 0 && result <= 1) return result;
result = -term1 + r13 * cos((dum1 + 4f * PI) / 3f);
if (result >= 0 && result <= 1) return result;
}
return null;
}
/**
* Solves the equation a*x^2 + b*x + c = 0
* @param a
* @param b
* @param c
* @return the solution for the quadratic function
*/
public static Float solveQuadratic(float a, float b, float c) {
float squaredB = squared(b);
float twoA = 2 * a;
float fourAC = 4 * a * c;
float result = (-b + sqrt(squaredB - fourAC)) / twoA;
if (result >= 0 && result <= 1) return result;
result = (-b - sqrt(squaredB - fourAC)) / twoA;
if (result >= 0 && result <= 1) return result;
return null;
}
/**
* Returns the square of the given value.
* @param f the value
* @return the square of the value
*/
public static float squared(float f) { return f * f; }
/**
* Returns the cubed value of the given one.
* @param f the value
* @return the cubed value
*/
public static float cubed(float f) { return f * f * f; }
/**
* Returns the cubic root of the given value.
* @param f the value
* @return the cubic root
*/
public static float cubicRoot(float f) { return (float) pow(f, 1f / 3f); }
/**
* Returns the square root of the given value.
* @param x the value
* @return the square root
*/
public static float sqrt(float x){ return (float)Math.sqrt(x); }
/**
* Returns the arc cosine at the given value.
* @param x the value
* @return the arc cosine
*/
public static float acos(float x){ return (float)Math.acos(x); }
static private final int SIN_BITS = 14; // 16KB. Adjust for accuracy.
static private final int SIN_MASK = ~(-1 << SIN_BITS);
static private final int SIN_COUNT = SIN_MASK + 1;
static private final float radFull = PI * 2;
static private final float degFull = 360;
static private final float radToIndex = SIN_COUNT / radFull;
static private final float degToIndex = SIN_COUNT / degFull;
/** multiply by this to convert from radians to degrees */
static public final float radiansToDegrees = 180f / PI;
static public final float radDeg = radiansToDegrees;
/** multiply by this to convert from degrees to radians */
static public final float degreesToRadians = PI / 180;
static public final float degRad = degreesToRadians;
static private class Sin {
static final float[] table = new float[SIN_COUNT];
static {
for (int i = 0; i < SIN_COUNT; i++)
table[i] = (float)Math.sin((i + 0.5f) / SIN_COUNT * radFull);
for (int i = 0; i < 360; i += 90)
table[(int)(i * degToIndex) & SIN_MASK] = (float)Math.sin(i * degreesToRadians);
}
}
/** Returns the sine in radians from a lookup table. */
static public final float sin (float radians) {
return Sin.table[(int)(radians * radToIndex) & SIN_MASK];
}
/** Returns the cosine in radians from a lookup table. */
static public final float cos (float radians) {
return Sin.table[(int)((radians + PI / 2) * radToIndex) & SIN_MASK];
}
/** Returns the sine in radians from a lookup table. */
static public final float sinDeg (float degrees) {
return Sin.table[(int)(degrees * degToIndex) & SIN_MASK];
}
/** Returns the cosine in radians from a lookup table. */
static public final float cosDeg (float degrees) {
return Sin.table[(int)((degrees + 90) * degToIndex) & SIN_MASK];
}
}