diff --git a/core/src/net/sf/openrocket/util/LinearInterpolator.java b/core/src/net/sf/openrocket/util/LinearInterpolator.java
index db422d52a..6a9a308b6 100644
--- a/core/src/net/sf/openrocket/util/LinearInterpolator.java
+++ b/core/src/net/sf/openrocket/util/LinearInterpolator.java
@@ -1,7 +1,7 @@
package net.sf.openrocket.util;
import java.util.Iterator;
-import java.util.Map;
+import java.util.SortedMap;
import java.util.TreeMap;
public class LinearInterpolator implements Cloneable {
@@ -14,7 +14,7 @@ public class LinearInterpolator implements Cloneable {
*/
public LinearInterpolator() {
}
-
+
/**
* Construct a LinearInterpolator
with the given points.
*
@@ -27,8 +27,8 @@ public class LinearInterpolator implements Cloneable {
public LinearInterpolator(double[] x, double[] y) {
addPoints(x,y);
}
-
-
+
+
/**
* Add the point to the linear interpolation.
*
@@ -38,7 +38,7 @@ public class LinearInterpolator implements Cloneable {
public void addPoint(double x, double y) {
sortMap.put(x, y);
}
-
+
/**
* Add the points to the linear interpolation.
*
@@ -56,41 +56,66 @@ public class LinearInterpolator implements Cloneable {
sortMap.put(x[i],y[i]);
}
}
-
-
-
- public double getValue(double x) {
- Map.Entry 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();
+
+
+ public double getValue(double x) {
+ double x1, x2;
+ 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.
+
+ // let's just make certain that our map is not empty.
+ if ( sortMap.isEmpty() ) {
+ throw new IllegalStateException("No points added yet to the interpolator.");
}
- x2 = e2.getKey();
- y1 = e1.getValue();
- y2 = e2.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();
+ }
+ // 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);
+
+ // 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();
+
+ // 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();
@@ -99,8 +124,8 @@ public class LinearInterpolator implements Cloneable {
}
return x;
}
-
-
+
+
@SuppressWarnings("unchecked")
@Override
public LinearInterpolator clone() {