/**
  * 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;
 }