/// <summary> /// /// </summary> /// <param name="start"></param> /// <param name="end"></param> /// <param name="ev0"></param> /// <param name="si"></param> private void ProcessOverlaps(int start, int end, SweepLineEvent ev0, SegmentIntersector si) { MonotoneChain mc0 = (MonotoneChain)ev0.Object; /* * 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 ev1 = (SweepLineEvent)events[i]; if (ev1.IsInsert) { MonotoneChain mc1 = (MonotoneChain)ev1.Object; // don't compare edges in same group // null group indicates that edges should be compared if (ev0.EdgeSet == null || (ev0.EdgeSet != ev1.EdgeSet)) { mc0.ComputeIntersections(mc1, si); nOverlaps++; } } } }
/// <summary> /// /// </summary> /// <param name="edgeSet"></param> /// <param name="x"></param> /// <param name="insertEvent"></param> /// <param name="obj"></param> public SweepLineEvent(object edgeSet, double x, SweepLineEvent insertEvent, object obj) { this.edgeSet = edgeSet; xValue = x; this.insertEvent = insertEvent; this.eventType = Insert; if (insertEvent != null) eventType = Delete; this.obj = obj; }
/// <summary> /// /// </summary> /// <param name="edge"></param> /// <param name="edgeSet"></param> private void Add(Edge edge, object edgeSet) { ICoordinate[] pts = edge.Coordinates; for (int i = 0; i < pts.Length - 1; i++) { SweepLineSegment ss = new SweepLineSegment(edge, i); SweepLineEvent insertEvent = new SweepLineEvent(edgeSet, ss.MinX, null, ss); events.Add(insertEvent); events.Add(new SweepLineEvent(edgeSet, ss.MaxX, insertEvent, ss)); } }
/// <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 PrepareEvents() { events.Sort(); for (int i = 0; i < events.Count; i++) { SweepLineEvent ev = (SweepLineEvent)events[i]; if (ev.IsDelete) { ev.InsertEvent.DeleteEventIndex = i; } } }
/// <summary> /// /// </summary> /// <param name="edgeSet"></param> /// <param name="x"></param> /// <param name="insertEvent"></param> /// <param name="obj"></param> public SweepLineEvent(object edgeSet, double x, SweepLineEvent insertEvent, object obj) { this.edgeSet = edgeSet; xValue = x; this.insertEvent = insertEvent; this.eventType = Insert; if (insertEvent != null) { eventType = Delete; } this.obj = obj; }
/// <summary> /// /// </summary> /// <param name="edge"></param> /// <param name="edgeSet"></param> private void Add(Edge edge, object edgeSet) { MonotoneChainEdge mce = edge.MonotoneChainEdge; int[] startIndex = mce.StartIndexes; for (int i = 0; i < startIndex.Length - 1; i++) { MonotoneChain mc = new MonotoneChain(mce, i); SweepLineEvent insertEvent = new SweepLineEvent(edgeSet, mce.GetMinX(i), null, mc); events.Add(insertEvent); events.Add(new SweepLineEvent(edgeSet, mce.GetMaxX(i), insertEvent, mc)); } }
/// <summary> /// /// </summary> /// <param name="si"></param> private void ComputeIntersections(SegmentIntersector si) { nOverlaps = 0; PrepareEvents(); for (int i = 0; i < events.Count; i++) { SweepLineEvent ev = (SweepLineEvent)events[i]; if (ev.IsInsert) { ProcessOverlaps(i, ev.DeleteEventIndex, ev, si); } } }
/// <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 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); }
/// <summary> /// /// </summary> /// <param name="start"></param> /// <param name="end"></param> /// <param name="ev0"></param> /// <param name="si"></param> private void ProcessOverlaps(int start, int end, SweepLineEvent ev0, SegmentIntersector si) { SweepLineSegment ss0 = (SweepLineSegment)ev0.Object; /* * 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 ev1 = (SweepLineEvent)events[i]; if (ev1.IsInsert) { SweepLineSegment ss1 = (SweepLineSegment)ev1.Object; if (ev0.EdgeSet == null || (ev0.EdgeSet != ev1.EdgeSet)) { ss0.ComputeIntersections(ss1, si); } nOverlaps++; } } }
/// <summary> /// /// </summary> /// <param name="start"></param> /// <param name="end"></param> /// <param name="ev0"></param> /// <param name="si"></param> private void ProcessOverlaps(int start, int end, SweepLineEvent ev0, SegmentIntersector si) { SweepLineSegment ss0 = (SweepLineSegment) ev0.Object; /* * 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 ev1 = (SweepLineEvent) events[i]; if (ev1.IsInsert) { SweepLineSegment ss1 = (SweepLineSegment) ev1.Object; if (ev0.EdgeSet == null || (ev0.EdgeSet != ev1.EdgeSet)) ss0.ComputeIntersections(ss1, si); nOverlaps++; } } }
/// <summary> /// /// </summary> /// <param name="start"></param> /// <param name="end"></param> /// <param name="ev0"></param> /// <param name="si"></param> private void ProcessOverlaps(int start, int end, SweepLineEvent ev0, SegmentIntersector si) { MonotoneChain mc0 = (MonotoneChain)ev0.Object; /* * 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 ev1 = (SweepLineEvent)events[i]; if (ev1.IsInsert) { MonotoneChain mc1 = (MonotoneChain)ev1.Object; // don't compare edges in same group // null group indicates that edges should be compared if (ev0.EdgeSet == null || (ev0.EdgeSet != ev1.EdgeSet)) { mc0.ComputeIntersections(mc1, si); nOverlaps++; } } } }