public static LineSegment PointsClosestPairIterative(List <Point> points) { Point?a = null, b = null; var queue = new PriorityQueue <Point>(new PointXCoordComparerInversed()); points.ForEach(p => queue.Add(p)); var t = new SkipList <Point>(new PointYCoordComparer()) { new Point { X = double.NegativeInfinity, Y = double.NegativeInfinity }, new Point { X = double.NegativeInfinity, Y = double.PositiveInfinity } }; var current = queue.Peek(); var firstActive = current; var delta = double.PositiveInfinity; while (queue.Count > 0) { var p = current; queue.Remove(current); if (queue.Count > 0) { current = queue.Peek(); } var r = t.Ceiling(p); var l = t.Previous(r); UpdateDeltaOnRight(ref p, ref r, ref delta, t, ref a, ref b); UpdateDeltaOnLeft(ref p, ref l, ref delta, t, ref a, ref b); UpdateActivePoints(ref p, ref firstActive, t, delta); t.Add(p); } return(new LineSegment(a ?? new Point(), b ?? new Point())); }
private static void UpdateDeltaOnLeft(ref Point p, ref Point l, ref double delta, SkipList <Point> t, ref Point?a, ref Point?b) { var i = 0; while (l != new Point(double.NegativeInfinity, double.NegativeInfinity) && (i < 4)) { var dist = D(p, l); if (dist < delta) { delta = dist; a = p; b = l; } l = t.Previous(l); if (l == default(Point)) { break; } i++; } }