Some package shifting. Alpha stack now toggleable.
This commit is contained in:
@@ -6,7 +6,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import mightypork.util.math.constraints.vect.Vect;
|
||||
import mightypork.util.constraints.vect.Vect;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package mightypork.util.math;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.vect.Vect;
|
||||
import mightypork.util.constraints.vect.Vect;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,8 +4,8 @@ package mightypork.util.math.color;
|
||||
import java.util.Stack;
|
||||
|
||||
import mightypork.util.annotations.FactoryMethod;
|
||||
import mightypork.util.constraints.num.Num;
|
||||
import mightypork.util.math.Calc;
|
||||
import mightypork.util.math.constraints.num.Num;
|
||||
|
||||
|
||||
/**
|
||||
@@ -36,7 +36,8 @@ public abstract class Color {
|
||||
public static final Color ORANGE = rgb(1, 0.78, 0);
|
||||
public static final Color PINK = rgb(1, 0.68, 0.68);
|
||||
|
||||
private static final Stack<Num> globalAlphaStack = new Stack<>();
|
||||
private static final Stack<Num> alphaStack = new Stack<>();
|
||||
private static volatile boolean alphaStackEnabled = true;
|
||||
|
||||
|
||||
@FactoryMethod
|
||||
@@ -160,8 +161,11 @@ public abstract class Color {
|
||||
{
|
||||
double alpha = rawAlpha();
|
||||
|
||||
for (Num n : globalAlphaStack) {
|
||||
alpha *= clamp(n.value());
|
||||
if (alphaStackEnabled) {
|
||||
|
||||
for (Num n : alphaStack) {
|
||||
alpha *= clamp(n.value());
|
||||
}
|
||||
}
|
||||
|
||||
return clamp(alpha);
|
||||
@@ -190,7 +194,11 @@ public abstract class Color {
|
||||
*/
|
||||
public static void pushAlpha(Num alpha)
|
||||
{
|
||||
globalAlphaStack.push(alpha);
|
||||
if (!alphaStackEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
alphaStack.push(alpha);
|
||||
}
|
||||
|
||||
|
||||
@@ -198,15 +206,39 @@ public abstract class Color {
|
||||
* Remove a pushed alpha multiplier from the stack. If there's no remaining
|
||||
* multiplier on the stack, an exception is raised.
|
||||
*
|
||||
* @return the popped multiplier
|
||||
* @throws IllegalStateException if the stack is empty
|
||||
*/
|
||||
public static Num popAlpha()
|
||||
public static void popAlpha()
|
||||
{
|
||||
if (globalAlphaStack.isEmpty()) {
|
||||
if (!alphaStackEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (alphaStack.isEmpty()) {
|
||||
throw new IllegalStateException("Global alpha stack underflow.");
|
||||
}
|
||||
|
||||
return globalAlphaStack.pop();
|
||||
alphaStack.pop();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Enable alpha stack. When disabled, pushAlpha() and popAlpha() have no
|
||||
* effect.
|
||||
*
|
||||
* @param yes
|
||||
*/
|
||||
public static void enableAlphaStack(boolean yes)
|
||||
{
|
||||
alphaStackEnabled = yes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true if alpha stack is enabled.
|
||||
*/
|
||||
public static boolean isAlphaStackEnabled()
|
||||
{
|
||||
return alphaStackEnabled;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package mightypork.util.math.color;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.num.Num;
|
||||
import mightypork.util.constraints.num.Num;
|
||||
|
||||
|
||||
public class ColorHsb extends Color {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package mightypork.util.math.color;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.num.Num;
|
||||
import mightypork.util.constraints.num.Num;
|
||||
|
||||
|
||||
public class ColorRgb extends Color {
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
package mightypork.util.math.constraints;
|
||||
|
||||
|
||||
/**
|
||||
* Constraint cache
|
||||
*
|
||||
* @author MightyPork
|
||||
* @param <C> constraint type
|
||||
*/
|
||||
public interface ConstraintCache<C> extends Pollable {
|
||||
|
||||
/**
|
||||
* Called after the cache has changed value (and digest).
|
||||
*/
|
||||
void onChange();
|
||||
|
||||
|
||||
/**
|
||||
* @return the cached value
|
||||
*/
|
||||
C getCacheSource();
|
||||
|
||||
|
||||
/**
|
||||
* Enable caching & digest caching
|
||||
*
|
||||
* @param yes enable caching
|
||||
*/
|
||||
void enableCaching(boolean yes);
|
||||
|
||||
|
||||
/**
|
||||
* @return true if caching is on
|
||||
*/
|
||||
boolean isCachingEnabled();
|
||||
|
||||
|
||||
/**
|
||||
* Update cached value and cached digest (if digest caching is enabled).<br>
|
||||
* source constraint is polled beforehand.
|
||||
*/
|
||||
@Override
|
||||
void poll();
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
package mightypork.util.math.constraints;
|
||||
|
||||
|
||||
/**
|
||||
* Parametrized implementation of a {@link Digestable}
|
||||
*
|
||||
* @author MightyPork
|
||||
* @param <D> digest class
|
||||
*/
|
||||
public abstract class DigestCache<D> implements Digestable<D> {
|
||||
|
||||
private D last_digest;
|
||||
private boolean caching_enabled;
|
||||
private boolean dirty = true;
|
||||
|
||||
|
||||
@Override
|
||||
public final D digest()
|
||||
{
|
||||
if (caching_enabled) {
|
||||
if (dirty || last_digest == null) {
|
||||
last_digest = createDigest();
|
||||
dirty = false;
|
||||
}
|
||||
|
||||
return last_digest;
|
||||
}
|
||||
|
||||
return createDigest();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return fresh new digest
|
||||
*/
|
||||
protected abstract D createDigest();
|
||||
|
||||
|
||||
@Override
|
||||
public final void enableDigestCaching(boolean yes)
|
||||
{
|
||||
caching_enabled = yes;
|
||||
markDigestDirty(); // mark dirty
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final boolean isDigestCachingEnabled()
|
||||
{
|
||||
return caching_enabled;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void markDigestDirty()
|
||||
{
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
package mightypork.util.math.constraints;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Interface for constraints that support digests. Digest is a small data object
|
||||
* with final fields, typically primitive, used for processing (such as
|
||||
* rendering or other very frequent operations).
|
||||
* </p>
|
||||
* <p>
|
||||
* Taking a digest is expensive, so if it needs to be done often and the value
|
||||
* changes are deterministic (such as, triggered by timing event or screen
|
||||
* resize), it's useful to cache the last digest and reuse it until such an
|
||||
* event occurs again.
|
||||
* </p>
|
||||
* <p>
|
||||
* Implementing class typically needs a field to store the last digest, a flag
|
||||
* that digest caching is enabled, and a flag that a digest is dirty.
|
||||
* </p>
|
||||
*
|
||||
* @author MightyPork
|
||||
* @param <D> digest class
|
||||
*/
|
||||
public interface Digestable<D> {
|
||||
|
||||
/**
|
||||
* Take a digest. If digest caching is enabled and the cached digest is
|
||||
* marked as dirty, a new one should be made.
|
||||
*
|
||||
* @return digest
|
||||
*/
|
||||
public D digest();
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Toggle digest caching.
|
||||
* </p>
|
||||
* <p>
|
||||
* To trigger update of the cache, call the <code>poll()</code> method.
|
||||
* </p>
|
||||
*
|
||||
* @param yes
|
||||
*/
|
||||
void enableDigestCaching(boolean yes);
|
||||
|
||||
|
||||
/**
|
||||
* @return true if digest caching is enabled.
|
||||
*/
|
||||
boolean isDigestCachingEnabled();
|
||||
|
||||
|
||||
/**
|
||||
* If digest caching is enabled, mark current cached value as "dirty". Dirty
|
||||
* digest should be re-created next time a value is requested.<br>
|
||||
*/
|
||||
void markDigestDirty();
|
||||
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package mightypork.util.math.constraints;
|
||||
|
||||
|
||||
/**
|
||||
* Can be asked to update it's state
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public interface Pollable {
|
||||
|
||||
/**
|
||||
* Update internal state
|
||||
*/
|
||||
void poll();
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package mightypork.util.math.constraints;
|
||||
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
/**
|
||||
* Used to poll a number of {@link Pollable}s
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class Poller implements Pollable {
|
||||
|
||||
private final Set<Pollable> pollables = new LinkedHashSet<>();
|
||||
|
||||
|
||||
/**
|
||||
* Add a pollable
|
||||
*
|
||||
* @param p pollable
|
||||
*/
|
||||
public void add(Pollable p)
|
||||
{
|
||||
pollables.add(p);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove a pollalbe
|
||||
*
|
||||
* @param p pollable
|
||||
*/
|
||||
public void remove(Pollable p)
|
||||
{
|
||||
pollables.remove(p);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void poll()
|
||||
{
|
||||
for (final Pollable p : pollables) {
|
||||
p.poll();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,750 +0,0 @@
|
||||
package mightypork.util.math.constraints.num;
|
||||
|
||||
|
||||
import mightypork.util.annotations.FactoryMethod;
|
||||
import mightypork.util.math.Calc;
|
||||
import mightypork.util.math.constraints.DigestCache;
|
||||
import mightypork.util.math.constraints.Digestable;
|
||||
import mightypork.util.math.constraints.num.caching.NumCache;
|
||||
import mightypork.util.math.constraints.num.caching.NumDigest;
|
||||
import mightypork.util.math.constraints.num.mutable.NumVar;
|
||||
import mightypork.util.math.constraints.num.proxy.NumBound;
|
||||
import mightypork.util.math.constraints.num.proxy.NumBoundAdapter;
|
||||
|
||||
|
||||
public abstract class Num implements NumBound, Digestable<NumDigest> {
|
||||
|
||||
public static final NumConst ZERO = Num.make(0);
|
||||
public static final NumConst ONE = Num.make(1);
|
||||
|
||||
|
||||
@FactoryMethod
|
||||
public static Num make(NumBound bound)
|
||||
{
|
||||
return new NumBoundAdapter(bound);
|
||||
}
|
||||
|
||||
|
||||
@FactoryMethod
|
||||
public static NumConst make(double value)
|
||||
{
|
||||
return new NumConst(value);
|
||||
}
|
||||
|
||||
|
||||
@FactoryMethod
|
||||
public static NumVar makeVar()
|
||||
{
|
||||
return makeVar(0);
|
||||
}
|
||||
|
||||
|
||||
@FactoryMethod
|
||||
public static NumVar makeVar(double value)
|
||||
{
|
||||
return new NumVar(value);
|
||||
}
|
||||
|
||||
|
||||
@FactoryMethod
|
||||
public static NumVar makeVar(Num copied)
|
||||
{
|
||||
return new NumVar(copied.value());
|
||||
}
|
||||
|
||||
private Num p_ceil;
|
||||
private Num p_floor;
|
||||
private Num p_sgn;
|
||||
private Num p_round;
|
||||
private Num p_atan;
|
||||
private Num p_acos;
|
||||
private Num p_asin;
|
||||
private Num p_tan;
|
||||
private Num p_cos;
|
||||
private Num p_sin;
|
||||
private Num p_cbrt;
|
||||
private Num p_sqrt;
|
||||
private Num p_cube;
|
||||
private Num p_square;
|
||||
private Num p_neg;
|
||||
private Num p_abs;
|
||||
|
||||
private DigestCache<NumDigest> dc = new DigestCache<NumDigest>() {
|
||||
|
||||
@Override
|
||||
protected NumDigest createDigest()
|
||||
{
|
||||
return new NumDigest(Num.this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public NumConst freeze()
|
||||
{
|
||||
return new NumConst(value());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wrap this constraint into a caching adapter. Value will stay fixed (ie.
|
||||
* no re-calculations) until cache receives a poll() call.
|
||||
*
|
||||
* @return the caching adapter
|
||||
*/
|
||||
public NumCache cached()
|
||||
{
|
||||
return new NumCache(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a snapshot of the current state, to be used for processing.
|
||||
*
|
||||
* @return digest
|
||||
*/
|
||||
|
||||
@Override
|
||||
public NumDigest digest()
|
||||
{
|
||||
return dc.digest();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void enableDigestCaching(boolean yes)
|
||||
{
|
||||
dc.enableDigestCaching(yes);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isDigestCachingEnabled()
|
||||
{
|
||||
return dc.isDigestCachingEnabled();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void markDigestDirty()
|
||||
{
|
||||
dc.markDigestDirty();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Num getNum()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the number
|
||||
*/
|
||||
public abstract double value();
|
||||
|
||||
|
||||
public Num add(final double addend)
|
||||
{
|
||||
return new Num() {
|
||||
|
||||
private final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return t.value() + addend;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public Num add(final Num addend)
|
||||
{
|
||||
return new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return t.value() + addend.value();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public Num sub(final double subtrahend)
|
||||
{
|
||||
return add(-subtrahend);
|
||||
}
|
||||
|
||||
|
||||
public Num abs()
|
||||
{
|
||||
if (p_abs == null) p_abs = new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return Math.abs(t.value());
|
||||
}
|
||||
};
|
||||
|
||||
return p_abs;
|
||||
}
|
||||
|
||||
|
||||
public Num sub(final Num subtrahend)
|
||||
{
|
||||
return new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return t.value() - subtrahend.value();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public Num div(final double factor)
|
||||
{
|
||||
return mul(1 / factor);
|
||||
}
|
||||
|
||||
|
||||
public Num div(final Num factor)
|
||||
{
|
||||
|
||||
return new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return t.value() / factor.value();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public Num mul(final double factor)
|
||||
{
|
||||
return new Num() {
|
||||
|
||||
private final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return t.value() * factor;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public Num mul(final Num factor)
|
||||
{
|
||||
|
||||
return new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return t.value() * factor.value();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public Num average(final double other)
|
||||
{
|
||||
return new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return (t.value() + other) / 2;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public Num average(final Num other)
|
||||
{
|
||||
return new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return (t.value() + other.value()) / 2;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public Num perc(final double percent)
|
||||
{
|
||||
return mul(percent / 100);
|
||||
}
|
||||
|
||||
|
||||
public Num perc(final Num percent)
|
||||
{
|
||||
return new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return t.value() * (percent.value() / 100);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public Num cos()
|
||||
{
|
||||
if (p_cos == null) p_cos = new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return Math.cos(t.value());
|
||||
}
|
||||
};
|
||||
|
||||
return p_cos;
|
||||
}
|
||||
|
||||
|
||||
public Num acos()
|
||||
{
|
||||
if (p_acos == null) p_acos = new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return Math.acos(t.value());
|
||||
}
|
||||
};
|
||||
|
||||
return p_acos;
|
||||
}
|
||||
|
||||
|
||||
public Num sin()
|
||||
{
|
||||
if (p_sin == null) p_sin = new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return Math.sin(t.value());
|
||||
}
|
||||
};
|
||||
|
||||
return p_sin;
|
||||
}
|
||||
|
||||
|
||||
public Num asin()
|
||||
{
|
||||
if (p_asin == null) p_asin = new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return Math.asin(t.value());
|
||||
}
|
||||
};
|
||||
|
||||
return p_asin;
|
||||
}
|
||||
|
||||
|
||||
public Num tan()
|
||||
{
|
||||
if (p_tan == null) p_tan = new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return Math.tan(t.value());
|
||||
}
|
||||
};
|
||||
|
||||
return p_tan;
|
||||
}
|
||||
|
||||
|
||||
public Num atan()
|
||||
{
|
||||
if (p_atan == null) p_atan = new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return Math.atan(t.value());
|
||||
}
|
||||
};
|
||||
|
||||
return p_atan;
|
||||
}
|
||||
|
||||
|
||||
public Num cbrt()
|
||||
{
|
||||
if (p_cbrt == null) p_cbrt = new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return Math.cbrt(t.value());
|
||||
}
|
||||
};
|
||||
|
||||
return p_cbrt;
|
||||
}
|
||||
|
||||
|
||||
public Num sqrt()
|
||||
{
|
||||
if (p_sqrt == null) p_sqrt = new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return Math.sqrt(t.value());
|
||||
}
|
||||
};
|
||||
|
||||
return p_sqrt;
|
||||
}
|
||||
|
||||
|
||||
public Num neg()
|
||||
{
|
||||
if (p_neg == null) p_neg = new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return -1 * t.value();
|
||||
}
|
||||
};
|
||||
|
||||
return p_neg;
|
||||
}
|
||||
|
||||
|
||||
public Num round()
|
||||
{
|
||||
if (p_round == null) p_round = new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return Math.round(t.value());
|
||||
}
|
||||
};
|
||||
|
||||
return p_round;
|
||||
}
|
||||
|
||||
|
||||
public Num floor()
|
||||
{
|
||||
if (p_floor == null) p_floor = new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return Math.floor(t.value());
|
||||
}
|
||||
};
|
||||
|
||||
return p_floor;
|
||||
}
|
||||
|
||||
|
||||
public Num ceil()
|
||||
{
|
||||
if (p_ceil == null) p_ceil = new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return Math.round(t.value());
|
||||
}
|
||||
};
|
||||
|
||||
return p_ceil;
|
||||
}
|
||||
|
||||
|
||||
public Num pow(final double other)
|
||||
{
|
||||
return new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return Math.pow(t.value(), other);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public Num pow(final Num power)
|
||||
{
|
||||
return new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return Math.pow(t.value(), power.value());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public Num cube()
|
||||
{
|
||||
if (p_cube == null) p_cube = new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
final double v = t.value();
|
||||
return v * v * v;
|
||||
}
|
||||
};
|
||||
|
||||
return p_cube;
|
||||
}
|
||||
|
||||
|
||||
public Num square()
|
||||
{
|
||||
if (p_square == null) p_square = new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
final double v = t.value();
|
||||
return v * v;
|
||||
}
|
||||
};
|
||||
|
||||
return p_square;
|
||||
}
|
||||
|
||||
|
||||
public Num half()
|
||||
{
|
||||
return mul(0.5);
|
||||
}
|
||||
|
||||
|
||||
public Num max(final double other)
|
||||
{
|
||||
return new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return Math.max(t.value(), other);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public Num max(final Num other)
|
||||
{
|
||||
return new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return Math.max(t.value(), other.value());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public Num min(final Num other)
|
||||
{
|
||||
return new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return Math.min(t.value(), other.value());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public Num min(final double other)
|
||||
{
|
||||
return new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return Math.min(t.value(), other);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public Num signum()
|
||||
{
|
||||
if (p_sgn == null) p_sgn = new Num() {
|
||||
|
||||
final Num t = Num.this;
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return Math.signum(t.value());
|
||||
}
|
||||
};
|
||||
|
||||
return p_sgn;
|
||||
}
|
||||
|
||||
|
||||
public boolean isNegative()
|
||||
{
|
||||
return value() < 0;
|
||||
}
|
||||
|
||||
|
||||
public boolean isPositive()
|
||||
{
|
||||
return value() > 0;
|
||||
}
|
||||
|
||||
|
||||
public boolean isZero()
|
||||
{
|
||||
return value() == 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
long temp;
|
||||
temp = Double.doubleToLongBits(value());
|
||||
result = prime * result + (int) (temp ^ (temp >>> 32));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj) return true;
|
||||
if (obj == null) return false;
|
||||
if (!(obj instanceof Num)) return false;
|
||||
final Num other = (Num) obj;
|
||||
|
||||
return value() == other.value();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return Calc.toString(value());
|
||||
}
|
||||
}
|
||||
@@ -1,268 +0,0 @@
|
||||
package mightypork.util.math.constraints.num;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.num.caching.NumDigest;
|
||||
|
||||
|
||||
/**
|
||||
* Constant number.<br>
|
||||
* It's arranged so that operations with constant arguments yield constant
|
||||
* results.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class NumConst extends Num {
|
||||
|
||||
private final double value;
|
||||
private NumDigest digest;
|
||||
|
||||
|
||||
NumConst(Num copied) {
|
||||
this.value = copied.value();
|
||||
}
|
||||
|
||||
|
||||
NumConst(double value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated No good to copy a constant.
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public NumConst freeze()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumDigest digest()
|
||||
{
|
||||
return (digest != null) ? digest : (digest = super.digest());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst add(double addend)
|
||||
{
|
||||
return Num.make(value() + addend);
|
||||
}
|
||||
|
||||
|
||||
public NumConst add(NumConst addend)
|
||||
{
|
||||
return Num.make(value + addend.value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst sub(double subtrahend)
|
||||
{
|
||||
return add(-subtrahend);
|
||||
}
|
||||
|
||||
|
||||
public NumConst sub(NumConst addend)
|
||||
{
|
||||
return Num.make(value - addend.value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst mul(double factor)
|
||||
{
|
||||
return Num.make(value() * factor);
|
||||
}
|
||||
|
||||
|
||||
public NumConst mul(NumConst addend)
|
||||
{
|
||||
return Num.make(value * addend.value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst div(double factor)
|
||||
{
|
||||
return mul(1 / factor);
|
||||
}
|
||||
|
||||
|
||||
public NumConst div(NumConst addend)
|
||||
{
|
||||
return Num.make(value / addend.value);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst perc(double percents)
|
||||
{
|
||||
return mul(percents / 100);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst neg()
|
||||
{
|
||||
return mul(-1);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst abs()
|
||||
{
|
||||
return Num.make(Math.abs(value()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst max(double other)
|
||||
{
|
||||
return Num.make(Math.max(value(), other));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst min(double other)
|
||||
{
|
||||
return Num.make(Math.min(value(), other));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst pow(double power)
|
||||
{
|
||||
return Num.make(Math.pow(value(), power));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst square()
|
||||
{
|
||||
final double v = value();
|
||||
return Num.make(v * v);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst cube()
|
||||
{
|
||||
final double v = value();
|
||||
return Num.make(v * v * v);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst sqrt()
|
||||
{
|
||||
return Num.make(Math.sqrt(value()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst cbrt()
|
||||
{
|
||||
return Num.make(Math.cbrt(value()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst sin()
|
||||
{
|
||||
return Num.make(Math.sin(value()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst cos()
|
||||
{
|
||||
return Num.make(Math.cos(value()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst tan()
|
||||
{
|
||||
return Num.make(Math.tan(value()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst asin()
|
||||
{
|
||||
return Num.make(Math.asin(value()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst acos()
|
||||
{
|
||||
return Num.make(Math.acos(value()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst atan()
|
||||
{
|
||||
return Num.make(Math.atan(value()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst signum()
|
||||
{
|
||||
return Num.make(Math.signum(value()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst average(double other)
|
||||
{
|
||||
return Num.make((value() + other) / 2);
|
||||
}
|
||||
|
||||
|
||||
public NumConst average(NumConst other)
|
||||
{
|
||||
return super.average(other).freeze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst round()
|
||||
{
|
||||
return Num.make(Math.round(value()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst ceil()
|
||||
{
|
||||
return Num.make(Math.ceil(value()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst floor()
|
||||
{
|
||||
return Num.make(Math.floor(value()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst half()
|
||||
{
|
||||
return mul(0.5);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
package mightypork.util.math.constraints.num.caching;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.ConstraintCache;
|
||||
import mightypork.util.math.constraints.num.Num;
|
||||
import mightypork.util.math.constraints.num.mutable.NumVar;
|
||||
import mightypork.util.math.constraints.num.proxy.NumAdapter;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A Num cache.
|
||||
* </p>
|
||||
* <p>
|
||||
* Values are held in a caching VectVar, and digest caching is enabled by
|
||||
* default.
|
||||
* </p>
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class AbstractNumCache extends NumAdapter implements ConstraintCache<Num> {
|
||||
|
||||
private final NumVar cache = Num.makeVar();
|
||||
private boolean inited = false;
|
||||
private boolean cachingEnabled = true;
|
||||
|
||||
|
||||
public AbstractNumCache() {
|
||||
enableDigestCaching(true); // it changes only on poll
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected final Num getSource()
|
||||
{
|
||||
if (!inited) markDigestDirty();
|
||||
|
||||
return (cachingEnabled ? cache : getCacheSource());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void poll()
|
||||
{
|
||||
inited = true;
|
||||
|
||||
// poll source
|
||||
final Num source = getCacheSource();
|
||||
source.markDigestDirty(); // poll cached
|
||||
|
||||
// store source value
|
||||
cache.setTo(source);
|
||||
|
||||
// mark my digest dirty
|
||||
markDigestDirty();
|
||||
|
||||
onChange();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public abstract void onChange();
|
||||
|
||||
|
||||
@Override
|
||||
public abstract Num getCacheSource();
|
||||
|
||||
|
||||
@Override
|
||||
public final void enableCaching(boolean yes)
|
||||
{
|
||||
cachingEnabled = yes;
|
||||
enableDigestCaching(yes);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final boolean isCachingEnabled()
|
||||
{
|
||||
return cachingEnabled;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package mightypork.util.math.constraints.num.caching;
|
||||
|
||||
|
||||
import mightypork.util.annotations.DefaultImpl;
|
||||
import mightypork.util.math.constraints.num.Num;
|
||||
|
||||
|
||||
/**
|
||||
* Num cache implementation
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class NumCache extends AbstractNumCache {
|
||||
|
||||
private final Num source;
|
||||
|
||||
|
||||
public NumCache(Num source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final Num getCacheSource()
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@DefaultImpl
|
||||
public void onChange()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
package mightypork.util.math.constraints.num.caching;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.num.Num;
|
||||
|
||||
|
||||
public class NumDigest {
|
||||
|
||||
public final double value;
|
||||
|
||||
|
||||
public NumDigest(Num num) {
|
||||
this.value = num.value();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("Num(%.1f)", value);
|
||||
}
|
||||
}
|
||||
@@ -1,378 +0,0 @@
|
||||
package mightypork.util.math.constraints.num.mutable;
|
||||
|
||||
|
||||
import mightypork.util.control.timing.Pauseable;
|
||||
import mightypork.util.control.timing.Updateable;
|
||||
import mightypork.util.math.Calc;
|
||||
import mightypork.util.math.Easing;
|
||||
|
||||
|
||||
/**
|
||||
* Double which supports delta timing
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class NumAnimated extends NumMutable implements Updateable, Pauseable {
|
||||
|
||||
/** target double */
|
||||
protected double to = 0;
|
||||
|
||||
/** last tick double */
|
||||
protected double from = 0;
|
||||
|
||||
/** how long the transition should last */
|
||||
protected double duration = 0;
|
||||
|
||||
/** current anim time */
|
||||
protected double elapsedTime = 0;
|
||||
|
||||
/** True if this animator is paused */
|
||||
protected boolean paused = false;
|
||||
|
||||
/** Easing fn */
|
||||
protected Easing easing = Easing.LINEAR;
|
||||
|
||||
/** Default duration (seconds) */
|
||||
private double defaultDuration = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Create linear animator
|
||||
*
|
||||
* @param value initial value
|
||||
*/
|
||||
public NumAnimated(double value) {
|
||||
setTo(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create animator with easing
|
||||
*
|
||||
* @param value initial value
|
||||
* @param easing easing function
|
||||
*/
|
||||
public NumAnimated(double value, Easing easing) {
|
||||
this(value);
|
||||
setEasing(easing);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create as copy of another
|
||||
*
|
||||
* @param other other animator
|
||||
*/
|
||||
public NumAnimated(NumAnimated other) {
|
||||
setTo(other);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return easing function
|
||||
*/
|
||||
public Easing getEasing()
|
||||
{
|
||||
return easing;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param easing easing function
|
||||
*/
|
||||
public void setEasing(Easing easing)
|
||||
{
|
||||
this.easing = easing;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get start value
|
||||
*
|
||||
* @return number
|
||||
*/
|
||||
public double getStart()
|
||||
{
|
||||
return from;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get end value
|
||||
*
|
||||
* @return number
|
||||
*/
|
||||
public double getEnd()
|
||||
{
|
||||
return to;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return current animation duration (seconds)
|
||||
*/
|
||||
public double getDuration()
|
||||
{
|
||||
return duration;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return elapsed time in current animation (seconds)
|
||||
*/
|
||||
public double getElapsed()
|
||||
{
|
||||
return elapsedTime;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return default animation duration (seconds)
|
||||
*/
|
||||
public double getDefaultDuration()
|
||||
{
|
||||
return defaultDuration;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param defaultDuration default animation duration (seconds)
|
||||
*/
|
||||
public void setDefaultDuration(double defaultDuration)
|
||||
{
|
||||
this.defaultDuration = defaultDuration;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get value at delta time
|
||||
*
|
||||
* @return the value
|
||||
*/
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
if (duration == 0) return to;
|
||||
return Calc.interpolate(from, to, (elapsedTime / duration), easing);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get how much of the animation is already finished
|
||||
*
|
||||
* @return completion ratio (0 to 1)
|
||||
*/
|
||||
public double getProgress()
|
||||
{
|
||||
if (duration == 0) return 1;
|
||||
return elapsedTime / duration;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void update(double delta)
|
||||
{
|
||||
if (paused || isFinished()) return;
|
||||
|
||||
elapsedTime = Calc.clampd(elapsedTime + delta, 0, duration);
|
||||
if (isFinished()) {
|
||||
duration = 0;
|
||||
elapsedTime = 0;
|
||||
from = to;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get if animation is finished
|
||||
*
|
||||
* @return is finished
|
||||
*/
|
||||
public boolean isFinished()
|
||||
{
|
||||
return duration == 0 || elapsedTime >= duration;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set to a value (without animation)
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
@Override
|
||||
public void setTo(double value)
|
||||
{
|
||||
from = to = value;
|
||||
elapsedTime = 0;
|
||||
duration = defaultDuration;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy other
|
||||
*
|
||||
* @param other
|
||||
*/
|
||||
public void setTo(NumAnimated other)
|
||||
{
|
||||
this.from = other.from;
|
||||
this.to = other.to;
|
||||
this.duration = other.duration;
|
||||
this.elapsedTime = other.elapsedTime;
|
||||
this.paused = other.paused;
|
||||
this.easing = other.easing;
|
||||
this.defaultDuration = other.defaultDuration;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Animate between two states, start from current value (if it's in between)
|
||||
*
|
||||
* @param from start value
|
||||
* @param to target state
|
||||
* @param time animation time (secs)
|
||||
*/
|
||||
public void animate(double from, double to, double time)
|
||||
{
|
||||
final double current = value();
|
||||
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
|
||||
final double progress = getProgressFromValue(current);
|
||||
|
||||
this.from = (progress > 0 ? current : from);
|
||||
|
||||
this.duration = time * (1 - progress);
|
||||
this.elapsedTime = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get progress already elapsed based on current value.<br>
|
||||
* Used to resume animation from current point in fading etc.
|
||||
*
|
||||
* @param value current value
|
||||
* @return progress ratio 0-1
|
||||
*/
|
||||
protected double getProgressFromValue(double value)
|
||||
{
|
||||
double p = 0;
|
||||
|
||||
if (from == to) return 0;
|
||||
|
||||
if (value >= from && value <= to) { // up
|
||||
p = ((value - from) / (to - from));
|
||||
} else if (value >= to && value <= from) { // down
|
||||
p = ((from - value) / (from - to));
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Animate to a value from current value
|
||||
*
|
||||
* @param to target state
|
||||
* @param duration animation duration (speeds)
|
||||
*/
|
||||
public void animate(double to, double duration)
|
||||
{
|
||||
this.from = value();
|
||||
this.to = to;
|
||||
this.duration = duration;
|
||||
this.elapsedTime = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Animate 0 to 1
|
||||
*
|
||||
* @param time animation time (secs)
|
||||
*/
|
||||
public void fadeIn(double time)
|
||||
{
|
||||
animate(0, 1, time);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Animate 1 to 0
|
||||
*
|
||||
* @param time animation time (secs)
|
||||
*/
|
||||
public void fadeOut(double time)
|
||||
{
|
||||
animate(1, 0, time);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Make a copy
|
||||
*
|
||||
* @return copy
|
||||
*/
|
||||
@Override
|
||||
public NumAnimated clone()
|
||||
{
|
||||
return new NumAnimated(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "Animation(" + from + " -> " + to + ", t=" + duration + "s, elapsed=" + elapsedTime + "s)";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set to zero and stop animation
|
||||
*/
|
||||
public void clear()
|
||||
{
|
||||
from = to = 0;
|
||||
elapsedTime = 0;
|
||||
duration = 0;
|
||||
paused = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Stop animation, keep current value
|
||||
*/
|
||||
public void stop()
|
||||
{
|
||||
from = to = value();
|
||||
elapsedTime = 0;
|
||||
duration = 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void pause()
|
||||
{
|
||||
paused = true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void resume()
|
||||
{
|
||||
paused = false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isPaused()
|
||||
{
|
||||
return paused;
|
||||
}
|
||||
|
||||
|
||||
public boolean isInProgress()
|
||||
{
|
||||
return !isFinished() && !isPaused();
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package mightypork.util.math.constraints.num.mutable;
|
||||
|
||||
|
||||
import mightypork.util.math.Calc;
|
||||
import mightypork.util.math.Calc.Deg;
|
||||
import mightypork.util.math.Easing;
|
||||
|
||||
|
||||
/**
|
||||
* Degree animator
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class NumAnimatedDeg extends NumAnimated {
|
||||
|
||||
public NumAnimatedDeg(NumAnimated other) {
|
||||
super(other);
|
||||
}
|
||||
|
||||
|
||||
public NumAnimatedDeg(double value) {
|
||||
super(value);
|
||||
}
|
||||
|
||||
|
||||
public NumAnimatedDeg(double value, Easing easing) {
|
||||
super(value, easing);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
if (duration == 0) return Deg.norm(to);
|
||||
return Calc.interpolateDeg(from, to, (elapsedTime / duration), easing);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected double getProgressFromValue(double value)
|
||||
{
|
||||
final double whole = Deg.diff(from, to);
|
||||
if (Deg.diff(value, from) < whole && Deg.diff(value, to) < whole) {
|
||||
final double partial = Deg.diff(from, value);
|
||||
return partial / whole;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package mightypork.util.math.constraints.num.mutable;
|
||||
|
||||
|
||||
import mightypork.util.math.Calc;
|
||||
import mightypork.util.math.Calc.Rad;
|
||||
import mightypork.util.math.Easing;
|
||||
|
||||
|
||||
/**
|
||||
* Radians animator
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class NumAnimatedRad extends NumAnimated {
|
||||
|
||||
public NumAnimatedRad(NumAnimated other) {
|
||||
super(other);
|
||||
}
|
||||
|
||||
|
||||
public NumAnimatedRad(double value) {
|
||||
super(value);
|
||||
}
|
||||
|
||||
|
||||
public NumAnimatedRad(double value, Easing easing) {
|
||||
super(value, easing);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
if (duration == 0) return Rad.norm(to);
|
||||
return Calc.interpolateRad(from, to, (elapsedTime / duration), easing);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected double getProgressFromValue(double value)
|
||||
{
|
||||
final double whole = Rad.diff(from, to);
|
||||
if (Rad.diff(value, from) < whole && Rad.diff(value, to) < whole) {
|
||||
final double partial = Rad.diff(from, value);
|
||||
return partial / whole;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package mightypork.util.math.constraints.num.mutable;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.num.Num;
|
||||
|
||||
|
||||
/**
|
||||
* Mutable numeric variable
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class NumMutable extends Num {
|
||||
|
||||
/**
|
||||
* Assign a value
|
||||
*
|
||||
* @param value new value
|
||||
*/
|
||||
public abstract void setTo(double value);
|
||||
|
||||
|
||||
/**
|
||||
* Assign a value
|
||||
*
|
||||
* @param value new value
|
||||
*/
|
||||
public void setTo(Num value)
|
||||
{
|
||||
setTo(value.value());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set to zero
|
||||
*/
|
||||
public void reset()
|
||||
{
|
||||
setTo(0);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
package mightypork.util.math.constraints.num.mutable;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.num.Num;
|
||||
|
||||
|
||||
/**
|
||||
* Mutable numeric variable.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class NumVar extends NumMutable {
|
||||
|
||||
private double value;
|
||||
|
||||
|
||||
public NumVar(Num value) {
|
||||
this(value.value());
|
||||
}
|
||||
|
||||
|
||||
public NumVar(double value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setTo(double value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package mightypork.util.math.constraints.num.proxy;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.num.Num;
|
||||
|
||||
|
||||
public abstract class NumAdapter extends Num {
|
||||
|
||||
protected abstract Num getSource();
|
||||
|
||||
|
||||
@Override
|
||||
public double value()
|
||||
{
|
||||
return getSource().value();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
package mightypork.util.math.constraints.num.proxy;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.num.Num;
|
||||
|
||||
|
||||
/**
|
||||
* Numeric constraint
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public interface NumBound {
|
||||
|
||||
/**
|
||||
* @return current value
|
||||
*/
|
||||
Num getNum();
|
||||
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package mightypork.util.math.constraints.num.proxy;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.num.Num;
|
||||
|
||||
|
||||
public class NumBoundAdapter extends NumAdapter implements PluggableNumBound {
|
||||
|
||||
private NumBound backing = null;
|
||||
|
||||
|
||||
public NumBoundAdapter() {
|
||||
}
|
||||
|
||||
|
||||
public NumBoundAdapter(NumBound bound) {
|
||||
backing = bound;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setNum(NumBound rect)
|
||||
{
|
||||
this.backing = rect;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Num getSource()
|
||||
{
|
||||
return backing.getNum();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package mightypork.util.math.constraints.num.proxy;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.num.Num;
|
||||
|
||||
|
||||
public class NumProxy extends NumAdapter {
|
||||
|
||||
private final Num source;
|
||||
|
||||
|
||||
public NumProxy(Num source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Num getSource()
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package mightypork.util.math.constraints.num.proxy;
|
||||
|
||||
|
||||
/**
|
||||
* Pluggable numeric constraint
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public interface PluggableNumBound extends NumBound {
|
||||
|
||||
/**
|
||||
* @param num bound to set
|
||||
*/
|
||||
abstract void setNum(NumBound num);
|
||||
|
||||
}
|
||||
@@ -1,943 +0,0 @@
|
||||
package mightypork.util.math.constraints.rect;
|
||||
|
||||
|
||||
import mightypork.util.annotations.FactoryMethod;
|
||||
import mightypork.util.math.constraints.DigestCache;
|
||||
import mightypork.util.math.constraints.Digestable;
|
||||
import mightypork.util.math.constraints.num.Num;
|
||||
import mightypork.util.math.constraints.num.NumConst;
|
||||
import mightypork.util.math.constraints.rect.builders.TiledRect;
|
||||
import mightypork.util.math.constraints.rect.caching.RectCache;
|
||||
import mightypork.util.math.constraints.rect.caching.RectDigest;
|
||||
import mightypork.util.math.constraints.rect.mutable.RectVar;
|
||||
import mightypork.util.math.constraints.rect.proxy.RectBound;
|
||||
import mightypork.util.math.constraints.rect.proxy.RectBoundAdapter;
|
||||
import mightypork.util.math.constraints.rect.proxy.RectVectAdapter;
|
||||
import mightypork.util.math.constraints.vect.Vect;
|
||||
import mightypork.util.math.constraints.vect.VectConst;
|
||||
|
||||
|
||||
/**
|
||||
* Common methods for all kinds of Rects
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class Rect implements RectBound, Digestable<RectDigest> {
|
||||
|
||||
public static final RectConst ZERO = new RectConst(0, 0, 0, 0);
|
||||
public static final RectConst ONE = new RectConst(0, 0, 1, 1);
|
||||
|
||||
|
||||
@FactoryMethod
|
||||
public static Rect make(Num width, Num height)
|
||||
{
|
||||
final Vect origin = Vect.ZERO;
|
||||
final Vect size = Vect.make(width, height);
|
||||
|
||||
return Rect.make(origin, size);
|
||||
}
|
||||
|
||||
|
||||
public static Rect make(Vect size)
|
||||
{
|
||||
return Rect.make(size.xn(), size.yn());
|
||||
}
|
||||
|
||||
|
||||
@FactoryMethod
|
||||
public static Rect make(RectBound bound)
|
||||
{
|
||||
return new RectBoundAdapter(bound);
|
||||
}
|
||||
|
||||
|
||||
@FactoryMethod
|
||||
public static Rect make(Num x, Num y, Num width, Num height)
|
||||
{
|
||||
final Vect origin = Vect.make(x, y);
|
||||
final Vect size = Vect.make(width, height);
|
||||
|
||||
return Rect.make(origin, size);
|
||||
}
|
||||
|
||||
|
||||
@FactoryMethod
|
||||
public static Rect make(Vect origin, Num width, Num height)
|
||||
{
|
||||
return make(origin, Vect.make(width, height));
|
||||
}
|
||||
|
||||
|
||||
@FactoryMethod
|
||||
public static Rect make(final Vect origin, final Vect size)
|
||||
{
|
||||
return new RectVectAdapter(origin, size);
|
||||
}
|
||||
|
||||
|
||||
@FactoryMethod
|
||||
public static RectConst make(NumConst width, NumConst height)
|
||||
{
|
||||
final VectConst origin = Vect.ZERO;
|
||||
final VectConst size = Vect.make(width, height);
|
||||
|
||||
return Rect.make(origin, size);
|
||||
}
|
||||
|
||||
|
||||
public static Rect make(Num side)
|
||||
{
|
||||
return make(side, side);
|
||||
}
|
||||
|
||||
|
||||
public static RectConst make(NumConst side)
|
||||
{
|
||||
return make(side, side);
|
||||
}
|
||||
|
||||
|
||||
public static RectConst make(double side)
|
||||
{
|
||||
return make(side, side);
|
||||
}
|
||||
|
||||
|
||||
@FactoryMethod
|
||||
public static RectConst make(NumConst x, NumConst y, NumConst width, NumConst height)
|
||||
{
|
||||
final VectConst origin = Vect.make(x, y);
|
||||
final VectConst size = Vect.make(width, height);
|
||||
|
||||
return Rect.make(origin, size);
|
||||
}
|
||||
|
||||
|
||||
@FactoryMethod
|
||||
public static RectConst make(final VectConst origin, final VectConst size)
|
||||
{
|
||||
return new RectConst(origin, size);
|
||||
}
|
||||
|
||||
|
||||
@FactoryMethod
|
||||
public static RectConst make(double width, double height)
|
||||
{
|
||||
return Rect.make(0, 0, width, height);
|
||||
}
|
||||
|
||||
|
||||
@FactoryMethod
|
||||
public static RectConst make(double x, double y, double width, double height)
|
||||
{
|
||||
return new RectConst(x, y, width, height);
|
||||
}
|
||||
|
||||
|
||||
@FactoryMethod
|
||||
public static RectVar makeVar(double x, double y)
|
||||
{
|
||||
return Rect.makeVar(0, 0, x, y);
|
||||
}
|
||||
|
||||
|
||||
@FactoryMethod
|
||||
public static RectVar makeVar(Rect copied)
|
||||
{
|
||||
return Rect.makeVar(copied.origin(), copied.size());
|
||||
}
|
||||
|
||||
|
||||
@FactoryMethod
|
||||
public static RectVar makeVar(Vect origin, Vect size)
|
||||
{
|
||||
return Rect.makeVar(origin.x(), origin.y(), size.x(), size.y());
|
||||
}
|
||||
|
||||
|
||||
@FactoryMethod
|
||||
public static RectVar makeVar(double x, double y, double width, double height)
|
||||
{
|
||||
return new RectVar(x, y, width, height);
|
||||
}
|
||||
|
||||
|
||||
@FactoryMethod
|
||||
public static RectVar makeVar()
|
||||
{
|
||||
return Rect.makeVar(Rect.ZERO);
|
||||
}
|
||||
|
||||
private Vect p_bl;
|
||||
private Vect p_bc;
|
||||
private Vect p_br;
|
||||
// p_t == origin
|
||||
private Vect p_tc;
|
||||
private Vect p_tr;
|
||||
|
||||
private Vect p_cl;
|
||||
private Vect p_cc;
|
||||
private Vect p_cr;
|
||||
|
||||
private Num p_x;
|
||||
private Num p_y;
|
||||
private Num p_w;
|
||||
private Num p_h;
|
||||
private Num p_l;
|
||||
private Num p_r;
|
||||
private Num p_t;
|
||||
private Num p_b;
|
||||
private Rect p_edge_l;
|
||||
private Rect p_edge_r;
|
||||
private Rect p_edge_t;
|
||||
private Rect p_edge_b;
|
||||
|
||||
private DigestCache<RectDigest> dc = new DigestCache<RectDigest>() {
|
||||
|
||||
@Override
|
||||
protected RectDigest createDigest()
|
||||
{
|
||||
return new RectDigest(Rect.this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get a copy of current value
|
||||
*
|
||||
* @return copy
|
||||
*/
|
||||
public RectConst freeze()
|
||||
{
|
||||
// must NOT call RectVal.make, it'd cause infinite recursion.
|
||||
return new RectConst(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Wrap this constraint into a caching adapter. Value will stay fixed (ie.
|
||||
* no re-calculations) until cache receives a poll() call.
|
||||
*
|
||||
* @return the caching adapter
|
||||
*/
|
||||
public RectCache cached()
|
||||
{
|
||||
return new RectCache(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RectDigest digest()
|
||||
{
|
||||
return dc.digest();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void enableDigestCaching(boolean yes)
|
||||
{
|
||||
dc.enableDigestCaching(yes);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isDigestCachingEnabled()
|
||||
{
|
||||
return dc.isDigestCachingEnabled();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void markDigestDirty()
|
||||
{
|
||||
dc.markDigestDirty();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Rect getRect()
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("Rect { at %s , size %s }", origin(), size());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Origin (top left).
|
||||
*
|
||||
* @return origin (top left)
|
||||
*/
|
||||
public abstract Vect origin();
|
||||
|
||||
|
||||
/**
|
||||
* Size (spanning right down from Origin).
|
||||
*
|
||||
* @return size vector
|
||||
*/
|
||||
public abstract Vect size();
|
||||
|
||||
|
||||
/**
|
||||
* Add vector to origin
|
||||
*
|
||||
* @param move offset vector
|
||||
* @return result
|
||||
*/
|
||||
public Rect move(final Vect move)
|
||||
{
|
||||
return new Rect() {
|
||||
|
||||
private final Rect t = Rect.this;
|
||||
|
||||
|
||||
@Override
|
||||
public Vect size()
|
||||
{
|
||||
return t.size();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Vect origin()
|
||||
{
|
||||
return t.origin().add(move);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public Rect moveX(Num x)
|
||||
{
|
||||
return move(x, Num.ZERO);
|
||||
}
|
||||
|
||||
|
||||
public Rect moveY(Num y)
|
||||
{
|
||||
return move(Num.ZERO, y);
|
||||
}
|
||||
|
||||
|
||||
public Rect moveX(double x)
|
||||
{
|
||||
return move(x, 0);
|
||||
}
|
||||
|
||||
|
||||
public Rect moveY(double y)
|
||||
{
|
||||
return move(0, y);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add X and Y to origin
|
||||
*
|
||||
* @param x x to add
|
||||
* @param y y to add
|
||||
* @return result
|
||||
*/
|
||||
public Rect move(final double x, final double y)
|
||||
{
|
||||
return new Rect() {
|
||||
|
||||
private final Rect t = Rect.this;
|
||||
|
||||
|
||||
@Override
|
||||
public Vect size()
|
||||
{
|
||||
return t.size();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Vect origin()
|
||||
{
|
||||
return t.origin().add(x, y);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public Rect move(final Num x, final Num y)
|
||||
{
|
||||
return new Rect() {
|
||||
|
||||
private final Rect t = Rect.this;
|
||||
|
||||
|
||||
@Override
|
||||
public Vect size()
|
||||
{
|
||||
return t.size();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Vect origin()
|
||||
{
|
||||
return t.origin().add(x, y);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shrink to sides
|
||||
*
|
||||
* @param shrink shrink size (horizontal and vertical)
|
||||
* @return result
|
||||
*/
|
||||
|
||||
public Rect shrink(Vect shrink)
|
||||
{
|
||||
return shrink(shrink.x(), shrink.y());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shrink to all sides
|
||||
*
|
||||
* @param shrink shrink
|
||||
* @return result
|
||||
*/
|
||||
public final Rect shrink(double shrink)
|
||||
{
|
||||
return shrink(shrink, shrink, shrink, shrink);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shrink to all sides
|
||||
*
|
||||
* @param shrink shrink
|
||||
* @return result
|
||||
*/
|
||||
public final Rect shrink(Num shrink)
|
||||
{
|
||||
return shrink(shrink, shrink, shrink, shrink);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shrink to sides at sides
|
||||
*
|
||||
* @param x horizontal shrink
|
||||
* @param y vertical shrink
|
||||
* @return result
|
||||
*/
|
||||
public Rect shrink(double x, double y)
|
||||
{
|
||||
return shrink(x, x, y, y);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shrink the rect
|
||||
*
|
||||
* @param left shrink
|
||||
* @param right shrink
|
||||
* @param top shrink
|
||||
* @param bottom shrink
|
||||
* @return result
|
||||
*/
|
||||
public Rect shrink(final double left, final double right, final double top, final double bottom)
|
||||
{
|
||||
return grow(-left, -right, -top, -bottom);
|
||||
}
|
||||
|
||||
|
||||
public Rect shrinkLeft(final double shrink)
|
||||
{
|
||||
return growLeft(-shrink);
|
||||
}
|
||||
|
||||
|
||||
public Rect shrinkRight(final double shrink)
|
||||
{
|
||||
return growLeft(-shrink);
|
||||
}
|
||||
|
||||
|
||||
public Rect shrinkTop(final double shrink)
|
||||
{
|
||||
return growUp(-shrink);
|
||||
}
|
||||
|
||||
|
||||
public Rect shrinkBottom(final double shrink)
|
||||
{
|
||||
return growDown(-shrink);
|
||||
}
|
||||
|
||||
|
||||
public Rect growLeft(final double shrink)
|
||||
{
|
||||
return grow(shrink, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
public Rect growRight(final double shrink)
|
||||
{
|
||||
return grow(0, shrink, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
public Rect growUp(final double shrink)
|
||||
{
|
||||
return grow(0, 0, shrink, 0);
|
||||
}
|
||||
|
||||
|
||||
public Rect growDown(final double shrink)
|
||||
{
|
||||
return grow(0, 0, 0, shrink);
|
||||
}
|
||||
|
||||
|
||||
public Rect shrinkLeft(final Num shrink)
|
||||
{
|
||||
return shrink(shrink, Num.ZERO, Num.ZERO, Num.ZERO);
|
||||
}
|
||||
|
||||
|
||||
public Rect shrinkRight(final Num shrink)
|
||||
{
|
||||
return shrink(Num.ZERO, shrink, Num.ZERO, Num.ZERO);
|
||||
}
|
||||
|
||||
|
||||
public Rect shrinkTop(final Num shrink)
|
||||
{
|
||||
return shrink(Num.ZERO, Num.ZERO, shrink, Num.ZERO);
|
||||
}
|
||||
|
||||
|
||||
public Rect shrinkBottom(final Num shrink)
|
||||
{
|
||||
return shrink(Num.ZERO, Num.ZERO, Num.ZERO, shrink);
|
||||
}
|
||||
|
||||
|
||||
public Rect growLeft(final Num shrink)
|
||||
{
|
||||
return grow(shrink, Num.ZERO, Num.ZERO, Num.ZERO);
|
||||
}
|
||||
|
||||
|
||||
public Rect growRight(final Num shrink)
|
||||
{
|
||||
return grow(Num.ZERO, shrink, Num.ZERO, Num.ZERO);
|
||||
}
|
||||
|
||||
|
||||
public Rect growUp(final Num shrink)
|
||||
{
|
||||
return grow(Num.ZERO, Num.ZERO, shrink, Num.ZERO);
|
||||
}
|
||||
|
||||
|
||||
public Rect growDown(final Num shrink)
|
||||
{
|
||||
return grow(Num.ZERO, Num.ZERO, Num.ZERO, shrink);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Grow to sides
|
||||
*
|
||||
* @param grow grow size (added to each side)
|
||||
* @return grown copy
|
||||
*/
|
||||
public final Rect grow(Vect grow)
|
||||
{
|
||||
return grow(grow.x(), grow.y());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Grow to all sides
|
||||
*
|
||||
* @param grow grow
|
||||
* @return result
|
||||
*/
|
||||
public final Rect grow(double grow)
|
||||
{
|
||||
return grow(grow, grow, grow, grow);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Grow to all sides
|
||||
*
|
||||
* @param grow grow
|
||||
* @return result
|
||||
*/
|
||||
public final Rect grow(Num grow)
|
||||
{
|
||||
return grow(grow, grow, grow, grow);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Grow to sides
|
||||
*
|
||||
* @param x horizontal grow
|
||||
* @param y vertical grow
|
||||
* @return result
|
||||
*/
|
||||
public final Rect grow(double x, double y)
|
||||
{
|
||||
return grow(x, x, y, y);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Grow the rect
|
||||
*
|
||||
* @param left growth
|
||||
* @param right growth
|
||||
* @param top growth
|
||||
* @param bottom growth
|
||||
* @return result
|
||||
*/
|
||||
public Rect grow(final double left, final double right, final double top, final double bottom)
|
||||
{
|
||||
return new Rect() {
|
||||
|
||||
private final Rect t = Rect.this;
|
||||
|
||||
|
||||
@Override
|
||||
public Vect size()
|
||||
{
|
||||
return t.size().add(left + right, top + bottom);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Vect origin()
|
||||
{
|
||||
return t.origin().sub(left, top);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public Rect shrink(final Num left, final Num right, final Num top, final Num bottom)
|
||||
{
|
||||
return new Rect() {
|
||||
|
||||
private final Rect t = Rect.this;
|
||||
|
||||
|
||||
@Override
|
||||
public Vect size()
|
||||
{
|
||||
return t.size().sub(left.add(right), top.add(bottom));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Vect origin()
|
||||
{
|
||||
return t.origin().add(left, top);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public Rect grow(final Num left, final Num right, final Num top, final Num bottom)
|
||||
{
|
||||
|
||||
return new Rect() {
|
||||
|
||||
private final Rect t = Rect.this;
|
||||
|
||||
|
||||
@Override
|
||||
public Vect size()
|
||||
{
|
||||
return t.size().add(left.add(right), top.add(bottom));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Vect origin()
|
||||
{
|
||||
return t.origin().sub(left, top);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Round coords
|
||||
*
|
||||
* @return result
|
||||
*/
|
||||
public Rect round()
|
||||
{
|
||||
|
||||
return new Rect() {
|
||||
|
||||
private final Rect t = Rect.this;
|
||||
|
||||
|
||||
@Override
|
||||
public Vect size()
|
||||
{
|
||||
return t.size().round();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Vect origin()
|
||||
{
|
||||
return t.origin().round();
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public Num x()
|
||||
{
|
||||
return p_x != null ? p_x : (p_x = origin().xn());
|
||||
}
|
||||
|
||||
|
||||
public Num y()
|
||||
{
|
||||
return p_y != null ? p_y : (p_y = origin().yn());
|
||||
}
|
||||
|
||||
|
||||
public Num width()
|
||||
{
|
||||
return p_w != null ? p_w : (p_w = size().xn());
|
||||
}
|
||||
|
||||
|
||||
public Num height()
|
||||
{
|
||||
return p_h != null ? p_h : (p_h = size().yn());
|
||||
}
|
||||
|
||||
|
||||
public Num left()
|
||||
{
|
||||
return p_l != null ? p_l : (p_l = origin().xn());
|
||||
}
|
||||
|
||||
|
||||
public Num right()
|
||||
{
|
||||
return p_r != null ? p_r : (p_r = origin().xn().add(size().xn()));
|
||||
}
|
||||
|
||||
|
||||
public Num top()
|
||||
{
|
||||
return p_t != null ? p_t : (p_t = origin().yn());
|
||||
}
|
||||
|
||||
|
||||
public Num bottom()
|
||||
{
|
||||
return p_b != null ? p_b : (p_b = origin().yn().add(size().yn()));
|
||||
}
|
||||
|
||||
|
||||
public Vect topLeft()
|
||||
{
|
||||
return origin();
|
||||
}
|
||||
|
||||
|
||||
public Vect topCenter()
|
||||
{
|
||||
return p_tc != null ? p_tc : (p_tc = origin().add(size().xn().half(), Num.ZERO));
|
||||
}
|
||||
|
||||
|
||||
public Vect topRight()
|
||||
{
|
||||
return p_tr != null ? p_tr : (p_tr = origin().add(size().xn(), Num.ZERO));
|
||||
}
|
||||
|
||||
|
||||
public Vect centerLeft()
|
||||
{
|
||||
return p_cl != null ? p_cl : (p_cl = origin().add(Num.ZERO, size().yn().half()));
|
||||
}
|
||||
|
||||
|
||||
public Vect center()
|
||||
{
|
||||
return p_cc != null ? p_cc : (p_cc = origin().add(size().half()));
|
||||
}
|
||||
|
||||
|
||||
public Vect centerRight()
|
||||
{
|
||||
return p_cr != null ? p_cr : (p_cr = origin().add(size().xn(), size().yn().half()));
|
||||
}
|
||||
|
||||
|
||||
public Vect bottomLeft()
|
||||
{
|
||||
return p_bl != null ? p_bl : (p_bl = origin().add(Num.ZERO, size().yn()));
|
||||
}
|
||||
|
||||
|
||||
public Vect bottomCenter()
|
||||
{
|
||||
return p_bc != null ? p_bc : (p_bc = origin().add(size().xn().half(), size().yn()));
|
||||
}
|
||||
|
||||
|
||||
public Vect bottomRight()
|
||||
{
|
||||
return p_br != null ? p_br : (p_br = origin().add(size().xn(), size().yn()));
|
||||
}
|
||||
|
||||
|
||||
public Rect leftEdge()
|
||||
{
|
||||
return p_edge_l != null ? p_edge_l : (p_edge_l = topLeft().expand(Num.ZERO, Num.ZERO, Num.ZERO, height()));
|
||||
}
|
||||
|
||||
|
||||
public Rect rightEdge()
|
||||
{
|
||||
return p_edge_r != null ? p_edge_r : (p_edge_r = topRight().expand(Num.ZERO, Num.ZERO, Num.ZERO, height()));
|
||||
}
|
||||
|
||||
|
||||
public Rect topEdge()
|
||||
{
|
||||
return p_edge_t != null ? p_edge_t : (p_edge_t = topLeft().expand(Num.ZERO, width(), Num.ZERO, Num.ZERO));
|
||||
}
|
||||
|
||||
|
||||
public Rect bottomEdge()
|
||||
{
|
||||
return p_edge_b != null ? p_edge_b : (p_edge_b = bottomLeft().expand(Num.ZERO, width(), Num.ZERO, Num.ZERO));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Center to given point
|
||||
*
|
||||
* @param point new center
|
||||
* @return centered
|
||||
*/
|
||||
public Rect centerTo(final Vect point)
|
||||
{
|
||||
return new Rect() {
|
||||
|
||||
Rect t = Rect.this;
|
||||
|
||||
|
||||
@Override
|
||||
public Vect size()
|
||||
{
|
||||
return t.size();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Vect origin()
|
||||
{
|
||||
return point.sub(t.size().half());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if point is inside this rectangle
|
||||
*
|
||||
* @param point point to test
|
||||
* @return is inside
|
||||
*/
|
||||
public boolean contains(Vect point)
|
||||
{
|
||||
final double x = point.x();
|
||||
final double y = point.y();
|
||||
|
||||
final double x1 = origin().x();
|
||||
final double y1 = origin().y();
|
||||
final double x2 = x1 + size().x();
|
||||
final double y2 = y1 + size().y();
|
||||
|
||||
return x >= x1 && y >= y1 && x <= x2 && y <= y2;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Center to given rect's center
|
||||
*
|
||||
* @param parent rect to center to
|
||||
* @return centered
|
||||
*/
|
||||
public Rect centerTo(Rect parent)
|
||||
{
|
||||
return centerTo(parent.center());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get TiledRect with given number of evenly spaced tiles. Tile indexes are
|
||||
* one-based by default.
|
||||
*
|
||||
* @param horizontal horizontal tile count
|
||||
* @param vertical vertical tile count
|
||||
* @return tiled rect
|
||||
*/
|
||||
public TiledRect tiles(int horizontal, int vertical)
|
||||
{
|
||||
return new TiledRect(this, horizontal, vertical);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get TiledRect with N columns and 1 row. Column indexes are one-based by
|
||||
* default.
|
||||
*
|
||||
* @param columns number of columns
|
||||
* @return tiled rect
|
||||
*/
|
||||
public TiledRect columns(int columns)
|
||||
{
|
||||
return new TiledRect(this, columns, 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get TiledRect with N rows and 1 column. Row indexes are one-based by
|
||||
* default.
|
||||
*
|
||||
* @param rows number of columns
|
||||
* @return tiled rect
|
||||
*/
|
||||
public TiledRect rows(int rows)
|
||||
{
|
||||
return new TiledRect(this, 1, rows);
|
||||
}
|
||||
}
|
||||
@@ -1,440 +0,0 @@
|
||||
package mightypork.util.math.constraints.rect;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.num.NumConst;
|
||||
import mightypork.util.math.constraints.rect.caching.RectDigest;
|
||||
import mightypork.util.math.constraints.vect.Vect;
|
||||
import mightypork.util.math.constraints.vect.VectConst;
|
||||
|
||||
|
||||
/**
|
||||
* Rectangle with constant bounds, that can never change.<br>
|
||||
* It's arranged so that operations with constant arguments yield constant
|
||||
* results.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class RectConst extends Rect {
|
||||
|
||||
private final VectConst pos;
|
||||
private final VectConst size;
|
||||
|
||||
// cached with lazy loading
|
||||
private NumConst v_b;
|
||||
private NumConst v_r;
|
||||
private VectConst v_br;
|
||||
private VectConst v_tc;
|
||||
private VectConst v_tr;
|
||||
private VectConst v_cl;
|
||||
private VectConst v_c;
|
||||
private VectConst v_cr;
|
||||
private VectConst v_bl;
|
||||
private VectConst v_bc;
|
||||
private RectConst v_round;
|
||||
private RectConst v_edge_l;
|
||||
private RectConst v_edge_r;
|
||||
private RectConst v_edge_t;
|
||||
private RectConst v_edge_b;
|
||||
private RectDigest digest;
|
||||
|
||||
|
||||
/**
|
||||
* Create at given origin, with given size.
|
||||
*
|
||||
* @param x
|
||||
* @param y
|
||||
* @param width
|
||||
* @param height
|
||||
*/
|
||||
RectConst(double x, double y, double width, double height) {
|
||||
this.pos = Vect.make(x, y);
|
||||
this.size = Vect.make(width, height);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create at given origin, with given size.
|
||||
*
|
||||
* @param origin
|
||||
* @param size
|
||||
*/
|
||||
RectConst(Vect origin, Vect size) {
|
||||
this.pos = origin.freeze();
|
||||
this.size = size.freeze();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create at given origin, with given size.
|
||||
*
|
||||
* @param another other coord
|
||||
*/
|
||||
RectConst(Rect another) {
|
||||
this.pos = another.origin().freeze();
|
||||
this.size = another.size().freeze();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated it's useless to copy a constant
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public RectConst freeze()
|
||||
{
|
||||
return this; // already constant
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RectDigest digest()
|
||||
{
|
||||
return (digest != null) ? digest : (digest = super.digest());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst origin()
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst size()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RectConst move(Vect move)
|
||||
{
|
||||
return move(move.x(), move.y());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RectConst move(double x, double y)
|
||||
{
|
||||
return Rect.make(pos.add(x, y), size);
|
||||
}
|
||||
|
||||
|
||||
public RectConst move(NumConst x, NumConst y)
|
||||
{
|
||||
return super.move(x, y).freeze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RectConst shrink(double left, double right, double top, double bottom)
|
||||
{
|
||||
return super.shrink(left, right, top, bottom).freeze();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RectConst grow(double left, double right, double top, double bottom)
|
||||
{
|
||||
return super.grow(left, right, top, bottom).freeze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RectConst round()
|
||||
{
|
||||
return (v_round != null) ? v_round : (v_round = Rect.make(pos.round(), size.round()));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst x()
|
||||
{
|
||||
return pos.xn();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst y()
|
||||
{
|
||||
return pos.yn();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst width()
|
||||
{
|
||||
return size.xn();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst height()
|
||||
{
|
||||
return size.yn();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst left()
|
||||
{
|
||||
return pos.xn();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst right()
|
||||
{
|
||||
return (v_r != null) ? v_r : (v_r = super.right().freeze());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst top()
|
||||
{
|
||||
return pos.yn();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst bottom()
|
||||
{
|
||||
return (v_b != null) ? v_b : (v_b = super.bottom().freeze());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst topLeft()
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst topCenter()
|
||||
{
|
||||
return (v_tc != null) ? v_tc : (v_tc = super.topCenter().freeze());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst topRight()
|
||||
{
|
||||
return (v_tr != null) ? v_tr : (v_tr = super.topRight().freeze());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst centerLeft()
|
||||
{
|
||||
return (v_cl != null) ? v_cl : (v_cl = super.centerLeft().freeze());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst center()
|
||||
{
|
||||
return (v_c != null) ? v_c : (v_c = super.center().freeze());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst centerRight()
|
||||
{
|
||||
return (v_cr != null) ? v_cr : (v_cr = super.centerRight().freeze());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst bottomLeft()
|
||||
{
|
||||
return (v_bl != null) ? v_bl : (v_bl = super.bottomLeft().freeze());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst bottomCenter()
|
||||
{
|
||||
return (v_bc != null) ? v_bc : (v_bc = super.bottomCenter().freeze());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst bottomRight()
|
||||
{
|
||||
return (v_br != null) ? v_br : (v_br = super.bottomRight().freeze());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RectConst leftEdge()
|
||||
{
|
||||
return (v_edge_l != null) ? v_edge_l : (v_edge_l = super.leftEdge().freeze());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RectConst rightEdge()
|
||||
{
|
||||
return (v_edge_r != null) ? v_edge_r : (v_edge_r = super.rightEdge().freeze());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RectConst topEdge()
|
||||
{
|
||||
return (v_edge_t != null) ? v_edge_t : (v_edge_t = super.topEdge().freeze());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RectConst bottomEdge()
|
||||
{
|
||||
return (v_edge_b != null) ? v_edge_b : (v_edge_b = super.bottomEdge().freeze());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Rect shrink(Vect shrink)
|
||||
{
|
||||
return super.shrink(shrink);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RectConst shrink(double x, double y)
|
||||
{
|
||||
return super.shrink(x, y).freeze();
|
||||
}
|
||||
|
||||
|
||||
public RectConst shrink(NumConst left, NumConst right, NumConst top, NumConst bottom)
|
||||
{
|
||||
return super.shrink(left, right, top, bottom).freeze();
|
||||
}
|
||||
|
||||
|
||||
public RectConst grow(NumConst left, NumConst right, NumConst top, NumConst bottom)
|
||||
{
|
||||
return super.grow(left, right, top, bottom).freeze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RectConst shrinkLeft(double shrink)
|
||||
{
|
||||
return super.shrinkLeft(shrink).freeze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RectConst shrinkRight(double shrink)
|
||||
{
|
||||
return super.shrinkRight(shrink).freeze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RectConst shrinkTop(double shrink)
|
||||
{
|
||||
return super.shrinkTop(shrink).freeze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RectConst shrinkBottom(double shrink)
|
||||
{
|
||||
return super.shrinkBottom(shrink).freeze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RectConst growLeft(double shrink)
|
||||
{
|
||||
return super.growLeft(shrink).freeze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RectConst growRight(double shrink)
|
||||
{
|
||||
return super.growRight(shrink).freeze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RectConst growUp(double shrink)
|
||||
{
|
||||
return super.growUp(shrink).freeze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RectConst growDown(double shrink)
|
||||
{
|
||||
return super.growDown(shrink).freeze();
|
||||
}
|
||||
|
||||
|
||||
public RectConst shrinkLeft(NumConst shrink)
|
||||
{
|
||||
return super.shrinkLeft(shrink).freeze();
|
||||
}
|
||||
|
||||
|
||||
public RectConst shrinkRight(NumConst shrink)
|
||||
{
|
||||
return super.shrinkRight(shrink).freeze();
|
||||
}
|
||||
|
||||
|
||||
public RectConst shrinkTop(NumConst shrink)
|
||||
{
|
||||
return super.shrinkTop(shrink).freeze();
|
||||
}
|
||||
|
||||
|
||||
public RectConst shrinkBottom(NumConst shrink)
|
||||
{
|
||||
return super.shrinkBottom(shrink).freeze();
|
||||
}
|
||||
|
||||
|
||||
public RectConst growLeft(NumConst shrink)
|
||||
{
|
||||
return super.growLeft(shrink).freeze();
|
||||
}
|
||||
|
||||
|
||||
public RectConst growRight(NumConst shrink)
|
||||
{
|
||||
return super.growRight(shrink).freeze();
|
||||
}
|
||||
|
||||
|
||||
public RectConst growUp(NumConst shrink)
|
||||
{
|
||||
return super.growUp(shrink).freeze();
|
||||
}
|
||||
|
||||
|
||||
public RectConst growBottom(NumConst shrink)
|
||||
{
|
||||
return super.growDown(shrink).freeze();
|
||||
}
|
||||
|
||||
|
||||
public RectConst centerTo(VectConst point)
|
||||
{
|
||||
return super.centerTo(point).freeze();
|
||||
}
|
||||
|
||||
|
||||
public RectConst centerTo(RectConst parent)
|
||||
{
|
||||
return super.centerTo(parent).freeze();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,149 +0,0 @@
|
||||
package mightypork.util.math.constraints.rect.builders;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.num.Num;
|
||||
import mightypork.util.math.constraints.rect.Rect;
|
||||
import mightypork.util.math.constraints.rect.proxy.RectProxy;
|
||||
|
||||
|
||||
/**
|
||||
* Utility for cutting rect into evenly sized cells.<br>
|
||||
* It's by default one-based, but this can be switched by calling the oneBased()
|
||||
* and zeroBased() methods.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class TiledRect extends RectProxy {
|
||||
|
||||
final private int tilesY;
|
||||
final private int tilesX;
|
||||
final private Num perRow;
|
||||
final private Num perCol;
|
||||
|
||||
private int based = 1;
|
||||
|
||||
|
||||
public TiledRect(Rect source, int horizontal, int vertical) {
|
||||
super(source);
|
||||
this.tilesX = horizontal;
|
||||
this.tilesY = vertical;
|
||||
|
||||
this.perRow = height().div(vertical);
|
||||
this.perCol = width().div(horizontal);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set to one-based mode, and return itself (for chaining).
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public TiledRect oneBased()
|
||||
{
|
||||
based = 1;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set to zero-based mode, and return itself (for chaining).
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public TiledRect zeroBased()
|
||||
{
|
||||
based = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a tile.
|
||||
*
|
||||
* @param x x position
|
||||
* @param y y position
|
||||
* @return tile
|
||||
* @throws IndexOutOfBoundsException when invalid index is specified.
|
||||
*/
|
||||
public Rect tile(int x, int y)
|
||||
{
|
||||
x -= based;
|
||||
y -= based;
|
||||
|
||||
if (x >= tilesX || x < 0) {
|
||||
throw new IndexOutOfBoundsException("X coordinate out fo range.");
|
||||
}
|
||||
|
||||
if (y >= tilesY || y < 0) {
|
||||
throw new IndexOutOfBoundsException("Y coordinate out of range.");
|
||||
}
|
||||
|
||||
final Num leftMove = left().add(perCol.mul(x));
|
||||
final Num topMove = top().add(perRow.mul(y));
|
||||
|
||||
return Rect.make(perCol, perRow).move(leftMove, topMove);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get a span (tile spanning across multiple cells)
|
||||
*
|
||||
* @param x_from x start position
|
||||
* @param y_from y start position
|
||||
* @param size_x horizontal size (columns)
|
||||
* @param size_y vertical size (rows)
|
||||
* @return tile the tile
|
||||
* @throws IndexOutOfBoundsException when invalid index is specified.
|
||||
*/
|
||||
public Rect span(int x_from, int y_from, int size_x, int size_y)
|
||||
{
|
||||
x_from -= based;
|
||||
y_from -= based;
|
||||
|
||||
final int x_to = x_from + size_x;
|
||||
final int y_to = y_from + size_y;
|
||||
|
||||
if (size_x <= 0 || size_y <= 0) {
|
||||
throw new IndexOutOfBoundsException("Size must be > 0.");
|
||||
}
|
||||
|
||||
if (x_from >= tilesX || x_from < 0 || x_to >= tilesX || x_to < 0) {
|
||||
throw new IndexOutOfBoundsException("X coordinate(s) out of range.");
|
||||
}
|
||||
|
||||
if (y_from >= tilesY || y_from < 0 || y_to >= tilesY || y_to < 0) {
|
||||
throw new IndexOutOfBoundsException("Y coordinate(s) out of range.");
|
||||
}
|
||||
|
||||
final Num leftMove = left().add(perCol.mul(x_from));
|
||||
final Num topMove = top().add(perRow.mul(y_from));
|
||||
|
||||
return Rect.make(perCol.mul(size_x), perRow.mul(size_y)).move(leftMove, topMove);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get n-th column
|
||||
*
|
||||
* @param n column index
|
||||
* @return the column tile
|
||||
* @throws IndexOutOfBoundsException when invalid index is specified.
|
||||
*/
|
||||
public Rect column(int n)
|
||||
{
|
||||
return tile(n, based);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get n-th row
|
||||
*
|
||||
* @param n row index
|
||||
* @return the row rect
|
||||
* @throws IndexOutOfBoundsException when invalid index is specified.
|
||||
*/
|
||||
public Rect row(int n)
|
||||
{
|
||||
return tile(based, n);
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
package mightypork.util.math.constraints.rect.caching;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.ConstraintCache;
|
||||
import mightypork.util.math.constraints.rect.Rect;
|
||||
import mightypork.util.math.constraints.rect.mutable.RectVar;
|
||||
import mightypork.util.math.constraints.rect.proxy.RectAdapter;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A rect cache.
|
||||
* </p>
|
||||
* <p>
|
||||
* Values are held in a caching VectVar, and digest caching is enabled by
|
||||
* default.
|
||||
* </p>
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class AbstractRectCache extends RectAdapter implements ConstraintCache<Rect> {
|
||||
|
||||
private final RectVar cache = Rect.makeVar();
|
||||
private boolean inited = false;
|
||||
private boolean cachingEnabled = true;
|
||||
|
||||
|
||||
public AbstractRectCache() {
|
||||
enableDigestCaching(true); // it changes only on poll
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected final Rect getSource()
|
||||
{
|
||||
if (!inited) poll();
|
||||
|
||||
return (cachingEnabled ? cache : getCacheSource());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void poll()
|
||||
{
|
||||
inited = true;
|
||||
|
||||
// poll source
|
||||
final Rect source = getCacheSource();
|
||||
source.markDigestDirty(); // poll cached
|
||||
|
||||
// store source value
|
||||
cache.setTo(source);
|
||||
|
||||
markDigestDirty();
|
||||
|
||||
onChange();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void enableCaching(boolean yes)
|
||||
{
|
||||
cachingEnabled = yes;
|
||||
enableDigestCaching(yes);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final boolean isCachingEnabled()
|
||||
{
|
||||
return cachingEnabled;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package mightypork.util.math.constraints.rect.caching;
|
||||
|
||||
|
||||
import mightypork.util.annotations.DefaultImpl;
|
||||
import mightypork.util.math.constraints.rect.Rect;
|
||||
|
||||
|
||||
/**
|
||||
* Rect cache implementation
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class RectCache extends AbstractRectCache {
|
||||
|
||||
private final Rect source;
|
||||
|
||||
|
||||
public RectCache(Rect source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final Rect getCacheSource()
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@DefaultImpl
|
||||
public void onChange()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package mightypork.util.math.constraints.rect.caching;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.rect.Rect;
|
||||
import mightypork.util.math.constraints.rect.RectConst;
|
||||
|
||||
|
||||
public class RectDigest {
|
||||
|
||||
public final double x;
|
||||
public final double y;
|
||||
public final double width;
|
||||
public final double height;
|
||||
|
||||
public final double left;
|
||||
public final double right;
|
||||
public final double top;
|
||||
public final double bottom;
|
||||
|
||||
|
||||
public RectDigest(Rect rect) {
|
||||
|
||||
final RectConst frozen = rect.freeze();
|
||||
|
||||
this.x = frozen.x().value();
|
||||
this.y = frozen.y().value();
|
||||
|
||||
this.width = frozen.width().value();
|
||||
this.height = frozen.height().value();
|
||||
|
||||
this.left = frozen.left().value();
|
||||
this.right = frozen.right().value();
|
||||
this.top = frozen.top().value();
|
||||
this.bottom = frozen.bottom().value();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("Rect{ at: (%.1f, %.1f), size: (%.1f, %.1f), bounds: L %.1f R %.1f T %.1f B %.1f }", x, y, width, height, left, right, top, bottom);
|
||||
}
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
package mightypork.util.math.constraints.rect.mutable;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.rect.Rect;
|
||||
import mightypork.util.math.constraints.vect.Vect;
|
||||
|
||||
|
||||
/**
|
||||
* Mutable rectangle; operations change it's state.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class RectMutable extends Rect {
|
||||
|
||||
/**
|
||||
* Set to other rect's coordinates
|
||||
*
|
||||
* @param rect other rect
|
||||
*/
|
||||
public void setTo(Rect rect)
|
||||
{
|
||||
setTo(rect.origin(), rect.size());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set to given size and position
|
||||
*
|
||||
* @param origin new origin
|
||||
* @param width new width
|
||||
* @param height new height
|
||||
*/
|
||||
public void setTo(Vect origin, double width, double height)
|
||||
{
|
||||
setTo(origin, Vect.make(width, height));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set to given size and position
|
||||
*
|
||||
* @param x origin.x
|
||||
* @param y origin.y
|
||||
* @param width new width
|
||||
* @param height new height
|
||||
*/
|
||||
public void setTo(double x, double y, double width, double height)
|
||||
{
|
||||
setTo(Vect.make(x, y), Vect.make(width, height));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set to given size and position
|
||||
*
|
||||
* @param origin new origin
|
||||
* @param size new size
|
||||
*/
|
||||
public void setTo(Vect origin, Vect size)
|
||||
{
|
||||
setOrigin(origin);
|
||||
setSize(size);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set to zero
|
||||
*/
|
||||
public void reset()
|
||||
{
|
||||
setTo(Vect.ZERO, Vect.ZERO);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set new origin
|
||||
*
|
||||
* @param origin new origin
|
||||
*/
|
||||
public abstract void setOrigin(Vect origin);
|
||||
|
||||
|
||||
/**
|
||||
* Set new size
|
||||
*
|
||||
* @param size new size
|
||||
*/
|
||||
public abstract void setSize(Vect size);
|
||||
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
package mightypork.util.math.constraints.rect.mutable;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.vect.Vect;
|
||||
import mightypork.util.math.constraints.vect.mutable.VectVar;
|
||||
|
||||
|
||||
public class RectVar extends RectMutable {
|
||||
|
||||
final VectVar pos = Vect.makeVar();
|
||||
final VectVar size = Vect.makeVar();
|
||||
|
||||
|
||||
/**
|
||||
* Create at given origin, with given size.
|
||||
*
|
||||
* @param x
|
||||
* @param y
|
||||
* @param width
|
||||
* @param height
|
||||
*/
|
||||
public RectVar(double x, double y, double width, double height) {
|
||||
this.pos.setTo(x, y);
|
||||
this.size.setTo(width, height);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Vect origin()
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Vect size()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setOrigin(Vect origin)
|
||||
{
|
||||
this.pos.setTo(origin);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setSize(Vect size)
|
||||
{
|
||||
this.size.setTo(size);
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package mightypork.util.math.constraints.rect.proxy;
|
||||
|
||||
|
||||
/**
|
||||
* Pluggable rect bound
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public interface PluggableRectBound extends RectBound {
|
||||
|
||||
/**
|
||||
* @param rect context to set
|
||||
*/
|
||||
abstract void setRect(RectBound rect);
|
||||
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
package mightypork.util.math.constraints.rect.proxy;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.rect.Rect;
|
||||
import mightypork.util.math.constraints.vect.Vect;
|
||||
import mightypork.util.math.constraints.vect.proxy.VectAdapter;
|
||||
|
||||
|
||||
/**
|
||||
* Rect proxy with abstract method for plugging in / generating rect
|
||||
* dynamically.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class RectAdapter extends Rect {
|
||||
|
||||
// adapters are needed in case the vect returned from source changes
|
||||
// (is replaced). This way, references to origin and rect will stay intact.
|
||||
|
||||
private final VectAdapter originAdapter = new VectAdapter() {
|
||||
|
||||
@Override
|
||||
protected Vect getSource()
|
||||
{
|
||||
return RectAdapter.this.getSource().origin();
|
||||
}
|
||||
};
|
||||
|
||||
private final VectAdapter sizeAdapter = new VectAdapter() {
|
||||
|
||||
@Override
|
||||
protected Vect getSource()
|
||||
{
|
||||
return RectAdapter.this.getSource().size();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return the proxied coord
|
||||
*/
|
||||
protected abstract Rect getSource();
|
||||
|
||||
|
||||
@Override
|
||||
public Vect origin()
|
||||
{
|
||||
return originAdapter;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Vect size()
|
||||
{
|
||||
return sizeAdapter;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package mightypork.util.math.constraints.rect.proxy;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.rect.Rect;
|
||||
|
||||
|
||||
/**
|
||||
* Rect constraint (ie. region)
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public interface RectBound {
|
||||
|
||||
/**
|
||||
* @return rect region
|
||||
*/
|
||||
Rect getRect();
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
package mightypork.util.math.constraints.rect.proxy;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.rect.Rect;
|
||||
|
||||
|
||||
/**
|
||||
* Pluggable rect bound adapter
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class RectBoundAdapter extends RectAdapter implements PluggableRectBound {
|
||||
|
||||
private RectBound backing = null;
|
||||
|
||||
|
||||
public RectBoundAdapter() {
|
||||
}
|
||||
|
||||
|
||||
public RectBoundAdapter(RectBound bound) {
|
||||
backing = bound;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setRect(RectBound rect)
|
||||
{
|
||||
this.backing = rect;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Rect getSource()
|
||||
{
|
||||
return backing.getRect();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package mightypork.util.math.constraints.rect.proxy;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.rect.Rect;
|
||||
|
||||
|
||||
public class RectProxy extends RectAdapter {
|
||||
|
||||
private final Rect source;
|
||||
|
||||
|
||||
public RectProxy(Rect source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Rect getSource()
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
package mightypork.util.math.constraints.rect.proxy;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.rect.Rect;
|
||||
import mightypork.util.math.constraints.vect.Vect;
|
||||
|
||||
|
||||
/**
|
||||
* Rect made of two {@link Vect}s
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class RectVectAdapter extends Rect {
|
||||
|
||||
private final Vect origin;
|
||||
private final Vect size;
|
||||
|
||||
|
||||
public RectVectAdapter(Vect origin, Vect size) {
|
||||
this.origin = origin;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Vect origin()
|
||||
{
|
||||
return origin;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Vect size()
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,373 +0,0 @@
|
||||
package mightypork.util.math.constraints.vect;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.num.Num;
|
||||
import mightypork.util.math.constraints.num.NumConst;
|
||||
import mightypork.util.math.constraints.rect.RectConst;
|
||||
import mightypork.util.math.constraints.vect.caching.VectDigest;
|
||||
|
||||
|
||||
/**
|
||||
* Coordinate with immutable numeric values.<br>
|
||||
* This coordinate is guaranteed to never change, as opposed to view.<br>
|
||||
* It's arranged so that operations with constant arguments yield constant
|
||||
* results.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public final class VectConst extends Vect {
|
||||
|
||||
private final double x, y, z;
|
||||
// non-parametric operations are cached using lazy load.
|
||||
private NumConst v_size;
|
||||
private VectConst v_neg;
|
||||
private VectConst v_ceil;
|
||||
private VectConst v_floor;
|
||||
private VectConst v_round;
|
||||
private VectConst v_half;
|
||||
private VectConst v_abs;
|
||||
private NumConst v_xc;
|
||||
private NumConst v_yc;
|
||||
private NumConst v_zc;
|
||||
private VectDigest digest;
|
||||
|
||||
|
||||
VectConst(Vect other) {
|
||||
this(other.x(), other.y(), other.z());
|
||||
}
|
||||
|
||||
|
||||
VectConst(double x, double y, double z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double x()
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double y()
|
||||
{
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double z()
|
||||
{
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return X constraint
|
||||
*/
|
||||
|
||||
@Override
|
||||
public final NumConst xn()
|
||||
{
|
||||
return (v_xc != null) ? v_xc : (v_xc = Num.make(this.x));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Y constraint
|
||||
*/
|
||||
|
||||
@Override
|
||||
public final NumConst yn()
|
||||
{
|
||||
return (v_yc != null) ? v_yc : (v_yc = Num.make(this.y));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Z constraint
|
||||
*/
|
||||
|
||||
@Override
|
||||
public final NumConst zn()
|
||||
{
|
||||
return (v_zc != null) ? v_zc : (v_zc = Num.make(this.z));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated it's useless to copy a constant
|
||||
*/
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public VectConst freeze()
|
||||
{
|
||||
return this; // it's constant already
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectDigest digest()
|
||||
{
|
||||
return (digest != null) ? digest : (digest = super.digest());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst abs()
|
||||
{
|
||||
return (v_abs != null) ? v_abs : (v_abs = super.abs().freeze());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst add(double x, double y)
|
||||
{
|
||||
return super.add(x, y).freeze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst add(double x, double y, double z)
|
||||
{
|
||||
return super.add(x, y, z).freeze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst half()
|
||||
{
|
||||
return (v_half != null) ? v_half : (v_half = super.half().freeze());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst mul(double d)
|
||||
{
|
||||
return super.mul(d).freeze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst mul(double x, double y)
|
||||
{
|
||||
return super.mul(x, y).freeze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst mul(double x, double y, double z)
|
||||
{
|
||||
return super.mul(x, y, z).freeze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst round()
|
||||
{
|
||||
return (v_round != null) ? v_round : (v_round = super.round().freeze());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst floor()
|
||||
{
|
||||
return (v_floor != null) ? v_floor : (v_floor = super.floor().freeze());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst ceil()
|
||||
{
|
||||
if (v_ceil != null) return v_ceil;
|
||||
return v_ceil = super.ceil().freeze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst sub(double x, double y)
|
||||
{
|
||||
return super.sub(x, y).freeze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst sub(double x, double y, double z)
|
||||
{
|
||||
return super.sub(x, y, z).freeze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst neg()
|
||||
{
|
||||
return (v_neg != null) ? v_neg : (v_neg = super.neg().freeze());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst norm(double size)
|
||||
{
|
||||
return super.norm(size).freeze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public NumConst size()
|
||||
{
|
||||
return (v_size != null) ? v_size : (v_size = super.size().freeze());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst withX(double x)
|
||||
{
|
||||
return super.withX(x).freeze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst withY(double y)
|
||||
{
|
||||
return super.withY(y).freeze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public VectConst withZ(double z)
|
||||
{
|
||||
return super.withZ(z).freeze();
|
||||
}
|
||||
|
||||
|
||||
public VectConst withX(NumConst x)
|
||||
{
|
||||
return super.withX(x).freeze();
|
||||
}
|
||||
|
||||
|
||||
public VectConst withY(NumConst y)
|
||||
{
|
||||
return super.withY(y).freeze();
|
||||
}
|
||||
|
||||
|
||||
public VectConst withZ(NumConst z)
|
||||
{
|
||||
return super.withZ(z).freeze();
|
||||
}
|
||||
|
||||
|
||||
public VectConst add(VectConst vec)
|
||||
{
|
||||
return super.add(vec).freeze();
|
||||
}
|
||||
|
||||
|
||||
public VectConst add(NumConst x, NumConst y)
|
||||
{
|
||||
return super.add(x, y).freeze();
|
||||
}
|
||||
|
||||
|
||||
public VectConst add(NumConst x, NumConst y, NumConst z)
|
||||
{
|
||||
return super.add(x, y, z).freeze();
|
||||
}
|
||||
|
||||
|
||||
public VectConst mul(VectConst vec)
|
||||
{
|
||||
return super.mul(vec).freeze();
|
||||
}
|
||||
|
||||
|
||||
public VectConst mul(NumConst d)
|
||||
{
|
||||
return super.mul(d).freeze();
|
||||
}
|
||||
|
||||
|
||||
public VectConst mul(NumConst x, NumConst y)
|
||||
{
|
||||
return super.mul(x, y).freeze();
|
||||
}
|
||||
|
||||
|
||||
public VectConst mul(NumConst x, NumConst y, NumConst z)
|
||||
{
|
||||
return super.mul(x, y, z).freeze();
|
||||
}
|
||||
|
||||
|
||||
public VectConst sub(VectConst vec)
|
||||
{
|
||||
return super.sub(vec).freeze();
|
||||
}
|
||||
|
||||
|
||||
public VectConst sub(NumConst x, NumConst y)
|
||||
{
|
||||
return super.sub(x, y).freeze();
|
||||
}
|
||||
|
||||
|
||||
public VectConst sub(NumConst x, NumConst y, NumConst z)
|
||||
{
|
||||
return super.sub(x, y, z).freeze();
|
||||
}
|
||||
|
||||
|
||||
public VectConst norm(NumConst size)
|
||||
{
|
||||
return super.norm(size).freeze();
|
||||
}
|
||||
|
||||
|
||||
public NumConst dist(VectConst point)
|
||||
{
|
||||
return super.dist(point).freeze();
|
||||
}
|
||||
|
||||
|
||||
public VectConst midTo(VectConst point)
|
||||
{
|
||||
return super.midTo(point).freeze();
|
||||
}
|
||||
|
||||
|
||||
public VectConst vectTo(VectConst point)
|
||||
{
|
||||
return super.vectTo(point).freeze();
|
||||
}
|
||||
|
||||
|
||||
public NumConst dot(VectConst vec)
|
||||
{
|
||||
return super.dot(vec).freeze();
|
||||
}
|
||||
|
||||
|
||||
public VectConst cross(VectConst vec)
|
||||
{
|
||||
return super.cross(vec).freeze();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public RectConst expand(double left, double right, double top, double bottom)
|
||||
{
|
||||
return super.expand(left, right, top, bottom).freeze();
|
||||
}
|
||||
|
||||
|
||||
public RectConst expand(NumConst left, NumConst right, NumConst top, NumConst bottom)
|
||||
{
|
||||
return super.expand(left, right, top, bottom).freeze();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
package mightypork.util.math.constraints.vect;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.vect.proxy.VectAdapter;
|
||||
|
||||
|
||||
public class VectProxy extends VectAdapter {
|
||||
|
||||
private final Vect source;
|
||||
|
||||
|
||||
public VectProxy(Vect source) {
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Vect getSource()
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
package mightypork.util.math.constraints.vect.caching;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.ConstraintCache;
|
||||
import mightypork.util.math.constraints.vect.Vect;
|
||||
import mightypork.util.math.constraints.vect.mutable.VectVar;
|
||||
import mightypork.util.math.constraints.vect.proxy.VectAdapter;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A vect cache.
|
||||
* </p>
|
||||
* <p>
|
||||
* Values are held in a caching VectVar, and digest caching is enabled by
|
||||
* default.
|
||||
* </p>
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class AbstractVectCache extends VectAdapter implements ConstraintCache<Vect> {
|
||||
|
||||
private final VectVar cache = Vect.makeVar();
|
||||
private boolean inited = false;
|
||||
private boolean cachingEnabled = true;
|
||||
|
||||
|
||||
public AbstractVectCache() {
|
||||
enableDigestCaching(true); // it changes only on poll
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected final Vect getSource()
|
||||
{
|
||||
if (!inited) markDigestDirty();
|
||||
|
||||
return (cachingEnabled ? cache : getCacheSource());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void poll()
|
||||
{
|
||||
inited = true;
|
||||
|
||||
// poll source
|
||||
final Vect source = getCacheSource();
|
||||
source.markDigestDirty(); // poll cached
|
||||
|
||||
// store source value
|
||||
cache.setTo(source);
|
||||
|
||||
markDigestDirty();
|
||||
|
||||
onChange();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void enableCaching(boolean yes)
|
||||
{
|
||||
cachingEnabled = yes;
|
||||
enableDigestCaching(yes);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final boolean isCachingEnabled()
|
||||
{
|
||||
return cachingEnabled;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package mightypork.util.math.constraints.vect.caching;
|
||||
|
||||
|
||||
import mightypork.util.annotations.DefaultImpl;
|
||||
import mightypork.util.math.constraints.vect.Vect;
|
||||
|
||||
|
||||
/**
|
||||
* Vect cache implementation
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class VectCache extends AbstractVectCache {
|
||||
|
||||
private final Vect source;
|
||||
|
||||
|
||||
public VectCache(Vect source) {
|
||||
this.source = source;
|
||||
enableDigestCaching(true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Vect getCacheSource()
|
||||
{
|
||||
return source;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@DefaultImpl
|
||||
public void onChange()
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package mightypork.util.math.constraints.vect.caching;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.vect.Vect;
|
||||
|
||||
|
||||
public class VectDigest {
|
||||
|
||||
public final double x;
|
||||
public final double y;
|
||||
public final double z;
|
||||
|
||||
|
||||
public VectDigest(Vect vect) {
|
||||
this.x = vect.x();
|
||||
this.y = vect.y();
|
||||
this.z = vect.z();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return String.format("Vect(%.1f, %.1f, %.1f)", x, y, z);
|
||||
}
|
||||
}
|
||||
@@ -1,291 +0,0 @@
|
||||
package mightypork.util.math.constraints.vect.mutable;
|
||||
|
||||
|
||||
import mightypork.util.annotations.FactoryMethod;
|
||||
import mightypork.util.control.timing.Pauseable;
|
||||
import mightypork.util.control.timing.Updateable;
|
||||
import mightypork.util.math.Easing;
|
||||
import mightypork.util.math.constraints.num.mutable.NumAnimated;
|
||||
import mightypork.util.math.constraints.vect.Vect;
|
||||
|
||||
|
||||
/**
|
||||
* 3D coordinated with support for transitions, mutable.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class VectAnimated extends VectMutable implements Pauseable, Updateable {
|
||||
|
||||
private final NumAnimated x, y, z;
|
||||
private double defaultDuration = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Create an animated vector; This way different easing / settings can be
|
||||
* specified for each coordinate.
|
||||
*
|
||||
* @param x x animator
|
||||
* @param y y animator
|
||||
* @param z z animator
|
||||
*/
|
||||
public VectAnimated(NumAnimated x, NumAnimated y, NumAnimated z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create an animated vector
|
||||
*
|
||||
* @param start initial positioon
|
||||
* @param easing animation easing
|
||||
*/
|
||||
public VectAnimated(Vect start, Easing easing) {
|
||||
x = new NumAnimated(start.x(), easing);
|
||||
y = new NumAnimated(start.y(), easing);
|
||||
z = new NumAnimated(start.z(), easing);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double x()
|
||||
{
|
||||
return x.value();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double y()
|
||||
{
|
||||
return y.value();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double z()
|
||||
{
|
||||
return z.value();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setTo(double x, double y, double z)
|
||||
{
|
||||
setX(x);
|
||||
setY(y);
|
||||
setZ(z);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setX(double x)
|
||||
{
|
||||
this.x.animate(x, defaultDuration);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setY(double y)
|
||||
{
|
||||
this.y.animate(y, defaultDuration);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setZ(double z)
|
||||
{
|
||||
this.z.animate(z, defaultDuration);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add offset with animation
|
||||
*
|
||||
* @param offset added offset
|
||||
* @param duration animation time (seconds)
|
||||
*/
|
||||
public void add(Vect offset, double duration)
|
||||
{
|
||||
animate(this.add(offset), duration);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Animate to given coordinates in given amount of time
|
||||
*
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param duration animation time (seconds)
|
||||
* @return this
|
||||
*/
|
||||
public VectAnimated animate(double x, double y, double z, double duration)
|
||||
{
|
||||
this.x.animate(x, duration);
|
||||
this.y.animate(y, duration);
|
||||
this.z.animate(z, duration);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Animate to given vec in given amount of time.
|
||||
*
|
||||
* @param target target (only it's current value will be used)
|
||||
* @param duration animation time (seconds)
|
||||
* @return this
|
||||
*/
|
||||
public VectAnimated animate(Vect target, double duration)
|
||||
{
|
||||
animate(target.x(), target.y(), target.z(), duration);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return the default duration (seconds)
|
||||
*/
|
||||
public double getDefaultDuration()
|
||||
{
|
||||
return defaultDuration;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set default animation duration (when changed without using animate())
|
||||
*
|
||||
* @param defaultDuration default duration (seconds)
|
||||
*/
|
||||
public void setDefaultDuration(double defaultDuration)
|
||||
{
|
||||
this.defaultDuration = defaultDuration;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void update(double delta)
|
||||
{
|
||||
x.update(delta);
|
||||
y.update(delta);
|
||||
z.update(delta);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void pause()
|
||||
{
|
||||
x.pause();
|
||||
y.pause();
|
||||
z.pause();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void resume()
|
||||
{
|
||||
x.resume();
|
||||
y.resume();
|
||||
z.resume();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isPaused()
|
||||
{
|
||||
return x.isPaused(); // BÚNO
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true if the animation is finished
|
||||
*/
|
||||
public boolean isFinished()
|
||||
{
|
||||
return x.isFinished(); // BÚNO
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return current animation duration
|
||||
*/
|
||||
public double getDuration()
|
||||
{
|
||||
return x.getDuration(); // BÚNO
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return elapsed time since the start of the animation
|
||||
*/
|
||||
public double getElapsed()
|
||||
{
|
||||
return x.getElapsed(); // BÚNO
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return animation progress (elapsed / duration)
|
||||
*/
|
||||
public double getProgress()
|
||||
{
|
||||
return x.getProgress(); // BÚNO
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set easing for all three coordinates
|
||||
*
|
||||
* @param easing
|
||||
*/
|
||||
public void setEasing(Easing easing)
|
||||
{
|
||||
x.setEasing(easing);
|
||||
y.setEasing(easing);
|
||||
z.setEasing(easing);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create an animated vector; This way different easing / settings can be
|
||||
* specified for each coordinate.
|
||||
*
|
||||
* @param x x animator
|
||||
* @param y y animator
|
||||
* @param z z animator
|
||||
* @return animated mutable vector
|
||||
*/
|
||||
@FactoryMethod
|
||||
public static VectAnimated makeVar(NumAnimated x, NumAnimated y, NumAnimated z)
|
||||
{
|
||||
return new VectAnimated(x, y, z);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create an animated vector
|
||||
*
|
||||
* @param start initial positioon
|
||||
* @param easing animation easing
|
||||
* @return animated mutable vector
|
||||
*/
|
||||
@FactoryMethod
|
||||
public static VectAnimated makeVar(Vect start, Easing easing)
|
||||
{
|
||||
return new VectAnimated(start, easing);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create an animated vector, initialized at 0,0,0
|
||||
*
|
||||
* @param easing animation easing
|
||||
* @return animated mutable vector
|
||||
*/
|
||||
@FactoryMethod
|
||||
public static VectAnimated makeVar(Easing easing)
|
||||
{
|
||||
return new VectAnimated(Vect.ZERO, easing);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
package mightypork.util.math.constraints.vect.mutable;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.vect.Vect;
|
||||
|
||||
|
||||
/**
|
||||
* Mutable coord
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
abstract class VectMutable extends Vect {
|
||||
|
||||
/**
|
||||
* Set all to zeros.
|
||||
*/
|
||||
public void reset()
|
||||
{
|
||||
setTo(0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set coordinates to match other coord.
|
||||
*
|
||||
* @param copied coord whose coordinates are used
|
||||
*/
|
||||
public void setTo(Vect copied)
|
||||
{
|
||||
setTo(copied.x(), copied.y(), copied.z());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set 2D coordinates.<br>
|
||||
* Z is unchanged.
|
||||
*
|
||||
* @param x x coordinate
|
||||
* @param y y coordinate
|
||||
*/
|
||||
public void setTo(double x, double y)
|
||||
{
|
||||
setX(x);
|
||||
setY(y);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set coordinates.
|
||||
*
|
||||
* @param x x coordinate
|
||||
* @param y y coordinate
|
||||
* @param z z coordinate
|
||||
*/
|
||||
public abstract void setTo(double x, double y, double z);
|
||||
|
||||
|
||||
/**
|
||||
* Set X coordinate.
|
||||
*
|
||||
* @param x x coordinate
|
||||
*/
|
||||
public abstract void setX(double x);
|
||||
|
||||
|
||||
/**
|
||||
* Set Y coordinate.
|
||||
*
|
||||
* @param y y coordinate
|
||||
*/
|
||||
public abstract void setY(double y);
|
||||
|
||||
|
||||
/**
|
||||
* Set Z coordinate.
|
||||
*
|
||||
* @param z z coordinate
|
||||
*/
|
||||
public abstract void setZ(double z);
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
package mightypork.util.math.constraints.vect.mutable;
|
||||
|
||||
|
||||
/**
|
||||
* Mutable coordinate.<br>
|
||||
* All Vec methods (except copy) alter data values and return this instance.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class VectVar extends VectMutable {
|
||||
|
||||
private double x, y, z;
|
||||
|
||||
|
||||
/**
|
||||
* @param x X coordinate
|
||||
* @param y Y coordinate
|
||||
* @param z Z coordinate
|
||||
*/
|
||||
public VectVar(double x, double y, double z) {
|
||||
super();
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double x()
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double y()
|
||||
{
|
||||
return y;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double z()
|
||||
{
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setTo(double x, double y, double z)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setX(double x)
|
||||
{
|
||||
this.x = x;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setY(double y)
|
||||
{
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setZ(double z)
|
||||
{
|
||||
this.z = z;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package mightypork.util.math.constraints.vect.proxy;
|
||||
|
||||
|
||||
/**
|
||||
* Pluggable vector constraint
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public interface PluggableVectBound extends VectBound {
|
||||
|
||||
/**
|
||||
* @param num bound to set
|
||||
*/
|
||||
abstract void setVect(VectBound num);
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package mightypork.util.math.constraints.vect.proxy;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.vect.Vect;
|
||||
|
||||
|
||||
/**
|
||||
* Vect proxy with abstract method for plugging in / generating coordinates
|
||||
* dynamically.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class VectAdapter extends Vect {
|
||||
|
||||
/**
|
||||
* @return the proxied coord
|
||||
*/
|
||||
protected abstract Vect getSource();
|
||||
|
||||
|
||||
@Override
|
||||
public double x()
|
||||
{
|
||||
return getSource().x();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double y()
|
||||
{
|
||||
return getSource().y();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double z()
|
||||
{
|
||||
return getSource().z();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
package mightypork.util.math.constraints.vect.proxy;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.vect.Vect;
|
||||
|
||||
|
||||
/**
|
||||
* Element holding a vector, used for constraint building.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public interface VectBound {
|
||||
|
||||
/**
|
||||
* @return the current vector.
|
||||
*/
|
||||
public Vect getVect();
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
package mightypork.util.math.constraints.vect.proxy;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.vect.Vect;
|
||||
|
||||
|
||||
public class VectBoundAdapter extends VectAdapter implements PluggableVectBound {
|
||||
|
||||
private VectBound backing = null;
|
||||
|
||||
|
||||
public VectBoundAdapter() {
|
||||
}
|
||||
|
||||
|
||||
public VectBoundAdapter(VectBound bound) {
|
||||
backing = bound;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void setVect(VectBound rect)
|
||||
{
|
||||
this.backing = rect;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Vect getSource()
|
||||
{
|
||||
return backing.getVect();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
package mightypork.util.math.constraints.vect.proxy;
|
||||
|
||||
|
||||
import mightypork.util.math.constraints.num.Num;
|
||||
import mightypork.util.math.constraints.num.proxy.NumBound;
|
||||
import mightypork.util.math.constraints.vect.Vect;
|
||||
|
||||
|
||||
/**
|
||||
* Coord view composed of given {@link NumBound}s, using their current values.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class VectNumAdapter extends Vect {
|
||||
|
||||
private final Num constrX;
|
||||
private final Num constrY;
|
||||
private final Num constrZ;
|
||||
|
||||
|
||||
public VectNumAdapter(Num x, Num y, Num z) {
|
||||
this.constrX = x;
|
||||
this.constrY = y;
|
||||
this.constrZ = z;
|
||||
}
|
||||
|
||||
|
||||
public VectNumAdapter(Num x, Num y) {
|
||||
this.constrX = x;
|
||||
this.constrY = y;
|
||||
this.constrZ = Num.ZERO;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double x()
|
||||
{
|
||||
return constrX.value();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double y()
|
||||
{
|
||||
return constrY.value();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public double z()
|
||||
{
|
||||
return constrZ.value();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user