/// <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); }
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) { ProjectionLocation projectionLocation = LocateProjection(other.start); ProjectionLocation projectionLocation2 = LocateProjection(other.end); if (projectionLocation != ProjectionLocation.SegmentAB && projectionLocation == projectionLocation2) { result = null; } else if ((start == other.start && projectionLocation2 == ProjectionLocation.RayA) || (start == other.end && projectionLocation == ProjectionLocation.RayA)) { result = start; } else { if ((!(end == other.start) || projectionLocation2 != ProjectionLocation.RayB) && (!(end == other.end) || projectionLocation != ProjectionLocation.RayB)) { throw new InvalidOperationException("Overlapping segments do not have a single intersection point."); } result = end; } } } else { result = GetIntersectionWith(other.line); if (result.HasValue && other.LocateProjection(result.Value) != ProjectionLocation.SegmentAB) { 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 /// 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 DoublePoint? GetIntersectionWith( LineSegment other ) { DoublePoint? 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; }