computeIntersect method

int computeIntersect(
  1. Coordinate p1,
  2. Coordinate p2,
  3. Coordinate q1,
  4. Coordinate q2,
)
override

Implementation

int computeIntersect(
    Coordinate p1, Coordinate p2, Coordinate q1, Coordinate q2) {
  _isProper = false;

  // first try a fast test to see if the envelopes of the lines intersect
  if (!Envelope.intersectsEnvelopeCoords(p1, p2, q1, q2))
    return LineIntersector.NO_INTERSECTION;

  // for each endpoint, compute which side of the other segment it lies
  // if both endpoints lie on the same side of the other segment,
  // the segments do not intersect
  int Pq1 = Orientation.index(p1, p2, q1);
  int Pq2 = Orientation.index(p1, p2, q2);

  if ((Pq1 > 0 && Pq2 > 0) || (Pq1 < 0 && Pq2 < 0)) {
    return LineIntersector.NO_INTERSECTION;
  }

  int Qp1 = Orientation.index(q1, q2, p1);
  int Qp2 = Orientation.index(q1, q2, p2);

  if ((Qp1 > 0 && Qp2 > 0) || (Qp1 < 0 && Qp2 < 0)) {
    return LineIntersector.NO_INTERSECTION;
  }

  bool collinear = Pq1 == 0 && Pq2 == 0 && Qp1 == 0 && Qp2 == 0;
  if (collinear) {
    return computeCollinearIntersection(p1, p2, q1, q2);
  }

  /**
   * At this point we know that there is a single intersection point
   * (since the lines are not collinear).
   */

  /**
   *  Check if the intersection is an endpoint. If it is, copy the endpoint as
   *  the intersection point. Copying the point rather than computing it
   *  ensures the point has the exact value, which is important for
   *  robustness. It is sufficient to simply check for an endpoint which is on
   *  the other line, since at this point we know that the inputLines must
   *  intersect.
   */
  if (Pq1 == 0 || Pq2 == 0 || Qp1 == 0 || Qp2 == 0) {
    _isProper = false;

    /**
     * Check for two equal endpoints.
     * This is done explicitly rather than by the orientation tests
     * below in order to improve robustness.
     *
     * [An example where the orientation tests fail to be consistent is
     * the following (where the true intersection is at the shared endpoint
     * POINT (19.850257749638203 46.29709338043669)
     *
     * LINESTRING ( 19.850257749638203 46.29709338043669, 20.31970698357233 46.76654261437082 )
     * and
     * LINESTRING ( -48.51001596420236 -22.063180333403878, 19.850257749638203 46.29709338043669 )
     *
     * which used to produce the INCORRECT result: (20.31970698357233, 46.76654261437082, NaN)
     *
     */
    if (p1.equals2D(q1) || p1.equals2D(q2)) {
      intPt[0] = p1;
    } else if (p2.equals2D(q1) || p2.equals2D(q2)) {
      intPt[0] = p2;
    }

    /**
     * Now check to see if any endpoint lies on the interior of the other segment.
     */
    else if (Pq1 == 0) {
      intPt[0] = new Coordinate.fromCoordinate(q1);
    } else if (Pq2 == 0) {
      intPt[0] = new Coordinate.fromCoordinate(q2);
    } else if (Qp1 == 0) {
      intPt[0] = new Coordinate.fromCoordinate(p1);
    } else if (Qp2 == 0) {
      intPt[0] = new Coordinate.fromCoordinate(p2);
    }
  } else {
    _isProper = true;
    intPt[0] = intersection(p1, p2, q1, q2);
  }
  return LineIntersector.POINT_INTERSECTION;
}