Guest User

Untitled

a guest
Feb 17th, 2019
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.40 KB | None | 0 0
  1. template <class T, std::size_t N>
  2. void KDTree<T,N>::nearest (
  3. const const KDNode<T,N> &node,
  4. const std::array<T, N> &point, // looking for closest node to this point
  5. const KDPoint<T,N> &closest, // closest node (so far)
  6. double &minDist,
  7. const uint depth) const
  8. {
  9. if (node->isLeaf()) {
  10. const double dist = distance(point, node->leaf->point);
  11. if (dist < minDist) {
  12. minDist = dist;
  13. closest = node->leaf;
  14. }
  15. } else {
  16. const T dim = depth % N;
  17. if (point[dim] < node->splitVal) {
  18. // search left first
  19. nearest(node->left, point, closest, minDist, depth + 1);
  20. if (point[dim] + minDist >= node->splitVal)
  21. nearest(node->right, point, closest, minDist, depth + 1);
  22. } else {
  23. // search right first
  24. nearest(node->right, point, closest, minDist, depth + 1);
  25. if (point[dim] - minDist <= node->splitVal)
  26. nearest(node->left, point, closest, minDist, depth + 1);
  27. }
  28. }
  29. }
  30.  
  31. // Nearest neighbour
  32. template <class T, std::size_t N>
  33. const KDPoint<T,N> KDTree<T,N>::nearest (const std::array<T, N> &point) const {
  34. const KDPoint<T,N> closest;
  35. double minDist = std::numeric_limits<double>::max();
  36. nearest(root, point, closest, minDist);
  37. return closest;
  38. }
  39.  
  40. template <class T, std::size_t N>
  41. double distance (const std::array<T, N> &p1, const std::array<T, N> &p2) {
  42. double d = 0.0;
  43. for (uint i = 0; i < N; ++i) {
  44. d += pow(p1[i] - p2[i], 2.0);
  45. }
  46. return sqrt(d);
  47. }
  48.  
  49. template <class T, std::size_t N>
  50. class KDPoint {
  51. public:
  52. KDPoint<T,N> (std::array<T,N> &&t) : point(std::move(t)) { };
  53. virtual ~KDPoint<T,N> () = default;
  54. std::array<T, N> point;
  55. };
  56.  
  57. template <class T, std::size_t N>
  58. class KDNode
  59. {
  60. public:
  61. KDNode () = delete;
  62. KDNode (const KDNode &) = delete;
  63. KDNode & operator = (const KDNode &) = delete;
  64. ~KDNode () = default;
  65.  
  66. // branch node
  67. KDNode (const T split,
  68. std::unique_ptr<const KDNode> &lhs,
  69. std::unique_ptr<const KDNode> &rhs) : splitVal(split), left(std::move(lhs)), right(std::move(rhs)) { };
  70. // leaf node
  71. KDNode (std::shared_ptr<const KDPoint<T,N>> p) : splitVal(0), leaf(p) { };
  72.  
  73. bool isLeaf (void) const { return static_cast<bool>(leaf); }
  74.  
  75. // data members
  76. const T splitVal;
  77. const std::unique_ptr<const KDNode<T,N>> left, right;
  78. const std::shared_ptr<const KDPoint<T,N>> leaf;
  79. };
  80.  
  81. template <class T, std::size_t N>
  82. class KDTree {
  83. public:
  84. KDTree () = delete;
  85. KDTree (const KDTree &) = delete;
  86. KDTree (KDTree &&t) : root(std::move(const_cast<std::unique_ptr<const KDNode<T,N>>&>(t.root))) { };
  87. KDTree & operator = (const KDTree &) = delete;
  88. ~KDTree () = default;
  89.  
  90. const KDPoint<T,N> nearest (const std::array<T, N> &point) const;
  91.  
  92. // Nearest neighbour search - runs in O(log n)
  93. void nearest (const std::unique_ptr<const KDNode<T,N>> &node,
  94. const std::array<T, N> &point,
  95. std::shared_ptr<const KDPoint<T,N>> &closest,
  96. double &minDist,
  97. const uint depth = 0) const;
  98.  
  99. // data members
  100. const std::unique_ptr<const KDNode<T,N>> root;
  101. };
Add Comment
Please, Sign In to add comment