1
0

update sweeplineff

This commit is contained in:
2019-05-18 19:47:28 +02:00
parent ec65d0d925
commit ba2c421e21
2 changed files with 38 additions and 58 deletions

View File

@@ -12,8 +12,8 @@ namespace TMI_practicum
var intersections = new Stack<Intersection>();
var events = new PriorityQueue<Event>();
var upperActive = new CircleTree<SegmentKey, Segment>();
var bottomActive = new CircleTree<SegmentKey, Segment>();
var upperActive = new CircleTree<SegmentKey, Circle>();
var bottomActive = new CircleTree<SegmentKey, Circle>();
foreach (var circle in circles)
@@ -29,17 +29,16 @@ namespace TMI_practicum
switch (e.Type)
{
case Event.EventType.Start:
upperActive.Add(new SegmentKey(e.X, e.Circle.Y, Segment.SegmentType.Upper, hash),
new Segment(Segment.SegmentType.Upper, e.Circle.Y, e.Circle));
bottomActive.Add(new SegmentKey(e.X, e.Circle.Y, Segment.SegmentType.Bottom, hash),
new Segment(Segment.SegmentType.Bottom, e.Circle.Y, e.Circle));
upperActive.Add(new SegmentKey(e.X, e.Circle.Y + e.Circle.R, SegmentKey.SegmentType.Upper, hash), e.Circle);
bottomActive.Add(new SegmentKey(e.X, e.Circle.Y - e.Circle.R, SegmentKey.SegmentType.Bottom, hash),
e.Circle);
CheckIntersections(upperActive, e, intersections, true);
CheckIntersections(bottomActive, e, intersections, false);
break;
case Event.EventType.End:
upperActive.Remove(new SegmentKey(e.X, e.Circle.Y, Segment.SegmentType.Upper, hash));
bottomActive.Remove(new SegmentKey(e.X, e.Circle.Y, Segment.SegmentType.Bottom, hash));
upperActive.Remove(new SegmentKey(e.X, e.Circle.Y + e.Circle.R, SegmentKey.SegmentType.Upper, hash));
bottomActive.Remove(new SegmentKey(e.X, e.Circle.Y - e.Circle.R, SegmentKey.SegmentType.Bottom, hash));
break;
default:
throw new ArgumentOutOfRangeException();
@@ -50,34 +49,36 @@ namespace TMI_practicum
return intersections;
}
private static void CheckIntersections(CircleTree<SegmentKey, Segment> active, Event e, Stack<Intersection> intersections, bool upper)
private static void CheckIntersections(CircleTree<SegmentKey, Circle> active, Event e, Stack<Intersection> intersections, bool upper)
{
Segment other;
Circle other = null;
Circle other2 = null;
try
{
other = upper
? active.FindSuccessor(new SegmentKey(e.X, e.Circle.Y, Segment.SegmentType.Upper, e.GetHashCode()))
: active.FindPredecessor(new SegmentKey(e.X, e.Circle.Y, Segment.SegmentType.Bottom, e.GetHashCode()));
other = upper? active.FindSuccessor(new SegmentKey(e.X, e.Circle.Y, SegmentKey.SegmentType.Upper, e.GetHashCode()))
:
active.FindPredecessor(new SegmentKey(e.X, e.Circle.Y, SegmentKey.SegmentType.Bottom, e.GetHashCode()));
other2 = upper? active.FindPredecessor(new SegmentKey(e.X, e.Circle.Y, SegmentKey.SegmentType.Upper, e.GetHashCode()))
:
active.FindSuccessor(new SegmentKey(e.X, e.Circle.Y, SegmentKey.SegmentType.Bottom, e.GetHashCode()));
}
catch (KeyNotFoundException)
{
return;
}
var intersects = e.Circle.FindIntersections(other.Circle);
if (intersects == null) return;
foreach (var intersection in intersects)
if (other != null)
{
if (upper)
var intersects = e.Circle.FindIntersections(other);
if (intersects != null)
{
if (intersection.Y < e.Circle.Y) continue;
foreach (var intersection in intersects)
{
if (upper && e.Circle.Y == intersection.Y) continue;
intersections.Push(intersection);
}
}
else
{
if (intersection.Y > e.Circle.Y) continue;
}
intersections.Push(intersection);
}
}
@@ -106,7 +107,6 @@ namespace TMI_practicum
public enum EventType
{
Start,
Intersect,
End
}
@@ -123,41 +123,15 @@ namespace TMI_practicum
}
}
private class Segment : IComparable<Segment>
{
public Segment(SegmentType type, double y, Circle circle)
{
_type = type;
_y = y;
Circle = circle;
}
private readonly SegmentType _type;
private readonly double _y;
public Circle Circle { get; }
public int CompareTo(Segment other)
{
throw new NotImplementedException();
}
public enum SegmentType
{
Bottom,
Upper,
Null
}
}
private struct SegmentKey : IComparable<SegmentKey>
{
private readonly double _x;
private readonly double _y;
private readonly Segment.SegmentType _type;
private readonly double? _y;
public double Y => _y ?? double.MinValue;
private readonly SegmentType _type;
private readonly int _identifier;
public SegmentKey(double x, double y, Segment.SegmentType type, int identifier)
public SegmentKey(double x, double y, SegmentType type, int identifier)
{
_y = y;
_type = type;
@@ -168,7 +142,7 @@ namespace TMI_practicum
public int CompareTo(SegmentKey other)
{
if (_identifier.Equals(other._identifier)) return _type.CompareTo(other._type);
if (!_y.Equals(other._y)) return _y.CompareTo(other._y);
if (!_y.Equals(other._y)) return Y.CompareTo(other.Y);
return _type.Equals(other._type) ? _x.CompareTo(other._x) : _type.CompareTo(other._type);
}
@@ -185,6 +159,12 @@ namespace TMI_practicum
{
return _identifier.GetHashCode() ^ _type.GetHashCode();
}
public enum SegmentType
{
Bottom,
Upper
}
}
}
public static class EnumerableExtensions