From 168262ea7b3141c3e09b73c1075f3e928204700e Mon Sep 17 00:00:00 2001 From: Arthur Bols Date: Tue, 21 May 2019 17:50:08 +0200 Subject: [PATCH] fuck alles --- TMI-practicum/Intersection.cs | 2 +- TMI-practicum/SweepLineEffAlgorithm.cs | 134 +++++++++++++++---------- 2 files changed, 84 insertions(+), 52 deletions(-) diff --git a/TMI-practicum/Intersection.cs b/TMI-practicum/Intersection.cs index 01eedac..19662fe 100644 --- a/TMI-practicum/Intersection.cs +++ b/TMI-practicum/Intersection.cs @@ -18,7 +18,7 @@ namespace TMI_practicum public override bool Equals(object obj) { - return obj is Intersection intersection && this == intersection; + return obj is Intersection && this == (Intersection) obj; } public static bool operator ==(Intersection x, Intersection y) { diff --git a/TMI-practicum/SweepLineEffAlgorithm.cs b/TMI-practicum/SweepLineEffAlgorithm.cs index 4158289..8437405 100644 --- a/TMI-practicum/SweepLineEffAlgorithm.cs +++ b/TMI-practicum/SweepLineEffAlgorithm.cs @@ -15,7 +15,6 @@ namespace TMI_practicum var events = new PriorityQueue(); var active = new C5.TreeDictionary(); - foreach (var circle in circles) { events.Enqueue(new Event(Event.EventType.Start, circle.X - circle.R, circle, circle.Y)); @@ -25,49 +24,82 @@ namespace TMI_practicum while (events.Count != 0) { Event e = events.Dequeue(); - int hash = e.GetHashCode(); + int hash = e.GetIdentifier(); _sweepline = e.X; switch (e.Type) { case Event.EventType.Start: - active.Add( - new SegmentKey(SegmentKey.SegmentType.Upper, hash, e.Circle), - e.Circle); - active.Add( - new SegmentKey(SegmentKey.SegmentType.Bottom, hash, e.Circle), - e.Circle); - - CheckIntersections(active, e, intersections, true, events); - CheckIntersections(active, e, intersections, false, events); + + var upper = new SegmentKey(SegmentKey.SegmentType.Upper, hash, e.Circle); + var lower = new SegmentKey(SegmentKey.SegmentType.Bottom, hash, e.Circle); + active.Add(upper, e.Circle); + active.Add(lower, e.Circle); + + if (active.TrySuccessor(upper, out var other)) + CheckIntersections(upper, other, e.Circle, intersections, true, events); + + if (active.TryPredecessor(lower, out other)) + CheckIntersections(lower, other, e.Circle, intersections, false, events); + break; case Event.EventType.End: - CheckIntersections(active, e, intersections, true, events); - CheckIntersections(active, e, intersections, false, events); - active.Remove(new SegmentKey(SegmentKey.SegmentType.Upper, - hash, e.Circle)); - active.Remove(new SegmentKey(SegmentKey.SegmentType.Bottom, - hash, e.Circle)); + + upper = new SegmentKey(SegmentKey.SegmentType.Upper, hash, e.Circle); + lower = new SegmentKey(SegmentKey.SegmentType.Bottom, hash, e.Circle); + if (active.TrySuccessor(upper, out other)) + CheckIntersections(upper, other, e.Circle, intersections, true, events); + + if (active.TryPredecessor(lower, out other)) + CheckIntersections(lower, other, e.Circle, intersections, false, events); + + active.Remove(upper); + active.Remove(lower); + break; case Event.EventType.Intersection: - var s1 = e.Segments[0].Key; - var s2 = e.Segments[1].Key; + var s1 = e.Segments[0]; + var s2 = e.Segments[1]; + + _sweepline -= 10e-12; + + active.Remove(s1.Key); + active.Remove(s2.Key); + + _sweepline += 20e-12; - active.Remove(s1); - active.Remove(s2); try { - active.Add(s2, e.Segments[1].Value); - active.Add(s1, e.Segments[0].Value); + active.Add(s2.Key, e.Segments[1].Value); + active.Add(s1.Key, e.Segments[0].Value); } catch (DuplicateNotAllowedException) { Console.WriteLine("error"); } - CheckIntersections(active, e, intersections, true, events); - CheckIntersections(active, e, intersections, false, events); + if (s1.Key.Type == SegmentKey.SegmentType.Upper) + { + if (active.TrySuccessor(s1.Key, out other)) + CheckIntersections(s1.Key, other, s1.Value, intersections, true, events); + } + else + { + if (active.TryPredecessor(s1.Key, out other)) + CheckIntersections(s1.Key, other, s1.Value, intersections, true, events); + } + + if (s2.Key.Type == SegmentKey.SegmentType.Upper) + { + if (active.TrySuccessor(s2.Key, out other)) + CheckIntersections(s2.Key, other, s2.Value, intersections, true, events); + } + else + { + if (active.TryPredecessor(s2.Key, out other)) + CheckIntersections(s2.Key, other, s2.Value, intersections, true, events); + } break; default: throw new ArgumentOutOfRangeException(); @@ -77,34 +109,23 @@ namespace TMI_practicum return intersections; } - private static void CheckIntersections(C5.TreeDictionary active, Event e, System.Collections.Generic.HashSet intersections, bool upper, PriorityQueue events) + private static void CheckIntersections(SegmentKey segment, C5.KeyValuePair neighbour, Circle circle, + ISet intersections, bool upper, PriorityQueue events) { - C5.KeyValuePair other; - SegmentKey s; - if (upper) - { - s = new SegmentKey(SegmentKey.SegmentType.Upper, - e.GetHashCode(), e.Circle); - if (!active.TrySuccessor(s, out other)) - return; - } - else - { - s = new SegmentKey(SegmentKey.SegmentType.Bottom, e.GetHashCode(), e.Circle); - if (!active.TryPredecessor( - s, out other)) - { - return; - } - } - - var intersects = e.Circle.FindIntersections(other.Value); + var intersects = circle.FindIntersections(neighbour.Value); if (intersects == null) return; foreach (var intersection in intersects) { +// if (upper) +// { +// if (intersection.Y < circle.Y) continue; +// } +// else if (intersection.Y > circle.Y) continue; + if (intersections.Contains(intersection)) continue; - events.Add(new Event(Event.EventType.Intersection, intersection.X, e.Circle, intersection.Y, new []{new C5.KeyValuePair(s, e.Circle), other})); + events.Add(new Event(Event.EventType.Intersection, intersection.X, circle, intersection.Y, + new[] {new C5.KeyValuePair(segment, circle), neighbour})); intersections.Add(intersection); } } @@ -135,7 +156,6 @@ namespace TMI_practicum Segments = segments; } - public int CompareTo(Event other) { return X.CompareTo(other.X); @@ -147,8 +167,20 @@ namespace TMI_practicum { int hash = 17; hash = hash * 23 + Type.GetHashCode(); - hash = hash * 23 + X.GetHashCode(); - hash = hash * 23 + Y.GetHashCode(); + hash = hash * 23 + Circle.X.GetHashCode(); + hash = hash * 23 + Circle.Y.GetHashCode(); + return hash; + } + } + + public int GetIdentifier() + { + unchecked + { + int hash = 17; + hash = hash * 23 + EventType.Start.GetHashCode(); + hash = hash * 23 + Circle.X.GetHashCode(); + hash = hash * 23 + Circle.Y.GetHashCode(); return hash; } } @@ -172,7 +204,7 @@ namespace TMI_practicum } } - private SegmentType Type { get; } + public SegmentType Type { get; } private readonly int _identifier; public SegmentKey(SegmentType type, int identifier, Circle circle)