Example #1
0
        /// <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);
        }