Пример #1
0
        /// <summary>
        /// Finds, provided it exists, the intersection point with the specified <see cref="LineSegment"/>.
        /// </summary>
        /// 
        /// <param name="other"><see cref="LineSegment"/> to find intersection with.</param>
        /// 
        /// <returns>Returns intersection point with the specified <see cref="LineSegment"/>, or <see langword="null"/>, if
        /// the two segments do not intersect.</returns>
        /// 
        /// <remarks><para>If the two segments do not intersect, the method returns <see langword="null"/>. If the two
        /// segments share multiple points, this throws an <see cref="InvalidOperationException"/>.
        /// </para></remarks>
        /// 
        /// <exception cref="InvalidOperationException">Thrown if the segments overlap - if they have
        /// multiple points in common.</exception>
        /// 
        public Point? GetIntersectionWith( LineSegment other )
        {
            Point? result = null;

            if ( ( line.Slope == other.line.Slope ) || ( line.IsVertical && other.line.IsVertical ) )
            {
                if ( line.Intercept == other.line.Intercept )
                {
                    // Collinear segments. Inspect and handle.
                    // Consider this segment AB and other as CD. (start/end in both cases)
                    // There are three cases:
                    // 0 shared points: C and D both project onto the same ray of AB
                    // 1 shared point: One of A or B equals one of C or D, and the other of C/D 
                    //      projects on the correct ray.
                    // Many shared points.

                    ProjectionLocation projC = LocateProjection( other.start ), projD = LocateProjection( other.end );

                    if ( ( projC != ProjectionLocation.SegmentAB ) && ( projC == projD ) )
                    {
                        // no shared points
                        result = null;
                    }
                    else if ( ( ( start == other.start ) && ( projD == ProjectionLocation.RayA ) ) ||
                              ( ( start == other.end ) && ( projC == ProjectionLocation.RayA ) ) )
                    {
                        // shared start point
                        result = start;
                    }
                    else if ( ( ( end == other.start ) && ( projD == ProjectionLocation.RayB ) ) ||
                              ( ( end == other.end ) && ( projC == ProjectionLocation.RayB ) ) )
                    {
                        // shared end point
                        result = end;
                    }
                    else
                    {
                        // overlapping
                        throw new InvalidOperationException( "Overlapping segments do not have a single intersection point." );
                    }
                }
            }
            else
            {
                result = GetIntersectionWith( other.line );

                if ( ( result.HasValue ) && ( other.LocateProjection( result.Value ) != ProjectionLocation.SegmentAB ) )
                {
                    // the intersection is on the extended line of this segment
                    result = null;
                }
            }

            return result;
        }
Пример #2
0
 /// <summary>
 /// Finds, provided it exists, the intersection point with the specified <see cref="LineSegment"/>.
 /// </summary>
 /// 
 /// <param name="other"><see cref="LineSegment"/> to find intersection with.</param>
 /// 
 /// <returns>Returns intersection point with the specified <see cref="LineSegment"/>, or <see langword="null"/>,
 /// if this line does not intersect with the segment.</returns>
 /// 
 /// <remarks><para>If the line and segment do not intersect, the method returns <see langword="null"/>.
 /// If the line and segment share multiple points, the method throws an <see cref="InvalidOperationException"/>.
 /// </para></remarks>
 /// 
 /// <exception cref="InvalidOperationException">Thrown if <paramref name="other"/> is a portion
 /// of this line.</exception>
 /// 
 public Point? GetIntersectionWith( LineSegment other )
 {
     return other.GetIntersectionWith( this );
 }