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); }
/// <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); }