Beispiel #1
0
        /// <summary>
        /// Performs the order modifying effect of a possible intersection point between two directly adjacent segments.
        /// </summary>
        /// <remarks>
        /// An intersection event may become invalid if the order of the segments were altered or the intersection point has been already passed by the sweep line since the enqueuing of the event.
        /// This method is safe to be applied for invalid intersections.
        /// </remarks>
        /// <param name="x">First segment.</param>
        /// <param name="y">Second segment.</param>
        /// <returns><c>true</c> if a new, valid intersection point was found and passed between <paramref name="x" /> and <paramref name="y" />; otherwise <c>false</c>.</returns>
        /// <exception cref="InvalidOperationException">Segment <paramref name="x" /> and <paramref name="y" /> do not intersect each other.</exception>
        public Boolean Intersect(SweepLineSegment x, SweepLineSegment y)
        {
            var comparer = ((SweepLineSegmentComparer)_tree.Comparer);
            SweepLineIntersection intersection = comparer.GetIntersection(x, y);

            if (intersection == SweepLineIntersection.NotExists)
            {
                throw new InvalidOperationException("The given segments do not intersect each other.");
            }
            if (intersection == SweepLineIntersection.Passed)
            {
                return(false);
            }

            /*
             * Segment order before intersection: belowBelow <-> below <-> above <-> aboveAbove
             * Segment order after intersection:  belowBelow <-> above <-> below <-> aboveAbove
             */
            SweepLineSegment below, above;

            if (x.Above == y)
            {
                below = x;
                above = y;
            }
            else if (y.Above == x)
            {
                below = y;
                above = x;
            }
            else
            {
                return(false);
            }

            _tree.Remove(x);
            _tree.Remove(y);
            comparer.PassIntersection(x, y);
            _tree.Insert(x);
            _tree.Insert(y);

            SweepLineSegment belowBelow = below.Below;
            SweepLineSegment aboveAbove = above.Above;

            below.Above = aboveAbove;
            below.Below = above;
            above.Below = belowBelow;
            above.Above = below;

            if (belowBelow != null)
            {
                belowBelow.Above = above;
            }
            if (aboveAbove != null)
            {
                aboveAbove.Below = below;
            }

            return(true);
        }
Beispiel #2
0
        /// <summary>
        /// Removes the specified sweep line segment.
        /// </summary>
        /// <param name="segment">The segment.</param>
        /// <exception cref="System.ArgumentNullException">The segment is null.</exception>
        public void Remove(SweepLineSegment segment)
        {
            if (segment == null)
            {
                throw new ArgumentNullException("segment", "The segment is null.");
            }

            _tree.SetCurrent(segment);
            if (_tree.Current == null)
            {
                return;
            }

            SweepLineSegment segmentAbove = _tree.GetNext();
            SweepLineSegment segmentBelow = _tree.GetPrev();

            if (segmentAbove != null)
            {
                segmentAbove.Below = segment.Below;
            }
            if (segmentBelow != null)
            {
                segmentBelow.Above = segment.Above;
            }

            _tree.Remove(segment);
        }
Beispiel #3
0
        /// <summary>
        /// Adds a new endpoint event to the sweep line.
        /// </summary>
        /// <param name="e">The event.</param>
        /// <returns>The sweep line segment created by addition of <paramref name="e" />.</returns>
        /// <exception cref="System.ArgumentNullException">e;The event is null.</exception>
        /// <exception cref="System.ArgumentException">
        /// The edge of the event is less than 0.;e
        /// or
        /// The edge of the event is greater than the number of edges in the source.;e
        /// </exception>
        public SweepLineSegment Add(EndPointEvent e)
        {
            // source: http://geomalgorithms.com/a09-_intersect-3.html

            if (e == null)
            {
                throw new ArgumentNullException("e", "The event is null.");
            }
            if (e.Edge < 0)
            {
                throw new ArgumentException("The edge of the event is less than 0.", "e");
            }
            if (e.Edge >= _source.Count - 1)
            {
                throw new ArgumentException("The edge of the event is greater than the number of edges in the source.", "e");
            }

            SweepLineSegment segment = new SweepLineSegment {
                Edge = e.Edge
            };
            Coordinate c1 = _source[e.Edge];
            Coordinate c2 = _source[e.Edge + 1];

            if (_coordinateComparer.Compare(c1, c2) <= 0)
            {
                segment.LeftCoordinate  = c1;
                segment.RightCoordinate = c2;
            }
            else
            {
                segment.LeftCoordinate  = c2;
                segment.RightCoordinate = c1;
            }

            _tree.Insert(segment);
            SweepLineSegment segmentAbove = _tree.GetNext();
            SweepLineSegment segmentBelow = _tree.GetPrev();

            if (segmentAbove != null)
            {
                segment.Above       = segmentAbove;
                segment.Above.Below = segment;
            }
            if (segmentBelow != null)
            {
                segment.Below       = segmentBelow;
                segment.Below.Above = segment;
            }
            return(segment);
        }
Beispiel #4
0
        /// <summary>
        /// Searches the sweep line for an endpoint event.
        /// </summary>
        /// <param name="e">The event.</param>
        /// <returns>The segment associated with the event.</returns>
        /// <exception cref="System.ArgumentNullException">e;The event is null.</exception>
        /// <exception cref="System.ArgumentException">
        /// The edge of the event is less than 0.
        /// or
        /// The edge of the event is greater than the number of edges in the source.
        /// </exception>
        public SweepLineSegment Search(EndPointEvent e)
        {
            if (e == null)
            {
                throw new ArgumentNullException("e", "The event is null.");
            }
            if (e.Edge < 0)
            {
                throw new ArgumentException("The edge of the event is less than 0.", "e");
            }
            if (e.Edge >= _source.Count - 1)
            {
                throw new ArgumentException("The edge of the event is greater than the number of edges in the source.", "e");
            }

            SweepLineSegment segment = new SweepLineSegment()
            {
                Edge = e.Edge
            };
            Coordinate c1 = _source[e.Edge];
            Coordinate c2 = _source[e.Edge + 1];

            if (_coordinateComparer.Compare(c1, c2) < 0)
            {
                segment.LeftCoordinate  = c1;
                segment.RightCoordinate = c2;
            }
            else
            {
                segment.LeftCoordinate  = c2;
                segment.RightCoordinate = c1;
            }

            SweepLineSegment segmentResult;

            if (_tree.TrySearch(segment, out segmentResult))
            {
                return(segmentResult);
            }
            else
            {
                return(null);
            }
        }