1 package net.sf.openrocket.util;
3 import java.util.Arrays;
4 import java.util.Iterator;
7 import java.util.TreeMap;
9 public class LinearInterpolator implements Cloneable {
11 private TreeMap<Double, Double> sortMap = new TreeMap<Double,Double>();
14 * Construct a <code>LinearInterpolator</code> with no points. Some points must be
15 * added using {@link #addPoints(double[], double[])} before using the interpolator.
17 public LinearInterpolator() {
21 * Construct a <code>LinearInterpolator</code> with the given points.
23 * @param x the x-coordinates of the points.
24 * @param y the y-coordinates of the points.
25 * @throws IllegalArgumentException if the lengths of <code>x</code> and <code>y</code>
27 * @see #addPoints(double[], double[])
29 public LinearInterpolator(double[] x, double[] y) {
33 public LinearInterpolator(List<Double> x, List<Double> y) {
38 * Add the point to the linear interpolation.
40 * @param x the x-coordinate of the point.
41 * @param y the y-coordinate of the point.
43 public void addPoint(double x, double y) {
48 * Add the points to the linear interpolation.
50 * @param x the x-coordinates of the points.
51 * @param y the y-coordinates of the points.
52 * @throws IllegalArgumentException if the lengths of <code>x</code> and <code>y</code>
55 public void addPoints(double[] x, double[] y) {
56 if (x.length != y.length) {
57 throw new IllegalArgumentException("Array lengths do not match, x="+x.length +
60 for (int i=0; i < x.length; i++) {
61 sortMap.put(x[i],y[i]);
65 public void addPoints(List<Double> x, List<Double> y){
66 if (x.size() != y.size()) {
67 throw new IllegalArgumentException("Array lengths do not match, x="+x.size() +
70 for (int i=0; i < x.size(); i++) {
71 sortMap.put( (Double) x.toArray()[i], (Double) y.toArray()[i]);
76 public double getValue(double x) {
77 Map.Entry<Double,Double> e1, e2;
81 e1 = sortMap.floorEntry(x);
84 // x smaller than any value in the set
85 e1 = sortMap.firstEntry();
87 throw new IllegalStateException("No points added yet to the interpolator.");
93 e2 = sortMap.higherEntry(x1);
96 // x larger than any value in the set
104 return (x - x1)/(x2-x1) * (y2-y1) + y1;
108 public double[] getXPoints() {
109 double[] x = new double[sortMap.size()];
110 Iterator<Double> iter = sortMap.keySet().iterator();
111 for (int i=0; iter.hasNext(); i++) {
118 @SuppressWarnings("unchecked")
120 public LinearInterpolator clone() {
122 LinearInterpolator other = (LinearInterpolator)super.clone();
123 other.sortMap = (TreeMap<Double,Double>)this.sortMap.clone();
125 } catch (CloneNotSupportedException e) {
126 throw new BugException("CloneNotSupportedException?!",e);
131 public static void main(String[] args) {
132 LinearInterpolator interpolator = new LinearInterpolator(
133 new double[] {1, 1.5, 2, 4, 5},
134 new double[] {0, 1, 0, 2, 2}
137 for (double x=0; x < 6; x+=0.1) {
138 System.out.printf("%.1f: %.2f\n", x, interpolator.getValue(x));
141 // Should be the same
143 ArrayList<Double> time = new ArrayList<Double>( Arrays.asList( new Double[] {1.0, 1.5, 2.0, 4.0, 5.0} ));
144 ArrayList<Double> y = new ArrayList<Double>( Arrays.asList( new Double[] {0.0, 1.0, 0.0, 2.0, 2.0} ));
146 LinearInterpolator interpolator2 = new LinearInterpolator(time,y);
147 for (double x=0; x < 6; x+=0.1) {
148 System.out.printf("%.1f: %.2f\n", x, interpolator2.getValue(x));