box2dLight.Spinor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of box2dlights Show documentation
Show all versions of box2dlights Show documentation
2D real-time lighting using box2d
package box2dLight;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.utils.StringBuilder;
public class Spinor {
float real;
float complex;
private static final float COSINE_THRESHOLD = 0.001f;
public Spinor() {
}
public Spinor(float angle) {
set(angle);
}
public Spinor(Spinor copyFrom) {
set(copyFrom);
}
public Spinor(float real, float complex) {
set(real, complex);
}
public Spinor set(float angle) {
angle /= 2;
set((float) Math.cos(angle), (float) Math.sin(angle));
return this;
}
public Spinor set(Spinor copyFrom) {
set(copyFrom.real, copyFrom.complex);
return this;
}
public Spinor set(float real, float complex) {
this.real = real;
this.complex = complex;
return this;
}
public Spinor scale(float t) {
real *= t;
complex *= t;
return this;
}
public Spinor invert() {
complex = -complex;
scale(len2());
return this;
}
public Spinor add(Spinor other) {
real += other.real;
complex += other.complex;
return this;
}
public Spinor add(float angle) {
angle /= 2;
real += Math.cos(angle);
complex += Math.sin(angle);
return this;
}
public Spinor sub(Spinor other) {
real -= other.real;
complex -= other.complex;
return this;
}
public Spinor sub(float angle) {
angle /= 2;
real -= Math.cos(angle);
complex -= Math.sin(angle);
return this;
}
public float len() {
return (float) Math.sqrt(real * real + complex * complex);
}
public float len2() {
return real * real + complex * complex;
}
public Spinor mul(Spinor other) {
set(real * other.real - complex * other.complex, real * other.complex
+ complex * other.real);
return this;
}
public Spinor nor() {
float length = len();
real /= length;
complex /= length;
return this;
}
public float angle() {
return (float) Math.atan2(complex, real) * 2;
}
public Spinor lerp(Spinor end, float alpha, Spinor tmp) {
scale(1 - alpha);
tmp.set(end).scale(alpha);
add(tmp);
nor();
return this;
}
public Spinor slerp(Spinor dest, float t) {
float tr, tc, omega, cosom, sinom, scale0, scale1;
// cosine
cosom = real * dest.real + complex * dest.complex;
// adjust signs
if (cosom < 0) {
cosom = -cosom;
tc = -dest.complex;
tr = -dest.real;
} else {
tc = dest.complex;
tr = dest.real;
}
// coefficients
if (1f - cosom > COSINE_THRESHOLD) {
omega = (float) Math.acos(cosom);
sinom = (float) Math.sin(omega);
scale0 = (float) Math.sin((1f - t) * omega) / sinom;
scale1 = (float) Math.sin(t * omega) / sinom;
} else {
scale0 = 1f - t;
scale1 = t;
}
// final calculation
complex = scale0 * complex + scale1 * tc;
real = scale0 * real + scale1 * tr;
return this;
}
@Override public String toString() {
StringBuilder result = new StringBuilder();
float radians = angle();
result.append("radians: ");
result.append(radians);
result.append(", degrees: ");
result.append(radians * MathUtils.radiansToDegrees);
return result.toString();
}
}