예제 #1
0
        /// <summary>
        /// Computes the intersection of one or more line strings.
        /// </summary>
        public void Compute()
        {
            this.intersections = new List <Coordinate>();
            this.edgeIndexes   = new List <Tuple <Int32, Int32> >();
            Event currentEvent = this.eventQueue.Next();

            while (currentEvent != null)
            {
                EndPointEvent endPointEvent = currentEvent as EndPointEvent;

                if (endPointEvent != null)
                {
                    this.ProcessEndPointEvent(endPointEvent);
                }

                IntersectionEvent intersectionEvent = currentEvent as IntersectionEvent;

                if (intersectionEvent != null)
                {
                    // intersection point event: switch the two concerned segments and check for possible intersection with their below and above segments
                    this.ProcessIntersectionEvent(intersectionEvent);
                }

                currentEvent = this.eventQueue.Next();
            }

            this.hasResult = true;
        }
        /// <summary>
        /// Computes the intersection of one or more line strings.
        /// </summary>
        public void Compute()
        {
            // source: http://geomalgorithms.com/a09-_intersect-3.html

            _intersections = new List <Coordinate>();
            _edgeIndices   = new List <Tuple <Int32, Int32> >();
            Event              currentEvent = _eventQueue.Next();
            SweepLineSegment   segment;
            IList <Coordinate> intersections;

            while (currentEvent != null)
            {
                if (currentEvent is EndPointEvent)
                {
                    EndPointEvent endPointEvent = (EndPointEvent)currentEvent;
                    switch (endPointEvent.Type)
                    {
                    // Left endpoint event: check for possible intersection with below and / or above segments.
                    case EventType.Left:
                        segment = _sweepLine.Add(endPointEvent);
                        if (segment.Above != null)
                        {
                            intersections = LineAlgorithms.Intersection(segment.LeftCoordinate, segment.RightCoordinate,
                                                                        segment.Above.LeftCoordinate, segment.Above.RightCoordinate,
                                                                        PrecisionModel);

                            if (intersections.Count > 0)
                            {
                                IntersectionEvent intersectionEvent = new IntersectionEvent
                                {
                                    Vertex = intersections[0],
                                    Below  = segment,
                                    Above  = segment.Above
                                };
                                _eventQueue.Add(intersectionEvent);
                            }
                        }
                        if (segment.Below != null)
                        {
                            intersections = LineAlgorithms.Intersection(segment.LeftCoordinate, segment.RightCoordinate,
                                                                        segment.Below.LeftCoordinate, segment.Below.RightCoordinate,
                                                                        PrecisionModel);

                            if (intersections.Count > 0)
                            {
                                IntersectionEvent intersectionEvent = new IntersectionEvent
                                {
                                    Vertex = intersections[0],
                                    Below  = segment.Below,
                                    Above  = segment
                                };
                                _eventQueue.Add(intersectionEvent);
                            }
                        }
                        break;

                    // Right endpoint event: check for possible intersection of the below and above segments.
                    case EventType.Right:
                        segment = _sweepLine.Search(endPointEvent);
                        if (segment != null)
                        {
                            if (segment.Above != null && segment.Below != null)
                            {
                                intersections = LineAlgorithms.Intersection(segment.Above.LeftCoordinate,
                                                                            segment.Above.RightCoordinate,
                                                                            segment.Below.LeftCoordinate,
                                                                            segment.Below.RightCoordinate,
                                                                            PrecisionModel);

                                if (intersections.Count > 0)
                                {
                                    IntersectionEvent intersectionEvent = new IntersectionEvent
                                    {
                                        Vertex = intersections[0],
                                        Below  = segment.Below,
                                        Above  = segment.Above
                                    };
                                    if (!_eventQueue.Contains(intersectionEvent))
                                    {
                                        _eventQueue.Add(intersectionEvent);
                                    }
                                }
                            }
                            _sweepLine.Remove(segment);
                        }
                        break;
                    }
                }

                // Intersection point event: switch the two concerned segments and check for possible intersection with their below and above segments.
                else if (currentEvent is IntersectionEvent)
                {
                    IntersectionEvent intersectionEvent = (IntersectionEvent)currentEvent;

                    /*
                     * Segment order before intersection: segmentBelow <-> segmentAbove <-> segment <-> segmentAboveAbove
                     * Segment order after intersection:  segmentBelow <-> segment <-> segmentAbove <-> segmentAboveAbove
                     */
                    segment = intersectionEvent.Above;
                    SweepLineSegment segmentAbove = intersectionEvent.Below;

                    // Handle closing intersection points when segments (partially) overlap each other.
                    if (intersectionEvent.IsClose)
                    {
                        if (!_sweepLine.IsAdjacent(segment.Edge, segmentAbove.Edge))
                        {
                            _intersections.Add(currentEvent.Vertex);
                            _edgeIndices.Add(Tuple.Create(Math.Min(segment.Edge, segmentAbove.Edge),
                                                          Math.Max(segment.Edge, segmentAbove.Edge)));
                        }
                    }

                    // It is possible that the previously detected intersection point is not a real intersection, because a new segment started between them,
                    // therefore a repeated check is necessary to carry out.
                    else if (_sweepLine.Add(intersectionEvent))
                    {
                        if (!_sweepLine.IsAdjacent(segment.Edge, segmentAbove.Edge))
                        {
                            _intersections.Add(currentEvent.Vertex);
                            _edgeIndices.Add(Tuple.Create(Math.Min(segment.Edge, segmentAbove.Edge),
                                                          Math.Max(segment.Edge, segmentAbove.Edge)));

                            intersections = LineAlgorithms.Intersection(segment.LeftCoordinate, segment.RightCoordinate,
                                                                        segmentAbove.LeftCoordinate, segmentAbove.RightCoordinate,
                                                                        PrecisionModel);

                            if (intersections.Count > 1 && !intersections[1].Equals(intersections[0]))
                            {
                                IntersectionEvent newIntersectionEvent = new IntersectionEvent
                                {
                                    Vertex  = intersections[1],
                                    Below   = segment,
                                    Above   = segmentAbove,
                                    IsClose = true,
                                };
                                _eventQueue.Add(newIntersectionEvent);
                            }
                        }

                        if (segmentAbove.Above != null)
                        {
                            intersections = LineAlgorithms.Intersection(segmentAbove.LeftCoordinate, segmentAbove.RightCoordinate,
                                                                        segmentAbove.Above.LeftCoordinate, segmentAbove.Above.RightCoordinate,
                                                                        PrecisionModel);

                            if (intersections.Count > 0 && intersections[0].X >= intersectionEvent.Vertex.X)
                            {
                                IntersectionEvent newIntersectionEvent = new IntersectionEvent
                                {
                                    Vertex = intersections[0],
                                    Below  = segmentAbove,
                                    Above  = segmentAbove.Above
                                };
                                if (!_eventQueue.Contains(newIntersectionEvent))
                                {
                                    _eventQueue.Add(newIntersectionEvent);
                                }
                            }
                        }

                        if (segment.Below != null)
                        {
                            intersections = LineAlgorithms.Intersection(segment.LeftCoordinate, segment.RightCoordinate,
                                                                        segment.Below.LeftCoordinate, segment.Below.RightCoordinate,
                                                                        PrecisionModel);

                            if (intersections.Count > 0 && intersections[0].X >= intersectionEvent.Vertex.X)
                            {
                                IntersectionEvent newIntersectionEvent = new IntersectionEvent
                                {
                                    Vertex = intersections[0],
                                    Below  = segment.Below,
                                    Above  = segment
                                };
                                if (!_eventQueue.Contains(newIntersectionEvent))
                                {
                                    _eventQueue.Add(newIntersectionEvent);
                                }
                            }
                        }
                    }
                }

                currentEvent = _eventQueue.Next();
            }
            _hasResult = true;
        }
예제 #3
0
        /// <summary>
        /// Processes the end point event.
        /// </summary>
        /// <param name="endPointEvent">The end point event.</param>
        private void ProcessEndPointEvent(EndPointEvent endPointEvent)
        {
            SweepLineSegment segment;
            Intersection     intersection;

            switch (endPointEvent.Type)
            {
            // left endpoint event: check for possible intersection with below and / or above segments
            case EventType.Left:
                segment = this.sweepLine.Add(endPointEvent);

                if (segment.Above != null)
                {
                    intersection = LineAlgorithms.Intersection(segment.LeftCoordinate, segment.RightCoordinate, segment.Above.LeftCoordinate, segment.Above.RightCoordinate, this.PrecisionModel);

                    if (intersection != null)
                    {
                        IntersectionEvent intersectionEvent = new IntersectionEvent
                        {
                            Vertex = intersection.Coordinate,
                            Below  = segment,
                            Above  = segment.Above
                        };
                        this.eventQueue.Add(intersectionEvent);
                    }
                }

                if (segment.Below != null)
                {
                    intersection = LineAlgorithms.Intersection(segment.LeftCoordinate, segment.RightCoordinate, segment.Below.LeftCoordinate, segment.Below.RightCoordinate, this.PrecisionModel);

                    if (intersection != null)
                    {
                        IntersectionEvent intersectionEvent = new IntersectionEvent
                        {
                            Vertex = intersection.Coordinate,
                            Below  = segment.Below,
                            Above  = segment
                        };
                        this.eventQueue.Add(intersectionEvent);
                    }
                }

                break;

            // right endpoint event: check for possible intersection of the below and above segments
            case EventType.Right:
                segment = this.sweepLine.Search(endPointEvent);

                if (segment != null)
                {
                    if (segment.Above != null && segment.Below != null)
                    {
                        intersection = LineAlgorithms.Intersection(segment.Above.LeftCoordinate, segment.Above.RightCoordinate, segment.Below.LeftCoordinate, segment.Below.RightCoordinate, this.PrecisionModel);

                        if (intersection != null)
                        {
                            IntersectionEvent intersectionEvent = new IntersectionEvent
                            {
                                Vertex = intersection.Coordinate,
                                Below  = segment.Below,
                                Above  = segment.Above
                            };
                            if (!this.eventQueue.Contains(intersectionEvent))
                            {
                                this.eventQueue.Add(intersectionEvent);
                            }
                        }
                    }

                    this.sweepLine.Remove(segment);
                }

                break;
            }
        }
예제 #4
0
        /// <summary>
        /// Computes whether one or more line strings specified by coordinates intersects with each other.
        /// </summary>
        public void Compute()
        {
            // source: http://geomalgorithms.com/a09-_intersect-3.html

            EndPointEvent    e = _eventQueue.Next();
            SweepLineSegment segment;

            while (e != null)
            {
                switch (e.Type)
                {
                case EventType.Left:
                    segment = _sweepLine.Add(e);
                    if (segment.Above != null && _sweepLine.IsAdjacent(segment.Edge, segment.Above.Edge) && segment.LeftCoordinate == segment.Above.LeftCoordinate)
                    {
                        _sweepLine.Intersect(segment, segment.Above);
                    }
                    else if (segment.Below != null && _sweepLine.IsAdjacent(segment.Edge, segment.Below.Edge) && segment.LeftCoordinate == segment.Below.LeftCoordinate)
                    {
                        _sweepLine.Intersect(segment, segment.Below);
                    }

                    if (segment.Above != null && !_sweepLine.IsAdjacent(segment.Edge, segment.Above.Edge) &&
                        LineAlgorithms.Intersects(segment.LeftCoordinate, segment.RightCoordinate,
                                                  segment.Above.LeftCoordinate, segment.Above.RightCoordinate,
                                                  PrecisionModel))
                    {
                        _hasResult = true;
                        _result    = true;
                        return;
                    }
                    if (segment.Below != null && !_sweepLine.IsAdjacent(segment.Edge, segment.Below.Edge) &&
                        LineAlgorithms.Intersects(segment.LeftCoordinate, segment.RightCoordinate,
                                                  segment.Below.LeftCoordinate, segment.Below.RightCoordinate,
                                                  PrecisionModel))
                    {
                        _hasResult = true;
                        _result    = true;
                        return;
                    }
                    break;

                case EventType.Right:
                    segment = _sweepLine.Search(e);
                    if (segment != null)
                    {
                        if (segment.Above != null && segment.Below != null && !_sweepLine.IsAdjacent(segment.Below.Edge, segment.Above.Edge) &&
                            LineAlgorithms.Intersects(segment.Above.LeftCoordinate, segment.Above.RightCoordinate,
                                                      segment.Below.LeftCoordinate, segment.Below.RightCoordinate,
                                                      PrecisionModel))
                        {
                            _hasResult = true;
                            _result    = true;
                            return;
                        }
                        _sweepLine.Remove(segment);
                    }
                    break;
                }

                e = _eventQueue.Next();
            }

            _hasResult = true;
            _result    = false;
        }
예제 #5
0
        /// <summary>
        /// Computes whether one or more line strings specified by coordinates intersects with each other.
        /// </summary>
        public void Compute()
        {
            EndPointEvent    e = this.eventQueue.Next();
            SweepLineSegment segment;

            while (e != null)
            {
                switch (e.Type)
                {
                case EventType.Left:
                    segment = this.sweepLine.Add(e);
                    if (segment.Above != null && this.sweepLine.IsAdjacent(segment.Edge, segment.Above.Edge) && segment.LeftCoordinate == segment.Above.LeftCoordinate)
                    {
                        this.sweepLine.Intersect(segment, segment.Above);
                    }
                    else if (segment.Below != null && this.sweepLine.IsAdjacent(segment.Edge, segment.Below.Edge) && segment.LeftCoordinate == segment.Below.LeftCoordinate)
                    {
                        this.sweepLine.Intersect(segment, segment.Below);
                    }

                    if (segment.Above != null && !this.sweepLine.IsAdjacent(segment.Edge, segment.Above.Edge) &&
                        LineAlgorithms.Intersects(segment.LeftCoordinate, segment.RightCoordinate,
                                                  segment.Above.LeftCoordinate, segment.Above.RightCoordinate,
                                                  this.PrecisionModel))
                    {
                        this.hasResult = true;
                        this.result    = true;
                        return;
                    }

                    if (segment.Below != null && !this.sweepLine.IsAdjacent(segment.Edge, segment.Below.Edge) &&
                        LineAlgorithms.Intersects(segment.LeftCoordinate, segment.RightCoordinate,
                                                  segment.Below.LeftCoordinate, segment.Below.RightCoordinate,
                                                  this.PrecisionModel))
                    {
                        this.hasResult = true;
                        this.result    = true;
                        return;
                    }

                    break;

                case EventType.Right:
                    segment = this.sweepLine.Search(e);
                    if (segment != null)
                    {
                        if (segment.Above != null && segment.Below != null && !this.sweepLine.IsAdjacent(segment.Below.Edge, segment.Above.Edge) &&
                            LineAlgorithms.Intersects(segment.Above.LeftCoordinate, segment.Above.RightCoordinate,
                                                      segment.Below.LeftCoordinate, segment.Below.RightCoordinate,
                                                      this.PrecisionModel))
                        {
                            this.hasResult = true;
                            this.result    = true;
                            return;
                        }

                        this.sweepLine.Remove(segment);
                    }

                    break;
                }

                e = this.eventQueue.Next();
            }

            this.hasResult = true;
            this.result    = false;
        }