KdTree.hpp
Go to the documentation of this file.
1 
2 namespace GfxTL
3 {
4  template< class ValueT, class BaseT >
6  {
7  memset(&_children, NULL, sizeof(_children));
8  }
9 
10  template< class ValueT, class BaseT >
12  const KdTreeCell< ValueT, BaseT >& cell)
13  : BaseT(cell)
14  , _split(cell._split)
15  , _box(cell._box)
16  {
17  if (cell._children[0])
18  {
19  _children[0] = new KdTreeCell< ValueT, BaseT >(*cell._children[0]);
20  }
21  else
22  {
23  _children[0] = NULL;
24  }
25  if (cell._children[1])
26  {
27  _children[1] = new KdTreeCell< ValueT, BaseT >(*cell._children[1]);
28  }
29  else
30  {
31  _children[1] = NULL;
32  }
33  }
34 
35  template< class ValueT, class BaseT >
37  {
38  for (unsigned int i = 0; i < 2; ++i)
39  if (_children[i])
40  {
41  delete _children[i];
42  }
43  }
44 
45  template< class ValueT, class BaseT >
46  const KdTreeCell< ValueT, BaseT >* KdTreeCell< ValueT, BaseT >::operator[](
47  unsigned int index) const
48  {
49  return _children[index];
50  }
51 
52  template< class ValueT, class BaseT >
53  KdTreeCell< ValueT, BaseT >* KdTreeCell< ValueT, BaseT >::operator[](
54  unsigned int index)
55  {
56  return _children[index];
57  }
58 
59  template< class ValueT, class BaseT >
60  void KdTreeCell< ValueT, BaseT >::Child(unsigned int index,
61  ThisType* child)
62  {
63  _children[index] = child;
64  }
65 
66  template< class ValueT, class BaseT >
67  const typename KdTreeCell< ValueT, BaseT >::SplitterType&
69  {
70  return _split;
71  }
72 
73  template< class ValueT, class BaseT >
74  const typename KdTreeCell< ValueT, BaseT >::BoxType&
75  KdTreeCell< ValueT, BaseT >::Box() const
76  {
77  return _box;
78  }
79 
80  template< class Strategies >
82  {
83  Clear();
84 
85  CellType* root = new CellType;
86  CellRange range;
87  RootRange(&range);
88  root->_box.Infinite();
89  Root(root);
90  Init(range, NULL, root);
91 
92  typedef std::pair< CellType*, CellRange > Pair;
93  std::deque< Pair > stack;
94  stack.push_back(Pair(root, range));
95  while (stack.size())
96  {
97  Pair p = stack.back();
98  stack.pop_back();
99  if (ShouldSubdivide(p.second))
100  {
101  Subdivide(p.first, p.second);
102  if (IsLeaf(*p.first)) // couldn't subdivide?
103  {
104  continue;
105  }
106  for (unsigned int i = 0; i < CellType::NChildren; ++i)
107  {
108  Range(*p.first, p.second, i, &range);
109  //Init(range, p.first, (*p.first)[i]);
110  stack.push_back(Pair((*p.first)[i], range));
111  }
112  }
113  }
114  }
115 
116  template< class Strategies >
117  void KdTree< Strategies >::Insert(DereferencedType s)
118  {
119  CellType* cell = Root();
120  CellRange range;
121  RootRange(&range);
122  if (!cell)
123  {
124  cell = new CellType;
125  Root(cell);
126  Init(range, NULL, cell);
127  }
128  Insert(cell, range, s);
129  }
130 
131  template< class Strategies >
132  template< class ContainerT >
134  unsigned int k, ContainerT* neighbors, ScalarType* dist) const
135  {
136  *dist = std::numeric_limits< ScalarType >::infinity();
137  neighbors->resize(0);
138  if (!Root())
139  {
140  return;
141  }
142  AABox< PointType > rootBox;
143  //rootBox.Infinite();
144  CellRange range;
145  RootRange(&range);
146  neighbors->reserve(k + 1);
147  NearestNeighbors(*Root(), range, rootBox, p, k, neighbors, dist);
148  if (*dist < std::numeric_limits< ScalarType >::infinity())
149  {
150  *dist = std::sqrt(*dist);
151  }
152  }
153 
154  template< class Strategies >
155  template< template< class > class ContainerT >
157  unsigned int k, LimitedHeap< NN, ContainerT >* neighbors, ScalarType* dist) const
158  {
159  *dist = std::numeric_limits< ScalarType >::infinity();
160  neighbors->resize(0);
161  if (!Root())
162  {
163  return;
164  }
165  neighbors->Limit(k);
166  CellRange range;
167  RootRange(&range);
168  NearestNeighborsL(*Root(), range, p, k, neighbors, dist);
169  //neighbors->sort_heap();
170  //std::sort_heap(neighbors->begin(), neighbors->end());
171  //if(*dist < std::numeric_limits< ScalarType >::infinity())
172  // *dist = std::sqrt(*dist);
173  }
174 
175  template< class Strategies >
176  template< class ContainerT >
178  unsigned int k, ScalarType eps,
179  ContainerT* neighbors, ScalarType* sqrDist) const
180  {
181  *sqrDist = std::numeric_limits< ScalarType >::infinity();
182  neighbors->resize(0);
183  if (!Root())
184  {
185  return;
186  }
187  AABox< PointType > rootBox;
188  //rootBox.Infinite();
189  CellRange range;
190  RootRange(&range);
191  neighbors->reserve(k + 1);
192  eps = 1 - eps;
193  ApproximateNearestNeighbors(*Root(), range, rootBox, p, k, eps * eps,
194  neighbors, sqrDist);
195  //if(*dist < std::numeric_limits< ScalarType >::infinity())
196  // *dist = std::sqrt(*dist);
197  }
198 
199  template< class Strategies >
200  template< class ContainerT >
202  ScalarType sqrRadius, ContainerT* points) const
203  {
204  points->resize(0);
205  if (!Root())
206  {
207  return;
208  }
209  CellRange range;
210  RootRange(&range);
211  PointsInSphere(*Root(), range, p, sqrRadius, points);
212  }
213 
214  template< class Strategies >
216  DereferencedType* d) const
217  {
218  if (!Root())
219  {
220  return false;
221  }
222  CellRange range;
223  RootRange(&range);
224  return Contains(*Root(), range, p, d);
225  }
226 
227  template< class Strategies >
228  bool KdTree< Strategies >::ShouldSubdivide(CellRange range) const
229  {
230  return range.second - range.first > 10;
231  }
232 
233  template< class Strategies >
234  void KdTree< Strategies >::Subdivide(CellType* cell, CellRange range)
235  {
236  PointType pmin = cell->_box.Min(), pmax = cell->_box.Max();
237  /*pmax = pmin = at(Dereference(range.first));
238  for(HandleType i = range.first + 1; i < range.second; ++i)
239  {
240  const PointType p = at(Dereference(i));
241  for(unsigned int j = 0; j < Dim; ++j)
242  {
243  if(pmin[j] > p[j])
244  pmin[j] = p[j];
245  else if(pmax[j] < p[j])
246  pmax[j] = p[j];
247  }
248  }*/
249 
250  PointType pdiff = pmax - pmin;
251  unsigned int axis = 0;
252  ScalarType length = pdiff[0];
253  for (unsigned int j = 1; j < Dim; ++j)
254  {
255  if (pdiff[j] > length)
256  {
257  axis = j;
258  length = pdiff[j];
259  }
260  }
261 
262  ScalarType split = (pmax[axis] + pmin[axis]) / 2;
263 
264  cell->_split.Set(axis, split);
265 
266  CellType* left, *right;
267  left = new CellType;
268  right = new CellType;
269  Split(cell->_split, range, left, right);
270  if (left->Size() == cell->Size() || right->Size() == cell->Size())
271  {
272  delete left;
273  delete right;
274  return;
275  }
276  //cell->_box.Split(cell->_split.Axis(), cell->_split.Value(),
277  // &left->_box, &right->_box);
278  cell->Child(0, left);
279  cell->Child(1, right);
280  CellRange childRange;
281  Range(*cell, range, 0, &childRange);
282  Init(childRange, cell, left);
283  Range(*cell, range, 1, &childRange);
284  Init(childRange, cell, right);
285  // refine split value
286  cell->_split.Value((right->Box().Min()[cell->_split.Axis()]
287  + left->Box().Max()[cell->_split.Axis()]) / 2);
288  }
289 
290  template< class Strategies >
291  void KdTree< Strategies >::Insert(CellType* cell, CellRange range,
292  DereferencedType s)
293  {
294  cell->_box += at(s);
295  if (IsLeaf(*cell))
296  {
297  BaseType::Insert(range, s);
298  if (ShouldSubdivide(range))
299  {
300  Subdivide(cell, range);
301  }
302  return;
303  }
304  bool left;
305  BaseType::SplitAndInsert(cell->Split(), range, s, (*cell)[0],
306  (*cell)[1], &left);
307  if (left)
308  {
309  CellRange lr;
310  Range(*cell, range, 0, &lr);
311  Insert((*cell)[0], lr, s);
312  }
313  else
314  {
315  CellRange rr;
316  Range(*cell, range, 1, &rr);
317  Insert((*cell)[1], rr, s);
318  }
319  }
320 
321  template< class Strategies >
322  template< class ContainerT >
324  CellRange range, const AABox< PointType >& box, const PointType& p,
325  unsigned int k, ContainerT* neighbors, ScalarType* dist2) const
326  {
327  if (IsLeaf(cell))
328  {
329  HandleType i = range.first, iend = range.second;
330  if (neighbors->size() + cell.Size() <= k)
331  {
332  for (; i != iend; ++i)
333  {
334  DereferencedType deref = Dereference(i);
335  PointType diff = at(deref);
336  diff -= p;
337  ScalarType d2 = diff * diff;
338  neighbors->push_back(NN(deref, d2));
339  }
340  std::sort(neighbors->begin(), neighbors->end());
341  *dist2 = neighbors->back().sqrDist;
342  return;
343  }
344  // let's find nearest neighbors from points within the cell
345  for (; i != iend; ++i)
346  {
347  DereferencedType deref = Dereference(i);
348  PointType diff = at(deref);
349  diff -= p;
350  ScalarType d2 = diff * diff;
351  if (neighbors->size() < k || d2 <= *dist2)
352  {
353  SortedNearestNeighborInsert(NN(deref, d2), k, neighbors);
354  *dist2 = neighbors->back().sqrDist;
355  }
356  }
357  return;
358  }
359  // descent into subtree containing p
360  unsigned int nearerChild, fartherChild;
361  if (cell.Split()(p) <= 0)
362  {
363  nearerChild = 0;
364  fartherChild = 1;
365  }
366  else
367  {
368  nearerChild = 1;
369  fartherChild = 0;
370  }
371  /*AABox< PointType > subBoxes[2];
372  box.Split(cell.Split().Axis(), cell.Split().Value(),
373  &subBoxes[0], &subBoxes[1]);*/
374 
375  CellRange childRange;
376  if (neighbors->size() < k || Intersect(cell[nearerChild]->Box(),
377  p, *dist2))
378  {
379  Range(cell, range, nearerChild, &childRange);
380  NearestNeighbors(*cell[nearerChild], childRange,
381  box/*subBoxes[nearerChild]*/, p, k, neighbors, dist2);
382  }
383 
384  // check if closer neighbor could be in other child
385  if (neighbors->size() < k || Intersect(cell[fartherChild]->Box()/*subBoxes[fartherChild]*/,
386  p, *dist2))
387  {
388  Range(cell, range, fartherChild, &childRange);
389  NearestNeighbors(*cell[fartherChild], childRange,
390  box/*subBoxes[fartherChild]*/, p, k, neighbors, dist2);
391  }
392  }
393 
394  template< class Strategies >
395  template< template< class > class ContainerT >
396  void KdTree< Strategies >::NearestNeighborsL(const CellType& cell,
397  const CellRange& range, const PointType& p, unsigned int k,
398  LimitedHeap< NN, ContainerT >* neighbors, ScalarType* dist2) const
399  {
400  if (IsLeaf(cell))
401  {
402  HandleType i = range.first, iend = range.second;
403  DereferencedType deref;
404  if (neighbors->size() + cell.Size() <= k)
405  {
406  for (; i != iend; ++i)
407  {
408  deref = Dereference(i);
409  neighbors->push_back(NN(deref,
410  p.SqrDistance(at(deref).Point())));
411  }
412  neighbors->MakeHeap();
413  *dist2 = neighbors->front().sqrDist;
414  return;
415  }
416  // let's find nearest neighbors from points within the cell
417  for (; i != iend; ++i)
418  {
419  deref = Dereference(i);
420  neighbors->PushHeap(NN(deref,
421  p.SqrDistance(at(deref).Point())));
422  *dist2 = neighbors->front().sqrDist;
423  }
424  return;
425  }
426  // descent into subtree containing p
427  unsigned int nearerChild, fartherChild;
428  const CellType* nChild, *fChild;
429  ScalarType splitDist = cell._split(p);
430  if (splitDist <= 0)
431  {
432  nearerChild = 0;
433  fartherChild = 1;
434  nChild = cell[0];
435  fChild = cell[1];
436  }
437  else
438  {
439  nearerChild = 1;
440  fartherChild = 0;
441  nChild = cell[1];
442  fChild = cell[0];
443  }
444 
445  CellRange childRange;
446  //if(neighbors->size() < k || Intersect(p, *dist2, nChild->_box.Min(),
447  // nChild->_box.Max()))
448  //{
449  Range(cell, range, nearerChild, &childRange);
450  NearestNeighborsL(*nChild, childRange, p, k, neighbors,
451  dist2);
452  //}
453 
454  // check if closer neighbor could be in other child
455  if (neighbors->size() < k || (splitDist * splitDist < *dist2 &&
456  Intersect(p, *dist2, fChild->_box.Min(), fChild->_box.Max())))
457  {
458  Range(cell, range, fartherChild, &childRange);
459  NearestNeighborsL(*fChild, childRange, p, k, neighbors,
460  dist2);
461  }
462  }
463 
464  template< class Strategies >
465  template< class ContainerT >
467  const CellType& cell, CellRange range, const AABox< PointType >& box,
468  const PointType& p, unsigned int k, ScalarType eps,
469  ContainerT* neighbors, ScalarType* sqrDist) const
470  {
471  if (IsLeaf(cell))
472  {
473  if (neighbors->size() + cell.Size() <= k)
474  {
475  for (HandleType i = range.first; i != range.second; ++i)
476  {
477  DereferencedType deref = Dereference(i);
478  PointType diff = at(deref);
479  diff -= p;
480  ScalarType d2 = diff * diff;
481  neighbors->push_back(NN(deref, d2));
482  }
483  std::sort(neighbors->begin(), neighbors->end());
484  *sqrDist = neighbors->back().sqrDist;
485  return;
486  }
487  // let's find nearest neighbors from points within the cell
488  for (HandleType i = range.first; i != range.second; ++i)
489  {
490  DereferencedType deref = Dereference(i);
491  PointType diff = at(deref);
492  diff -= p;
493  ScalarType d2 = diff * diff;
494  if (neighbors->size() < k || d2 <= *sqrDist)
495  {
496  SortedNearestNeighborInsert(NN(deref, d2), k, neighbors);
497  *sqrDist = neighbors->back().sqrDist;
498  }
499  }
500  return;
501  }
502  // descent into subtree containing p
503  unsigned int nearerChild, fartherChild;
504  if (cell.Split()(p) <= 0)
505  {
506  nearerChild = 0;
507  fartherChild = 1;
508  }
509  else
510  {
511  nearerChild = 1;
512  fartherChild = 0;
513  }
514  /*AABox< PointType > subBoxes[2];
515  box.Split(cell.Split().Axis(), cell.Split().Value(),
516  &subBoxes[0], &subBoxes[1]);*/
517 
518  CellRange childRange;
519  if (neighbors->size() < k || Intersect(cell[nearerChild]->Box(),
520  p, eps * (*sqrDist)))
521  {
522  Range(cell, range, nearerChild, &childRange);
523  ApproximateNearestNeighbors(*cell[nearerChild], childRange,
524  box/*subBoxes[nearerChild]*/, p, k, eps, neighbors, sqrDist);
525  }
526 
527  // check if closer neighbor could be in other child
528  if (neighbors->size() < k || Intersect(cell[fartherChild]->Box()/*subBoxes[fartherChild]*/,
529  p, eps * (*sqrDist)))
530  {
531  Range(cell, range, fartherChild, &childRange);
532  ApproximateNearestNeighbors(*cell[fartherChild], childRange,
533  box/*subBoxes[fartherChild]*/, p, k, eps, neighbors, sqrDist);
534  }
535  }
536 
537  template< class Strategies >
538  template< class ContainerT >
539  void KdTree< Strategies >::PointsInSphere(const CellType& cell,
540  const CellRange& range, const PointType& p, ScalarType sqrRadius,
541  ContainerT* points) const
542  {
543  if (IsLeaf(cell))
544  {
545  for (HandleType i = range.first; i < range.second; ++i)
546  {
547  DereferencedType deref = Dereference(i);
548  ScalarType sqrDist = p.SqrDistance(at(deref));
549  if (sqrDist <= sqrRadius)
550  {
551  points->push_back(NN(deref, sqrDist));
552  }
553  }
554  }
555  else
556  {
557  CellRange childRange;
558  if (Intersect(p, sqrRadius, cell[0]->_box.Min(),
559  cell[0]->_box.Max()))
560  {
561  Range(cell, range, 0, &childRange);
562  PointsInSphere(*(cell[0]), childRange, p, sqrRadius, points);
563  }
564  if (Intersect(p, sqrRadius, cell[1]->_box.Min(),
565  cell[1]->_box.Max()))
566  {
567  Range(cell, range, 1, &childRange);
568  PointsInSphere(*(cell[1]), childRange, p, sqrRadius, points);
569  }
570  }
571  }
572 
573  template< class Strategies >
575  const CellRange range, const PointType& p, DereferencedType* d) const
576  {
577  if (IsLeaf(cell))
578  {
579  for (HandleType i = range.first; i < range.second; ++i)
580  {
581  DereferencedType deref = Dereference(i);
582  if (p == at(deref))
583  {
584  *d = deref;
585  return true;
586  }
587  }
588  return false;
589  }
590  // descent into subtree containing p
591  unsigned int nearerChild = cell.Split()(p) <= 0 ? 0 : 1;
592  CellRange childRange;
593  Range(cell, range, nearerChild, &childRange);
594  return Contains(*cell[nearerChild], childRange, p, d);
595  }
596 
597  template< class Strategies >
598  void KdTree< Strategies >::Init(const CellRange& range, const CellType*,
599  CellType* cell)
600  {
601  PointType pmin, pmax;
602  pmax = pmin = at(Dereference(range.first));
603  for (HandleType i = range.first + 1; i != range.second; ++i)
604  {
605  const PointType p = at(Dereference(i));
606  for (unsigned int j = 0; j < Dim; ++j)
607  {
608  if (pmin[j] > p[j])
609  {
610  pmin[j] = p[j];
611  }
612  else if (pmax[j] < p[j])
613  {
614  pmax[j] = p[j];
615  }
616  }
617  }
618  cell->_box.Min() = pmin;
619  cell->_box.Max() = pmax;
620  }
621 };
GfxTL::KdTreeCell::operator[]
ThisType & operator[](unsigned int i)
Definition: KdTree.h:45
GfxTL::sqrt
VectorXD< D, T > sqrt(const VectorXD< D, T > &a)
Definition: VectorXD.h:662
visionx::armem::pointcloud::PointType
PointType
Definition: constants.h:78
GfxTL::NearestNeighbors
void NearestNeighbors(unsigned int k, const Point &p, const Points &points, size_t size, std::vector< NearestNeighbor< typename Points::size_type, typename Point::ScalarType > > *n)
Definition: NearestNeighbors.h:135
index
uint8_t index
Definition: EtherCATFrame.h:59
GfxTL::KdTree
Definition: KdTree.h:152
armarx::Contains
bool Contains(const ContainerType &container, const ElementType &searchElement)
Definition: algorithm.h:295
armarx::Split
std::vector< std::string > Split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
Definition: StringHelperTemplates.h:35
GfxTL::KdTreeCell::Child
void Child(unsigned int i, ThisType *cell)
Definition: KdTree.h:55
GfxTL::NN::sqrDist
ScalarType sqrDist
Definition: NearestNeighbor.h:12
GfxTL::FlatCopyVector::push_back
void push_back(const T &nn)
Definition: FlatCopyVector.h:178
GfxTL::LimitedHeap::MakeHeap
void MakeHeap()
Definition: LimitedHeap.h:78
GfxTL::NN
Definition: NearestNeighbor.h:8
GfxTL::SortedNearestNeighborInsert
void SortedNearestNeighborInsert(const NN &nn, unsigned int k, NNs *n)
Definition: NearestNeighbors.h:57
GfxTL::FlatCopyVector::size
size_t size() const
Definition: FlatCopyVector.h:112
GfxTL::KdTreeCell
Definition: KdTree.h:22
GfxTL::KdTreeCell::KdTreeCell
KdTreeCell()
Definition: KdTree.h:31
GfxTL::KdTree::ScalarType
ScalarTypeDeferer< value_type >::ScalarType ScalarType
Definition: KdTree.h:184
GfxTL::KdTree::Build
void Build()
Definition: KdTree.h:240
visionx::Point
Eigen::Vector3f Point
Definition: ObjectShapeClassification.h:69
GfxTL
Definition: AABox.h:8
GfxTL::KdTreeCell::~KdTreeCell
~KdTreeCell()
Definition: KdTree.h:36
GfxTL::KdTree::ApproximateNearestNeighbors
void ApproximateNearestNeighbors(const PointT &p, unsigned int k, EpsilonT epsilon, LimitedHeap< typename NNTypeHelper< PointT >::NNType, std::less< typename NNTypeHelper< PointT >::NNType >, ContainerT > *neighbors) const
Definition: KdTree.h:454
GfxTL::KdTree::DereferencedType
BaseType::DereferencedType DereferencedType
Definition: KdTree.h:183
GfxTL::LimitedHeap
Definition: LimitedHeap.h:14
GfxTL::FlatCopyVector::front
T & front()
Definition: FlatCopyVector.h:293
GfxTL::LimitedHeap::PushHeap
void PushHeap(const value_type &t)
Definition: LimitedHeap.h:110
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
GfxTL::LimitedHeap::Limit
void Limit(size_type limit)
Definition: LimitedHeap.h:51
GfxTL::FlatCopyVector::resize
void resize(size_t s)
Definition: FlatCopyVector.h:122
GfxTL::KdTree::Contains
bool Contains(const PointT &p, DereferencedType *dref) const
Definition: KdTree.h:475
GfxTL::AABox
Definition: AABox.h:18
armarx::split
std::vector< std::string > split(const std::string &source, const std::string &splitBy, bool trimElements=false, bool removeEmptyElements=false)
Definition: StringHelpers.cpp:36
GfxTL::KdTree::NearestNeighbors
void NearestNeighbors(const PointT &p, unsigned int k, LimitedHeapT *neighbors) const
Definition: KdTree.h:380