/// <summary> /// Returns the intersection of the specified segment with this bounding box. If there is no intersection, /// then this returns null. If the intersection is a corner, then the LineSegment will be degenerate, /// that is both the coordinates will be the same. Otherwise, the segment will be returned so that the /// direction is the same as the original segment. /// </summary> /// <param name="self">The IEnvelope to use with this method</param> /// <param name="segment">The LineSegment to intersect.</param> /// <returns>An ILineSegment that is cropped to fit within the bounding box.</returns> public static ILineSegment Intersection(this IEnvelope self, ILineSegment segment) { if (self == null) { return(null); } if (self.IsNull) { return(null); } if (segment == null) { return(null); } // If the line segment is completely contained by this envelope, simply return the original. if (self.Contains(segment.P0) && self.Contains(segment.P1)) { return(segment); } int count = 0; Coordinate[] borderPoints = new Coordinate[2]; ILineSegment[] border = self.BorderSegments(); for (int i = 0; i < 4; i++) { borderPoints[count] = border[i].Intersection(segment); if (borderPoints[count] != null) { count++; if (count > 1) { break; } } } // If there are two intersections, the line crosses this envelope if (count == 2) { Vector v = new Vector(segment.P0, segment.P1); Vector t = new Vector(borderPoints[0], borderPoints[1]); return(t.Dot(v) < 0 ? new LineSegment(borderPoints[1], borderPoints[0]) : new LineSegment(borderPoints[0], borderPoints[1])); } // if there is only one intersection, we probably have one point contained and one point not-contained if (count == 1) { if (self.Contains(segment.P0)) { // P1 got cropped, so make a line from p0 to the cropped point return(new LineSegment(segment.P0, borderPoints[0])); } return(self.Contains(segment.P1) ? new LineSegment(borderPoints[0], segment.P1) : new LineSegment(borderPoints[0], borderPoints[0])); } return(null); }