Class HCoordinate

  1 /*
  2  * Copyright (c) 2016 Vivid Solutions.
  3  *
  4  * All rights reserved. This program and the accompanying materials
  5  * are made available under the terms of the Eclipse Public License 2.0
  6  * and Eclipse Distribution License v. 1.0 which accompanies this distribution.
  7  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
  8  * and the Eclipse Distribution License is available at
  9  *
 10  * http://www.eclipse.org/org/documents/edl-v10.php.
 11  */
 12 package org.locationtech.jts.algorithm;
 13  
 14 import org.locationtech.jts.geom.Coordinate;
 15  
 16 /**
 17  * Represents a homogeneous coordinate in a 2-D coordinate space.
 18  * In JTS {@link HCoordinate}s are used as a clean way
 19  * of computing intersections between line segments.
 20  *
 21  * @author David Skea
 22  * @version 1.7
 23  */
 24 public class HCoordinate
 25 {
 26  
 27   /**
 28    * Computes the (approximate) intersection point between two line segments
 29    * using homogeneous coordinates.
 30    * <p>
 31    * Note that this algorithm is
 32    * not numerically stable; i.e. it can produce intersection points which
 33    * lie outside the envelope of the line segments themselves.  In order
 34    * to increase the precision of the calculation input points should be normalized
 35    * before passing them to this routine.
 36    * 
 37    * @deprecated use {@link Intersection#intersection(Coordinate, Coordinate, Coordinate, Coordinate)}
 38    */
 39   public static Coordinate intersection(
 40       Coordinate p1, Coordinate p2,
 41       Coordinate q1, Coordinate q2)
 42       throws NotRepresentableException
 43   {
 44       // unrolled computation
 45     double px = p1.y - p2.y;
 46     double py = p2.x - p1.x;
 47     double pw = p1.x * p2.y - p2.x * p1.y;
 48     
 49     double qx = q1.y - q2.y;
 50     double qy = q2.x - q1.x;
 51     double qw = q1.x * q2.y - q2.x * q1.y;
 52     
 53     double x = py * qw - qy * pw;
 54     double y = qx * pw - px * qw;
 55     double w = px * qy - qx * py;
 56     
 57     double xInt = x/w;
 58     double yInt = y/w;
 59     
 60     if ((Double.isNaN(xInt)) || (Double.isInfinite(xInt)
 61             || Double.isNaN(yInt)) || (Double.isInfinite(yInt))) {
 62       throw new NotRepresentableException();
 63     }
 64     
 65     return new Coordinate(xInt, yInt);
 66   }
 67  
 68   /*
 69   public static Coordinate OLDintersection(
 70       Coordinate p1, Coordinate p2,
 71       Coordinate q1, Coordinate q2)
 72       throws NotRepresentableException
 73   {
 74     HCoordinate l1 = new HCoordinate(p1, p2);
 75     HCoordinate l2 = new HCoordinate(q1, q2);
 76     HCoordinate intHCoord = new HCoordinate(l1, l2);
 77     Coordinate intPt = intHCoord.getCoordinate();
 78     return intPt;
 79   }
 80   */
 81  
 82   public double x,y,w;
 83  
 84   public HCoordinate() {
 85     x = 0.0;
 86     y = 0.0;
 87     w = 1.0;
 88   }
 89  
 90   public HCoordinate(double _x, double _y, double _w) {
 91     x = _x;
 92     y = _y;
 93     w = _w;
 94   }
 95  
 96   public HCoordinate(double _x, double _y) {
 97     x = _x;
 98     y = _y;
 99     w = 1.0;
100   }
101  
102   public HCoordinate(Coordinate p) {
103     x = p.x;
104     y = p.y;
105     w = 1.0;
106   }
107  
108   public HCoordinate(HCoordinate p1, HCoordinate p2) 
109   {
110     x = p1.y * p2.w - p2.y * p1.w;
111     y = p2.x * p1.w - p1.x * p2.w;
112     w = p1.x * p2.y - p2.x * p1.y;
113   }
114  
115   /**
116    * Constructs a homogeneous coordinate which is the intersection of the lines
117    * define by the homogenous coordinates represented by two
118    * {@link Coordinate}s.
119    * 
120    * @param p1
121    * @param p2
122    */
123   public HCoordinate(Coordinate p1, Coordinate p2) 
124   {
125       // optimization when it is known that w = 1
126     x = p1.y - p2.y;
127     y = p2.x - p1.x;
128     w = p1.x * p2.y - p2.x * p1.y;
129   }
130   
131   public HCoordinate(Coordinate p1, Coordinate p2, Coordinate q1, Coordinate q2) 
132   {
133       // unrolled computation
134     double px = p1.y - p2.y;
135     double py = p2.x - p1.x;
136     double pw = p1.x * p2.y - p2.x * p1.y;
137     
138     double qx = q1.y - q2.y;
139     double qy = q2.x - q1.x;
140     double qw = q1.x * q2.y - q2.x * q1.y;
141     
142     x = py * qw - qy * pw;
143     y = qx * pw - px * qw;
144     w = px * qy - qx * py;
145   }
146   
147   public double getX() throws NotRepresentableException {
148     double a = x/w;
149     if ((Double.isNaN(a)) || (Double.isInfinite(a))) {
150       throw new NotRepresentableException();
151     }
152     return a;
153   }
154  
155   public double getY() throws NotRepresentableException {
156     double a = y/w;
157     if  ((Double.isNaN(a)) || (Double.isInfinite(a))) {
158       throw new NotRepresentableException();
159     }
160     return a;
161   }
162  
163   public Coordinate getCoordinate() throws NotRepresentableException {
164     Coordinate p = new Coordinate();
165     p.x = getX();
166     p.y = getY();
167     return p;
168   }
169 }
170