Ejemplo n.º 1
0
        private static IEnumerable <SegmentIntersection> GetSegmentIntersectionsXY(
            int sourceLineIdx,
            [NotNull] Line3D sourceLine,
            [NotNull] ISegmentList segmentList,
            double tolerance,
            [CanBeNull] SegmentIntersection previousLinearIntersection)
        {
            if (previousLinearIntersection != null)
            {
                // speculation: this segment also runs along the next / previous target
                SegmentIntersection continuousIntersection =
                    TryGetContinuousLinearIntersection(
                        sourceLineIdx, sourceLine, segmentList, previousLinearIntersection,
                        tolerance);

                if (continuousIntersection != null)
                {
                    yield return(continuousIntersection);

                    yield break;
                }
            }

            IEnumerable <KeyValuePair <int, Line3D> > segmentsByIndex =
                segmentList.FindSegments(sourceLine, tolerance);

            foreach (SegmentIntersection intersection in
                     IntersectLineWithLinestringXY(
                         sourceLine, sourceLineIdx, segmentsByIndex, tolerance))
            {
                yield return(intersection);
            }
        }
Ejemplo n.º 2
0
        public static bool LinesContainXY([NotNull] ISegmentList segments,
                                          [NotNull] Pnt3D testPoint,
                                          double tolerance)
        {
            foreach (KeyValuePair <int, Line3D> segmentsAroundPoint in
                     segments.FindSegments(testPoint, tolerance))
            {
                Line3D segment = segmentsAroundPoint.Value;

                if (segment.IntersectsPointXY(testPoint, tolerance))
                {
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 3
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);
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Determines whether the horizontal ray from the test point to XMin crosses
        /// the specified segments an odd number of times.
        /// NOTE: For test points exactly on the boundary the result depends on whether
        /// the the point is on the right or the left boundary!
        /// </summary>
        /// <param name="segments"></param>
        /// <param name="testPoint"></param>
        /// <param name="tolerance"></param>
        /// <returns></returns>
        private static bool HasRayOddCrossingNumber([NotNull] ISegmentList segments,
                                                    [NotNull] IPnt testPoint,
                                                    double tolerance)
        {
            bool result = false;

            // Get the intersecting segments along the horizontal line from XMin to the testPoint
            IEnumerable <KeyValuePair <int, Line3D> > intersectingSegments =
                segments.FindSegments(segments.XMin, testPoint.Y, testPoint.X, testPoint.Y,
                                      tolerance);

            foreach (KeyValuePair <int, Line3D> path2Segment in intersectingSegments.OrderBy(
                         kvp => kvp.Key))
            {
                Line3D segment = path2Segment.Value;

                Pnt3D previous = segment.StartPoint;
                Pnt3D vertex   = segment.EndPoint;

                if (vertex.Y < testPoint.Y && previous.Y >= testPoint.Y ||               // downward crossing
                    previous.Y < testPoint.Y && vertex.Y >= testPoint.Y)                 // upward crossing
                {
                    double dX = previous.X - vertex.X;
                    double dY = previous.Y - vertex.Y;

                    double y = testPoint.Y - vertex.Y;

                    if (vertex.X + y * dX / dY < testPoint.X)
                    {
                        result = !result;
                    }
                }
            }

            return(result);
        }