/* * The JTS Topology Suite is a collection of Java classes that * implement the fundamental operations required to validate a given * geo-spatial data set to a known topological specification. * * Copyright (C) 2001 Vivid Solutions * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; 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.revolsys.geometry.algorithm; import com.revolsys.geometry.model.Point; import com.revolsys.geometry.model.impl.PointDoubleXY; /** * Represents a homogeneous coordinate in a 2-D coordinate space. * In JTS {@link HCoordinate}s are used as a clean way * of computing intersections between line segments. * * @author David Skea * @version 1.7 */ public class HCoordinate { public static Point intersection(final double line1x1, final double line1y1, final double line1x2, final double line1y2, final double line2x1, final double line2y1, final double line2x2, final double line2y2) { final double px = line1y1 - line1y2; final double py = line1x2 - line1x1; final double pw = line1x1 * line1y2 - line1x2 * line1y1; final double qx = line2y1 - line2y2; final double qy = line2x2 - line2x1; final double qw = line2x1 * line2y2 - line2x2 * line2y1; final double x = py * qw - qy * pw; final double y = qx * pw - px * qw; final double w = px * qy - qx * py; final double xInt = x / w; final double yInt = y / w; if (Double.isFinite(xInt) && Double.isFinite(yInt)) { return new PointDoubleXY(xInt, yInt); } else { throw new NotRepresentableException(); } } /** * Computes the (approximate) intersection point between two line segments * using homogeneous coordinates. * <p> * Note that this algorithm is * not numerically stable; i.e. it can produce intersection points which * lie outside the envelope of the line segments themselves. In order * to increase the precision of the calculation input points should be normalized * before passing them to this routine. */ public static Point intersection(final Point p1, final Point p2, final Point q1, final Point q2) { final double line1x1 = p1.getX(); final double line1y1 = p1.getY(); final double line1x2 = p2.getX(); final double line1y2 = p2.getY(); final double line2x1 = q1.getX(); final double line2y1 = q1.getY(); final double line2x2 = q2.getX(); final double line2y2 = q2.getY(); // unrolled computation return intersection(line1x1, line1y1, line1x2, line1y2, line2x1, line2y1, line2x2, line2y2); } /* * public static Point OLDintersection( Point p1, Point p2, Point q1, Point q2) throws * NotRepresentableException { HCoordinate l1 = new HCoordinate(p1, p2); HCoordinate l2 = new * HCoordinate(q1, q2); HCoordinate intHCoord = new HCoordinate(l1, l2); Point intPt = * intHCoord.getCoordinate(); return intPt; } */ public double x, y, w; public HCoordinate() { this.x = 0.0; this.y = 0.0; this.w = 1.0; } public HCoordinate(final double _x, final double _y) { this.x = _x; this.y = _y; this.w = 1.0; } public HCoordinate(final double _x, final double _y, final double _w) { this.x = _x; this.y = _y; this.w = _w; } public HCoordinate(final HCoordinate p1, final HCoordinate p2) { this.x = p1.y * p2.w - p2.y * p1.w; this.y = p2.x * p1.w - p1.x * p2.w; this.w = p1.x * p2.y - p2.x * p1.y; } public HCoordinate(final Point p) { this.x = p.getX(); this.y = p.getY(); this.w = 1.0; } /** * Constructs a homogeneous coordinate which is the intersection of the lines * define by the homogenous coordinates represented by two * {@link Coordinates}s. * * @param p1 * @param p2 */ public HCoordinate(final Point p1, final Point p2) { // optimization when it is known that w = 1 this.x = p1.getY() - p2.getY(); this.y = p2.getX() - p1.getX(); this.w = p1.getX() * p2.getY() - p2.getX() * p1.getY(); } public HCoordinate(final Point p1, final Point p2, final Point q1, final Point q2) { // unrolled computation final double px = p1.getY() - p2.getY(); final double py = p2.getX() - p1.getX(); final double pw = p1.getX() * p2.getY() - p2.getX() * p1.getY(); final double qx = q1.getY() - q2.getY(); final double qy = q2.getX() - q1.getX(); final double qw = q1.getX() * q2.getY() - q2.getX() * q1.getY(); this.x = py * qw - qy * pw; this.y = qx * pw - px * qw; this.w = px * qy - qx * py; } public Point getCoordinate() { final double x = getX(); final double y = getY(); return new PointDoubleXY(x, y); } public double getX() { final double a = this.x / this.w; if (Double.isFinite(a)) { return a; } else { throw new NotRepresentableException(); } } public double getY() { final double a = this.y / this.w; if (Double.isFinite(a)) { return a; } else { throw new NotRepresentableException(); } } }