private static SegmentIntersection TryGetContinuousLinearIntersection( int lineIdx, [NotNull] Line3D line1, [NotNull] ISegmentList segmentList2, [CanBeNull] SegmentIntersection previous, double tolerance) { if (previous == null || previous.SourceIndex + 1 != lineIdx) { // We jumped over some source segments return(null); } int?targetIdx = previous.LinearIntersectionInOppositeDirection ? segmentList2.PreviousSegmentIndex(previous.TargetIndex) : segmentList2.NextSegmentIndex(previous.TargetIndex); if (targetIdx == null) { return(null); } Line3D targetSegment = segmentList2.GetSegment(targetIdx.Value); if (targetSegment.EqualsXY(line1, tolerance)) { SegmentIntersection resultIntersection = SegmentIntersection.CreateCoincidenceIntersectionXY( lineIdx, targetIdx.Value, previous.LinearIntersectionInOppositeDirection); return(resultIntersection); } return(null); }
/// <summary> /// Returns all self intersections except the intersection between consecutive segments. /// </summary> /// <param name="sourceLineGlobalIdx"></param> /// <param name="sourceLine"></param> /// <param name="containingSegmentList"></param> /// <param name="tolerance"></param> /// <returns></returns> public static IEnumerable <SegmentIntersection> GetRelevantSelfIntersectionsXY( int sourceLineGlobalIdx, [NotNull] Line3D sourceLine, [NotNull] ISegmentList containingSegmentList, double tolerance) { // a predicate, i.e. i != sourceGlobalIdx && i != sourceGlobalIdx - 1 && i != sourceGlobalIdx + 1 Predicate <int> predicate = i => i != sourceLineGlobalIdx; IEnumerable <KeyValuePair <int, Line3D> > segmentsByGlobalIdx = containingSegmentList.FindSegments(sourceLine, tolerance, true, predicate); foreach (SegmentIntersection intersection in IntersectLineWithLinestringXY( sourceLine, sourceLineGlobalIdx, segmentsByGlobalIdx, tolerance)) { int?nextSegmentIndex = containingSegmentList.NextSegmentIndex(intersection.SourceIndex); if (nextSegmentIndex == intersection.TargetIndex && !intersection.HasLinearIntersection) { continue; } int?previousSegmentIndex = containingSegmentList.PreviousSegmentIndex(intersection.SourceIndex); if (previousSegmentIndex == intersection.TargetIndex && !intersection.HasLinearIntersection) { continue; } yield return(intersection); } }
public int?GetNonIntersectingTargetSegmentIndex( [NotNull] ISegmentList target, bool forwardAlongTarget) { if (SegmentIntersection.HasLinearIntersection) { if (Type == IntersectionPointType.LinearIntersectionIntermediate) { return(null); } // search the first non-intersecting point at the and of the linear intersection bool deviationIsBackward = Type == IntersectionPointType.LinearIntersectionStart; if (SegmentIntersection.LinearIntersectionInOppositeDirection) { deviationIsBackward = !deviationIsBackward; } if ((deviationIsBackward && forwardAlongTarget) || (!deviationIsBackward && !forwardAlongTarget)) { return(null); } // get the first non-intersecting point after the linear intersection, check its side: if (SegmentIntersection.TargetStartIntersects && SegmentIntersection.TargetEndIntersects) { // Target is within source (or equal to source) return(forwardAlongTarget ? target.NextSegmentIndex(SegmentIntersection.TargetIndex) : target.PreviousSegmentIndex(SegmentIntersection.TargetIndex)); } if (!SegmentIntersection.TargetStartIntersects && !SegmentIntersection.TargetEndIntersects) { // Source is completely within target return(SegmentIntersection.TargetIndex); } // Either the source start or the source end intersects but not both // The same must be the case for the target Assert.True( SegmentIntersection.TargetEndIntersects ^ SegmentIntersection.TargetStartIntersects, "Either target start or end is expected to intersect"); } if (SegmentIntersection.TargetStartIntersects) { return(forwardAlongTarget ? SegmentIntersection.TargetIndex : target.PreviousSegmentIndex(SegmentIntersection.TargetIndex)); } if (SegmentIntersection.TargetEndIntersects) { return(forwardAlongTarget ? target.NextSegmentIndex(SegmentIntersection.TargetIndex) : SegmentIntersection.TargetIndex); } // By now all linear cases should have been handled Assert.False(SegmentIntersection.HasLinearIntersection, "Not all linear cases were handled."); return(SegmentIntersection.TargetIndex); }