/// <summary> /// /// </summary> /// <param name="x"></param> /// <param name="insertEvent"></param> /// <param name="sweepInt"></param> public SweepLineEvent(double x, SweepLineEvent insertEvent, SweepLineInterval sweepInt) { _xValue = x; _insertEvent = insertEvent; _eventType = insertEvent != null ? SweepLineEventType.Delete : SweepLineEventType.Insert; _sweepInt = sweepInt; }
/// <summary> /// /// </summary> /// <param name="sweepInt"></param> public virtual void Add(SweepLineInterval sweepInt) { SweepLineEvent insertEvent = new SweepLineEvent(sweepInt.Min, null, sweepInt); _events.Add(insertEvent); _events.Add(new SweepLineEvent(sweepInt.Max, insertEvent, sweepInt)); }
/// <summary> /// /// </summary> /// <param name="action"></param> public virtual void ComputeOverlaps(ISweepLineOverlapAction action) { _nOverlaps = 0; BuildIndex(); for (int i = 0; i < _events.Count; i++) { SweepLineEvent ev = (SweepLineEvent)_events[i]; if (ev.IsInsert) { ProcessOverlaps(i, ev.DeleteEventIndex, ev.Interval, action); } } }
/// <summary> /// Because Delete Events have a link to their corresponding Insert event, /// it is possible to compute exactly the range of events which must be /// compared to a given Insert event object. /// </summary> private void BuildIndex() { if (_indexBuilt) { return; } _events.Sort(); for (int i = 0; i < _events.Count; i++) { SweepLineEvent ev = (SweepLineEvent)_events[i]; if (ev.IsDelete) { ev.InsertEvent.DeleteEventIndex = i; } } _indexBuilt = true; }
/// <summary> /// /// </summary> /// <param name="start"></param> /// <param name="end"></param> /// <param name="s0"></param> /// <param name="action"></param> private void ProcessOverlaps(int start, int end, SweepLineInterval s0, ISweepLineOverlapAction action) { /* * Since we might need to test for self-intersections, * include current insert event object in list of event objects to test. * Last index can be skipped, because it must be a Delete event. */ for (int i = start; i < end; i++) { SweepLineEvent ev = (SweepLineEvent)_events[i]; if (ev.IsInsert) { SweepLineInterval s1 = ev.Interval; action.Overlap(s0, s1); _nOverlaps++; } } }
/// <summary> /// ProjectionEvents are ordered first by their x-value, and then by their eventType. /// It is important that Insert events are sorted before Delete events, so that /// items whose Insert and Delete events occur at the same x-value will be /// correctly handled. /// </summary> /// <param name="o"></param> public virtual int CompareTo(object o) { SweepLineEvent pe = (SweepLineEvent)o; if (_xValue < pe._xValue) { return(-1); } if (_xValue > pe._xValue) { return(1); } if (_eventType < pe._eventType) { return(-1); } if (_eventType > pe._eventType) { return(1); } return(0); }