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