/// <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 ); }
/// <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; }
/// <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)); }