public bool IsOnTheRightSide([NotNull] ISegmentList source, [NotNull] Pnt3D testPoint, bool disregardOrientation = false) { Assert.True(source.IsClosed, "Source must be closed ring(s)"); Linestring sourceRing = source.GetPart(SourcePartIndex); double sourceRatio; int sourceSegmentIdx = GetLocalSourceIntersectionSegmentIdx(sourceRing, out sourceRatio); Line3D sourceSegment = sourceRing[sourceSegmentIdx]; if (sourceRatio > 0 && sourceRatio < 1) { // The intersection is on the source segment's interior return(sourceSegment.IsLeftXY(testPoint) < 0); } Line3D previousSegment, nextSegment; // Intersection at source vertex 0 or 1 -> get the 2 adjacent segments // ReSharper disable once CompareOfFloatsByEqualityOperator if (sourceRatio == 0) { previousSegment = sourceRing.PreviousSegmentInRing(sourceSegmentIdx, true); nextSegment = SegmentIntersection.IsSourceZeroLength2D ? sourceRing.NextSegmentInRing(sourceSegmentIdx, true) : sourceSegment; } else // sourceRatio == 1 { previousSegment = SegmentIntersection.IsSourceZeroLength2D ? sourceRing.PreviousSegmentInRing( sourceSegmentIdx, true) : sourceSegment; nextSegment = sourceRing.NextSegmentInRing(sourceSegmentIdx, true); } bool result = GeomTopoOpUtils.IsOnTheRightSide(previousSegment.StartPoint, Point, nextSegment.EndPoint, testPoint); if (!disregardOrientation && sourceRing.ClockwiseOriented == false) { result = !result; } return(result); }
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; } } }
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; } } }