/** * Determines the orientation of a LineSegment relative to this segment. The concept of * orientation is specified as follows: Given two line segments A and L, * * <ul * <li> * A is to the left of a segment L if A lies wholly in the closed half-plane lying to the left * of L * <li>A is to the right of a segment L if A lies wholly in the closed half-plane lying to the * right of L * <li>otherwise, A has indeterminate orientation relative to L. This happens if A is collinear * with L or if A crosses the line determined by L. * </ul> * * @param seg the LineSegment to compare * @return 1 if <code>seg</code> is to the left of this segment * @return -1 if <code>seg</code> is to the right of this segment * @return 0 if <code>seg</code> is collinear to or crosses this segment */ public int orientationIndex(LineSegment seg) { int orient0 = CGAlgorithms.orientationIndex(p0, p1, seg.p0); int orient1 = CGAlgorithms.orientationIndex(p0, p1, seg.p1); // this handles the case where the points are L or collinear if (orient0 >= 0 && orient1 >= 0) return Math.max(orient0, orient1); // this handles the case where the points are R or collinear if (orient0 <= 0 && orient1 <= 0) return Math.max(orient0, orient1); // points lie on opposite sides ==> indeterminate orientation return 0; }
public void computeIntersection(Coordinate p, Coordinate p1, Coordinate p2) { isProper = false; // do between check first, since it is faster than the orientation test if (Envelope.intersects(p1, p2, p)) { if ((CGAlgorithms.orientationIndex(p1, p2, p) == 0) && (CGAlgorithms.orientationIndex(p2, p1, p) == 0)) { isProper = true; if (p.equals(p1) || p.equals(p2)) { isProper = false; } result = POINT_INTERSECTION; return; } } result = NO_INTERSECTION; }
/** * Determines the orientation index of a {@link Coordinate} relative to this segment. The * orientation index is as defined in {@link CGAlgorithms#computeOrientation}. * * @param p the coordinate to compare * @return 1 (LEFT) if <code>p</code> is to the left of this segment * @return -1 (RIGHT) if <code>p</code> is to the right of this segment * @return 0 (COLLINEAR) if <code>p</code> is collinear with this segment * @see CGAlgorithms#computeOrientation(Coordinate, Coordinate, Coordinate) */ public int orientationIndex(Coordinate p) { return CGAlgorithms.orientationIndex(p0, p1, p); }
protected 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.intersects(p1, p2, q1, q2)) return 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 = CGAlgorithms.orientationIndex(p1, p2, q1); int Pq2 = CGAlgorithms.orientationIndex(p1, p2, q2); if ((Pq1 > 0 && Pq2 > 0) || (Pq1 < 0 && Pq2 < 0)) { return NO_INTERSECTION; } int Qp1 = CGAlgorithms.orientationIndex(q1, q2, p1); int Qp2 = CGAlgorithms.orientationIndex(q1, q2, p2); if ((Qp1 > 0 && Qp2 > 0) || (Qp1 < 0 && Qp2 < 0)) { return NO_INTERSECTION; } boolean 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. * * <p>[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) * * <p>LINESTRING ( 19.850257749638203 46.29709338043669, 20.31970698357233 46.76654261437082 ) * and LINESTRING ( -48.51001596420236 -22.063180333403878, 19.850257749638203 * 46.29709338043669 ) * * <p>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(q1); } else if (Pq2 == 0) { intPt[0] = new Coordinate(q2); } else if (Qp1 == 0) { intPt[0] = new Coordinate(p1); } else if (Qp2 == 0) { intPt[0] = new Coordinate(p2); } } else { isProper = true; intPt[0] = intersection(p1, p2, q1, q2); } return POINT_INTERSECTION; }