/// <summary> /// Computes the (approximate) intersection point between two line segments /// using homogeneous coordinates. /// </summary> /// <remarks> /// <para> /// 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. /// </para> /// </remarks> public static Coordinate Intersection(Coordinate p1, Coordinate p2, Coordinate q1, Coordinate 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); Coordinate intPt = intHCoord.Coordinate; return(intPt); }
/// <summary> /// This method computes the actual value of the intersection point. /// </summary> /// <param name="p1">The starting coordinate of first line.</param> /// <param name="p2">The ending coordinate of first line.</param> /// <param name="q1">The starting coordinate of seocnd line.</param> /// <param name="q2">The ending coordinate of second line.</param> /// <returns>The coordinate of the intersection point.</returns> /// <remarks> /// 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. /// </remarks> private Coordinate Intersection(Coordinate p1, Coordinate p2, Coordinate q1, Coordinate q2) { Coordinate n1 = new Coordinate(p1); Coordinate n2 = new Coordinate(p2); Coordinate n3 = new Coordinate(q1); Coordinate n4 = new Coordinate(q2); Coordinate normPt = new Coordinate(); NormalizeToEnvCentre(n1, n2, n3, n4, normPt); Coordinate intPt = null; try { intPt = HCoordinate.Intersection(n1, n2, n3, n4); } catch (AlgorithmException ex) { ExceptionManager.Publish(ex); } 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.ToString()); } if (m_objPrecisionModel != null) { intPt.MakePrecise(m_objPrecisionModel); } return(intPt); }
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; }