Exemplo n.º 1
0
 public EventPoint(PointFr value, EventPointType type, LineSegmentFr?segment, SweepLine sweepLine)
 {
     PointValue = value;
     Type       = type;
     Segment    = segment;
     SweepLine  = sweepLine;
 }
Exemplo n.º 2
0
 public EventPoint(PointFr value, EventPointType type, LineSegmentFr[] crossingSegments, SweepLine sweepLine)
 {
     PointValue       = value;
     Type             = type;
     CrossingSegments = crossingSegments;
     SweepLine        = sweepLine;
 }
Exemplo n.º 3
0
        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);
        }