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"); } }
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); } } }
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); } } }