private bool AddIntersections(double start, double end, HatchNestingNode hatchNode) { //расчет пересечений с помощью логики сканирующей линии //сформировать очередь событий начала и конца каждого сегмента (вертикальные сегменты при этом не брать в расчет!) //перейти по очереди до start, получить пересекаемые отрезки и точки пересечения, //затем до end, получить пересекаемые отрезки и точки пересечения //БУДУТ ПОЛУЧЕНЫ ТОЧКИ ПЕРЕСЕЧЕНИЯ ТАМ, ГДЕ ВЕРТИКАЛЬНЫЙ СЕГМЕНТ СТЫКУЕТСЯ С НЕВЕРТИКАЛЬНЫМ //БУДУТ ДУБЛИРОВАТЬСЯ ТОЧКИ ПЕРЕСЕЧЕНИЙ В ТОЧКАХ СТЫКОВКИ ДВУХ СОСЕДНИХ СЕГМЕНТОВ КОНТУРА C5.IntervalHeap <SweepLineEvent> queue = new C5.IntervalHeap <SweepLineEvent>(); foreach (Curve2d curve2d in hatchNode.Boundary.GetCurves()) { LineSegment2d lineSegment2D = (LineSegment2d)curve2d; double p0x = lineSegment2D.StartPoint.X; double p1x = lineSegment2D.EndPoint.X; if (Math.Abs(p0x - p1x) < Tolerance.Global.EqualPoint) { continue;//вертикальные сегменты не интересуют } double segStart = double.NegativeInfinity; double segEnd = double.NegativeInfinity; if (p0x < p1x) { segStart = p0x; segEnd = p1x; } else { segStart = p1x; segEnd = p0x; } queue.Add(new SweepLineEvent(segStart, true, lineSegment2D)); queue.Add(new SweepLineEvent(segEnd, false, lineSegment2D)); } HashSet <LineSegment2d> currSegments = new HashSet <LineSegment2d>(); Action goThoughEvent = () => { SweepLineEvent e = queue.DeleteMin(); if (e.Start) { currSegments.Add(e.LineSegment2D); } else { currSegments.Remove(e.LineSegment2D); } }; while (queue.Count > 0 && queue.FindMin().Position < start)//пройти все события до start { goThoughEvent(); } //TODO: В ТЕКУЩЕМ НАБОРЕ СЕГМЕНТОВ МОГУТ НАХОДИТЬСЯ 2 СТЫКУЮЩИХСЯ СЕГМЕНТА, ДАЮЩИЕ В РЕЗУЛЬТАТЕ ОДНУ И ТУ ЖЕ ТОЧКУ ПЕРЕСЕЧЕНИЯ //если на одной из вертикалей только одна точка пересечения, то не учитывать ее bool result0 = false; foreach (LineSegment2d seg in currSegments)//получить пересечения { result0 = AddIntersection(seg, startVert, hatchNode, startVertSorted); } while (queue.Count > 0 && queue.FindMin().Position < end)//пройти все события до end { goThoughEvent(); } bool result1 = false; foreach (LineSegment2d seg in currSegments)//получить пересечения { result1 = AddIntersection(seg, endVert, hatchNode, endVertSorted); } return(result0 || result1); }
public void Add( SweepLineInterval sweepInt ) { SweepLineEvent insertEvent = new SweepLineEvent( sweepInt.Min, null, sweepInt); _events.Add( insertEvent ); _events.Add( new SweepLineEvent( sweepInt.Max, insertEvent, sweepInt ) ); }