private static Linestring CreateWithBoundaryLoop(Linestring containingSourceRing, Linestring touchingInteriorRing, IntersectionPoint3D touchIntersection, double tolerance) { double sourceTouchPointRatio; int sourceTouchSegmentIdx = touchIntersection.GetLocalSourceIntersectionSegmentIdx( containingSourceRing, out sourceTouchPointRatio); List <Linestring> subcurves = new List <Linestring>(); subcurves.Add(containingSourceRing.GetSubcurve( 0, 0, sourceTouchSegmentIdx, sourceTouchPointRatio, false)); double targetTouchPointRatio; int targetTouchSegmentIdx = touchIntersection.GetLocalTargetIntersectionSegmentIdx( touchingInteriorRing, out targetTouchPointRatio); subcurves.Add(touchingInteriorRing.GetSubcurve( targetTouchSegmentIdx, targetTouchPointRatio, false, true)); subcurves.Add(containingSourceRing.GetSubcurve( sourceTouchSegmentIdx, sourceTouchPointRatio, containingSourceRing.SegmentCount - 1, 1, false)); Linestring withBoundaryLoop = GeomTopoOpUtils.MergeConnectedLinestrings(subcurves, null, tolerance); return(withBoundaryLoop); }
protected static Linestring GetTargetSubcurve( [NotNull] Linestring target, [NotNull] IntersectionPoint3D fromIntersection, [NotNull] IntersectionPoint3D toIntersection, bool forward) { double fromDistanceAlongAsRatio; int fromIndex = fromIntersection.GetLocalTargetIntersectionSegmentIdx( target, out fromDistanceAlongAsRatio); double toDistanceAlongAsRatio; int toIndex = toIntersection.GetLocalTargetIntersectionSegmentIdx( target, out toDistanceAlongAsRatio); if (!forward && fromIntersection.VirtualTargetVertex > toIntersection.VirtualTargetVertex) { } Linestring subcurve = target.GetSubcurve( fromIndex, fromDistanceAlongAsRatio, toIndex, toDistanceAlongAsRatio, false, !forward); // Replace the start / end with the actual intersection (correct source Z, exactly matching previous subcurve end) subcurve.ReplacePoint(0, fromIntersection.Point); subcurve.ReplacePoint(subcurve.SegmentCount, toIntersection.Point); return(subcurve); }
private bool CanFollowTarget(IntersectionPoint3D startingAt, bool forward, int initialSourcePart) { if (Target.GetPart(startingAt.TargetPartIndex).IsClosed) { return(true); } if (forward && !CanConnectToSourcePartAlongTargetForward(startingAt, initialSourcePart)) { // last intersection along a non-closed target (dangle!), cannot follow return(false); } if (!forward && !CanConnectToSourcePartAlongTargetBackwards(startingAt, initialSourcePart)) { // first intersection along a non-closed target, cannot follow return(false); } return(true); }
protected override IntersectionPoint3D FollowUntilNextIntersection( IntersectionPoint3D previousIntersection, bool continueOnSource, int partIndex, bool continueForward, out Linestring subcurve) { IntersectionPoint3D nextIntersection; if (continueOnSource) { nextIntersection = GetNextIntersectionAlongSource(previousIntersection); subcurve = GetSourceSubcurve(previousIntersection, nextIntersection); } else { // TODO: Handle verticals? nextIntersection = GetNextIntersectionAlongTarget(previousIntersection, continueForward); Linestring targetPart = Target.GetPart(previousIntersection.TargetPartIndex); subcurve = GetTargetSubcurve(targetPart, previousIntersection, nextIntersection, continueForward); } return(nextIntersection); }
/// <summary> /// Creates the IntersectionPoint3D of type <see cref="IntersectionPointType.LinearIntersectionEnd"/> /// that corresponds to the second intersection along the source segment. /// </summary> /// <param name="intersection">The intersection</param> /// <param name="sourceSegments"></param> /// <param name="targetSegments"></param> /// <returns></returns> public static IntersectionPoint3D GetLinearIntersectionEnd( [NotNull] SegmentIntersection intersection, [NotNull] ISegmentList sourceSegments, [NotNull] ISegmentList targetSegments) { Line3D sourceSegment = sourceSegments[intersection.SourceIndex]; double endFactor; Pnt3D toPoint = intersection.GetLinearIntersectionEnd(sourceSegment, out endFactor); int sourcePartIdx; int sourceSegmentIndex = sourceSegments.GetLocalSegmentIndex( intersection.SourceIndex, out sourcePartIdx); IntersectionPoint3D result = new IntersectionPoint3D( toPoint, sourceSegmentIndex + endFactor, intersection) { Type = IntersectionPointType.LinearIntersectionEnd, SourcePartIndex = sourcePartIdx }; int targetPartIdx; result.VirtualTargetVertex = CalculateVirtualTargetVertex( targetSegments, result.Type, intersection, out targetPartIdx); result.TargetPartIndex = targetPartIdx; return(result); }
protected Linestring GetSourceSubcurve( [NotNull] IntersectionPoint3D fromIntersection, [NotNull] IntersectionPoint3D toIntersection) { Assert.ArgumentCondition( fromIntersection.SourcePartIndex == toIntersection.SourcePartIndex, "Cannot jump between source parts"); Linestring source = GetSourcePart(fromIntersection.SourcePartIndex); double fromDistanceAlongAsRatio; int fromIndex = fromIntersection.GetLocalSourceIntersectionSegmentIdx( source, out fromDistanceAlongAsRatio); double toDistanceAlongAsRatio; int toIndex = toIntersection.GetLocalSourceIntersectionSegmentIdx( source, out toDistanceAlongAsRatio); Linestring subcurve = source.GetSubcurve( fromIndex, fromDistanceAlongAsRatio, toIndex, toDistanceAlongAsRatio, false); return(subcurve); }
private static void ClassifyIntersection([NotNull] ISegmentList source, [NotNull] ISegmentList target, [NotNull] IntersectionPoint3D intersectionPoint, out bool isInbound, out bool isOutbound) { Assert.False(intersectionPoint.Type == IntersectionPointType.Unknown, "Cannot classify unknown intersection type."); if (intersectionPoint.Type == IntersectionPointType.LinearIntersectionIntermediate) { isInbound = false; isOutbound = false; return; } int?previousTargetSegment = intersectionPoint.GetNonIntersectingTargetSegmentIndex(target, false); int?nextTargetSegment = intersectionPoint.GetNonIntersectingTargetSegmentIndex(target, true); Pnt3D previousPntAlongTarget = previousTargetSegment == null ? null : target[previousTargetSegment.Value].StartPoint; Pnt3D nextPntAlongTarget = nextTargetSegment == null ? null : target[nextTargetSegment.Value].EndPoint; isInbound = nextPntAlongTarget != null && intersectionPoint.IsOnTheRightSide(source, nextPntAlongTarget, true); isOutbound = previousPntAlongTarget != null && intersectionPoint.IsOnTheRightSide(source, previousPntAlongTarget, true); }
public IntersectionRun(IntersectionPoint3D nextIntersection, Linestring subcurve, Pnt3D includedRingStartPoint) { _includedRingStartPoint = includedRingStartPoint; NextIntersection = nextIntersection; Subcurve = subcurve; }
protected override void SetTurnDirection( IntersectionPoint3D startIntersection, IntersectionPoint3D intersection, ref bool alongSource, ref int partIndex, ref bool forward) { SetTurnDirection(startIntersection, intersection, ref alongSource, ref partIndex, ref forward, PreferredTurnDirection); }
protected override void SetTurnDirection( IntersectionPoint3D startIntersection, IntersectionPoint3D intersection, ref bool alongSource, ref int partIndex, ref bool forward) { Assert.AreEqual(TurnDirection.Right, PreferredTurnDirection, "Unsupported turn direction for single ring navigator"); // First set the base line, along which we're arriving at the junction: double distanceAlongSource; int sourceSegmentIdx = intersection.GetLocalSourceIntersectionSegmentIdx(_sourceRing, out distanceAlongSource); Line3D entryLine = GetEntryLine(intersection, _sourceRing, _target, alongSource, forward); Line3D alongSourceLine = distanceAlongSource < 1 ? _sourceRing[sourceSegmentIdx] : _sourceRing.NextSegmentInRing(sourceSegmentIdx); double?sourceForwardDirection = GetDirectionChange(entryLine, alongSourceLine); double?targetForwardDirection; double?targetBackwardDirection; GetAlongTargetDirectionChanges(intersection, entryLine, out targetForwardDirection, out targetBackwardDirection); // Order the direction change: the largest is the right-most if (IsMoreRight(sourceForwardDirection, targetForwardDirection)) { if (IsMoreRight(sourceForwardDirection, targetBackwardDirection)) { alongSource = true; forward = true; } else if (IsMoreRight(targetBackwardDirection, sourceForwardDirection)) { alongSource = false; forward = false; } } else if (IsMoreRight(targetForwardDirection, sourceForwardDirection)) { if (IsMoreRight(targetForwardDirection, targetBackwardDirection)) { alongSource = false; forward = true; } else if (IsMoreRight(targetBackwardDirection, targetForwardDirection)) { alongSource = false; forward = false; } } }
protected override IntersectionPoint3D GetNextIntersectionAlongSource( IntersectionPoint3D thisIntersection) { int previousSourceIdx = IntersectionOrders[thisIntersection].Key; int nextAlongSourceIdx = (previousSourceIdx + 1) % IntersectionsAlongSource.Count; IntersectionPoint3D nextIntersection = IntersectionsAlongSource[nextAlongSourceIdx]; return(nextIntersection); }
protected override IntersectionPoint3D FollowUntilNextIntersection( IntersectionPoint3D previousIntersection, bool continueOnSource, int partIndex, bool continueForward, out Linestring subcurve) { IntersectionPoint3D nextIntersection; if (continueOnSource) { nextIntersection = GetNextIntersectionAlongSource(previousIntersection); subcurve = GetSourceSubcurve(previousIntersection, nextIntersection); } else { int previousTargetIdx = IntersectionOrders[previousIntersection].Value; // If there are vertical rings, there can be 2 intersections at the exact same target distance int otherDirectionIdx = GetNextAlongTargetIdx( previousTargetIdx, !continueForward, IntersectionsAlongTarget); double epsilon = MathUtils.GetDoubleSignificanceEpsilon( previousIntersection.Point.X, previousIntersection.Point.Y); int nextAlongTargetIdx; if (MathUtils.AreEqual( IntersectionsAlongTarget[otherDirectionIdx].VirtualTargetVertex, IntersectionsAlongTarget[previousTargetIdx].VirtualTargetVertex, epsilon)) { // vertical ring, 2 intersections at same XY location nextAlongTargetIdx = otherDirectionIdx; } else { nextAlongTargetIdx = GetNextAlongTargetIdx( previousTargetIdx, continueForward, IntersectionsAlongTarget); } nextIntersection = IntersectionsAlongTarget[nextAlongTargetIdx]; subcurve = GetTargetSubcurve(_target, previousIntersection, nextIntersection, continueForward); } return(nextIntersection); }
private static void TryAddLinearIntersectionStretch( [CanBeNull] IntersectionPoint3D startPoint, [CanBeNull] IntersectionPoint3D endPoint, [NotNull] List <IntersectionPoint3D> result) { if (startPoint != null) { result.Add(startPoint); } if (endPoint != null) { result.Add(endPoint); } }
protected IntersectionPoint3D GetNextIntersectionAlongTarget( IntersectionPoint3D current, bool continueForward) { int nextAlongTargetIdx; int count = 0; int currentTargetIdx = IntersectionOrders[current].Value; do { nextAlongTargetIdx = (currentTargetIdx + (continueForward ? 1 : -1)) % IntersectionsAlongTarget.Count; // TODO: CollectionUtils.GetPreviousInCircularList() if (nextAlongTargetIdx < 0) { nextAlongTargetIdx += IntersectionsAlongTarget.Count; } Assert.True(count++ <= IntersectionsAlongTarget.Count, "Cannot find next intersection in same target part"); currentTargetIdx = nextAlongTargetIdx; } while (IntersectionsAlongTarget[nextAlongTargetIdx].TargetPartIndex != current.TargetPartIndex); //int currentTargetIdx = IntersectionOrders[current].Value; //int nextAlongTargetIdx = (currentTargetIdx + (continueForward ? 1 : -1)) % // IntersectionsAlongTarget.Count; //// TODO: CollectionUtils.GetPreviousInCircularList() //if (nextAlongTargetIdx < 0) //{ // nextAlongTargetIdx += IntersectionsAlongTarget.Count; //} //IntersectionPoint3D next = IntersectionsAlongTarget[nextAlongTargetIdx]; //int count = 0; //while (next.TargetPartIndex != partIndex) //{ // next = GetNextIntersectionAlongTarget(next, continueForward, partIndex); // Assert.True(count < IntersectionsAlongTarget.Count, // "Cannot find next intersection in same target part"); //} return(IntersectionsAlongTarget[nextAlongTargetIdx]); }
protected IntersectionPoint3D GetNextIntersectionAlongTarget( IntersectionPoint3D current, bool continueForward) { int currentTargetIdx = IntersectionOrders[current].Value; int nextAlongTargetIdx = (currentTargetIdx + (continueForward ? 1 : -1)) % IntersectionsAlongTarget.Count; // TODO: CollectionUtils.GetPreviousInCircularList() if (nextAlongTargetIdx < 0) { nextAlongTargetIdx += IntersectionsAlongTarget.Count; } return(IntersectionsAlongTarget[nextAlongTargetIdx]); }
private bool IsFirstIntersectionInTargetPart(IntersectionPoint3D intersection) { int targetIdx = IntersectionOrders[intersection].Value; // Any previous intersection in the same part that intersects the same source part? while (--targetIdx >= 0) { IntersectionPoint3D previousIntersection = IntersectionsAlongTarget[targetIdx]; if (previousIntersection.TargetPartIndex == intersection.TargetPartIndex && previousIntersection.SourcePartIndex == intersection.SourcePartIndex) { return(false); } } return(true); }
private bool IsLastIntersectionInTargetPart(IntersectionPoint3D intersection, int initialSourcePartIdx) { int targetIdx = IntersectionOrders[intersection].Value; // Any following intersection in the same target part that intersects the same source part? while (++targetIdx < IntersectionsAlongTarget.Count) { IntersectionPoint3D laterIntersection = IntersectionsAlongTarget[targetIdx]; if (laterIntersection.TargetPartIndex == intersection.TargetPartIndex && laterIntersection.SourcePartIndex == initialSourcePartIdx) { return(false); } } return(true); }
private bool CanConnectToSourcePartAlongTargetBackwards( IntersectionPoint3D fromIntersection, int initialSourcePartIdx) { int targetIdx = IntersectionOrders[fromIntersection].Value; // Any previous intersection in the same part that intersects the same source part? while (--targetIdx >= 0) { IntersectionPoint3D previousIntersection = IntersectionsAlongTarget[targetIdx]; if (previousIntersection.TargetPartIndex == fromIntersection.TargetPartIndex && previousIntersection.SourcePartIndex == initialSourcePartIdx) { return(true); } } return(false); }
private static Linestring GetSourceSubcurve( [NotNull] Linestring source, [NotNull] IntersectionPoint3D fromIntersection, [NotNull] IntersectionPoint3D toIntersection) { double fromDistanceAlongAsRatio; int fromIndex = fromIntersection.GetLocalSourceIntersectionSegmentIdx( source, out fromDistanceAlongAsRatio); double toDistanceAlongAsRatio; int toIndex = toIntersection.GetLocalSourceIntersectionSegmentIdx( source, out toDistanceAlongAsRatio); Linestring subcurve = source.GetSubcurve( fromIndex, fromDistanceAlongAsRatio, toIndex, toDistanceAlongAsRatio, false); return(subcurve); }
private bool CanConnectToSourcePartAlongTargetForward( [NotNull] IntersectionPoint3D fromIntersection, int initialSourcePartIdx) { int targetIdx = IntersectionOrders[fromIntersection].Value; // Any following intersection along the same target part that intersects the required source part? while (++targetIdx < IntersectionsAlongTarget.Count) { IntersectionPoint3D laterIntersection = IntersectionsAlongTarget[targetIdx]; if (laterIntersection.TargetPartIndex == fromIntersection.TargetPartIndex && laterIntersection.SourcePartIndex == initialSourcePartIdx) { return(true); } } return(false); }
protected override IntersectionPoint3D GetNextIntersectionAlongSource( IntersectionPoint3D thisIntersection) { int previousSourceIdx = IntersectionOrders[thisIntersection].Key; int nextSourceIdx = previousSourceIdx + 1; if (nextSourceIdx == IntersectionsAlongSource.Count) { nextSourceIdx = 0; } int thisPartIdx = thisIntersection.SourcePartIndex; if (nextSourceIdx < IntersectionsAlongSource.Count && IntersectionsAlongSource[nextSourceIdx].SourcePartIndex == thisPartIdx) { return(IntersectionsAlongSource[nextSourceIdx]); } return(IntersectionsAlongSource.First(i => i.SourcePartIndex == thisPartIdx)); }
private void GetAlongTargetDirectionChanges( int initialSourcePart, [NotNull] IntersectionPoint3D startingAt, [NotNull] Line3D entryLine, out double?targetForwardDirection, out double?targetBackwardDirection) { targetForwardDirection = null; targetBackwardDirection = null; if (CanFollowTarget(startingAt, true, initialSourcePart)) { int?forwardSegmentIdx = startingAt.GetNonIntersectingTargetSegmentIndex(Target, true); if (forwardSegmentIdx != null) { Line3D targetForward = Target[forwardSegmentIdx.Value]; targetForwardDirection = GetDirectionChange(entryLine, targetForward); } } if (CanFollowTarget(startingAt, false, initialSourcePart)) { int?backwardSegmentIdx = startingAt.GetNonIntersectingTargetSegmentIndex(Target, false); if (backwardSegmentIdx != null) { Line3D targetBackward = Target[backwardSegmentIdx.Value].Clone(); targetBackward.ReverseOrientation(); targetBackwardDirection = GetDirectionChange(entryLine, targetBackward); } } }
private bool CanFollowTarget(IntersectionPoint3D startingAt, bool forward) { if (_target.IsClosed) { return(true); } int targetIdx = IntersectionOrders[startingAt].Value; if (forward && targetIdx == IntersectionsAlongTarget.Count - 1) { // last intersection along a non-closed target (dangle!), cannot follow return(false); } if (!forward && targetIdx == 0) { // first intersection along a non-closed target, cannot follow return(false); } return(true); }
private void SetTurnDirection( IntersectionPoint3D startIntersection, IntersectionPoint3D intersection, ref bool alongSource, ref int partIndex, ref bool forward, TurnDirection preferredDirection) { // First set the base line, along which we're arriving at the junction: Linestring sourceRing = Source.GetPart(intersection.SourcePartIndex); Linestring target = Target.GetPart(intersection.TargetPartIndex); Line3D entryLine = GetEntryLine(intersection, sourceRing, target, alongSource, forward); double distanceAlongSource; int sourceSegmentIdx = intersection.GetLocalSourceIntersectionSegmentIdx(sourceRing, out distanceAlongSource); Line3D alongSourceLine = distanceAlongSource < 1 ? sourceRing[sourceSegmentIdx] : sourceRing.NextSegmentInRing(sourceSegmentIdx); double?sourceForwardDirection = GetDirectionChange(entryLine, alongSourceLine); double?targetForwardDirection; double?targetBackwardDirection; GetAlongTargetDirectionChanges(startIntersection.SourcePartIndex, intersection, entryLine, out targetForwardDirection, out targetBackwardDirection); // Order the direction change if (true == IsMore(preferredDirection, sourceForwardDirection, targetForwardDirection)) { if (true == IsMore(preferredDirection, sourceForwardDirection, targetBackwardDirection)) { alongSource = true; forward = true; } else if (true == IsMore(preferredDirection, targetBackwardDirection, sourceForwardDirection)) { alongSource = false; forward = false; } } else if (true == IsMore(preferredDirection, targetForwardDirection, sourceForwardDirection)) { if (true == IsMore(preferredDirection, targetForwardDirection, targetBackwardDirection)) { alongSource = false; forward = true; } else if (true == IsMore(preferredDirection, targetBackwardDirection, targetForwardDirection)) { alongSource = false; forward = false; } } }
/// <summary> /// Gets the line that enters the intersection point when moving along as specified /// with the direction parameters alongSource and forward. /// </summary> /// <param name="intoIntersection"></param> /// <param name="target"></param> /// <param name="alongSource"></param> /// <param name="forward"></param> /// <param name="source"></param> /// <returns></returns> protected static Line3D GetEntryLine([NotNull] IntersectionPoint3D intoIntersection, [NotNull] Linestring source, [NotNull] Linestring target, bool alongSource, bool forward) { Line3D entryLine; if (alongSource) { double distanceAlongSource; int sourceSegmentIdx = intoIntersection.GetLocalSourceIntersectionSegmentIdx( source, out distanceAlongSource); entryLine = distanceAlongSource > 0 ? source[sourceSegmentIdx] : source.PreviousSegmentInRing(sourceSegmentIdx); } else { double distanceAlongTarget; int targetSegmentIdx = intoIntersection.GetLocalTargetIntersectionSegmentIdx( target, out distanceAlongTarget); if (forward) { if (distanceAlongTarget > 0) { entryLine = target[targetSegmentIdx]; } else { // There must be a previous segment if we have come along the target int previousTargetIdx = Assert.NotNull(target.PreviousSegmentIndex(targetSegmentIdx)).Value; entryLine = target[previousTargetIdx]; } } else { if (distanceAlongTarget < 1) { entryLine = target[targetSegmentIdx]; } else { // There must be a next segment if we have come backwards along the target int nextTargetIdx = Assert.NotNull(target.NextSegmentIndex(targetSegmentIdx)).Value; entryLine = target[nextTargetIdx]; } entryLine = entryLine.Clone(); entryLine.ReverseOrientation(); } } return(entryLine); }
private IEnumerable <IntersectionRun> NavigateSubcurves( IntersectionPoint3D startIntersection) { if (VisitedOutboundTarget.Contains(startIntersection) || VisitedInboundTarget.Contains(startIntersection)) { yield break; } IntersectionPoint3D previousIntersection = startIntersection; IntersectionPoint3D nextIntersection = null; int count = 0; // Start by following the source: bool continueOnSource = true; bool forward = true; int partIndex = startIntersection.SourcePartIndex; while (nextIntersection == null || !nextIntersection.Point.Equals(startIntersection.Point)) { Assert.True(count++ <= IntersectionPoints.Count, "Intersections seen twice"); if (nextIntersection != null) { // Determine if at the next intersection we must // - continue along the source (e.g. because the source touches from the inside) // - continue along the target (forward or backward) SetTurnDirection(startIntersection, previousIntersection, ref continueOnSource, ref partIndex, ref forward); } Linestring subcurve; nextIntersection = FollowUntilNextIntersection( previousIntersection, continueOnSource, partIndex, forward, out subcurve); Pnt3D containedSourceStart = null; if (continueOnSource && previousIntersection.SourcePartIndex == nextIntersection.SourcePartIndex && (MathUtils.AreEqual(previousIntersection.VirtualSourceVertex, 0) || forward && previousIntersection.VirtualSourceVertex > nextIntersection.VirtualSourceVertex)) { Linestring sourcePart = GetSourcePart(previousIntersection.SourcePartIndex); containedSourceStart = sourcePart.StartPoint; } if (continueOnSource) { // Remove, if we follow the source through an intersection from other start. // This happens with vertical rings and multiple targets. if (IntersectionsOutboundTarget.Contains(previousIntersection)) { // TODO: if the current startIntersection is inbound make sure the left/right assignment is cleared! VisitedOutboundTarget.Add(previousIntersection); } else if (IntersectionsInboundTarget.Contains(previousIntersection)) { // TODO: if the current startIntersection is outbound make sure the left/right assignment is cleared! VisitedInboundTarget.Add(previousIntersection); } } IntersectionRun next = new IntersectionRun(nextIntersection, subcurve, containedSourceStart); next.ContinuingOnSource = continueOnSource; yield return(next); previousIntersection = nextIntersection; } }
protected abstract void SetTurnDirection( [NotNull] IntersectionPoint3D startIntersection, [NotNull] IntersectionPoint3D intersection, ref bool alongSource, ref int partIndex, ref bool forward);
protected abstract IntersectionPoint3D FollowUntilNextIntersection( [NotNull] IntersectionPoint3D previousIntersection, bool continueOnSource, int partIndex, bool continueForward, out Linestring subcurve);
public static IntersectionPoint3D CreateSingleIntersectionPoint( [NotNull] SegmentIntersection intersection, [NotNull] ISegmentList sourceSegments, [NotNull] ISegmentList targetSegments, double tolerance) { Line3D sourceSegment = sourceSegments.GetSegment(intersection.SourceIndex); double?targetIntersectionFactorOnSource = intersection.GetIntersectionPointFactorAlongSource(); int sourcePartIdx; int sourceSegmentIndex = sourceSegments.GetLocalSegmentIndex( intersection.SourceIndex, out sourcePartIdx); Pnt3D point; double sourceIndex; // ReSharper disable once CompareOfFloatsByEqualityOperator if (targetIntersectionFactorOnSource == 0) { point = sourceSegment.StartPoint; sourceIndex = sourceSegmentIndex; } // ReSharper disable once CompareOfFloatsByEqualityOperator else if (targetIntersectionFactorOnSource == 1) { point = sourceSegment.EndPoint; sourceIndex = sourceSegmentIndex + 1; } else { point = sourceSegment.GetPointAlong( targetIntersectionFactorOnSource.Value, true); sourceIndex = sourceSegmentIndex + targetIntersectionFactorOnSource.Value; } IntersectionPoint3D result = new IntersectionPoint3D(point, sourceIndex, intersection) { SourcePartIndex = sourcePartIdx }; bool?targetDeviatesToLeft; result.Type = intersection.IsCrossingInPoint( sourceSegments, targetSegments, tolerance, out targetDeviatesToLeft) ? IntersectionPointType.Crossing : IntersectionPointType.TouchingInPoint; result.TargetDeviatesToLeftOfSource = targetDeviatesToLeft; int targetPartIdx; result.VirtualTargetVertex = CalculateVirtualTargetVertex( targetSegments, result.Type, intersection, out targetPartIdx); result.TargetPartIndex = targetPartIdx; return(result); }
protected abstract IntersectionPoint3D GetNextIntersectionAlongSource( IntersectionPoint3D thisIntersection);