public EventPoint(PointFr value, EventPointType type, LineSegmentFr?segment, SweepLine sweepLine) { PointValue = value; Type = type; Segment = segment; SweepLine = sweepLine; }
public EventPoint(PointFr value, EventPointType type, LineSegmentFr[] crossingSegments, SweepLine sweepLine) { PointValue = value; Type = type; CrossingSegments = crossingSegments; SweepLine = sweepLine; }
private readonly TreeDictionary <PointFr, C5.LinkedList <EventPoint> > _events; // Posortowana mapa punktów i odpowiadających im zdarzeń public EventQueue(C5.HashSet <LineSegmentFr> segments, SweepLine sweepLine) // Tworzy nową kolejkę zdarzeń przy użyciu zestawu odcinków { if (segments.Count <= 0) { throw new ArgumentException($"Kolekcja {nameof(segments)} nie może być pusta"); } _events = new TreeDictionary <PointFr, C5.LinkedList <EventPoint> >(new PointFrXThenYComparer()); var minY = Fraction.PositiveInfinity; var maxY = Fraction.NegativeInfinity; var minDeltaX = Fraction.PositiveInfinity; var xs = new TreeSet <Fraction>(); foreach (var s in segments) { xs.Add(s.StartPoint.X); xs.Add(s.EndPoint.X); if (s.MinY < minY) { minY = s.MinY; } if (s.MaxY > maxY) { maxY = s.MaxY; } Insert(s.StartPoint, new EventPoint(s.StartPoint, EventPointType.Left, s, sweepLine)); Insert(s.EndPoint, new EventPoint(s.EndPoint, EventPointType.Right, s, sweepLine)); } var xsArray = xs.ToArray(); for (var i = 1; i < xsArray.Length; i++) { var tempDeltaX = xsArray[i] - xsArray[i - 1]; if (tempDeltaX < minDeltaX) { minDeltaX = tempDeltaX; } } var deltaY = maxY - minY; var slope = deltaY / minDeltaX * -1; // * 1000 sweepLine.SweepLineValue = new LineFr(PointFr.Origin, new PointFr(0, 1)); // slope, PointFr.Origin sweepLine.EventQueue = this; // Porzuciłem pomysł dynamicznego zmianu nachylenia miotły, ponieważ wymagało to obliczania dużych wartości przecięć z osiami wykresu dla prostej przy użyciu Ułamków (StackOverflowException) }
public static Dictionary <PointFr, C5.HashSet <LineSegmentFr> > IntersectionsBentleyOttmann(C5.HashSet <LineSegmentFr> segments, out Dictionary <PointFr, LineFr> sweepLines) { if (segments.Count < 2) { sweepLines = null; return(new Dictionary <PointFr, C5.HashSet <LineSegmentFr> >()); } var sweepLine = new SweepLine(); var eventQueue = new EventQueue(segments, sweepLine); while (!eventQueue.isEmpty()) { var eventPoints = eventQueue.DeleteMin(); sweepLine.HandleEventPoints(eventPoints); } sweepLines = sweepLine.OldSweepLineValues; return(sweepLine.Intersections); }