Mercurial > dive4elements > gnv-client
view gnv-artifacts/src/main/java/de/intevation/gnv/math/Point2d.java @ 1129:ccfa07b88476
merged geo-backend
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:14:01 +0200 |
parents | f953c9a559d8 |
children |
line wrap: on
line source
/* * Copyright (c) 2010 by Intevation GmbH * * This program is free software under the LGPL (>=v2.1) * Read the file LGPL.txt coming with the software for details * or visit http://www.gnu.org/licenses/ if it does not exist. */ package de.intevation.gnv.math; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Envelope; import java.util.Comparator; import org.apache.log4j.Logger; /** * Point which besides the x, y, z coodinates has an index i, j pair * to model neighborhood. * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a> */ public class Point2d extends Coordinate { private static Logger log = Logger.getLogger(Point2d.class); /** * Numerical tolerance epsilon: {@value} */ public static final double EPSILON = 1e-3d; /** * Compares two Point2ds by their x coordinates */ public static final Comparator X_COMPARATOR = new Comparator() { public int compare(Object a, Object b) { double xa = ((Coordinate)a).x; double xb = ((Coordinate)b).x; if (xa < xb) return -1; if (xa > xb) return +1; return 0; } }; /** * Compares two Point2ds by their y coordinates. */ public static final Comparator Y_COMPARATOR = new Comparator() { public int compare(Object a, Object b) { double ya = ((Coordinate)a).y; double yb = ((Coordinate)b).y; if (ya < yb) return -1; if (ya > yb) return +1; return 0; } }; /** * The i index of this Point2d. */ public int i; /** * The j index of this Point2d. */ public int j; /** * Default constructor. */ public Point2d() { } /** * Constructor setting x and y coordinate. * @param x The x coordinate. * @param y The y coordinate. */ public Point2d(double x, double y) { super(x, y); } /** * Constructor setting x, y and i, j. * @param x The x coordinate. * @param y The y coordinate. * @param i The i index. * @param j The j index. */ public Point2d(double x, double y, int i, int j) { super(x, y); this.i = i; this.j = j; } /** * Constructor setting x, y, z and i, j. * @param x The x coordinate. * @param y The y coordinate. * @param z The z coordinate. * @param i The i index. * @param j The j index. */ public Point2d(double x, double y, double z, int i, int j) { super(x, y, z); this.i = i; this.j = j; } /** * Calculates the L1 distance to another Point2d. * @param other The other Point2d. * @return The L1 distance. */ public double L1(Point2d other) { return L1Comparator.L1(this, other); } /** * Creates an envelope around this Point2d with * the numerical tolerance of {@link #EPSILON}. * @return The envelope. */ public Envelope envelope() { return envelope(EPSILON); } /** *Creates an envelope around this Point2d with * a given tolerance. * @param epsilon The tolerance in all directions. * @return The envelope. */ public Envelope envelope(double epsilon) { return new Envelope( x-epsilon, x+epsilon, y-epsilon, y+epsilon); } /** * Given this and another Point2d it looks if there is * a gap between the in points in i index direction. * @param other The other Point2d. * @return true if there is is a gap, else false. */ public boolean hasIGap(Point2d other) { return Math.abs(i - other.i) > 1; } /** * Given this and another Point2d it looks if there is * a gap between the in points in j index direction. * @param other The other Point2d. * @return true if there is is a gap, else false. */ public boolean hasJGap(Point2d other) { return Math.abs(j - other.j) > 1; } /** * Given this and another Point2d a new Point2d is * created via {@link #newPoint() }. The x, y coordinate * of the new point is on the line of this and the other * given point at a given scaling point. * @param t The scaling factor. * @param other The other point. * @return The new Point2d. */ public Point2d extrapolate(double t, Point2d other) { if (other == null) { return null; } Point2d p = newPoint(); p.x = t*(other.x - x) + x; p.y = t*(other.y - y) + y; return p; } /** * Creates a new Point2d or an instance of a subclass. * Override this in subclasses. * @return The new Point2d. */ public Point2d newPoint() { return new Point2d(0d, 0d); } /** * Creates a new Point2d or an instance of a subclass * at a given coordinate. * Override this in subclasses. * @param x The x coordinate. * @param y The y coordinate. * @return The new point. */ public Point2d newPoint(double x, double y) { return new Point2d(x, y); } /** * Sets the z value to the inverse distance weighting (IDW) value * of the z values of a set of given points. * @param ps The points from wich the z values are taken * to calculate the IDW. */ public void inverseDistanceWeighting(Point2d [] ps) { double sum = 0d; double [] d = new double[ps.length]; for (int i = 0; i < ps.length; ++i) { Point2d p = ps[i]; if (p != null) { double di = distance(p); if (di < 1e-5d) { z = p.z; return; } di = 1d/di; d[i] = di; sum += di; } } if (sum == 0d) { return; } double v = 0d; for (int i = 0; i < ps.length; ++i) { Point2d p = ps[i]; if (p != null) { v += p.z*d[i]; } } z = v/sum; } /** * Creates a new point via {@link #newPoint() } with the * x,y coordinates of the center of a given set of * coordinates. * @param ps The points from which the x,y coordinates are * taken to calculate the center. * @return The new center point. */ public static Point2d average(Point2d [] ps) { Point2d p = null; int count = 0; for (int i = 0; i < ps.length; ++i) { Point2d t = ps[i]; if (t != null) { ++count; if (p == null) { p = t.newPoint(t.x, t.y); } else { p.x += t.x; p.y += t.y; } } } if (p != null) { double s = 1d/count; p.x *= s; p.y *= s; } return p; } /** * Checks if this Point2d is near to at least one point * out of a given set of points. Near is defined by an * euclidian distance small than {@link #EPSILON}. * @param ps The set of points to be tested. * @return true if this Point2d is near to one of the given * points, else false. */ public boolean near(Point2d [] ps) { for (int i = 0; i < ps.length; ++i) { Point2d p = ps[i]; if (p != null && distance(p) > EPSILON) { return false; } } return true; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :