comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/WKmsOperation.java @ 925:0cb1a70b8b92

Added the math needed to calculate "W-Differenzen" in "Laengsschnitten" flys-artifacts/trunk@2277 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Sun, 03 Jul 2011 15:33:33 +0000
parents
children 302461d5d071
comparison
equal deleted inserted replaced
924:f7761914f745 925:0cb1a70b8b92
1 package de.intevation.flys.artifacts.math;
2
3 import de.intevation.flys.artifacts.model.WKms;
4 import de.intevation.flys.artifacts.model.WKmsImpl;
5
6 import java.util.Arrays;
7
8 public abstract class WKmsOperation
9 {
10 public static final double EPSILON = 1e-6;
11
12 public static final class KmW
13 implements Comparable<KmW>
14 {
15 protected double km;
16 protected double w;
17
18 public KmW(double km, double w) {
19 this.km = km;
20 this.w = w;
21 }
22
23 public int compareTo(KmW other) {
24 return km < other.km
25 ? -1
26 : km > other.km ? +1 : 0;
27 }
28
29 public boolean kmEquals(KmW other) {
30 return Math.abs(km - other.km) < EPSILON;
31 }
32
33 public double subtract(KmW other) {
34 return w - other.w;
35 }
36 } // class KmW
37
38 public static final WKmsOperation SUBTRACTION = new WKmsOperation() {
39
40 @Override
41 public WKms operate(WKms a, WKms b) {
42 return subtract(a, b);
43 }
44 };
45
46 protected WKmsOperation() {
47 }
48
49 public abstract WKms operate(WKms a, WKms b);
50
51 public static WKms subtract(WKms minuend, WKms subtrahend) {
52
53 int M = minuend .size();
54 int S = subtrahend.size();
55
56 // Don't subtract empty sets
57 if (M < 1 || S < 1) {
58 return new WKmsImpl();
59 }
60
61 KmW [] ms = new KmW[M];
62 KmW [] ss = new KmW[S];
63
64 for (int i = 0; i < M; ++i) {
65 ms[i] = new KmW(minuend.getKm(i), minuend.getW(i));
66 }
67
68 for (int i = 0; i < S; ++i) {
69 ss[i] = new KmW(subtrahend.getKm(i), subtrahend.getW(i));
70 }
71
72 Arrays.sort(ms);
73 Arrays.sort(ss);
74
75 // no overlap -> empty result set
76 if (ms[0].km > ss[S-1].km || ss[0].km > ms[M-1].km) {
77 return new WKmsImpl();
78 }
79
80 WKmsImpl result = new WKmsImpl();
81
82 int mi = 0;
83 int si = 0;
84
85 OUT: while (mi < M && si < S) {
86 KmW m = ms[mi];
87 KmW s = ss[si];
88
89 if (m.km + EPSILON < s.km) {
90 // minuend is before subtrahend
91
92 while (ms[mi].km + EPSILON < s.km) {
93 if (++mi >= M) {
94 break OUT;
95 }
96 }
97
98 if (ms[mi].km + EPSILON > s.km) {
99 double mw = Linear.linear(
100 s.km,
101 ms[mi-1].km, ms[mi].km,
102 ms[mi-1].w, ms[mi].w);
103 result.add(s.km, mw - s.w);
104 ++si;
105 }
106 else { // s.km == ms[mi].km
107 result.add(s.km, ms[mi].subtract(s));
108 ++mi;
109 ++si;
110 }
111 }
112 else if (m.km > s.km + EPSILON) {
113 // subtrahend is before minuend
114
115 while (m.km > ss[si].km + EPSILON) {
116 if (++si >= S) {
117 break OUT;
118 }
119 }
120
121 if (ss[si].km + EPSILON > m.km) {
122 double sw = Linear.linear(
123 m.km,
124 ss[si-1].km, ss[si].km,
125 ss[si-1].w, ss[si].w);
126 result.add(m.km, m.w - sw);
127 }
128 else { // ss[si].km == m.km
129 result.add(m.km, m.subtract(ss[si]));
130 ++mi;
131 ++si;
132 }
133 }
134 else { // m.km == s.km
135 result.add(s.km, m.subtract(s));
136 ++mi;
137 ++si;
138 }
139 }
140
141 return result;
142 }
143 }
144 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :

http://dive4elements.wald.intevation.org