public Rect(Rect r) { this.min = new Point(r.min); this.max = new Point(r.max); }
private static void nearest(BDNode tree, Point target, Rect rect, double max_dist_sqd, int level, NearestNeighborList nnl) { if (tree == null) return; Point pivot = tree.Coord; double pivot_to_target = pivot.SquareDistance(target); Rect left_rect = rect; Rect right_rect = new Rect(rect); bool target_in_left; if (level % 2 == 0) { left_rect.max.X = pivot.X; right_rect.min.X = pivot.X; target_in_left = target.X < pivot.X; } else { left_rect.max.Y = pivot.Y; right_rect.min.Y = pivot.Y; target_in_left = target.Y < pivot.Y; } BDNode nearer_node, further_node; Rect nearer_rect, further_rect; if (target_in_left) { nearer_node = tree.Left; nearer_rect = left_rect; further_node = tree.Right; further_rect = right_rect; } else { nearer_node = tree.Right; nearer_rect = right_rect; further_node = tree.Left; further_rect = left_rect; } nearest(nearer_node, target, nearer_rect, max_dist_sqd, level + 1, nnl); BDNode nearest_node = (BDNode)nnl.getHighest(); double dist_sqd; if (!nnl.isCapacityReached()) dist_sqd = Double.MaxValue; else dist_sqd = nnl.getMaxPriority(); max_dist_sqd = Math.Min(max_dist_sqd, dist_sqd); Point closest = further_rect.Closest(target); if (closest.Distance(target) < Math.Sqrt(max_dist_sqd)) { if (pivot_to_target < dist_sqd) { nearest_node = tree; dist_sqd = pivot_to_target; nnl.insert(tree, dist_sqd); if (nnl.isCapacityReached()) max_dist_sqd = nnl.getMaxPriority(); else max_dist_sqd = Double.MaxValue; } nearest(further_node, target, further_rect, max_dist_sqd, level + 1, nnl); BDNode temp_nearest = (BDNode)nnl.getHighest(); double temp_dist_sqd = nnl.getMaxPriority(); if (temp_dist_sqd < dist_sqd) { nearest_node = temp_nearest; dist_sqd = temp_dist_sqd; } } else if (pivot_to_target < max_dist_sqd) { nearest_node = tree; dist_sqd = pivot_to_target; } }
#pragma warning restore 0642 public static void nnbr(TwoDNode kd, Point target, Rect hr, double max_dist_sqd, int lev, NearestNeighborList nnl) { if (kd == null) return; int s = lev % 2; Point pivot = kd.key; double pivot_to_target = pivot.SquareDistance(target); Rect left_r = hr; Rect right_r = new Rect(hr); bool target_in_left; if (s == 0) { left_r.max.X = pivot.X; right_r.min.X = pivot.X; target_in_left = target.X < pivot.X; } else { left_r.max.Y = pivot.Y; right_r.min.Y = pivot.Y; target_in_left = target.Y < pivot.Y; } TwoDNode nearer_node; Rect nearer_rect; TwoDNode further_node; Rect further_rect; if (target_in_left) { nearer_node = kd.left; nearer_rect = left_r; further_node = kd.right; further_rect = right_r; } else { nearer_node = kd.right; nearer_rect = right_r; further_node = kd.left; further_rect = left_r; } nnbr(nearer_node, target, nearer_rect, max_dist_sqd, lev + 1, nnl); TwoDNode nearest = (TwoDNode)nnl.getHighest(); double dist_sqd; if (!nnl.isCapacityReached()) dist_sqd = Double.MaxValue; else dist_sqd = nnl.getMaxPriority(); max_dist_sqd = Math.Min(max_dist_sqd, dist_sqd); Point closest = further_rect.Closest(target); if (closest.Distance(target) < Math.Sqrt(max_dist_sqd)) { if (pivot_to_target < dist_sqd) { nearest = kd; dist_sqd = pivot_to_target; if (!kd.deleted) nnl.insert(kd, dist_sqd); if (nnl.isCapacityReached()) max_dist_sqd = nnl.getMaxPriority(); else max_dist_sqd = Double.MaxValue; } nnbr(further_node, target, further_rect, max_dist_sqd, lev + 1, nnl); TwoDNode temp_nearest = (TwoDNode)nnl.getHighest(); double temp_dist_sqd = nnl.getMaxPriority(); if (temp_dist_sqd < dist_sqd) { nearest = temp_nearest; dist_sqd = temp_dist_sqd; } } else if (pivot_to_target < max_dist_sqd) { nearest = kd; dist_sqd = pivot_to_target; } }