Beispiel #1
0
        /// <summary>
        /// Performs a vertical sweep, calling the given event handler delegate.
        /// </summary>
        /// <param name="eventHandler"></param>
        public void VerticalSweep(HandleEvent eventHandler)
        {
            E ev;

            while (Events.FindMin(out ev))
            {
                if (!Events.Delete(ev))
                {
                    throw new ArgumentException("Failed to delete event " + RuntimeHelpers.GetHashCode(ev) + " - " + ev);
                }

                Line = new Line(ev.Pos, ev.Pos + new Vector2(1f, 0f));

                eventHandler(Events, Status, ev);
            }
        }
        public void HandleEvent(IBST <IntersectionSweepEvent> events, IBST <IntersectionStatusItem> status,
                                IntersectionSweepEvent ev)
        {
            if (ev.IsStart)
            {
                ev.StatusItem = new IntersectionStatusItem(ev);
                status.Insert(ev.StatusItem);

                IntersectionStatusItem prev, next;
                bool prevFound = status.FindNextSmallest(ev.StatusItem, out prev);
                bool nextFound = status.FindNextBiggest(ev.StatusItem, out next);

                if (prevFound)
                {
                    LineSegment otherSegment = prev.SweepEvent.Segment;
                    Vector2?    intersection = ev.Segment.IntersectProper(otherSegment);
                    if (intersection != null)
                    {
                        events.Insert(new IntersectionSweepEvent(intersection.Value, false, false,
                                                                 ev.Segment, otherSegment));
                    }
                }

                if (nextFound)
                {
                    LineSegment otherSegment = next.SweepEvent.Segment;
                    Vector2?    intersection = ev.Segment.IntersectProper(otherSegment);
                    if (intersection != null)
                    {
                        events.Insert(new IntersectionSweepEvent(intersection.Value, false, false,
                                                                 ev.Segment, otherSegment));
                    }
                }
            }
            else if (ev.IsEnd)
            {
                ev = ev.OtherEvent;
                if (ev.StatusItem == null)
                {
                    return;
                }

                IntersectionStatusItem prev, next;
                bool prevFound = status.FindNextSmallest(ev.StatusItem, out prev);
                bool nextFound = status.FindNextBiggest(ev.StatusItem, out next);

                status.Delete(ev.StatusItem);

                if (nextFound && prevFound)
                {
                    LineSegment segment      = prev.SweepEvent.Segment;
                    LineSegment otherSegment = next.SweepEvent.Segment;
                    Vector2?    intersection = segment.IntersectProper(otherSegment);
                    if (intersection != null)
                    {
                        events.Insert(new IntersectionSweepEvent(intersection.Value, false, false,
                                                                 segment, otherSegment));
                    }
                }
            }
            else if (ev.IsIntersection)
            {
                // stop on first intersection
                intersected = new List <Edge>
                {
                    new Edge(new Vertex(ev.Segment.Point1), new Vertex(ev.Segment.Point2)),
                    new Edge(new Vertex(ev.OtherSegment.Point1), new Vertex(ev.OtherSegment.Point2))
                };
                events.Clear();
                status.Clear();
            }
            else
            {
                throw new Exception("Invalid event type");
            }
        }
Beispiel #3
0
        private void HandleEvent(IBST <SweepEvent> events, IBST <StatusItem> status, SweepEvent ev)
        {
            ResultEvents.Add(ev);

            // Optimization 2
            if ((Operation == OperationType.Intersection && ev.Point.x > RightBound) ||
                (Operation == OperationType.Difference && ev.Point.x > SubjectBoundingBox.xMax))
            {
                // We need to connect edges now, so just clear all events. This will result in us immediately
                // going to ConnectEdges() since there are no more events to handle.
                InitializeEvents(new List <SweepEvent>());
                return;
            }

            if (ev.IsStart) // The line segment must be inserted into status
            {
                ev.StatusItem = new StatusItem(ev);
                if (!status.Insert(ev.StatusItem))
                {
                    throw new ArgumentException("Failed to insert into state");
                }

                StatusItem prev;
                var        prevFound = status.FindNextSmallest(ev.StatusItem, out prev);

                ComputeFields(ev, prev, prevFound);

                StatusItem next;
                if (status.FindNextBiggest(ev.StatusItem, out next))
                {
                    // Process a possible intersection between "ev" and its next neighbor in status
                    if (PossibleIntersection(ev, next.SweepEvent, events) == 2)
                    {
                        ComputeFields(ev, prev, prevFound);
                        ComputeFields(next.SweepEvent, ev.StatusItem, true);
                    }
                }

                // Process a possible intersection between "ev" and its previous neighbor in status
                if (prevFound)
                {
                    if (PossibleIntersection(prev.SweepEvent, ev, events) == 2)
                    {
                        StatusItem prevprev;
                        var        prevprevFound = status.FindNextSmallest(prev, out prevprev);

                        ComputeFields(prev.SweepEvent, prevprev, prevprevFound);
                        ComputeFields(ev, prev, prevFound);
                    }
                }
            }
            else
            {
                // The line segment must be removed from status
                ev = ev.OtherEvent; // We work with the left event

                StatusItem prev, next;
                var        prevFound = status.FindNextSmallest(ev.StatusItem, out prev);
                var        nextFound = status.FindNextBiggest(ev.StatusItem, out next);

                // Delete line segment associated to "ev" from status and check for intersection between the neighbors of "ev" in status
                status.Delete(ev.StatusItem);

                if (nextFound && prevFound)
                {
                    PossibleIntersection(prev.SweepEvent, next.SweepEvent, events);
                }
            }
        }
Beispiel #4
0
        public new void HandleEvent(IBST <SweepEvent> events, IBST <StatusItem> status, SweepEvent ev)
        {
            // keep track of added events for visualization
            producedEvents.Add(ev);

            if (ev.IsStart)
            {
                ComparePreEvent = true;
                if (!status.Insert(ev.StatusItem))
                {
                    throw new ArgumentException("Failed to insert into state");
                }

                StatusItem prev;
                if (status.FindNextSmallest(ev.StatusItem, out prev))
                {
                    CheckIntersection(prev, ev.StatusItem, events);
                }

                StatusItem next;
                if (status.FindNextBiggest(ev.StatusItem, out next))
                {
                    CheckIntersection(ev.StatusItem, next, events);
                }
            }
            else if (ev.IsEnd)
            {
                ComparePreEvent = false;
                StatusItem prev;
                bool       hasPrev = status.FindNextSmallest(ev.StatusItem, out prev);

                StatusItem next;
                bool       hasNext = status.FindNextBiggest(ev.StatusItem, out next);
                if (!status.Delete(ev.StatusItem))
                {
                    throw new InvalidInitialGeneralPosition("Could not delete from status : (");
                }

                if (hasPrev && hasNext)
                {
                    CheckIntersection(prev, next, events);
                }
            }
            else if (ev.IsIntersection)
            {
                StatusItem left  = ev.StatusItem;
                StatusItem right = ev.IntersectingStatusItem;
                this.intersections.Add(new Intersection(left.LineObject, right.LineObject));
                // Remove
                ComparePreEvent = true;
                if (!status.Delete(left))
                {
                    throw new InvalidInitialGeneralPosition(left + " not deleted.");
                }
                if (!status.Delete(right))
                {
                    throw new InvalidInitialGeneralPosition(right + " not deleted.");
                }

                // Swap
                ComparePreEvent = false;

                // Add
                status.Insert(left);
                status.Insert(right);

                // NOTE: At this point, ComparePreEvent = false implies that right PRECEDES left now

                StatusItem prev;
                if (status.FindNextSmallest(right, out prev))
                {
                    CheckIntersection(prev, right, events);
                }

                StatusItem next;
                if (status.FindNextBiggest(left, out next))
                {
                    CheckIntersection(left, next, events);
                }
            }
        }