Ejemplo n.º 1
0
 public PointFr?Intersection(EventPoint ep)  // Przecięcie z miotłą lub null jeśli nie ma
 {
     if (ep.Type == EventPointType.Intersection)
     {
         return(ep.PointValue);
     }
     if (ep.Segment == null || SweepLineValue == null)
     {
         throw new ArgumentException("Wartość ep.Segment i SweepLineValue nie może być pusta");
     }
     return(((LineSegmentFr)ep.Segment).Intersection((LineFr)SweepLineValue));
 }
Ejemplo n.º 2
0
        private void CheckIntersection(EventPoint ep1, EventPoint ep2) // Sprawdza czy istnieje przecięcie pomiędzy dwoma zdarzeniami
        {
            if (CurrentSweepPoint == null)
            {
                return;
            }
            var currentSweepPoint = (PointFr)CurrentSweepPoint;

            if (ep1 == null || ep2 == null || ep1.Type == EventPointType.Intersection || ep2.Type == EventPointType.Intersection) // Zatrzymaj jeżeli conajmniej jedno ze zdarzeń jest puste lub jest przecięciem
            {
                return;
            }
            if (ep2.Segment == null || ep1.Segment == null)
            {
                throw new ArgumentException("Wartość ep1.Segment i ep2.Segment nie może być pusta");
            }

            var pNullable = ((LineSegmentFr)ep1.Segment).Intersection((LineSegmentFr)ep2.Segment); // Znajdź punkt przecięcia pomiędzy liniami zdarzeń

            if (pNullable == null)
            {
                return;
            }
            var p = (PointFr)pNullable;

            var existing = new C5.HashSet <EventPoint>();

            if (_intersections.ContainsKey(p))
            {
                existing = _intersections[p]; // Dodaj przecięcie do słownika
                _intersections.Remove(p);
            }

            existing.Add(ep1);
            existing.Add(ep2);
            _intersections.Add(p, existing);

            if (SweepLineValue == null)
            {
                throw new ArgumentException("Wartość miotły nie może być pusta");
            }

            var sweepLineValue = (LineFr)SweepLineValue;

            if (p.IsRightOf(sweepLineValue) || (sweepLineValue.Contains(p) && p.Y > currentSweepPoint.Y)) // Jeśli przecięcie jest po prawej stronie miotły lub na miotle i powyzej obecnego zdarzenia, dodaj do kolejki
            {
                var intersection = new EventPoint(p, EventPointType.Intersection, (LineSegmentFr?)null, this);
                EventQueue.Insert(p, intersection);
            }
        }
Ejemplo n.º 3
0
        private void MoveSweepLineTo(EventPoint ep) // Przesuń miotłę do nowego punktu zdarzenia
        {
            CurrentSweepPoint = ep.PointValue;
            if (SweepLineValue == null)
            {
                throw new ArgumentException("Wartość SweepLineValue nie może być pusta podczas zmiany stanu miotły");
            }
            SweepLineValue = new LineFr(((LineFr)SweepLineValue).Slope, (PointFr)CurrentSweepPoint);

            if (!OldSweepLineValues.ContainsKey((PointFr)CurrentSweepPoint))
            {
                OldSweepLineValues.Add((PointFr)CurrentSweepPoint, (LineFr)SweepLineValue);
            }
        }
Ejemplo n.º 4
0
        public void Insert(PointFr p, EventPoint ep) // Wstawia zdarzenie ep w punkcie p do bieżącej kolejki zdarzeń zdarzenia Right są dodawane na początku, pozostałe na końcu
        {
            var existing = new C5.LinkedList <EventPoint>();

            if (_events.Exists(kvp => kvp.Key.Equals(p)))
            {
                existing = _events[p];
                _events.Remove(p);
            }

            if (ep.Type == EventPointType.Right) // Zdarzenia 'Right' powinny byc na początku listy
            {
                existing.Insert(0, ep);
            }
            else
            {
                existing.Add(ep);
            }
            _events.Add(p, existing);
        }
Ejemplo n.º 5
0
        private void HandleEventPoint(EventPoint eventPoint)
        {
            switch (eventPoint.Type)
            {
            case EventPointType.Left:
                IsBefore = false;
                Insert(eventPoint);
                CheckIntersection(eventPoint, Above(eventPoint));
                CheckIntersection(eventPoint, Below(eventPoint));
                break;

            case EventPointType.Right:
                IsBefore = true;
                Remove(eventPoint);
                CheckIntersection(Above(eventPoint), Below(eventPoint));
                break;

            case EventPointType.Intersection:
                IsBefore = true;
                var set      = _intersections[eventPoint.PointValue];
                var toInsert = new Stack <EventPoint>();
                foreach (var ep in set.Where(Remove))     // jeżeli zdarzenie nie zostało usunięte, trzeba je później dodać
                {
                    toInsert.Push(ep);
                }
                IsBefore = false;

                while (toInsert.Count > 0)     // Wstaw wszystkie zdarzenia, które zostały usunięte
                {
                    var ep = toInsert.Pop();
                    Insert(ep);
                    CheckIntersection(ep, Above(ep));
                    CheckIntersection(ep, Below(ep));
                }
                break;
            }
        }
Ejemplo n.º 6
0
 public EventPoint Below(EventPoint ep) // Zdarzenie pod obecnym
 {
     EventPoints.TryPredecessor(ep, out var below);
     return(below);
 }
Ejemplo n.º 7
0
 public EventPoint Above(EventPoint ep) // Zdarzenie nad obecnym
 {
     EventPoints.TrySuccessor(ep, out var above);
     return(above);
 }
Ejemplo n.º 8
0
 public bool Remove(EventPoint ep)
 {
     return(EventPoints.Remove(ep));
 }
Ejemplo n.º 9
0
 public bool Insert(EventPoint ep) // Dodaj zdarzenie i zwróć true jeżeli zostało poprawnie dodane
 {
     return(EventPoints.Add(ep));
 }