fuck alles
This commit is contained in:
@@ -18,7 +18,7 @@ namespace TMI_practicum
|
|||||||
|
|
||||||
public override bool Equals(object obj)
|
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)
|
public static bool operator ==(Intersection x, Intersection y)
|
||||||
{
|
{
|
||||||
|
@@ -15,7 +15,6 @@ namespace TMI_practicum
|
|||||||
var events = new PriorityQueue<Event>();
|
var events = new PriorityQueue<Event>();
|
||||||
var active = new C5.TreeDictionary<SegmentKey, Circle>();
|
var active = new C5.TreeDictionary<SegmentKey, Circle>();
|
||||||
|
|
||||||
|
|
||||||
foreach (var circle in circles)
|
foreach (var circle in circles)
|
||||||
{
|
{
|
||||||
events.Enqueue(new Event(Event.EventType.Start, circle.X - circle.R, circle, circle.Y));
|
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)
|
while (events.Count != 0)
|
||||||
{
|
{
|
||||||
Event e = events.Dequeue();
|
Event e = events.Dequeue();
|
||||||
int hash = e.GetHashCode();
|
int hash = e.GetIdentifier();
|
||||||
_sweepline = e.X;
|
_sweepline = e.X;
|
||||||
|
|
||||||
switch (e.Type)
|
switch (e.Type)
|
||||||
{
|
{
|
||||||
case Event.EventType.Start:
|
case Event.EventType.Start:
|
||||||
active.Add(
|
|
||||||
new SegmentKey(SegmentKey.SegmentType.Upper, hash, e.Circle),
|
var upper = new SegmentKey(SegmentKey.SegmentType.Upper, hash, e.Circle);
|
||||||
e.Circle);
|
var lower = new SegmentKey(SegmentKey.SegmentType.Bottom, hash, e.Circle);
|
||||||
active.Add(
|
active.Add(upper, e.Circle);
|
||||||
new SegmentKey(SegmentKey.SegmentType.Bottom, hash, e.Circle),
|
active.Add(lower, e.Circle);
|
||||||
e.Circle);
|
|
||||||
|
if (active.TrySuccessor(upper, out var other))
|
||||||
CheckIntersections(active, e, intersections, true, events);
|
CheckIntersections(upper, other, e.Circle, intersections, true, events);
|
||||||
CheckIntersections(active, e, intersections, false, events);
|
|
||||||
|
if (active.TryPredecessor(lower, out other))
|
||||||
|
CheckIntersections(lower, other, e.Circle, intersections, false, events);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case Event.EventType.End:
|
case Event.EventType.End:
|
||||||
CheckIntersections(active, e, intersections, true, events);
|
|
||||||
CheckIntersections(active, e, intersections, false, events);
|
upper = new SegmentKey(SegmentKey.SegmentType.Upper, hash, e.Circle);
|
||||||
active.Remove(new SegmentKey(SegmentKey.SegmentType.Upper,
|
lower = new SegmentKey(SegmentKey.SegmentType.Bottom, hash, e.Circle);
|
||||||
hash, e.Circle));
|
if (active.TrySuccessor(upper, out other))
|
||||||
active.Remove(new SegmentKey(SegmentKey.SegmentType.Bottom,
|
CheckIntersections(upper, other, e.Circle, intersections, true, events);
|
||||||
hash, e.Circle));
|
|
||||||
|
if (active.TryPredecessor(lower, out other))
|
||||||
|
CheckIntersections(lower, other, e.Circle, intersections, false, events);
|
||||||
|
|
||||||
|
active.Remove(upper);
|
||||||
|
active.Remove(lower);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case Event.EventType.Intersection:
|
case Event.EventType.Intersection:
|
||||||
var s1 = e.Segments[0].Key;
|
var s1 = e.Segments[0];
|
||||||
var s2 = e.Segments[1].Key;
|
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
|
try
|
||||||
{
|
{
|
||||||
active.Add(s2, e.Segments[1].Value);
|
active.Add(s2.Key, e.Segments[1].Value);
|
||||||
active.Add(s1, e.Segments[0].Value);
|
active.Add(s1.Key, e.Segments[0].Value);
|
||||||
}
|
}
|
||||||
catch (DuplicateNotAllowedException)
|
catch (DuplicateNotAllowedException)
|
||||||
{
|
{
|
||||||
Console.WriteLine("error");
|
Console.WriteLine("error");
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckIntersections(active, e, intersections, true, events);
|
if (s1.Key.Type == SegmentKey.SegmentType.Upper)
|
||||||
CheckIntersections(active, e, intersections, false, events);
|
{
|
||||||
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentOutOfRangeException();
|
throw new ArgumentOutOfRangeException();
|
||||||
@@ -77,34 +109,23 @@ namespace TMI_practicum
|
|||||||
return intersections;
|
return intersections;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CheckIntersections(C5.TreeDictionary<SegmentKey, Circle> active, Event e, System.Collections.Generic.HashSet<Intersection> intersections, bool upper, PriorityQueue<Event> events)
|
private static void CheckIntersections(SegmentKey segment, C5.KeyValuePair<SegmentKey, Circle> neighbour, Circle circle,
|
||||||
|
ISet<Intersection> intersections, bool upper, PriorityQueue<Event> events)
|
||||||
{
|
{
|
||||||
C5.KeyValuePair<SegmentKey, Circle> other;
|
|
||||||
SegmentKey s;
|
|
||||||
|
|
||||||
if (upper)
|
var intersects = circle.FindIntersections(neighbour.Value);
|
||||||
{
|
|
||||||
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);
|
|
||||||
if (intersects == null) return;
|
if (intersects == null) return;
|
||||||
foreach (var intersection in intersects)
|
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;
|
if (intersections.Contains(intersection)) continue;
|
||||||
events.Add(new Event(Event.EventType.Intersection, intersection.X, e.Circle, intersection.Y, new []{new C5.KeyValuePair<SegmentKey, Circle>(s, e.Circle), other}));
|
events.Add(new Event(Event.EventType.Intersection, intersection.X, circle, intersection.Y,
|
||||||
|
new[] {new C5.KeyValuePair<SegmentKey, Circle>(segment, circle), neighbour}));
|
||||||
intersections.Add(intersection);
|
intersections.Add(intersection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,7 +156,6 @@ namespace TMI_practicum
|
|||||||
Segments = segments;
|
Segments = segments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int CompareTo(Event other)
|
public int CompareTo(Event other)
|
||||||
{
|
{
|
||||||
return X.CompareTo(other.X);
|
return X.CompareTo(other.X);
|
||||||
@@ -147,8 +167,20 @@ namespace TMI_practicum
|
|||||||
{
|
{
|
||||||
int hash = 17;
|
int hash = 17;
|
||||||
hash = hash * 23 + Type.GetHashCode();
|
hash = hash * 23 + Type.GetHashCode();
|
||||||
hash = hash * 23 + X.GetHashCode();
|
hash = hash * 23 + Circle.X.GetHashCode();
|
||||||
hash = hash * 23 + Y.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;
|
return hash;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,7 +204,7 @@ namespace TMI_practicum
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private SegmentType Type { get; }
|
public SegmentType Type { get; }
|
||||||
private readonly int _identifier;
|
private readonly int _identifier;
|
||||||
|
|
||||||
public SegmentKey(SegmentType type, int identifier, Circle circle)
|
public SegmentKey(SegmentType type, int identifier, Circle circle)
|
||||||
|
Reference in New Issue
Block a user