// remove a point from sorted sweep line public int RemoveSweep(SegPoint sp, double x) { spYComparer.x = x; int pos = items.BinarySearch(sp, spYComparer); if (pos >= 0) { items.RemoveAt(pos); } return(pos); }
/*/ remove a point sorted by x position * public void Remove(SegPoint sp) * { * int pos = items.BinarySearch(sp); * if (pos >= 0) * items.RemoveAt(pos); * }*/ // add a point sorted by intersection of all existing lines in the list with a vertical line positioned at x public int AddSweep(SegPoint sp, double x) { spYComparer.x = x; int pos = items.BinarySearch(sp, spYComparer); if (pos < 0) { pos = ~pos; items.Insert(pos, sp); } return(pos); }
// add a point sorted by x position public int Add(SegPoint sp) { int pos = items.BinarySearch(sp); if (pos < 0) { pos = ~pos; items.Insert(pos, sp); sp.segpix = pos; } return(pos); }
// a (hopefully) faster version of FindIntersections() // based on article from: http://geomalgorithms.com/a09-_intersect-3.html public void FindIntersectionsFast() { // 1. add endpoints sorted leftmost to rightmost SegPointList segPoints = new SegPointList(); for (int i = 0; i < segments.Count; i++) { SegPoint sp1 = new SegPoint(segments[i], i, true); SegPoint sp2 = new SegPoint(segments[i], i, false); sp1.otherPoint = sp2; sp2.otherPoint = sp1; segPoints.Add(sp1); segPoints.Add(sp2); } SegPointList sweepPoints = new SegPointList(); int segix = 0; while (segix < segPoints.Count) { SegPoint sp = segPoints.items[segix]; if (sp.isLeft) { // add to sweep line and test intersections with upper and lower segments int sp_pos = sweepPoints.AddSweep(sp); if (sp_pos > 0) { TestIntersections(segPoints, sweepPoints, sp_pos - 1, sp_pos); } if (sp_pos < (sweepPoints.Count - 1)) { TestIntersections(segPoints, sweepPoints, sp_pos, sp_pos + 1); } } else { // remove segment from sweep file and test intersection of neighboring segments int sp_pos = sweepPoints.RemoveSweep(sp.otherPoint); if ((sp_pos > 0) && (sp_pos < sweepPoints.Count)) { TestIntersections(segPoints, sweepPoints, sp_pos - 1, sp_pos); } } segix++; } }
private void TestIntersections(SegPointList segPoints, SegPointList sweepPoints, int sp_pos1, int sp_pos2) { SegPoint sp1 = sweepPoints.items[sp_pos1]; SegPoint sp2 = sweepPoints.items[sp_pos2]; List <Segment2D> splits = sp1.seg.Intersect(sp2.seg, this); if (splits != null) { // splits must be >= 2 foreach (Segment2D seg in splits) { SegPoint nspL = new SegPoint(seg, 0, true); SegPoint nspR = new SegPoint(seg, 0, false); nspR.otherPoint = nspL; nspL.otherPoint = nspR; if (Object.ReferenceEquals(nspL.pt, sp1.pt)) { // matches begining of sp1, replace sp1 with new segment in all places nspL.segix = sp1.segix; nspL.segpix = sp1.segpix; segPoints.items[nspL.segpix] = nspL; segments[nspL.segix] = seg; sweepPoints.items[sp_pos1] = nspL; } else if (Object.ReferenceEquals(nspL.pt, sp2.pt)) { // matches begining of sp2, replace sp2 with new segment in all places nspL.segix = sp2.segix; nspL.segpix = sp2.segpix; segPoints.items[nspL.segpix] = nspL; segments[nspL.segix] = seg; sweepPoints.items[sp_pos2] = nspL; } else { // new segment, add everywhere nspL.segix = segments.Count; segments.Add(seg); segPoints.Add(nspL); } nspR.segix = nspL.segix; if (Object.ReferenceEquals(nspR.pt, sp1.otherPoint.pt)) { // matches ending of sp1, replace sp1 endings in all places nspR.segpix = sp1.otherPoint.segpix; segPoints.items[nspR.segpix] = nspR; //sweepPoints.items[sp_pos1] = nspL; } else if (Object.ReferenceEquals(nspR.pt, sp2.otherPoint.pt)) { // matches ending of sp2, replace sp2 endings in all places nspR.segpix = sp2.otherPoint.segpix; segPoints.items[nspR.segpix] = nspR; //sweepPoints.items[sp_pos2] = nspL; } else { // new segment point, add to segment points segPoints.Add(nspR); } } } }
public int RemoveSweep(SegPoint sp) { return(RemoveSweep(sp, sp.pt.x)); }
public int AddSweep(SegPoint sp) { return(AddSweep(sp, sp.pt.x)); }