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)); }
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); } }
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); } }
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); }
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; } }
public EventPoint Below(EventPoint ep) // Zdarzenie pod obecnym { EventPoints.TryPredecessor(ep, out var below); return(below); }
public EventPoint Above(EventPoint ep) // Zdarzenie nad obecnym { EventPoints.TrySuccessor(ep, out var above); return(above); }
public bool Remove(EventPoint ep) { return(EventPoints.Remove(ep)); }
public bool Insert(EventPoint ep) // Dodaj zdarzenie i zwróć true jeżeli zostało poprawnie dodane { return(EventPoints.Add(ep)); }