/** * 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 Coordinate intersection(Coordinate p1, Coordinate p2, Coordinate q1, Coordinate q2) throws NotRepresentableException { HCoordinate l1 = new HCoordinate(new HCoordinate(p1), new HCoordinate(p2)); HCoordinate l2 = new HCoordinate(new HCoordinate(q1), new HCoordinate(q2)); HCoordinate intHCoord = new HCoordinate(l1, l2); Coordinate intPt = intHCoord.getCoordinate(); return intPt; }
/** * Adds a mitre join connecting the two reflex offset segments. The mitre will be beveled if it * exceeds the mitre ratio limit. * * @param offset0 the first offset segment * @param offset1 the second offset segment * @param distance the offset distance */ private void addMitreJoin( final Coordinate p, final LineSegment offset0, final LineSegment offset1, final double distance) { boolean isMitreWithinLimit = true; Coordinate intPt = null; /** * This computation is unstable if the offset segments are nearly collinear. Howver, this * situation should have been eliminated earlier by the check for whether the offset segment * endpoints are almost coincident */ try { intPt = HCoordinate.intersection(offset0.p0, offset0.p1, offset1.p0, offset1.p1); final double mitreRatio = distance <= 0.0 ? 1.0 : intPt.distance(p) / Math.abs(distance); if (mitreRatio > m_bufferParams.getMitreLimit()) isMitreWithinLimit = false; } catch (final NotRepresentableException ex) { intPt = new Coordinate(0, 0); isMitreWithinLimit = false; } if (isMitreWithinLimit) { m_bufferBuilder.addVertices(intPt); } else { addLimitedMitreJoin(distance, m_bufferParams.getMitreLimit()); } }
/** * Computes the intersection point of the lines of infinite extent defined by two line segments * (if there is one). There may be 0, 1 or an infinite number of intersection points between two * lines. If there is a unique intersection point, it is returned. Otherwise, <tt>null</tt> is * returned. If more information is required about the details of the intersection, the {@link * RobustLineIntersector} class should be used. * * @param line a line segment defining an straight line with infinite extent * @return an intersection point, or <code>null</code> if there is no point of intersection or an * infinite number of intersection points * @see RobustLineIntersector */ public Coordinate lineIntersection(LineSegment line) { try { Coordinate intPt = HCoordinate.intersection(p0, p1, line.p0, line.p1); return intPt; } catch (NotRepresentableException ex) { // eat this exception, and return null; } return null; }
/** * Computes a segment intersection using homogeneous coordinates. Round-off error can cause the * raw computation to fail, (usually due to the segments being approximately parallel). If this * happens, a reasonable approximation is computed instead. * * @param p1 a segment endpoint * @param p2 a segment endpoint * @param q1 a segment endpoint * @param q2 a segment endpoint * @return the computed intersection point */ private Coordinate safeHCoordinateIntersection( Coordinate p1, Coordinate p2, Coordinate q1, Coordinate q2) { Coordinate intPt = null; try { intPt = HCoordinate.intersection(p1, p2, q1, q2); } catch (NotRepresentableException e) { // System.out.println("Not calculable: " + this); // compute an approximate result // intPt = CentralEndpointIntersector.getIntersection(p1, p2, q1, q2); intPt = nearestEndpoint(p1, p2, q1, q2); // System.out.println("Snapped to " + intPt); } return intPt; }