// currently unused public HRect Intersection(HRect r) { HPoint newmin = new HPoint(this.min.Coord.Length); HPoint newmax = new HPoint(this.min.Coord.Length); for (int i = 0; i < this.min.Coord.Length; ++i) { newmin.Coord[i] = Math.Max(this.min.Coord[i], r.min.Coord[i]); newmax.Coord[i] = Math.Min(this.max.Coord[i], r.max.Coord[i]); if (newmin.Coord[i] >= newmax.Coord[i]) { return(null); } } return(new HRect(newmin, newmax)); }
private NearestNeighborList <KDNode <T> > getNbrs(double[] key, int n, Predicate <T> checker) { if (key.Length != this.m_K) { throw new KeySizeException(); } NearestNeighborList <KDNode <T> > nnl = new NearestNeighborList <KDNode <T> >(n); // initial call is with infinite hyper-rectangle and max distance HRect hr = HRect.InfiniteHRect(key.Length); double max_dist_sqd = Double.MaxValue; HPoint keyp = new HPoint(key); if (this.m_count > 0) { long timeout = (this.m_timeout > 0) ? (CurrentTimeMillis() + this.m_timeout) : 0; KDNode <T> .NearestNeighbors(this.m_root, keyp, hr, max_dist_sqd, 0, this.m_K, nnl, checker, timeout); } return(nnl); }
// currently unused public HRect Intersection(HRect r) { HPoint newmin = new HPoint(this.min.Coord.Length); HPoint newmax = new HPoint(this.min.Coord.Length); for (int i = 0; i < this.min.Coord.Length; ++i) { newmin.Coord[i] = Math.Max(this.min.Coord[i], r.min.Coord[i]); newmax.Coord[i] = Math.Min(this.max.Coord[i], r.max.Coord[i]); if (newmin.Coord[i] >= newmax.Coord[i]) { return null; } } return new HRect(newmin, newmax); }
private static void hrCopy(HRect hr_src, HRect hr_dst) { hpCopy(hr_src.Min, hr_dst.Min); hpCopy(hr_src.Max, hr_dst.Max); }
// Method Nearest Neighbor from Andrew Moore's thesis. Numbered // comments are direct quotes from there. NearestNeighborList solution // courtesy of Bjoern Heckel. public static void NearestNeighbors <T>(KDNode <T> kd, HPoint target, HRect hr, double max_dist_sqd, int lev, int K, NearestNeighborList <KDNode <T> > nnl, Predicate <T> checker, long timeout) { // 1. if kd is empty then set dist-sqd to infinity and exit. if (kd == null) { return; } if ((timeout > 0) && (timeout < DateTime.Now.TimeOfDay.TotalMilliseconds)) { return; } // 2. s := split field of kd int s = lev % K; // 3. pivot := dom-elt field of kd HPoint pivot = kd.key; double pivot_to_target = HPoint.SqrDist(pivot, target); // 4. Cut hr into to sub-hyperrectangles left-hr and right-hr. // The cut plane is through pivot and perpendicular to the s // dimension. HRect left_hr = hr; // optimize by not cloning HRect right_hr = (HRect)hr.Clone(); left_hr.Max.Coord[s] = pivot.Coord[s]; right_hr.Min.Coord[s] = pivot.Coord[s]; // 5. target-in-left := target_s <= pivot_s bool target_in_left = target.Coord[s] < pivot.Coord[s]; KDNode <T> nearer_kd; HRect nearer_hr; KDNode <T> further_kd; HRect further_hr; // 6. if target-in-left then // 6.1. nearer-kd := left field of kd and nearer-hr := left-hr // 6.2. further-kd := right field of kd and further-hr := right-hr if (target_in_left) { nearer_kd = kd.left; nearer_hr = left_hr; further_kd = kd.right; further_hr = right_hr; } // // 7. if not target-in-left then // 7.1. nearer-kd := right field of kd and nearer-hr := right-hr // 7.2. further-kd := left field of kd and further-hr := left-hr else { nearer_kd = kd.right; nearer_hr = right_hr; further_kd = kd.left; further_hr = left_hr; } // 8. Recursively call Nearest Neighbor with paramters // (nearer-kd, target, nearer-hr, max-dist-sqd), storing the // results in nearest and dist-sqd NearestNeighbors(nearer_kd, target, nearer_hr, max_dist_sqd, lev + 1, K, nnl, checker, timeout); // KDNode<T> nearest = nnl.getHighest(); double dist_sqd; if (!nnl.IsCapacityReached()) { dist_sqd = Double.MaxValue; } else { dist_sqd = nnl.MaxPriority; } // 9. max-dist-sqd := minimum of max-dist-sqd and dist-sqd max_dist_sqd = Math.Min(max_dist_sqd, dist_sqd); // 10. A nearer point could only lie in further-kd if there were some // part of further-hr within distance max-dist-sqd of // target. HPoint closest = further_hr.Closest(target); if (HPoint.SqrDist(closest, target) < max_dist_sqd) { // 10.1 if (pivot-target)^2 < dist-sqd then if (pivot_to_target < dist_sqd) { // 10.1.1 nearest := (pivot, range-elt field of kd) // nearest = kd; // 10.1.2 dist-sqd = (pivot-target)^2 dist_sqd = pivot_to_target; // add to nnl if (!kd.deleted && ((checker == null) || checker.Invoke(kd.value))) { nnl.Insert(kd, dist_sqd); } // 10.1.3 max-dist-sqd = dist-sqd // max_dist_sqd = dist_sqd; if (nnl.IsCapacityReached()) { max_dist_sqd = nnl.MaxPriority; } else { max_dist_sqd = Double.MaxValue; } } // 10.2 Recursively call Nearest Neighbor with parameters // (further-kd, target, further-hr, max-dist_sqd), // storing results in temp-nearest and temp-dist-sqd NearestNeighbors(further_kd, target, further_hr, max_dist_sqd, lev + 1, K, nnl, checker, timeout); } }