Ejemplo n.º 1
0
        /// <summary>
        /// Computes the (approximate) intersection point between two line segments
        /// using homogeneous coordinates.
        /// 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.
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="q1"></param>
        /// <param name="q2"></param>
        /// <returns></returns>
        public static ICoordinate Intersection(ICoordinate p1, ICoordinate p2, ICoordinate q1, ICoordinate q2)
        {
            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);
            ICoordinate intPt     = intHCoord.Coordinate;

            return(intPt);
        }
Ejemplo n.º 2
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="p1"></param>
 /// <param name="p2"></param>
 public HCoordinate(HCoordinate p1, HCoordinate p2)
 {
     x = p1.y * p2.w - p2.y * p1.w;
     y = p2.x * p1.w - p1.x * p2.w;
     w = p1.x * p2.y - p2.x * p1.y;
 }
        /// <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 ICoordinate Intersection(ICoordinate p1, ICoordinate p2, ICoordinate q1, ICoordinate q2)
        {
            ICoordinate n1     = new Coordinate(p1);
            ICoordinate n2     = new Coordinate(p2);
            ICoordinate n3     = new Coordinate(q1);
            ICoordinate n4     = new Coordinate(q2);
            ICoordinate normPt = new Coordinate();

            NormalizeToEnvCentre(n1, n2, n3, n4, normPt);

            ICoordinate intPt = null;

            try
            {
                intPt = HCoordinate.Intersection(n1, n2, n3, n4);
            }
            catch (NotRepresentableException)
            {
                Assert.ShouldNeverReachHere("Coordinate for intersection is not calculable");
            }

            intPt.X += normPt.X;
            intPt.Y += normPt.Y;

            /*
             *
             * 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)
             */
            if (!IsInSegmentEnvelopes(intPt))
            {
                Trace.WriteLine("Intersection outside segment envelopes: " + intPt);
            }

            /*
             * // disabled until a better solution is found
             * if(!IsInSegmentEnvelopes(intPt))
             * {
             *  Trace.WriteLine("first value outside segment envelopes: " + intPt);
             *
             *  IteratedBisectionIntersector ibi = new IteratedBisectionIntersector(p1, p2, q1, q2);
             *  intPt = ibi.Intersection;
             * }
             * if(!IsInSegmentEnvelopes(intPt))
             * {
             *  Trace.WriteLine("ERROR - outside segment envelopes: " + intPt);
             *
             *  IteratedBisectionIntersector ibi = new IteratedBisectionIntersector(p1, p2, q1, q2);
             *  Coordinate testPt = ibi.Intersection;
             * }
             */

            if (precisionModel != null)
            {
                precisionModel.MakePrecise(intPt);
            }

            return(intPt);
        }