示例#1
0
        /// <summary>
        /// Appends the coordinates to the queue.
        /// </summary>
        /// <param name="coordinates">The collection of coordinates.</param>
        private void AppendCoordinates(IEnumerable <Coordinate> coordinates)
        {
            if (coordinates == null)
            {
                return;
            }

            IEnumerator <Coordinate> enumerator = coordinates.GetEnumerator();

            if (!enumerator.MoveNext())
            {
                return;
            }

            Coordinate previous, current = enumerator.Current;

            while (enumerator.MoveNext())
            {
                if (enumerator.Current == null)
                {
                    continue;
                }

                previous = current;
                current  = enumerator.Current;

                EndPointEvent firstEvent = new EndPointEvent {
                    Edge = this.coordinateCount, Vertex = previous
                };
                EndPointEvent secondEvent = new EndPointEvent {
                    Edge = this.coordinateCount, Vertex = current
                };

                Int32 compare = this.comparer.Compare(previous, current);
                if (compare == 0)
                {
                    continue;
                }

                if (compare < 0)
                {
                    firstEvent.Type  = EventType.Left;
                    secondEvent.Type = EventType.Right;
                }
                else
                {
                    firstEvent.Type  = EventType.Right;
                    secondEvent.Type = EventType.Left;
                }

                this.eventHeap.Insert(firstEvent);
                this.eventHeap.Insert(secondEvent);

                this.coordinateCount++;
            }

            this.coordinateCount++;
        }
示例#2
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">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 Add(EndPointEvent e)
        {
            if (e == null)
            {
                throw new ArgumentNullException(nameof(e));
            }
            if (e.Edge < 0)
            {
                throw new ArgumentException(CoreMessages.EventEdgeIsLessThan0, nameof(e));
            }
            if (e.Edge >= this.source.Count - 1)
            {
                throw new ArgumentException(CoreMessages.EventEdgeIsGreaterThanNumberOfEdges, nameof(e));
            }

            SweepLineSegment segment = new SweepLineSegment {
                Edge = e.Edge
            };

            if (this.coordinateComparer.Compare(this.source[e.Edge], this.source[e.Edge + 1]) <= 0)
            {
                segment.LeftCoordinate  = this.source[e.Edge];
                segment.RightCoordinate = this.source[e.Edge + 1];
            }
            else
            {
                segment.LeftCoordinate  = this.source[e.Edge + 1];
                segment.RightCoordinate = this.source[e.Edge];
            }

            this.tree.Insert(segment);
            SweepLineSegment segmentAbove = this.tree.GetNext();
            SweepLineSegment segmentBelow = this.tree.GetPrevious();

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

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

            return(segment);
        }
示例#3
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">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(nameof(e));
            }
            if (e.Edge < 0)
            {
                throw new ArgumentException(CoreMessages.EventEdgeIsLessThan0, nameof(e));
            }
            if (e.Edge >= this.source.Count - 1)
            {
                throw new ArgumentException(CoreMessages.EventEdgeIsGreaterThanNumberOfEdges, nameof(e));
            }

            SweepLineSegment segment = new SweepLineSegment()
            {
                Edge = e.Edge
            };

            if (this.coordinateComparer.Compare(this.source[e.Edge], this.source[e.Edge + 1]) < 0)
            {
                segment.LeftCoordinate  = this.source[e.Edge];
                segment.RightCoordinate = this.source[e.Edge + 1];
            }
            else
            {
                segment.LeftCoordinate  = this.source[e.Edge + 1];
                segment.RightCoordinate = this.source[e.Edge];
            }

            SweepLineSegment segmentResult;

            if (this.tree.TrySearch(segment, out segmentResult))
            {
                return(segmentResult);
            }
            else
            {
                return(null);
            }
        }
示例#4
0
        /// <summary>
        /// Compares two <see cref="Event" /> instances and returns a value indicating whether one is less than, equal to, or greater than the other.
        /// </summary>
        /// <remarks>
        /// Events primarily compared by their vertex coordinate, secondarily by their type.
        /// </remarks>
        /// <param name="x">The first <see cref="Event" /> to compare.</param>
        /// <param name="y">The second <see cref="Event" /> to compare.</param>
        /// <returns>A signed integer that indicates the relative values of <paramref name="x" /> and <paramref name="y" />.</returns>
        public Int32 Compare(Event x, Event y)
        {
            if (x == null || y == null)
            {
                return(0);
            }

            Int32 result = this.coordinateComparer.Compare(x.Vertex, y.Vertex);

            if (result != 0)
            {
                return(result);
            }

            EndPointEvent     ex = x as EndPointEvent;
            EndPointEvent     ey = y as EndPointEvent;
            IntersectionEvent ix = x as IntersectionEvent;
            IntersectionEvent iy = y as IntersectionEvent;

            if (ex != null && ey != null)
            {
                result = ex.Type.CompareTo(ey.Type);
                if (result == 0)
                {
                    result = ex.Edge.CompareTo(ey.Edge);
                }
            }
            else if (ix != null && iy != null)
            {
                if (result == 0)
                {
                    result = this.coordinateComparer.Compare(ix.Below.LeftCoordinate, iy.Below.LeftCoordinate);
                }
                if (result == 0)
                {
                    result = this.coordinateComparer.Compare(ix.Above.LeftCoordinate, iy.Above.LeftCoordinate);
                }
                if (result == 0)
                {
                    result = this.coordinateComparer.Compare(ix.Below.RightCoordinate, iy.Below.RightCoordinate);
                }
                if (result == 0)
                {
                    result = this.coordinateComparer.Compare(ix.Above.RightCoordinate, iy.Above.RightCoordinate);
                }
                if (result == 0)
                {
                    result = ix.Below.Edge.CompareTo(iy.Below.Edge);
                }
                if (result == 0)
                {
                    result = ix.Above.Edge.CompareTo(iy.Above.Edge);
                }
                if (result == 0)
                {
                    result = ix.IsClosing.CompareTo(iy.IsClosing);
                }
            }
            else if (ex != null && iy != null)
            {
                result = ex.Type == EventType.Left ? -1 : 1;
            }
            else if (ix != null && ey != null)
            {
                result = ey.Type == EventType.Left ? 1 : -1;
            }

            return(result);
        }