/// <summary> /// 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. /// </summary> private static Coordinate SafeHCoordinateIntersection(Coordinate p1, Coordinate p2, Coordinate q1, Coordinate q2) { Coordinate intPt; try { intPt = HCoordinate.Intersection(p1, p2, q1, q2); } catch (NotRepresentableException e) { intPt = CentralEndpointIntersector.GetIntersection(p1, p2, q1, q2); } return(intPt); }
/// <summary> /// This method computes the actual value of the intersection point. /// To obtain the maximum precision from the intersection calculation, /// the coordinates are normalized by subtracting the minimum /// ordinate values (in absolute value). This has the effect of /// removing common significant digits from the calculation to /// maintain more bits of precision. /// </summary> /// <param name="p1"></param> /// <param name="p2"></param> /// <param name="q1"></param> /// <param name="q2"></param> /// <returns></returns> private Coordinate Intersection(Coordinate p1, Coordinate p2, Coordinate q1, Coordinate q2) { Coordinate intPt = IntersectionWithNormalization(p1, p2, q1, q2); /* * // TESTING ONLY * var intPtDD = CGAlgorithmsDD.Intersection(p1, p2, q1, q2); * var dist = intPt.Distance(intPtDD); * System.Console.WriteLine(intPt + " - " + intPtDD + " dist = " + dist); * //intPt = intPtDD; */ /* * Due to rounding it can happen that the computed intersection is * outside the envelopes of the input segments. Clearly this * is inconsistent. * This code checks this condition and forces a more reasonable answer * * MD - May 4 2005 - This is still a problem. Here is a failure case: * * LINESTRING (2089426.5233462777 1180182.3877339689, 2085646.6891757075 1195618.7333999649) * LINESTRING (1889281.8148903656 1997547.0560044837, 2259977.3672235999 483675.17050843034) * int point = (2097408.2633752143,1144595.8008114607) * * MD - Dec 14 2006 - This does not seem to be a failure case any longer */ if (!IsInSegmentEnvelopes(intPt)) { // compute a safer result intPt = CentralEndpointIntersector.GetIntersection(p1, p2, q1, q2); } if (PrecisionModel != null) { PrecisionModel.MakePrecise(intPt); } return(intPt); }
/// <summary> /// Computes an approximate intersection of two line segments /// by taking the most central of the endpoints of the segments. /// This is effective in cases where the segments are nearly parallel /// and should intersect at an endpoint. /// </summary> /// <param name="p00">The 1st coordinate of the 1st line segement.</param> /// <param name="p01">The 2nd coordinate of the 1st line segemen.</param> /// <param name="p10">The 1st coordinate of the 2nd line segement.</param> /// <param name="p11">The 2nd coordinate of the 2nd line segement.</param> /// <returns></returns> public static Coordinate GetIntersection(Coordinate p00, Coordinate p01, Coordinate p10, Coordinate p11) { var intor = new CentralEndpointIntersector(p00, p01, p10, p11); return(intor.Intersection); }
/// <summary> /// Computes an approximate intersection of two line segments /// by taking the most central of the endpoints of the segments. /// This is effective in cases where the segments are nearly parallel /// and should intersect at an endpoint. /// </summary> /// <param name="p00">The 1st coordinate of the 1st line segement.</param> /// <param name="p01">The 2nd coordinate of the 1st line segemen.</param> /// <param name="p10">The 1st coordinate of the 2nd line segement.</param> /// <param name="p11">The 2nd coordinate of the 2nd line segement.</param> /// <returns></returns> public static Coordinate GetIntersection(Coordinate p00, Coordinate p01, Coordinate p10, Coordinate p11) { var intor = new CentralEndpointIntersector(p00, p01, p10, p11); return intor.Intersection; }