@Override public boolean findNearest( P point , double maxDistance , NnData<P> result ) { if( maxDistance < 0 ) search.setMaxDistance(Double.MAX_VALUE); else search.setMaxDistance(maxDistance); KdTree.Node found = search.findNeighbor(point); if( found == null ) return false; result.point = (P)found.point; result.index = found.index; result.distance = search.getDistance(); return true; }
/** * Make sure the distance it returns is correct */ @Test public void checkDistance() { KdTreeSearch1<double[]> alg = createAlg(); KdTree tree = createTreeA(); alg.setTree(tree); alg.setMaxDistance(Double.MAX_VALUE); double[] pt = new double[]{11.5,8.2}; KdTree.Node found = alg.findNeighbor(pt); double d0 = ((double[])found.point)[0]-pt[0]; double d1 = ((double[])found.point)[1]-pt[1]; assertEquals(d0*d0 + d1*d1,alg.getDistance(),1e-8); } }
/** * See if it can handle a null leaf */ @Test public void findClosest_nullLeaf() { KdTreeSearch1<double[]> alg = createAlg(); KdTree tree = createTreeWithNull(); alg.setTree(tree); alg.setMaxDistance(Double.MAX_VALUE); // the first decision will be incorrect and it will need to back track KdTree.Node found = alg.findNeighbor(new double[]{2, 3}); assertSame(found, tree.root); }
/** * The tree is empty and it should always fail */ @Test public void findClosest_empty() { KdTreeSearch1<double[]> alg = createAlg(); alg.setTree( new KdTree(2) ); KdTree.Node found = alg.findNeighbor(new double[]{11, 8}); assertNull(found); }
@Override public void setPoints(List<P> points, boolean trackIndicies) { if( tree != null ) memory.recycleGraph(tree); tree = constructor.construct(points,trackIndicies); search.setTree(tree); searchN.setTree(tree); }
/** * See if max distance is being respected */ @Test public void findClosest_maxDistance() { KdTree tree = new KdTree(2); tree.root = new KdTree.Node(new double[]{1,2}); KdTreeSearch1<double[]> alg = createAlg(); alg.setTree( tree ); alg.setMaxDistance(2); KdTree.Node found = alg.findNeighbor(new double[]{11, 8}); assertNull(found); found = alg.findNeighbor(new double[]{1, 1.5}); assertSame(found, tree.root); }
/** * The tree is a leaf and should always return the same result */ @Test public void findClosest_leaf() { KdTree tree = new KdTree(2); tree.root = new KdTree.Node(new double[]{1,2}); KdTreeSearch1<double[]> alg =createAlg(); alg.setTree( tree ); KdTree.Node found = alg.findNeighbor(new double[]{11, 8}); assertSame(found, tree.root); found = alg.findNeighbor(new double[]{2, 5}); assertSame(found, tree.root); }
@Override public void setPoints(List<P> points, boolean trackIndicies) { if( tree != null ) memory.recycleGraph(tree); tree = constructor.construct(points,trackIndicies); search.setTree(tree); searchN.setTree(tree); }
/** * Try several searches and see if they all produce good results */ @Test public void findClosest_basic() { KdTreeSearch1<double[]> alg = createAlg(); KdTree tree = createTreeA(); alg.setTree(tree); alg.setMaxDistance(Double.MAX_VALUE); // the first decision will be incorrect and it will need to back track KdTree.Node found = alg.findNeighbor(new double[]{11, 8}); assertSame(found, tree.root.right.right); // the root will be the best match found = alg.findNeighbor(new double[]{1.001, 1.99999}); assertSame(found, tree.root); // a point on the left branch will be a perfect fit found = alg.findNeighbor(new double[]{2, 0.8}); assertSame(found, tree.root.left.right); // a point way outside the tree's bounds found = alg.findNeighbor(new double[]{-10000, 0.5}); assertSame(found, tree.root.left.left); }
@Override public boolean findNearest( P point , double maxDistance , NnData<P> result ) { if( maxDistance < 0 ) search.setMaxDistance(Double.MAX_VALUE); else search.setMaxDistance(maxDistance); KdTree.Node found = search.findNeighbor(point); if( found == null ) return false; result.point = (P)found.point; result.index = found.index; result.distance = search.getDistance(); return true; }