/// <summary> /// Cuts back a horizontal line segment to the closest intersection with this line. /// Used in point in polygon. /// </summary> /// <param name="s">Start of horizontal segment.</param> /// <param name="e">End of segment (will be modified if segment intersects this line)</param> /// <param name="status">Return code indicating whether an error has arisen (returned /// as 0 if no error).</param> /// <returns>True if the horizontal line was cut back.</returns> internal override bool GetCloser(IPointGeometry s, ref PointGeometry e, out uint status) { status = 0; // Remember the initial end of segment PointGeometry initEnd = new PointGeometry(e); // Represent the horizontal segment in a class of its own HorizontalRay hseg = new HorizontalRay(s, e.X - s.X); if (!hseg.IsValid) { status = 1; return(false); } IPointGeometry[] data = this.Data; // Get relative position code for the start of the line. If it's // somewhere on the horizontal segment, cut the line back. byte scode = Geom.GetPositionCode(data[0], s, e); if (scode == 0) { e = new PointGeometry(Start); } // Loop through each line segment, testing the end of each segment // against the horizontal segment. byte ecode; for (int i = 1; i < data.Length; scode = ecode, i++) { // Get the position code for the end of the line segment ecode = Geom.GetPositionCode(data[i], s, e); // If it's coincident with the horizontal segment, cut the // line back. Otherwise see whether there is any potential // intersection to cut back to. if (ecode == 0) { e = new PointGeometry(data[i]); } else if ((scode & ecode) == 0) { IPosition x = null; if (hseg.Intersect(data[i - 1], data[i], ref x)) { e = new PointGeometry(x); } } } // Return flag to indicate whether we got closer or not. return(!e.IsCoincident(initEnd)); }
/// <summary> /// Cuts back a horizontal line segment to the closest intersection with this line. /// Used in point in polygon. /// </summary> /// <param name="s">Start of horizontal segment.</param> /// <param name="e">End of segment (will be modified if segment intersects this line)</param> /// <param name="status">Return code indicating whether an error has arisen (returned /// as 0 if no error).</param> /// <returns>True if the horizontal line was cut back.</returns> internal override bool GetCloser(IPointGeometry s, ref PointGeometry e, out uint status) { status = 0; // Remember the initial end of segment PointGeometry initEnd = new PointGeometry(e); // Represent the horizontal segment in a class of its own HorizontalRay hseg = new HorizontalRay(s, e.X - s.X); if (!hseg.IsValid) { status = 1; return(false); } // Get relative position code for the start of the line. If it's // somewhere on the horizontal segment, cut the line back. byte scode = Geom.GetPositionCode(Start, s, e); if (scode == 0) { e = new PointGeometry(Start); } // Get the position code for the end of the line segment byte ecode = Geom.GetPositionCode(End, s, e); // If it's coincident with the horizontal segment, cut the // line back. Otherwise see whether there is any potential // intersection to cut back to. if (ecode == 0) { e = new PointGeometry(End); } else if ((scode & ecode) == 0) { IPosition x = null; if (hseg.Intersect(Start, End, ref x)) { e = new PointGeometry(x); } } // Return flag to indicate whether we got closer or not. return(!e.IsCoincident(initEnd)); }