using System; using System.Collections.Generic; using Medallion.Collections; namespace TMI_practicum { public static class SweepLineAlgorithm { public static IEnumerable Solve(IList circles) { var events = new PriorityQueue(); var intersections = new HashSet(); var active = new List(); foreach (var circle in circles) { events.Enqueue(new Event(Event.EventType.Start, circle.X - circle.R, circle)); events.Enqueue(new Event(Event.EventType.End, circle.X + circle.R, circle)); } while (events.Count != 0) { Event e = events.Dequeue(); switch (e.Type) { case Event.EventType.Start: active.Add(e.Circle); CheckIntersections(active, e.Circle, intersections); break; case Event.EventType.End: active.Remove(e.Circle); break; default: throw new ArgumentOutOfRangeException(); } } return intersections; } private static void CheckIntersections(IEnumerable active, Circle circle, HashSet intersections) { foreach (var otherCircle in active) { if (circle.Equals(otherCircle)) continue; var intersects = circle.FindIntersections(otherCircle); if (intersects == null) continue; foreach (var intersection in intersects) { intersections.Add(intersection); } } } private struct Event : IComparable { public EventType Type { get; } public Circle Circle { get; } public double X { get; } public enum EventType { Start, End } public Event(EventType type, double x, Circle circle) { Type = type; X = x; Circle = circle; } public int CompareTo(Event other) { return X.CompareTo(other.X); } } } }