package de.lessvoid.nifty.tools;
import javax.annotation.Nonnull;
import java.util.ArrayList;
/**
* A value computed based on linear interpolation between a set of points.
*
* @author void
*/
public class LinearInterpolator {
@Nonnull
private final ArrayList<Point> curve = new ArrayList<Point>();
private float maxX = 0;
public void addPoint(final float x, final float y) {
curve.add(new Point(x, y));
}
public void prepare() {
maxX = calcMaxX(curve);
for (Point p : curve) {
p.x = p.x / maxX;
}
}
public float getMaxX() {
return maxX;
}
public float getValue(final float x) {
Point p0 = curve.get(0);
for (int i = 1; i < curve.size(); i++) {
Point p1 = curve.get(i);
if (isInInterval(x, p0, p1)) {
return calcValue(x, p0, p1);
}
p0 = p1;
}
if (x > curve.get(curve.size() - 1).x) {
return curve.get(curve.size() - 1).y;
} else if (x < curve.get(0).x) {
return curve.get(0).y;
} else {
return 0.0f;
}
}
private boolean isInInterval(final float x, @Nonnull final Point p0, @Nonnull final Point p1) {
return x >= p0.x && x <= p1.x;
}
private float calcValue(final float x, @Nonnull final Point p0, @Nonnull final Point p1) {
float st = (x - p0.x) / (p1.x - p0.x);
return p0.y + st * (p1.y - p0.y);
}
private float calcMaxX(@Nonnull final ArrayList<Point> curve) {
float maxX = -1.0f;
for (Point p : curve) {
if (p.x > maxX) {
maxX = p.x;
}
}
return maxX;
}
public static class Point {
public float x;
public final float y;
public Point(final float x, final float y) {
this.x = x;
this.y = y;
}
}
}