Initial commit
[debian/openrocket] / src / net / sf / openrocket / util / LinearInterpolator.java
diff --git a/src/net/sf/openrocket/util/LinearInterpolator.java b/src/net/sf/openrocket/util/LinearInterpolator.java
new file mode 100644 (file)
index 0000000..00efe3a
--- /dev/null
@@ -0,0 +1,128 @@
+package net.sf.openrocket.util;
+
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class LinearInterpolator implements Cloneable {
+
+       private TreeMap<Double, Double> sortMap = new TreeMap<Double,Double>();
+
+       /**
+        * Construct a <code>LinearInterpolator</code> with no points.  Some points must be
+        * added using {@link #addPoints(double[], double[])} before using the interpolator.
+        */
+       public LinearInterpolator() {
+       }
+       
+       /**
+        * Construct a <code>LinearInterpolator</code> with the given points.
+        * 
+        * @param x             the x-coordinates of the points.
+        * @param y             the y-coordinates of the points.
+        * @throws IllegalArgumentException             if the lengths of <code>x</code> and <code>y</code>
+        *                                                                              are not equal.
+        * @see #addPoints(double[], double[])
+        */
+       public LinearInterpolator(double[] x, double[] y) {
+               addPoints(x,y);
+       }
+       
+       
+       /**
+        * Add the point to the linear interpolation.
+        * 
+        * @param x             the x-coordinate of the point.
+        * @param y             the y-coordinate of the point.
+        */
+       public void addPoint(double x, double y) {
+               sortMap.put(x, y);
+       }
+       
+       /**
+        * Add the points to the linear interpolation.
+        * 
+        * @param x             the x-coordinates of the points.
+        * @param y             the y-coordinates of the points.
+        * @throws IllegalArgumentException             if the lengths of <code>x</code> and <code>y</code>
+        *                                                                              are not equal.
+        */
+       public void addPoints(double[] x, double[] y) {
+               if (x.length != y.length) {
+                       throw new IllegalArgumentException("Array lengths do not match, x="+x.length +
+                                       " y="+y.length);
+               }
+               for (int i=0; i < x.length; i++) {
+                       sortMap.put(x[i],y[i]);
+               }
+       }
+       
+       
+       
+       public double getValue(double x) {
+               Map.Entry<Double,Double> e1, e2;
+               double x1, x2;
+               double y1, y2;
+               
+               e1 = sortMap.floorEntry(x);
+               
+               if (e1 == null) {
+                       // x smaller than any value in the set
+                       e1 = sortMap.firstEntry();
+                       if (e1 == null) {
+                               throw new IllegalStateException("No points added yet to the interpolator.");
+                       }
+                       return e1.getValue();
+               }
+               
+               x1 = e1.getKey();
+               e2 = sortMap.higherEntry(x1);
+
+               if (e2 == null) {
+                       // x larger than any value in the set
+                       return e1.getValue();
+               }
+               
+               x2 = e2.getKey();
+               y1 = e1.getValue();
+               y2 = e2.getValue();
+               
+               return (x - x1)/(x2-x1) * (y2-y1) + y1;
+       }
+       
+       
+       public double[] getXPoints() {
+               double[] x = new double[sortMap.size()];
+               Iterator<Double> iter = sortMap.keySet().iterator();
+               for (int i=0; iter.hasNext(); i++) {
+                       x[i] = iter.next();
+               }
+               return x;
+       }
+       
+       
+       @SuppressWarnings("unchecked")
+       @Override
+       public LinearInterpolator clone() {
+               try {
+                       LinearInterpolator other = (LinearInterpolator)super.clone();
+                       other.sortMap = (TreeMap<Double,Double>)this.sortMap.clone();
+                       return other;
+               } catch (CloneNotSupportedException e) {
+                       throw new RuntimeException("CloneNotSupportedException?!",e);
+               }
+       }
+
+       
+       public static void main(String[] args) {
+               LinearInterpolator interpolator = new LinearInterpolator(
+                               new double[] {1, 1.5, 2, 4, 5},
+                               new double[] {0, 1,   0, 2, 2}
+               );
+               
+               for (double x=0; x < 6; x+=0.1) {
+                       System.out.printf("%.1f:  %.2f\n", x, interpolator.getValue(x));
+               }
+       }
+       
+}