Mercurial > dive4elements > river
diff artifacts/src/main/java/org/dive4elements/river/artifacts/model/WQDay.java @ 7494:4de4b19b6be6
Fixed half broken interpolation code for lines to 'Dauerlinie'.
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Fri, 01 Nov 2013 13:25:54 +0100 |
parents | 8b614d152a79 |
children | 5e38e2924c07 |
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/WQDay.java Fri Nov 01 12:12:24 2013 +0100 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/WQDay.java Fri Nov 01 13:25:54 2013 +0100 @@ -8,6 +8,12 @@ package org.dive4elements.river.artifacts.model; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; + +import org.dive4elements.river.artifacts.math.Linear; + import gnu.trove.TIntArrayList; /** @@ -19,6 +25,19 @@ public class WQDay extends WQ { + public static final Comparator<double []> FIRST_CMP = new Comparator<double []>() { + @Override + public int compare(double [] a, double [] b) { + double diff = a[0] - b[0]; + if (diff < 0d) return -1; + if (diff > 0d) return +1; + return 0; + } + }; + + public static final double EPSILON = 1e-4; + + protected TIntArrayList days; public WQDay() { @@ -52,6 +71,68 @@ return days.getQuick(idx); } + private static final Double interpolateX(ArrayList<double []> dxs, double x) { + + Collections.sort(dxs, FIRST_CMP); + + if (Math.abs(x - dxs.get(0)[1]) < EPSILON) { + return dxs.get(0)[0]; + } + + for (int i = 1, S = dxs.size(); i < S; ++i) { + double [] curr = dxs.get(i); + if (Math.abs(x - curr[1]) < EPSILON) { + return curr[0]; + } + + double [] prev = dxs.get(i-1); + double x1 = Math.min(prev[1], curr[1]); + double x2 = Math.max(prev[1], curr[1]); + if (x > x1 && x < x2) { + return Linear.linear( + x, + prev[1], curr[1], + prev[0], curr[0]); + } + } + + return null; + } + + public Double interpolateDayByW(double w) { + + int S = days.size(); + + if (S == 0) { + return null; + } + + ArrayList<double[]> dws = new ArrayList<double[]>(S); + + for (int i = 0; i < S; ++i) { + dws.add(new double[] { getDay(i), getW(i) }); + } + + return interpolateX(dws, w); + } + + public Double interpolateDayByQ(double q) { + + int S = days.size(); + + if (S == 0) { + return null; + } + + ArrayList<double[]> dqs = new ArrayList<double[]>(S); + + for (int i = 0; i < S; ++i) { + dqs.add(new double[] { getDay(i), getQ(i) }); + } + + return interpolateX(dqs, q); + } + @Override public void removeNaNs() {