stefankoegl / kdtree

A Python implementation of a kd-tree
ISC License
371 stars 118 forks source link

v0.15 search_nn_dist does not return the expected point #36

Closed nicolas-f closed 6 years ago

nicolas-f commented 7 years ago

Hi,

The point is at a distance less than 0.6 But the query result is empty.

Here the unit test:

    def test_search_nn_dist2(self):
        points = [[0.25, 0.25, 1.600000023841858], [0.75, 0.25, 1.600000023841858], [1.25, 0.25, 1.600000023841858],
               [1.75, 0.25, 1.600000023841858], [2.25, 0.25, 1.600000023841858], [2.75, 0.25, 1.600000023841858]]

        expected = [0.25, 0.25, 1.600000023841858]
        tree = kdtree.create(points)
        rmax = 1.0
        search_p = [0.42621034383773804, 0.18793821334838867, 1.44510018825531]
        results = tree.search_nn_dist(search_p, rmax)
        found = False
        for result in results:
            if result.data == expected:
                found = True
                break
        self.assertTrue(found)

Maybe I don't understand the distance parameter ?

Thanks for the help. You library is great !

nicolas-f commented 7 years ago

If I'm using the same code that last unit test, it fails also:

    def test_search_nn_dist2(self):
        pointslst = [[0.25, 0.25, 1.600000023841858], [0.75, 0.25, 1.600000023841858], [1.25, 0.25, 1.600000023841858],
               [1.75, 0.25, 1.600000023841858], [2.25, 0.25, 1.600000023841858], [2.75, 0.25, 1.600000023841858]]

        tree = kdtree.create(pointslst)
        points = [p for p in tree.inorder()]
        search_p = [0.42621034383773804, 0.18793821334838867, 1.44510018825531]

        for p in points:
            dist = p.dist(search_p)
            nn = tree.search_nn_dist(search_p, dist)
            for pn in points:
                if pn in nn:
                    self.assertTrue(pn.dist(search_p) < dist, '%s in %s but %s < %s' % (pn, nn, pn.dist(search_p), dist))
                else:
                    self.assertTrue(pn.dist(search_p) >= dist,
                                    '%s not in %s but %s >= %s' % (pn, nn, pn.dist(search_p), dist))
eyaler commented 7 years ago

@nicolas-f did you find out what's going on?

nicolas-f commented 7 years ago

Nope. I don't use this function anymore. I use the function search_knn now.

grapemix commented 7 years ago

The search_nn_dist() return unexpected result to me too and the test case for search_nn_dist() also miss some points. For example, in the test case:

points = [(x,y) for x in range(10) for y in range(10)] tree = kdtree.create(points) nn = tree.search_nn_dist((5,5), 2.5)

self.assertEqual(len(nn), 4) self.assertTrue( (6,6) in nn) self.assertTrue( (5,5) in nn) self.assertTrue( (5,6) in nn) self.assertTrue( (6,5) in nn)

The point(4,4) is missing. The Euclidean distance between (5,5) and (4,4) is 1.414214 and hence should be included if the radius param is 2.5.

I've made a pull request for this bug.

stefankoegl commented 6 years ago

Fixed by #37 - I will release a new version soon.