package tc.oc.commons.bukkit.geometry; import java.util.Optional; import java.util.function.DoubleUnaryOperator; public class LinearFunction implements DoubleUnaryOperator { private final double linear, constant; private LinearFunction(double linear, double constant) { this.linear = linear; this.constant = constant; } private static final LinearFunction IDENTITY = new LinearFunction(1, 0); public static LinearFunction identity() { return IDENTITY; } public static LinearFunction of(double linear, double constant) { return new LinearFunction(linear, constant); } public static LinearFunction scale(double linear) { return new LinearFunction(linear, 0); } public static LinearFunction translate(double constant) { return new LinearFunction(1, constant); } public static LinearFunction fixed(double fixed) { return new LinearFunction(0, fixed); } public double linear() { return linear; } public double constant() { return constant; } public double apply(double n) { return linear * n + constant; } @Override public double applyAsDouble(double operand) { return apply(operand); } public boolean isIdentity() { return linear == 1 && constant == 0; } public boolean isInvertible() { return linear != 0; } public Optional<LinearFunction> inverse() { if(linear == 0) { return Optional.empty(); } else { return Optional.of(new LinearFunction(1 / linear, -constant / linear)); } } public LinearFunction append(LinearFunction that) { return new LinearFunction(this.linear * that.linear, this.linear * that.constant + this.constant); } public LinearFunction prepend(LinearFunction that) { return that.append(this); } }