/*
* The Unified Mapping Platform (JUMP) is an extensible, interactive GUI
* for visualizing and manipulating spatial features with geometry and attributes.
*
* Copyright (C) 2003 Vivid Solutions
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* For more information, contact:
*
* Vivid Solutions
* Suite #1A
* 2328 Government Street
* Victoria BC V8T 5G5
* Canada
*
* (250)385-6040
* www.vividsolutions.com
*/
package com.vividsolutions.jump.geom;
import java.awt.geom.Point2D;
import java.util.Collection;
import java.util.Iterator;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.util.Assert;
import com.vividsolutions.jump.util.MathUtil;
/**
* Utility functions for working with Coordinates.
*/
public class CoordUtil {
/**
* Returns the average of two Coordinates.
* @param c1 one coordinate
* @param c2 another coordinate
* @return a new Coordinate with the average x and average y
*/
public static Coordinate average(Coordinate c1, Coordinate c2) {
if (Double.isNaN(c1.z) || Double.isNaN(c2.z))
return new Coordinate(MathUtil.avg(c1.x, c2.x), MathUtil.avg(c1.y, c2.y));
else
return new Coordinate(MathUtil.avg(c1.x, c2.x), MathUtil.avg(c1.y, c2.y),
MathUtil.avg(c1.z, c2.z));
}
/**
* @param coordinates not empty
*/
public static Coordinate average(Collection coordinates) {
Assert.isTrue(!coordinates.isEmpty());
double xSum = 0;
double ySum = 0;
double zSum = 0;
boolean zNanFound = false;
for (Iterator i = coordinates.iterator(); i.hasNext();) {
Coordinate coordinate = (Coordinate) i.next();
xSum += coordinate.x;
ySum += coordinate.y;
if (!Double.isNaN(coordinate.z))
zSum += coordinate.z;
else
zNanFound = true;
}
if (zNanFound)
return new Coordinate(xSum / coordinates.size(),
ySum / coordinates.size());
else
return new Coordinate(xSum / coordinates.size(),
ySum / coordinates.size(), zSum / coordinates.size());
}
/**
* @param coordinates not empty
*/
public static Coordinate closest(Collection coordinates, Coordinate p) {
Assert.isTrue(!coordinates.isEmpty());
Coordinate closest = (Coordinate) coordinates.iterator().next();
for (Iterator i = coordinates.iterator(); i.hasNext();) {
Coordinate candidate = (Coordinate) i.next();
if (p.distance(candidate) < p.distance(closest)) {
closest = candidate;
}
}
return closest;
}
/**
* Adds two coordinates.
* @param c1 the first coordinate
* @param c2 the second coordinate
* @return a new coordinate: c1 + c2
*/
public static Coordinate add(Coordinate c1, Coordinate c2) {
if (Double.isNaN(c1.z) || Double.isNaN(c2.z))
return new Coordinate(c1.x + c2.x, c1.y + c2.y);
else
return new Coordinate(c1.x + c2.x, c1.y + c2.y, c1.z + c2.z);
}
/**
* Subtracts two coordinates.
* @param c1 the first coordinate
* @param c2 the second coordinate
* @return a new coordinate: c1 - c2
*/
public static Coordinate subtract(Coordinate c1, Coordinate c2) {
if (Double.isNaN(c1.z) || Double.isNaN(c2.z))
return new Coordinate(c1.x - c2.x, c1.y - c2.y);
else
return new Coordinate(c1.x - c2.x, c1.y - c2.y, c1.z - c2.z);
}
/**
* Multiplies a scalar and a coordinate.
* @param d the scalar
* @param c the coordinate
* @return a new coordinate: d * c
*/
public static Coordinate multiply(double d, Coordinate c) {
if (Double.isNaN(c.z))
return new Coordinate(d * c.x, d * c.y);
else
return new Coordinate(d * c.x, d * c.y, d * c.z);
}
/**
* Divides a coordinate by a scalar.
* @param c the coordinate
* @param d the scalar *
* @return a new coordinate: c / d
*/
public static Coordinate divide(Coordinate c, double d) {
if (Double.isNaN(c.z))
return new Coordinate(c.x / d, c.y / d);
else
return new Coordinate(c.x / d, c.y / d, c.z / d);
}
public static Coordinate toCoordinate(Point2D point) {
return new Coordinate(point.getX(), point.getY());
}
public static Point2D toPoint2D(Coordinate coordinate) {
return new Point2D.Double(coordinate.x, coordinate.y);
}
public static Point2D add(Point2D a, Point2D b) {
return new Point2D.Double(a.getX() + b.getX(), a.getY() + b.getY());
}
public static Point2D subtract(Point2D a, Point2D b) {
return new Point2D.Double(a.getX() - b.getX(), a.getY() - b.getY());
}
}