/// <summary> /// Returns the points from the target that deviate from the source, i.e. that are on neither of the sourceLines. /// </summary> /// <param name="targetSegments"></param> /// <param name="sourceLine1"></param> /// <param name="sourceLine2"></param> /// <param name="xyTolerance"></param> /// <param name="before"></param> /// <param name="after"></param> private void GetNonIntersectingTargetPoints(ISegmentList targetSegments, Line3D sourceLine1, Line3D sourceLine2, double xyTolerance, [CanBeNull] out Pnt3D before, [CanBeNull] out Pnt3D after) { Line3D thisTargetSegment = targetSegments[TargetIndex]; before = null; after = null; double?targetStartIntersectionFactor = GetTargetStartIntersectionFactor(); double?targetEndIntersectionFactor = GetTargetEndIntersectionFactor(); if (targetStartIntersectionFactor == null && targetEndIntersectionFactor == null) { // The target interior intersects the source start before = thisTargetSegment.StartPoint; after = thisTargetSegment.EndPoint; } else if (targetStartIntersectionFactor != null) { Line3D previousTargetSegment = targetSegments.PreviousSegment(TargetIndex); if (previousTargetSegment != null) { before = previousTargetSegment.StartPoint; after = thisTargetSegment.EndPoint; } } else // targetEndIntersectionFactor != null { Line3D nextTargetSegment = targetSegments.NextSegment(TargetIndex); if (nextTargetSegment != null) { before = thisTargetSegment.StartPoint; after = nextTargetSegment.EndPoint; } } if (before != null) { if (sourceLine1.IntersectsPointXY(before, xyTolerance) || sourceLine2.IntersectsPointXY(before, xyTolerance)) { before = null; } } if (after != null) { if (sourceLine1.IntersectsPointXY(after, xyTolerance) || sourceLine2.IntersectsPointXY(after, xyTolerance)) { after = null; } } }
/// <summary> /// Determines whether the two paths cross (i.e. the intersection is a point) in this intersection. /// </summary> /// <param name="sourceSegments"></param> /// <param name="targetSegments"></param> /// <param name="tolerance"></param> /// <param name="targetDeviatesToLeft">If there is no crossing: Whether the target segment deviates /// to the left of the source.</param> /// <returns></returns> public bool IsCrossingInPoint([NotNull] ISegmentList sourceSegments, [NotNull] ISegmentList targetSegments, double tolerance, out bool?targetDeviatesToLeft) { targetDeviatesToLeft = null; if (HasLinearIntersection) { return(false); } if (SingleInteriorIntersectionFactor != null) { // interior/interior targetDeviatesToLeft = true; return(true); } Line3D sourceLine = sourceSegments[SourceIndex]; // Target start/end on source interior: check previous/next target segments if (TargetStartIsOnSourceInterior) { Line3D thisTargetSegment = targetSegments[TargetIndex]; Line3D previousTargetSegment = targetSegments.PreviousSegment(TargetIndex); if (previousTargetSegment == null) { return(false); } if (ArePointsOnDifferentSide(sourceLine, previousTargetSegment.StartPoint, thisTargetSegment.EndPoint, tolerance, out targetDeviatesToLeft)) { return(true); } } if (TargetEndIsOnSourceInterior) { // check the sides of the target segment and the next target segment Line3D thisTargetSegment = targetSegments[TargetIndex]; Line3D nextTargetSegment = targetSegments.NextSegment(TargetIndex); if (nextTargetSegment == null) { return(false); } if (ArePointsOnDifferentSide(sourceLine, thisTargetSegment.StartPoint, nextTargetSegment.EndPoint, tolerance, out targetDeviatesToLeft)) { return(true); } } if (SourceStartIntersects) { Line3D previousSource = sourceSegments.PreviousSegment(SourceIndex, true); return(TargetCrossesBetweenSourceSegments(previousSource, sourceLine, targetSegments, tolerance, out targetDeviatesToLeft)); } if (SourceEndIntersects) { Line3D nextSource = sourceSegments.NextSegment(SourceIndex, true); return(TargetCrossesBetweenSourceSegments(sourceLine, nextSource, targetSegments, tolerance, out targetDeviatesToLeft)); } return(false); }