예제 #1
0
        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);
        }
예제 #2
0
        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;
                }
            }
        }
예제 #3
0
        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;
                }
            }
        }