Mercurial > dive4elements > gnv-client
comparison gnv-artifacts/src/main/java/de/intevation/gnv/math/Point2d.java @ 875:5e9efdda6894
merged gnv-artifacts/1.0
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:13:56 +0200 |
parents | 6cff63d0c434 |
children | f953c9a559d8 |
comparison
equal
deleted
inserted
replaced
722:bb3ffe7d719e | 875:5e9efdda6894 |
---|---|
1 package de.intevation.gnv.math; | |
2 | |
3 import com.vividsolutions.jts.geom.Coordinate; | |
4 import com.vividsolutions.jts.geom.Envelope; | |
5 | |
6 import java.util.Comparator; | |
7 | |
8 import org.apache.log4j.Logger; | |
9 | |
10 /** | |
11 * Point which besides the x, y, z coodinates has an index i, j pair | |
12 * to model neighborhood. | |
13 * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a> | |
14 */ | |
15 public class Point2d | |
16 extends Coordinate | |
17 { | |
18 private static Logger log = Logger.getLogger(Point2d.class); | |
19 | |
20 /** | |
21 * Numerical tolerance epsilon: {@value} | |
22 */ | |
23 public static final double EPSILON = 1e-3d; | |
24 | |
25 /** | |
26 * Compares two Point2ds by their x coordinates | |
27 */ | |
28 public static final Comparator X_COMPARATOR = new Comparator() { | |
29 public int compare(Object a, Object b) { | |
30 double xa = ((Coordinate)a).x; | |
31 double xb = ((Coordinate)b).x; | |
32 if (xa < xb) return -1; | |
33 if (xa > xb) return +1; | |
34 return 0; | |
35 } | |
36 }; | |
37 | |
38 /** | |
39 * Compares two Point2ds by their y coordinates. | |
40 */ | |
41 public static final Comparator Y_COMPARATOR = new Comparator() { | |
42 public int compare(Object a, Object b) { | |
43 double ya = ((Coordinate)a).y; | |
44 double yb = ((Coordinate)b).y; | |
45 if (ya < yb) return -1; | |
46 if (ya > yb) return +1; | |
47 return 0; | |
48 } | |
49 }; | |
50 | |
51 /** | |
52 * The i index of this Point2d. | |
53 */ | |
54 public int i; | |
55 /** | |
56 * The j index of this Point2d. | |
57 */ | |
58 public int j; | |
59 | |
60 /** | |
61 * Default constructor. | |
62 */ | |
63 public Point2d() { | |
64 } | |
65 | |
66 /** | |
67 * Constructor setting x and y coordinate. | |
68 * @param x The x coordinate. | |
69 * @param y The y coordinate. | |
70 */ | |
71 public Point2d(double x, double y) { | |
72 super(x, y); | |
73 } | |
74 | |
75 /** | |
76 * Constructor setting x, y and i, j. | |
77 * @param x The x coordinate. | |
78 * @param y The y coordinate. | |
79 * @param i The i index. | |
80 * @param j The j index. | |
81 */ | |
82 public Point2d(double x, double y, int i, int j) { | |
83 super(x, y); | |
84 this.i = i; | |
85 this.j = j; | |
86 } | |
87 | |
88 /** | |
89 * Constructor setting x, y, z and i, j. | |
90 * @param x The x coordinate. | |
91 * @param y The y coordinate. | |
92 * @param z The z coordinate. | |
93 * @param i The i index. | |
94 * @param j The j index. | |
95 */ | |
96 public Point2d(double x, double y, double z, int i, int j) { | |
97 super(x, y, z); | |
98 this.i = i; | |
99 this.j = j; | |
100 } | |
101 | |
102 /** | |
103 * Calculates the L1 distance to another Point2d. | |
104 * @param other The other Point2d. | |
105 * @return The L1 distance. | |
106 */ | |
107 public double L1(Point2d other) { | |
108 return L1Comparator.L1(this, other); | |
109 } | |
110 | |
111 /** | |
112 * Creates an envelope around this Point2d with | |
113 * the numerical tolerance of {@link #EPSILON}. | |
114 * @return The envelope. | |
115 */ | |
116 public Envelope envelope() { | |
117 return envelope(EPSILON); | |
118 } | |
119 | |
120 /** | |
121 *Creates an envelope around this Point2d with | |
122 * a given tolerance. | |
123 * @param epsilon The tolerance in all directions. | |
124 * @return The envelope. | |
125 */ | |
126 public Envelope envelope(double epsilon) { | |
127 return new Envelope( | |
128 x-epsilon, x+epsilon, | |
129 y-epsilon, y+epsilon); | |
130 } | |
131 | |
132 /** | |
133 * Given this and another Point2d it looks if there is | |
134 * a gap between the in points in i index direction. | |
135 * @param other The other Point2d. | |
136 * @return true if there is is a gap, else false. | |
137 */ | |
138 public boolean hasIGap(Point2d other) { | |
139 return Math.abs(i - other.i) > 1; | |
140 } | |
141 | |
142 /** | |
143 * Given this and another Point2d it looks if there is | |
144 * a gap between the in points in j index direction. | |
145 * @param other The other Point2d. | |
146 * @return true if there is is a gap, else false. | |
147 */ | |
148 public boolean hasJGap(Point2d other) { | |
149 return Math.abs(j - other.j) > 1; | |
150 } | |
151 | |
152 /** | |
153 * Given this and another Point2d a new Point2d is | |
154 * created via {@link #newPoint() }. The x, y coordinate | |
155 * of the new point is on the line of this and the other | |
156 * given point at a given scaling point. | |
157 * @param t The scaling factor. | |
158 * @param other The other point. | |
159 * @return The new Point2d. | |
160 */ | |
161 public Point2d extrapolate(double t, Point2d other) { | |
162 if (other == null) { | |
163 return null; | |
164 } | |
165 Point2d p = newPoint(); | |
166 p.x = t*(other.x - x) + x; | |
167 p.y = t*(other.y - y) + y; | |
168 return p; | |
169 } | |
170 | |
171 /** | |
172 * Creates a new Point2d or an instance of a subclass. | |
173 * Override this in subclasses. | |
174 * @return The new Point2d. | |
175 */ | |
176 public Point2d newPoint() { | |
177 return new Point2d(0d, 0d); | |
178 } | |
179 | |
180 /** | |
181 * Creates a new Point2d or an instance of a subclass | |
182 * at a given coordinate. | |
183 * Override this in subclasses. | |
184 * @param x The x coordinate. | |
185 * @param y The y coordinate. | |
186 * @return The new point. | |
187 */ | |
188 public Point2d newPoint(double x, double y) { | |
189 return new Point2d(x, y); | |
190 } | |
191 | |
192 /** | |
193 * Sets the z value to the inverse distance weighting (IDW) value | |
194 * of the z values of a set of given points. | |
195 * @param ps The points from wich the z values are taken | |
196 * to calculate the IDW. | |
197 */ | |
198 public void inverseDistanceWeighting(Point2d [] ps) { | |
199 | |
200 double sum = 0d; | |
201 | |
202 double [] d = new double[ps.length]; | |
203 | |
204 for (int i = 0; i < ps.length; ++i) { | |
205 Point2d p = ps[i]; | |
206 if (p != null) { | |
207 double di = distance(p); | |
208 if (di < 1e-5d) { z = p.z; return; } | |
209 di = 1d/di; | |
210 d[i] = di; | |
211 sum += di; | |
212 } | |
213 } | |
214 | |
215 if (sum == 0d) { | |
216 return; | |
217 } | |
218 | |
219 double v = 0d; | |
220 | |
221 for (int i = 0; i < ps.length; ++i) { | |
222 Point2d p = ps[i]; | |
223 if (p != null) { | |
224 v += p.z*d[i]; | |
225 } | |
226 } | |
227 z = v/sum; | |
228 } | |
229 | |
230 /** | |
231 * Creates a new point via {@link #newPoint() } with the | |
232 * x,y coordinates of the center of a given set of | |
233 * coordinates. | |
234 * @param ps The points from which the x,y coordinates are | |
235 * taken to calculate the center. | |
236 * @return The new center point. | |
237 */ | |
238 public static Point2d average(Point2d [] ps) { | |
239 | |
240 Point2d p = null; | |
241 int count = 0; | |
242 | |
243 for (int i = 0; i < ps.length; ++i) { | |
244 Point2d t = ps[i]; | |
245 if (t != null) { | |
246 ++count; | |
247 if (p == null) { | |
248 p = t.newPoint(t.x, t.y); | |
249 } | |
250 else { | |
251 p.x += t.x; | |
252 p.y += t.y; | |
253 } | |
254 } | |
255 } | |
256 | |
257 if (p != null) { | |
258 double s = 1d/count; | |
259 p.x *= s; | |
260 p.y *= s; | |
261 } | |
262 | |
263 return p; | |
264 } | |
265 | |
266 /** | |
267 * Checks if this Point2d is near to at least one point | |
268 * out of a given set of points. Near is defined by an | |
269 * euclidian distance small than {@link #EPSILON}. | |
270 * @param ps The set of points to be tested. | |
271 * @return true if this Point2d is near to one of the given | |
272 * points, else false. | |
273 */ | |
274 public boolean near(Point2d [] ps) { | |
275 | |
276 for (int i = 0; i < ps.length; ++i) { | |
277 Point2d p = ps[i]; | |
278 if (p != null && distance(p) > EPSILON) { | |
279 return false; | |
280 } | |
281 } | |
282 | |
283 return true; | |
284 } | |
285 } | |
286 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |