// Test for closest pairs to P in set sS (P is a point in the strip) PointSet testStripPoint(PointSet S, Point P, PointSet sS, Point M, Boolean lookDIR) { Point Q; // Draw P's bounding box if (DELAY > 50) { drawDQBoundingBox(S, P, M, lookDIR); pause(DELAY); } for (int j = 0; j < sS.points.Count; j++) { Q = sS.pointAt(j); // if Q is in P's bounding box //if ((Math.Abs(P.x - Q.x) <= S.dmin) && //(Math.Abs(P.y - Q.y) <= S.dmin)) //{ // draw a red segment to show that it is being compared if (DELAY > 50) { drawSegment(P, Q); pause(DELAY); } numComparisons++; S = testBoundingBoxPoint(S, P, Q); // erase the red segment after the comparison if (DELAY > 50) { eraseSegment(P, Q, Color.Yellow); pause(DELAY); } //} } // Erase P's bounding box if (DELAY > 50) { drawDQStrip(S, M); } return S; }
public double ClosestPairDQ(PointSet S, ref PointSet current) { if (S.points.Count <= 1) { S.dmin = inf; } else { // calculate co-ordinates of median point int median = (int)Math.Ceiling((decimal)S.points.Count / 2); Point M = S.pointAt(median - 1); // calculate two subproblems (median in first subset) PointSet S1 = subSet(S, 0, median - 1); PointSet S2 = subSet(S, median, S.points.Count - 1); // highlight the whole set if (DELAY > 50) { drawField(S, Color.Cyan); drawVertical(M, Color.Blue); pause(DELAY); eraseVertical(M); eraseField(S); } // recursively calculate solutions to sub-problems S.dmin = Math.Min(ClosestPairDQ(S1, ref current), ClosestPairDQ(S2, ref current)); // highlight the whole set, and solutions for each subset if (DELAY > 50) { drawField(S, Color.Cyan); drawVertical(M, Color.Blue); pause(DELAY); } // merge two sub-solutions S = merge(S, S1, S2, ref current); // highlight set in gray b/c solution has been computed if (DELAY > 50) { eraseVertical(M); eraseField(S); drawField(S, Color.LightGray); pause(DELAY); } } return S.dmin; }
// returns a subset of containing the elements of S from fromIndex to // toIndex inclusive public PointSet subSet(PointSet S, int fromIndex, int toIndex) { PointSet T = new PointSet(); for (int i = fromIndex; i <= toIndex; i++) { T.add(S.pointAt(i)); } return T; }
PointSet merge(PointSet S, PointSet S1, PointSet S2, ref PointSet WorkSet) { Point M = S1.pointAt(S1.points.Count - 1); // draw the strip about the median if (DELAY > 50) { drawDQStrip(S, M); pause(DELAY); } for (int i = 0; i < S.points.Count; i++) { Point P = S.pointAt(i); if (Math.Abs(P.x - M.x) <= S.dmin) { // P is in S1, only look in S2 if (S1.contains(P)) { S = testStripPoint(S, P, S2, M, true); } // P is in S2, only look in S1 if (S2.contains(P)) { S = testStripPoint(S, P, S1, M, false); } // update miniMUM distance if (S.dmin < WorkSet.dmin) { WorkSet.dmin = S.dmin; if (WorkSet.closestPair.Count == 0) { WorkSet.closestPair.Add(S.closestPair[0]); WorkSet.closestPair.Add(S.closestPair[1]); } else { WorkSet.closestPair[0] = S.closestPair[0]; WorkSet.closestPair[1] = S.closestPair[1]; } } } } return S; }
public void drawPoints(PointSet S, Color c) { for (int i = 0; i < S.points.Count; i++) { Point P = S.pointAt(i); drawPoint(P); } }