From 27991857d9f2c95f80b85179ec62429f1aebbf37 Mon Sep 17 00:00:00 2001 From: kruland2607 Date: Thu, 9 Aug 2012 15:04:36 +0000 Subject: [PATCH] Fix commit from revision 953 which reverted a bunch of changes related to Froyo compatibility. git-svn-id: https://openrocket.svn.sourceforge.net/svnroot/openrocket/trunk@962 180e2498-e6e9-4542-8430-84ac67f01cd8 --- .../openrocket/util/LinearInterpolator.java | 107 +++++++++--------- 1 file changed, 55 insertions(+), 52 deletions(-) diff --git a/core/src/net/sf/openrocket/util/LinearInterpolator.java b/core/src/net/sf/openrocket/util/LinearInterpolator.java index 1631a9de..e16726bb 100644 --- a/core/src/net/sf/openrocket/util/LinearInterpolator.java +++ b/core/src/net/sf/openrocket/util/LinearInterpolator.java @@ -1,9 +1,8 @@ package net.sf.openrocket.util; -import java.util.Arrays; import java.util.Iterator; import java.util.List; -import java.util.Map; +import java.util.SortedMap; import java.util.TreeMap; public class LinearInterpolator implements Cloneable { @@ -16,7 +15,7 @@ public class LinearInterpolator implements Cloneable { */ public LinearInterpolator() { } - + /** * Construct a LinearInterpolator with the given points. * @@ -29,11 +28,11 @@ public class LinearInterpolator implements Cloneable { public LinearInterpolator(double[] x, double[] y) { addPoints(x,y); } - + public LinearInterpolator(List x, List y) { addPoints(x,y); } - + /** * Add the point to the linear interpolation. * @@ -43,7 +42,7 @@ public class LinearInterpolator implements Cloneable { public void addPoint(double x, double y) { sortMap.put(x, y); } - + /** * Add the points to the linear interpolation. * @@ -61,7 +60,7 @@ public class LinearInterpolator implements Cloneable { sortMap.put(x[i],y[i]); } } - + public void addPoints(List x, List y){ if (x.size() != y.size()) { throw new IllegalArgumentException("Array lengths do not match, x="+x.size() + @@ -71,40 +70,65 @@ public class LinearInterpolator implements Cloneable { sortMap.put( (Double) x.toArray()[i], (Double) y.toArray()[i]); } } - - + + public double getValue(double x) { - Map.Entry e1, e2; double x1, x2; - double y1, y2; + Double y1, y2; + // Froyo does not support floorEntry, firstEntry or higherEntry. We instead have to + // resort to using other more awkward methods. + + y1 = sortMap.get(x); + + if ( y1 != null ) { + // Wow, x was a key in the map. Such luck. + return y1.doubleValue(); + } + + // we now know that x is not in the map, so we need to find the lower and higher keys. - e1 = sortMap.floorEntry(x); + // let's just make certain that our map is not empty. + if ( sortMap.isEmpty() ) { + throw new IllegalStateException("No points added yet to the interpolator."); + } - 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(); + // firstKey in the map - cannot be null since the map is not empty. + Double firstKey = sortMap.firstKey(); + + // x is smaller than the first entry in the map. + if ( x < firstKey.doubleValue() ) { + y1 = sortMap.get(firstKey); + return y1.doubleValue(); } - x1 = e1.getKey(); - e2 = sortMap.higherEntry(x1); + // floor key is the largest key smaller than x - since we have at least one key, + // and x>=firstKey, we know that floorKey != null. + Double floorKey = sortMap.subMap(firstKey, x).lastKey(); + + x1 = floorKey.doubleValue(); + y1 = sortMap.get(floorKey); - if (e2 == null) { - // x larger than any value in the set - return e1.getValue(); + // Now we need to find the key that is greater or equal to x + SortedMap tailMap = sortMap.tailMap(x); + + // Check if x is bigger than all the entries. + if ( tailMap.isEmpty() ) { + return y1.doubleValue(); } + Double ceilKey = tailMap.firstKey(); - x2 = e2.getKey(); - y1 = e1.getValue(); - y2 = e2.getValue(); + // Check if x is bigger than all the entries. + if ( ceilKey == null ) { + return y1.doubleValue(); + } + x2 = ceilKey.doubleValue(); + y2 = sortMap.get(ceilKey); + return (x - x1)/(x2-x1) * (y2-y1) + y1; } - - + + public double[] getXPoints() { double[] x = new double[sortMap.size()]; Iterator iter = sortMap.keySet().iterator(); @@ -113,8 +137,8 @@ public class LinearInterpolator implements Cloneable { } return x; } - - + + @SuppressWarnings("unchecked") @Override public LinearInterpolator clone() { @@ -127,25 +151,4 @@ public class LinearInterpolator implements Cloneable { } } - - 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)); - } - - // Should be the same - - ArrayList time = new ArrayList( Arrays.asList( new Double[] {1.0, 1.5, 2.0, 4.0, 5.0} )); - ArrayList y = new ArrayList( Arrays.asList( new Double[] {0.0, 1.0, 0.0, 2.0, 2.0} )); - - LinearInterpolator interpolator2 = new LinearInterpolator(time,y); - for (double x=0; x < 6; x+=0.1) { - System.out.printf("%.1f: %.2f\n", x, interpolator2.getValue(x)); - } - } } -- 2.30.2