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