[PATCH] Fixed half broken interpolation code for lines to 'Dauerlinie'
Wald Commits
scm-commit at wald.intevation.org
Fri Nov 1 13:28:22 CET 2013
# HG changeset patch
# User Sascha L. Teichmann <teichmann at intevation.de>
# Date 1383308754 -3600
# Node ID 4de4b19b6be66fa934b3cc5a1fd4cbf95c439515
# Parent 8cdc863271499c1b3624c560cd0f915f591efefb
Fixed half broken interpolation code for lines to 'Dauerlinie'.
diff -r 8cdc86327149 -r 4de4b19b6be6 artifacts/src/main/java/org/dive4elements/river/artifacts/model/MainValuesQFacet.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/MainValuesQFacet.java Fri Nov 01 12:12:24 2013 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/MainValuesQFacet.java Fri Nov 01 13:25:54 2013 +0100
@@ -20,7 +20,6 @@
import org.dive4elements.artifactdatabase.state.DefaultFacet;
import org.dive4elements.river.artifacts.MainValuesArtifact;
-import org.dive4elements.river.artifacts.math.Linear;
import org.dive4elements.river.jfree.RiverAnnotation;
import org.dive4elements.river.jfree.StickyAxisAnnotation;
@@ -51,7 +50,6 @@
this.isAtGauge = atGauge;
}
-
/**
* Set the hit-point in Q where a line drawn from the axis would hit the
* curve in WQDay (if hit).
@@ -59,34 +57,14 @@
*/
protected static void setHitPoint(WQDay wqday, StickyAxisAnnotation annotation) {
- if (wqday.size() == 0) {
- return;
+ float q = annotation.getPos();
+ Double day = wqday.interpolateDayByQ(q);
+
+ if (day != null) {
+ annotation.setHitPoint(day.floatValue());
}
-
- int idx = 0;
- float q = annotation.getPos();
- boolean qIncreases = wqday.getQ(0) < wqday.getQ(wqday.size()-1);
- if (qIncreases) {
- while (idx < wqday.size() && wqday.getQ(idx) < q) {
- idx++;
- }
- }
- else {
- idx = wqday.size() -1;
- while (idx > 0 && wqday.getQ(idx) > q) {
- idx--;
- }
- }
-
- double day = 0d;
- int mod = (qIncreases) ? -1 : +1;
- if (idx != 0 && idx <= wqday.size()-1) {
- day = Linear.linear(q, wqday.getQ(idx +mod), wqday.getQ(idx),
- wqday.getDay(idx+mod), wqday.getDay(idx));
- annotation.setHitPoint((float)day);
- }
- else {
- logger.debug("StickyAnnotation does not hit wqday curve");
+ else if (logger.isDebugEnabled()) {
+ logger.debug("StickyAnnotation does not hit wqday curve: " + q);
}
}
diff -r 8cdc86327149 -r 4de4b19b6be6 artifacts/src/main/java/org/dive4elements/river/artifacts/model/MainValuesWFacet.java
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/MainValuesWFacet.java Fri Nov 01 12:12:24 2013 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/MainValuesWFacet.java Fri Nov 01 13:25:54 2013 +0100
@@ -20,7 +20,6 @@
import org.dive4elements.artifactdatabase.state.DefaultFacet;
import org.dive4elements.river.artifacts.MainValuesArtifact;
-import org.dive4elements.river.artifacts.math.Linear;
import org.dive4elements.river.jfree.RiverAnnotation;
import org.dive4elements.river.jfree.StickyAxisAnnotation;
import org.dive4elements.river.exports.fixings.FixChartGenerator;
@@ -54,35 +53,15 @@
* Employ linear interpolation.
*/
protected static void setHitPoint(WQDay wqday, StickyAxisAnnotation annotation) {
+ float w = annotation.getPos();
- if (wqday.size() == 0) {
- return;
+ Double day = wqday.interpolateDayByW(w);
+
+ if (day != null) {
+ annotation.setHitPoint(day.floatValue());
}
-
- int idx = 0;
- float w = annotation.getPos();
- boolean wIncreases = wqday.getW(0) < wqday.getW(wqday.size()-1);
- if (wIncreases) {
- while (idx < wqday.size() && wqday.getW(idx) < w) {
- idx++;
- }
- }
- else {
- idx = wqday.size() -1;
- while (idx > 0 && wqday.getW(idx) > w) {
- idx--;
- }
- }
-
- double day = 0d;
- int mod = (wIncreases) ? -1 : +1;
- if (idx != 0 && idx < wqday.size()-1-mod) {
- day = Linear.linear(w, wqday.getW(idx +mod), wqday.getW(idx),
- wqday.getDay(idx+mod), wqday.getDay(idx));
- annotation.setHitPoint((float)day);
- }
- else {
- logger.debug("StickyAnnotation does not hit wqday curve");
+ else if (logger.isDebugEnabled()) {
+ logger.debug("StickyAnnotation does not hit wqday curve: " + w);
}
}
diff -r 8cdc86327149 -r 4de4b19b6be6 artifacts/src/main/java/org/dive4elements/river/artifacts/model/WQDay.java
--- 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() {
More information about the Dive4elements-commits
mailing list