An Gradle Struktur angepasst

This commit is contained in:
ngb
2022-07-11 14:06:47 +02:00
parent 944249ce82
commit 921e2fb3ef
4 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,200 @@
package schule.ngb.zm.anim;
import schule.ngb.zm.Color;
import schule.ngb.zm.Constants;
import schule.ngb.zm.Vector;
import schule.ngb.zm.tasks.FrameSynchronizedTask;
import schule.ngb.zm.tasks.TaskRunner;
import schule.ngb.zm.util.Log;
import schule.ngb.zm.util.Validator;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.Future;
import java.util.function.*;
public class Animations {
public static final <T> Future<T> animateProperty( String propName, T target, double to, int runtime, DoubleUnaryOperator easing ) {
double from;
try {
from = callGetter(target, propName, double.class);
} catch( InvocationTargetException | NoSuchMethodException |
IllegalAccessException ex ) {
throw new RuntimeException("Can't access property getter for animation.", ex);
}
Method propSetter;
try {
propSetter = findSetter(target, propName, double.class);
} catch( NoSuchMethodException ex ) {
throw new RuntimeException("Can't find property setter for animation.", ex);
}
return animateProperty(target, from, to, runtime, easing, ( d ) -> {
try {
propSetter.invoke(target, d);
} catch( IllegalAccessException | InvocationTargetException e ) {
throw new RuntimeException("Can't access property setter for animation.", e);
}
});
}
public static final <T> Future<T> animateProperty( String propName, T target, Color to, int runtime, DoubleUnaryOperator easing ) {
Color from;
try {
from = callGetter(target, propName, Color.class);
} catch( InvocationTargetException | NoSuchMethodException |
IllegalAccessException ex ) {
throw new RuntimeException("Can't access property getter for animation.", ex);
}
Method propSetter;
try {
propSetter = findSetter(target, propName, Color.class);
} catch( NoSuchMethodException ex ) {
throw new RuntimeException("Can't find property setter for animation.", ex);
}
return animateProperty(target, from, to, runtime, easing, ( d ) -> {
try {
propSetter.invoke(target, d);
} catch( IllegalAccessException | InvocationTargetException e ) {
throw new RuntimeException("Can't access property setter for animation.", e);
}
});
}
public static final <T> Future<T> animateProperty( String propName, T target, Vector to, int runtime, DoubleUnaryOperator easing ) {
Vector from;
try {
from = callGetter(target, propName, Vector.class);
} catch( InvocationTargetException | NoSuchMethodException |
IllegalAccessException ex ) {
throw new RuntimeException("Can't access property getter for animation.", ex);
}
Method propSetter;
try {
propSetter = findSetter(target, propName, Vector.class);
} catch( NoSuchMethodException ex ) {
throw new RuntimeException("Can't find property setter for animation.", ex);
}
return animateProperty(target, from, to, runtime, easing, ( d ) -> {
try {
propSetter.invoke(target, d);
} catch( IllegalAccessException | InvocationTargetException e ) {
throw new RuntimeException("Can't access property setter for animation.", e);
}
});
}
private static final <T, R> R callGetter( T target, String propName, Class<R> propType ) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
String getterName = makeMethodName("get", propName);
Method getter = target.getClass().getMethod(getterName);
if( getter != null && getter.getReturnType().equals(propType) ) {
return (R) getter.invoke(target);
} else {
throw new NoSuchMethodException(String.format("No getter for property <%s> found.", propName));
}
}
private static final <T, R> Method findSetter( T target, String propName, Class<R> propType ) throws NoSuchMethodException {
String setterName = makeMethodName("set", propName);
Method setter = target.getClass().getMethod(setterName, propType);
if( setter != null && setter.getReturnType().equals(void.class) && setter.getParameterCount() == 1 ) {
return setter;
} else {
throw new NoSuchMethodException(String.format("No setter for property <%s> found.", propName));
}
}
private static final String makeMethodName( String prefix, String propName ) {
String firstChar = propName.substring(0, 1).toUpperCase();
String tail = "";
if( propName.length() > 1 ) {
tail = propName.substring(1);
}
return prefix + firstChar + tail;
}
public static final <T> Future<T> animateProperty( T target, final double from, final double to, int runtime, DoubleUnaryOperator easing, DoubleConsumer propSetter ) {
Validator.requireNotNull(target);
Validator.requireNotNull(propSetter);
return animate(target, runtime, easing, ( e ) -> propSetter.accept(Constants.interpolate(from, to, e)));
}
public static final <T> Future<T> animateProperty( T target, final Color from, final Color to, int runtime, DoubleUnaryOperator easing, Consumer<Color> propSetter ) {
return animate(target, runtime, easing, ( e ) -> propSetter.accept(Color.interpolate(from, to, e)));
}
public static final <T> Future<T> animateProperty( T target, final Vector from, final Vector to, int runtime, DoubleUnaryOperator easing, Consumer<Vector> propSetter ) {
return animate(target, runtime, easing, ( e ) -> propSetter.accept(Vector.interpolate(from, to, e)));
}
public static final <T, R> Future<T> animateProperty( T target, R from, R to, int runtime, DoubleUnaryOperator easing, DoubleFunction<R> interpolator, Consumer<R> propSetter ) {
return animate(target, runtime, easing, interpolator, ( t, r ) -> propSetter.accept(r));
}
public static final <T, R> Future<T> animate( T target, int runtime, DoubleUnaryOperator easing, DoubleFunction<R> interpolator, BiConsumer<T, R> applicator ) {
return animate(target, runtime, easing, ( e ) -> applicator.accept(target, interpolator.apply(e)));
}
public static final <T> Future<T> animate( T target, int runtime, DoubleUnaryOperator easing, DoubleConsumer stepper ) {
/*final long starttime = System.currentTimeMillis();
return TaskRunner.run(() -> {
double t = 0.0;
do {
// One animation step for t in [0,1]
stepper.accept(easing.applyAsDouble(t));
try {
Thread.sleep(1000 / Constants.framesPerSecond);
} catch( InterruptedException ex ) {
}
t = (double) (System.currentTimeMillis() - starttime) / (double) runtime;
} while( t < 1.0 );
stepper.accept(easing.applyAsDouble(1.0));
}, target);*/
return TaskRunner.run(new FrameSynchronizedTask() {
double t = 0.0;
final long starttime = System.currentTimeMillis();
@Override
public void update( double delta ) {
// One animation step for t in [0,1]
stepper.accept(easing.applyAsDouble(t));
t = (double) (System.currentTimeMillis() - starttime) / (double) runtime;
running = (t <= 1.0);
}
@Override
protected void finish() {
stepper.accept(easing.applyAsDouble(1.0));
}
}, target);
}
public static final <T, R> Future<T> animate( T target, int runtime, Animator<T, R> animator ) {
return animate(
target, runtime,
animator::easing,
animator::interpolator,
animator::applicator
);
}
/*public static <T> Future<?> animate( Animation<T> animation ) {
animation.start();
return null;
}
public static <T> Future<?> animate( Animation<T> animation, DoubleUnaryOperator easing ) {
animation.start(easing);
return null;
}*/
public static final Log LOG = Log.getLogger(Animations.class);
}

View File

@@ -0,0 +1,11 @@
package schule.ngb.zm.anim;
public interface Animator<T, R> {
double easing(double t);
R interpolator(double e);
void applicator(T target, R value);
}

View File

@@ -0,0 +1,320 @@
package schule.ngb.zm.anim;
import java.util.function.DoubleUnaryOperator;
/**
* @see <a href="https://easings.net/de">Cheat Sheet für Easing-Funktionen</a>
*/
public class Easing {
public static final DoubleUnaryOperator DEFAULT_EASING = Easing::smooth;
public static final DoubleUnaryOperator thereAndBack() {
return Easing::thereAndBack;
}
public static final DoubleUnaryOperator thereAndBack( final DoubleUnaryOperator baseEasing ) {
return ( t ) -> thereAndBack(t, baseEasing);
}
public static final double thereAndBack( double t ) {
return thereAndBack(t, DEFAULT_EASING);
}
public static final double thereAndBack( double t, DoubleUnaryOperator baseEasing ) {
if( t < 0.5 ) {
return baseEasing.applyAsDouble(2 * t);
} else {
return baseEasing.applyAsDouble(2 - 2 * t);
}
}
public static final DoubleUnaryOperator halfAndHalf( final DoubleUnaryOperator firstEasing, final DoubleUnaryOperator secondEasing ) {
return ( t ) -> halfAndHalf(t, firstEasing, secondEasing);
}
public static final DoubleUnaryOperator halfAndHalf( final DoubleUnaryOperator firstEasing, final DoubleUnaryOperator secondEasing, final double split ) {
return ( t ) -> halfAndHalf(t, firstEasing, secondEasing, split);
}
public static final double halfAndHalf( double t, DoubleUnaryOperator firstEasing, DoubleUnaryOperator secondEasing ) {
return halfAndHalf(t, firstEasing, secondEasing, 0.5);
}
public static final double halfAndHalf( double t, DoubleUnaryOperator firstEasing, DoubleUnaryOperator secondEasing, double split ) {
if( t < split ) {
return firstEasing.applyAsDouble(2 * t);
} else {
return secondEasing.applyAsDouble(1 - 2 * t);
}
}
/*
* Functions taken from easings.net
*/
public static final DoubleUnaryOperator linear() {
return Easing::linear;
}
public static final double linear( double t ) {
return t;
}
public static final DoubleUnaryOperator quadIn() {
return Easing::quadIn;
}
public static final double quadIn( double t ) {
return t * t;
}
public static final DoubleUnaryOperator quadOut() {
return Easing::quadOut;
}
public static final double quadOut( double t ) {
return 1 - (1 - t) * (1 - t);
}
public static final DoubleUnaryOperator quadInOut() {
return Easing::quadInOut;
}
public static final double quadInOut( double t ) {
return t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;
}
public static final DoubleUnaryOperator cubicIn() {
return Easing::cubicIn;
}
public static final double cubicIn( double t ) {
return t * t * t;
}
public static final DoubleUnaryOperator cubicOut() {
return Easing::cubicOut;
}
public static final double cubicOut( double t ) {
return 1 - Math.pow(1 - t, 3);
}
public static final DoubleUnaryOperator cubicInOut() {
return Easing::cubicInOut;
}
public static final double cubicInOut( double t ) {
return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
}
public static final DoubleUnaryOperator sineIn() {
return Easing::sineIn;
}
public static final double sineIn( double t ) {
return 1 - Math.cos((t * Math.PI) / 2);
}
public static final DoubleUnaryOperator sineOut() {
return Easing::sineOut;
}
public static final double sineOut( double t ) {
return Math.sin((t * Math.PI) / 2);
}
public static final DoubleUnaryOperator sineInOut() {
return Easing::sineInOut;
}
public static final double sineInOut( double t ) {
return -(Math.cos(Math.PI * t) - 1) / 2;
}
public static final DoubleUnaryOperator elasticIn() {
return Easing::elasticIn;
}
public static final double elasticIn( double t ) {
double c4 = (2 * Math.PI) / 3;
return t == 0
? 0
: t == 1
? 1
: -Math.pow(2, 10 * t - 10) * Math.sin((t * 10 - 10.75) * c4);
}
public static final DoubleUnaryOperator elasticOut() {
return Easing::elasticOut;
}
public static final double elasticOut( double t ) {
double c4 = (2 * Math.PI) / 3;
return t == 0
? 0
: t == 1
? 1
: Math.pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * c4) + 1;
}
public static final DoubleUnaryOperator elasticInOut() {
return Easing::elasticInOut;
}
public static final double elasticInOut( double t ) {
double c5 = (2 * Math.PI) / 4.5;
return t == 0
? 0
: t == 1
? 1
: t < 0.5
? -(Math.pow(2, 20 * t - 10) * Math.sin((20 * t - 11.125) * c5)) / 2
: (Math.pow(2, -20 * t + 10) * Math.sin((20 * t - 11.125) * c5)) / 2 + 1;
}
public static final DoubleUnaryOperator bounceIn() {
return Easing::bounceIn;
}
public static final double bounceIn( double t ) {
return 1 - bounceOut(1 - t);
}
public static final DoubleUnaryOperator bounceOut() {
return Easing::bounceOut;
}
public static final double bounceOut( double t ) {
double n1 = 7.5625;
double d1 = 2.75;
if( t < 1.0 / d1 ) {
return n1 * t * t;
} else if( t < 2.0 / d1 ) {
return n1 * (t -= 1.5 / d1) * t + 0.75;
} else if( t < 2.5 / d1 ) {
return n1 * (t -= 2.25 / d1) * t + 0.9375;
} else {
return n1 * (t -= 2.625 / d1) * t + 0.984375;
}
}
public static final DoubleUnaryOperator bounceInOut() {
return Easing::bounceInOut;
}
public static final double bounceInOut( double t ) {
return t < 0.5
? (1 - bounceOut(1 - 2 * t)) / 2
: (1 + bounceOut(2 * t - 1)) / 2;
}
public static final DoubleUnaryOperator backIn() {
return Easing::backIn;
}
public static final double backIn( double t ) {
double c1 = 1.70158;
double c3 = c1 + 1;
return c3 * t * t * t - c1 * t * t;
}
public static final DoubleUnaryOperator backOut() {
return Easing::backOut;
}
public static final double backOut( double t ) {
double c1 = 1.70158;
double c3 = c1 + 1;
return 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2);
}
public static final DoubleUnaryOperator backInOut() {
return Easing::backInOut;
}
public static final double backInOut( double t ) {
double c1 = 1.70158;
double c2 = c1 * 1.525;
return t < 0.5
? (Math.pow(2 * t, 2) * ((c2 + 1) * 2 * t - c2)) / 2
: (Math.pow(2 * t - 2, 2) * ((c2 + 1) * (t * 2 - 2) + c2) + 2) / 2;
}
/*
* Functions from manim community
*/
public static final DoubleUnaryOperator smooth() {
return Easing::smooth;
}
public static final double smooth( double t ) {
double error = sigmoid(-INFLECTION / 2.0);
return Math.min(
Math.max(
(sigmoid(INFLECTION * (t - 0.5)) - error) / (1 - 2 * error),
0
),
1.0
);
}
public static final double rushIn( double t ) {
return 2 * smooth(t / 2.0);
}
public static final double rushOut( double t ) {
return 2 * smooth(t / 2.0 + 0.5) - 1;
}
public static final double doubleSmooth( double t ) {
if( t < 0.5 )
return 0.5 * smooth(2 * t);
else
return 0.5 * (1 + smooth(2 * t - 1));
}
public static final double hobbit( double t ) {
double new_t = t < 0.5 ? 2 * t : 2 * (1 - t);
return smooth(new_t);
}
public static final DoubleUnaryOperator wiggle() {
return Easing::wiggle;
}
public static final DoubleUnaryOperator wiggle( final int wiggles ) {
return (t) -> Easing.wiggle(t, wiggles);
}
public static final double wiggle( double t ) {
return wiggle(t, 2);
}
public static final double wiggle( double t, int wiggles ) {
return hobbit(t) * Math.sin(wiggles * Math.PI * t);
}
public static double INFLECTION = 10.0;
public static final double sigmoid( double x ) {
return 1.0 / (1 + Math.exp(-x));
}
private Easing() {
}
}