示例#1
0
        private static SegmentIntersection TryGetContinuousLinearIntersection(
            int lineIdx,
            [NotNull] Line3D line1,
            [NotNull] ISegmentList segmentList2,
            [CanBeNull] SegmentIntersection previous,
            double tolerance)
        {
            if (previous == null ||
                previous.SourceIndex + 1 != lineIdx)
            {
                // We jumped over some source segments
                return(null);
            }

            int?targetIdx = previous.LinearIntersectionInOppositeDirection
                                                 ? segmentList2.PreviousSegmentIndex(previous.TargetIndex)
                                                 : segmentList2.NextSegmentIndex(previous.TargetIndex);

            if (targetIdx == null)
            {
                return(null);
            }

            Line3D targetSegment =
                segmentList2.GetSegment(targetIdx.Value);

            if (targetSegment.EqualsXY(line1, tolerance))
            {
                SegmentIntersection resultIntersection =
                    SegmentIntersection.CreateCoincidenceIntersectionXY(
                        lineIdx, targetIdx.Value,
                        previous.LinearIntersectionInOppositeDirection);

                return(resultIntersection);
            }

            return(null);
        }
示例#2
0
        /// <summary>
        /// Returns all self intersections except the intersection between consecutive segments.
        /// </summary>
        /// <param name="sourceLineGlobalIdx"></param>
        /// <param name="sourceLine"></param>
        /// <param name="containingSegmentList"></param>
        /// <param name="tolerance"></param>
        /// <returns></returns>
        public static IEnumerable <SegmentIntersection> GetRelevantSelfIntersectionsXY(
            int sourceLineGlobalIdx,
            [NotNull] Line3D sourceLine,
            [NotNull] ISegmentList containingSegmentList,
            double tolerance)
        {
            // a predicate, i.e. i != sourceGlobalIdx && i != sourceGlobalIdx - 1 && i != sourceGlobalIdx + 1
            Predicate <int> predicate = i => i != sourceLineGlobalIdx;

            IEnumerable <KeyValuePair <int, Line3D> > segmentsByGlobalIdx =
                containingSegmentList.FindSegments(sourceLine, tolerance, true,
                                                   predicate);

            foreach (SegmentIntersection intersection in
                     IntersectLineWithLinestringXY(
                         sourceLine, sourceLineGlobalIdx, segmentsByGlobalIdx, tolerance))
            {
                int?nextSegmentIndex =
                    containingSegmentList.NextSegmentIndex(intersection.SourceIndex);

                if (nextSegmentIndex == intersection.TargetIndex &&
                    !intersection.HasLinearIntersection)
                {
                    continue;
                }

                int?previousSegmentIndex =
                    containingSegmentList.PreviousSegmentIndex(intersection.SourceIndex);
                if (previousSegmentIndex == intersection.TargetIndex &&
                    !intersection.HasLinearIntersection)
                {
                    continue;
                }

                yield return(intersection);
            }
        }
示例#3
0
        public int?GetNonIntersectingTargetSegmentIndex(
            [NotNull] ISegmentList target,
            bool forwardAlongTarget)
        {
            if (SegmentIntersection.HasLinearIntersection)
            {
                if (Type == IntersectionPointType.LinearIntersectionIntermediate)
                {
                    return(null);
                }

                // search the first non-intersecting point at the and of the linear intersection
                bool deviationIsBackward =
                    Type == IntersectionPointType.LinearIntersectionStart;

                if (SegmentIntersection.LinearIntersectionInOppositeDirection)
                {
                    deviationIsBackward = !deviationIsBackward;
                }

                if ((deviationIsBackward && forwardAlongTarget) ||
                    (!deviationIsBackward && !forwardAlongTarget))
                {
                    return(null);
                }

                // get the first non-intersecting point after the linear intersection, check its side:
                if (SegmentIntersection.TargetStartIntersects &&
                    SegmentIntersection.TargetEndIntersects)
                {
                    // Target is within source (or equal to source)
                    return(forwardAlongTarget
                                                       ? target.NextSegmentIndex(SegmentIntersection.TargetIndex)
                                                       : target.PreviousSegmentIndex(SegmentIntersection.TargetIndex));
                }

                if (!SegmentIntersection.TargetStartIntersects &&
                    !SegmentIntersection.TargetEndIntersects)
                {
                    // Source is completely within target
                    return(SegmentIntersection.TargetIndex);
                }

                // Either the source start or the source end intersects but not both
                // The same must be the case for the target
                Assert.True(
                    SegmentIntersection.TargetEndIntersects ^
                    SegmentIntersection.TargetStartIntersects,
                    "Either target start or end is expected to intersect");
            }

            if (SegmentIntersection.TargetStartIntersects)
            {
                return(forwardAlongTarget
                                               ? SegmentIntersection.TargetIndex
                                               : target.PreviousSegmentIndex(SegmentIntersection.TargetIndex));
            }

            if (SegmentIntersection.TargetEndIntersects)
            {
                return(forwardAlongTarget
                                               ? target.NextSegmentIndex(SegmentIntersection.TargetIndex)
                                               : SegmentIntersection.TargetIndex);
            }

            // By now all linear cases should have been handled
            Assert.False(SegmentIntersection.HasLinearIntersection,
                         "Not all linear cases were handled.");

            return(SegmentIntersection.TargetIndex);
        }