# HG changeset patch # User Sascha L. Teichmann # Date 1317746179 0 # Node ID b5209452f6bb75406e07ec3fb6a9902caec6bb96 # Parent 68260e38029aa8f3b35787a744ab5d3af85bf338 flys/issue31: Simplified the back jump correction code a lot. flys-artifacts/trunk@2888 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r 68260e38029a -r b5209452f6bb flys-artifacts/ChangeLog --- 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 + + 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 * src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java: diff -r 68260e38029a -r b5209452f6bb flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/BackJumpCorrector.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 :