changeset 1674:b5209452f6bb

flys/issue31: Simplified the back jump correction code a lot. flys-artifacts/trunk@2888 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Tue, 04 Oct 2011 16:36:19 +0000
parents 68260e38029a
children 19d0eb41e923
files flys-artifacts/ChangeLog flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/BackJumpCorrector.java
diffstat 2 files changed, 56 insertions(+), 87 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Tue Oct 04 15:30:09 2011 +0000
+++ b/flys-artifacts/ChangeLog	Tue Oct 04 16:36:19 2011 +0000
@@ -1,3 +1,10 @@
+2011-10-04	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	Worked on flys/issue31
+
+	* src/main/java/de/intevation/flys/artifacts/math/BackJumpCorrector.java:
+	  Simplified the code a lot. Needs testing. Maybe flys/issue31 is gone
+
 2011-10-04  Ingo Weinzierl <ingo@intevation.de>
 
 	* src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java:
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/BackJumpCorrector.java	Tue Oct 04 15:30:09 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/BackJumpCorrector.java	Tue Oct 04 16:36:19 2011 +0000
@@ -108,97 +108,35 @@
                 ws = corrected = (double [])ws.clone();
             }
 
-            int    back = i-2;
-            double distance = Math.abs(km[i] - km[i-1]);
-            double rest = 0.0;
-            double ikm  = 0.0;
+            double above = aboveWaterKM(km, ws, i);
 
-            while (back > -1) {
-                if (ws[back] < ws[i]) { // under water
-                    // continue scanning backwards
-                    distance += Math.abs(km[back+1] - km[back]);
-                    --back;
-                    continue;
-                }
-                if (ws[back] > ws[i]) { // over water
-                    // need to calculate intersection
-                    log.debug("intersection case");
-                    double m = (km[back+1]-km[back])/(ws[back+1]-ws[back]);
-                    double b = km[back]-ws[back]*m;
-                    ikm = m*ws[i] + b;
-                    distance += Math.abs(ikm - km[back+1]);
-                    rest = Math.abs(km[back] - ikm);
-                }
-                else {
-                    // equals height at ws[back]
-                    log.debug("exact height match");
-                    distance += Math.abs(km[back+1] - km[back]);
-                    ikm = km[back];
-                }
-                break;
-            }
-
-            if (back <= 0) {
-                //log.debug("run over left border");
-                // fill with same as ws[i]
+            if (Double.isNaN(above)) { // run over start km
+                // fill all previous
                 for (int j = 0; j < i; ++j) {
                     ws[j] = ws[i];
                 }
                 continue;
             }
 
+            double distance = Math.abs(km[i] - above);
+
             double quarterDistance = 0.25*distance;
 
-            // Now further seek back for the max height
-
-            double restDistance = Math.max(0.0, quarterDistance - rest);
-            --back;
-
-            double mkmw = ws[i];
-            double mkm  = km[0];
+            double start = above - quarterDistance;
 
-            while (back > -1) {
-                double d = Math.abs(km[back+1] - km[back]);
-                restDistance -= d;
-                if (restDistance > 0.0) {
-                    --back;
-                    continue;
-                }
-                if (restDistance < 0.0) {
-                    // need to calculate intersection
-                    if (km[back] == km[back+1]) { // should not happen
-                        mkm = km[back];
-                        mkmw = 0.5*(ws[back] + ws[back+1]);
-                    }
-                    else {
-                        double m = (ws[back+1]-ws[back])/(km[back+1]-km[back]);
-                        double b = ws[back] - km[back]*m;
-                        mkm = km[back] + restDistance;
-                        mkmw = m*mkm + b;
-                    }
-                }
-                else {
-                    // exact match
-                    mkm  = km[back];
-                    mkmw = ws[back];
-                }
-                break;
+            double startHeight = DoubleUtil.interpolateSorted(km, ws, start);
+
+            if (Double.isNaN(startHeight)) {
+                // run over start km
+                startHeight = ws[0];
             }
 
-            double factor = back >= 0 && Math.abs(restDistance) < 1e-4
-                ? 1.0
-                : 1.0 - Math.min(1, Math.max(0, restDistance/quarterDistance));
-
-            double ikmw = factor*0.25*(mkmw-ws[i]) + ws[i];
+            double between = above + quarterDistance;
 
-            double end = ikm + quarterDistance*factor;
+            double betweenHeight = ws[i] + 0.25*(startHeight - ws[i]);
 
-            double [] x = { mkm,  ikm,  end   };
-            double [] y = { mkmw, ikmw, ws[i] };
-
-            if (interpolator == null) {
-                interpolator = new SplineInterpolator();
-            }
+            double [] x = { start,  between,  km[i] };
+            double [] y = { startHeight, betweenHeight, ws[i] };
 
             if (log.isDebugEnabled()) {
                 for (int j = 0; j < x.length; ++j) {
@@ -206,6 +144,10 @@
                 }
             }
 
+            if (interpolator == null) {
+                interpolator = new SplineInterpolator();
+            }
+
             PolynomialSplineFunction spline;
 
             try {
@@ -226,16 +168,8 @@
                     }
                 }
 
-                for (back = Math.max(back, 0);
-                     back < i && km[back] < end;
-                     ++back
-                ) {
-                    // to 3/4 point fill with spline values
-                    ws[back] = spline.value(km[back]);
-                }
-                while (back < i) {
-                    // fill the rest with ws[i]
-                    ws[back++] = ws[i];
+                for (int j = i-1; j > 0 && ws[j] < startHeight; --j) {
+                    ws[j] = spline.value(km[j]);
                 }
             }
             catch (ArgumentOutsideDomainException aode) {
@@ -247,5 +181,33 @@
 
         return !backjumps.isEmpty();
     }
+
+
+    protected static double aboveWaterKM(
+        double [] km, 
+        double [] ws, 
+        int       wIndex
+    ) {
+        double w = ws[wIndex];
+
+        while (--wIndex >= 0) {
+            // still under water
+            if (ws[wIndex] < w) continue;
+
+            if (ws[wIndex] > w) {
+                // f(ws[wIndex])   = km[wIndex]
+                // f(ws[wIndex+1]) = km[wIndex+1]
+                return Linear.linear(
+                    w,
+                    ws[wIndex], ws[wIndex+1],
+                    km[wIndex], km[wIndex+1]);
+            }
+            else {
+                return km[wIndex];
+            }
+        }
+
+        return Double.NaN;
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org