AAKdTree.hpp
Go to the documentation of this file.
1 
2 namespace GfxTL
3 {
4  //-- AAKdCell
5 
6  template< class Point, class Base >
8  {
9  memset(_children, 0, sizeof(_children));
10  };
11 
12  template< class Point, class Base >
14  : _axis(cell._axis)
15  , _splitValue(cell._splitValue)
16  {
17  if (cell._children[0])
18  {
19  _children[0] = new AAKdCell< Point, Base >(*cell._children[0]);
20  }
21  else
22  {
23  _children[0] = NULL;
24  }
25  if (cell._children[1])
26  {
27  _children[1] = new AAKdCell< Point, Base >(*cell._children[1]);
28  }
29  else
30  {
31  _children[1] = NULL;
32  }
33  }
34 
35  template< class Point, class Base >
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 Point, class Base >
48  {
49  return _children[index];
50  }
51 
52  template< class Point, class Base >
55  {
56  return _children[index];
57  }
58 
59  template< class Point, class Base >
60  void AAKdCell< Point, Base >::Child(unsigned int index, ThisType* child)
61  {
62  _children[index] = child;
63  }
64 
65  template< class Point, class Base >
68  {
69  return _splitValue;
70  }
71 
72  template< class Point, class Base >
74  {
75  _splitValue = split;
76  }
77 
78  template< class Point, class Base >
79  unsigned int AAKdCell< Point, Base >::Axis() const
80  {
81  return _axis;
82  }
83 
84  template< class Point, class Base >
85  void AAKdCell< Point, Base >::Axis(unsigned int axis)
86  {
87  _axis = axis;
88  }
89 
90  //-- AAKdTree
91 
92  template< class Strategies >
94  {
95  Clear();
96 
97  CellType* root = new CellType;
98  RootCellData(AACube< PointType >(), root); // implemented by TreeData
99  Root(root);
100 
101  std::list< CellType* > stack;
102  stack.push_back(root);
103  while (stack.size())
104  {
105  CellType* c = stack.back();
106  stack.pop_back();
107  if (ShouldSubdivide(c))
108  {
109  Subdivide(c);
110  if (IsLeaf(*c)) // couldn't subdivide?
111  {
112  continue;
113  }
114  for (unsigned int i = 0; i < CellType::NChildren; ++i)
115  {
116  stack.push_back((*c)[i]);
117  }
118  }
119  }
120  };
121 
122  template< class Strategies >
124  ScalarType radius, std::vector< size_t >* points) const
125  {
126  points->clear();
127  if (!Root())
128  {
129  return;
130  }
131  PointsInSphere(Root(), center, radius, points);
132  };
133 
134  template< class Strategies >
137  std::vector< size_t >* points) const
138  {
139  points->clear();
140  if (!Root())
141  {
142  return;
143  }
144  PointType center;
145  cube.Center(&center);
146  PointsInAACube(Root(), center, cube.Width() / 2, points);
147  }
148 
149  template< class Strategies >
151  ScalarType width, std::vector< size_t >* points) const
152  {
153  points->clear();
154  if (!Root())
155  {
156  return;
157  }
158  PointsInAACube(Root(), center, width / 2, points);
159  }
160 
161  template< class Strategies >
164  {
165  // iterate over all cells and readjust cell data
166  CellType* c = Root();
167  if (!c)
168  {
169  c = new CellType;
170  Root(c);
171  }
172  RootCellData(AACube< PointType >(), c);
173  std::list< CellType* > stack;
174  stack.push_back(c);
175  while (stack.size())
176  {
177  c = stack.back();
178  stack.pop_back();
179  if (!IsLeaf(c))
180  {
181  if (!ShouldSubdivide(c))
182  {
183  for (unsigned int i = 0; i < CellType::NChildren; ++i)
184  {
185  delete (*c)[i];
186  c->Child(i, NULL);
187  }
188  }
189  else
190  {
191  ReadjustData(c);
192  for (unsigned int i = 0; i < CellType::NChildren; ++i)
193  {
194  stack.push_back((*c)[i]);
195  }
196  }
197  }
198  else if (ShouldSubdivide(c))
199  {
200  Subdivide(c);
201  for (unsigned int i = 0; i < CellType::NChildren; ++i)
202  {
203  stack.push_back((*c)[i]);
204  }
205  }
206  }
207  StrategyBaseType::RefreshWithNewTreeData(bc);
208  }
209 
210  template< class Strategies >
212  size_t* neighbor, ScalarType* dist) const
213  {
214  *dist = std::numeric_limits< ScalarType >::infinity();
215  if (!Root())
216  {
217  return;
218  }
219  AABox< PointType > rootBox;
220  rootBox.Infinite();
221  NearestNeighbor(*Root(), rootBox, p, neighbor, dist);
222  if (*dist < std::numeric_limits< ScalarType >::infinity())
223  {
224  *dist = std::sqrt(*dist);
225  }
226  }
227 
228  template< class Strategies >
230  unsigned int k, std::vector< NN >* neighbors,
231  ScalarType* dist) const
232  {
233  *dist = std::numeric_limits< ScalarType >::infinity();
234  if (!Root())
235  {
236  return;
237  }
238  size_t worstIdx = 0;
239  AABox< PointType > rootBox;
240  rootBox.Infinite();
241  neighbors->clear();
242  neighbors->reserve(k + 1);
243  KNearestNeighbors(*Root(), rootBox, p, k, neighbors, &worstIdx, dist);
244  if (*dist < std::numeric_limits< ScalarType >::infinity())
245  {
246  *dist = std::sqrt(*dist);
247  }
248  }
249 
250  template< class Strategies >
251  void AAKdTree< Strategies >::NearestNeighbor(const CellType& cell,
252  const AABox< PointType >& box, const PointType& p,
253  size_t* neighbor, ScalarType* dist2) const
254  {
255  if (IsLeaf(cell))
256  {
257  // let's find nearest neighbor from points within the cell
258  for (size_t i = 0; i < cell.Size(); ++i)
259  {
260  size_t idx = Translate(cell.Points() + i);
261  PointType diff = PointTranslated(idx) - p;
262  ScalarType d2 = diff * diff;
263  if (d2 < *dist2)
264  {
265  *dist2 = d2;
266  *neighbor = idx;
267  }
268  }
269  return;
270  }
271  // descent into subtree containing p
272  unsigned int nearerChild, fartherChild;
273  if (p[cell.Axis()] <= cell.Split())
274  {
275  nearerChild = 0;
276  fartherChild = 1;
277  }
278  else
279  {
280  nearerChild = 1;
281  fartherChild = 0;
282  }
283  AABox< PointType > subBoxes[2];
284  box.Split(cell.Axis(), cell.Split(), &subBoxes[0], &subBoxes[1]);
285  NearestNeighbor(*cell[nearerChild], subBoxes[nearerChild],
286  p, neighbor, dist2);
287 
288  // check if closer neighbor could be in other child
289  if (Intersect(subBoxes[fartherChild], p, *dist2))
290  NearestNeighbor(*cell[fartherChild], subBoxes[fartherChild],
291  p, neighbor, dist2);
292  }
293 
294  template< class Strategies >
295  void AAKdTree< Strategies >::KNearestNeighbors(const CellType& cell,
296  const AABox< PointType >& box, const PointType& p, unsigned int k,
297  std::vector< NN >* neighbors, size_t* worstIdx,
298  ScalarType* dist2) const
299  {
300  if (IsLeaf(cell))
301  {
302  // let's find nearest neighbors from points within the cell
303  for (size_t i = 0; i < cell.Size(); ++i)
304  {
305  size_t idx = Translate(cell.Points() + i);
306  PointType diff = PointTranslated(idx) - p;
307  ScalarType d2 = diff * diff;
308  if (neighbors->size() < k)
309  {
310  neighbors->push_back(NN(idx, d2));
311  FindFurthestNearestNeighbor(*neighbors, neighbors->size(),
312  worstIdx, dist2);
313  }
314  else if (d2 < *dist2)
315  {
316  (*neighbors)[*worstIdx] = NN(idx, d2);
317  FindFurthestNearestNeighbor(*neighbors, neighbors->size(),
318  worstIdx, dist2);
319  }
320  }
321  return;
322  }
323  // descent into subtree containing p
324  unsigned int nearerChild, fartherChild;
325  if (p[cell.Axis()] <= cell.Split())
326  {
327  nearerChild = 0;
328  fartherChild = 1;
329  }
330  else
331  {
332  nearerChild = 1;
333  fartherChild = 0;
334  }
335  AABox< PointType > subBoxes[2];
336  box.Split(cell.Axis(), cell.Split(), &subBoxes[0], &subBoxes[1]);
337 
338  KNearestNeighbors(*cell[nearerChild], subBoxes[nearerChild], p, k,
339  neighbors, worstIdx, dist2);
340 
341  // check if closer neighbor could be in other child
342  if (neighbors->size() < k || Intersect(subBoxes[fartherChild],
343  p, *dist2))
344  KNearestNeighbors(*cell[fartherChild], subBoxes[fartherChild],
345  p, k, neighbors, worstIdx, dist2);
346  }
347 
348  template< class Strategies >
349  void AAKdTree< Strategies >::ReadjustData(CellType* cell)
350  {
351  if (!cell->Size())
352  {
353  return;
354  }
355  PointType pmin, pmax;
356  pmax = pmin = PointTranslated(Translate(cell->Points()));
357  for (size_t i = 1; i < cell->Size(); ++i)
358  {
359  const PointType& p =
360  PointTranslated(Translate(cell->Points() + i));
361  for (unsigned int j = 0; j < Dim; ++j)
362  {
363  if (pmin[j] > p[j])
364  {
365  pmin[j] = p[j];
366  }
367  else if (pmax[j] < p[j])
368  {
369  pmax[j] = p[j];
370  }
371  }
372  }
373 
374  PointType pdiff = pmax - pmin;
375  unsigned int axis = 0;
376  ScalarType length = pdiff[0];
377  for (unsigned int j = 1; j < Dim; ++j)
378  {
379  if (pdiff[j] > length)
380  {
381  axis = j;
382  length = pdiff[j];
383  }
384  }
385 
386  ScalarType split = (pmax[axis] + pmin[axis]) / 2;
387 
388  CellType* left = (*cell)[0],
389  *right = (*cell)[1];
390  SplitAlongAxis(*cell, axis, split, left, right); // implemented by TreeData
391  cell->Split(split);
392  cell->Axis(axis);
393  }
394 
395  template< class Strategies >
396  void AAKdTree< Strategies >::PointsInSphere(const CellType* cell,
397  const PointType& center, ScalarType radius,
398  std::vector< size_t >* points) const
399  {
400  if (IsLeaf(cell))
401  {
402  ScalarType radius2 = radius * radius;
403  for (size_t i = 0; i < cell->Size(); ++i)
404  {
405  size_t ind = Translate(cell->Points() + i);
406  const PointType& p = PointTranslated(ind);
407  PointType d = p - center;
408  if ((d * d) <= radius2)
409  {
410  points->push_back(ind);
411  }
412  }
413  }
414  else
415  {
416  ScalarType d = center[cell->Axis()] - cell->Split();
417  if (d + radius >= 0)
418  {
419  PointsInSphere((*cell)[1], center, radius, points);
420  }
421  if (d - radius <= 0)
422  {
423  PointsInSphere((*cell)[0], center, radius, points);
424  }
425  }
426  }
427 
428  template< class Strategies >
429  void AAKdTree< Strategies >::PointsInAACube(const CellType* cell,
430  const PointType& center, ScalarType radius,
431  std::vector< HandleType >* points) const
432  {
433  if (IsLeaf(cell))
434  {
435  for (size_t i = 0; i < cell->Size(); ++i)
436  {
437  size_t ind = Translate(cell->Points() + i);
438  const PointType& p = PointTranslated(ind);
439  PointType d = p - center;
440  bool isInside = true;
441  for (unsigned int j = 0; j < PointType::Dim; ++j)
442  {
443  if (Absolute(d[j]) > radius)
444  {
445  isInside = false;
446  break;
447  }
448  }
449  if (isInside)
450  {
451  points->push_back(ind);
452  }
453  }
454  }
455  else
456  {
457  ScalarType d = center[cell->Axis()] - cell->Split();
458  if (d + radius >= 0)
459  {
460  PointsInAACube((*cell)[1], center, radius, points);
461  }
462  if (d - radius <= 0)
463  {
464  PointsInAACube((*cell)[0], center, radius, points);
465  }
466  }
467  }
468 
469  template< class Strategies >
470  bool AAKdTree< Strategies >::ShouldSubdivide(const CellType* cell) const
471  {
472  if (cell->Size() > 10)
473  {
474  return true;
475  }
476  return false;
477  }
478 
479  template< class Strategies >
480  void AAKdTree< Strategies >::Subdivide(CellType* cell)
481  {
482  PointType pmin, pmax;
483  pmax = pmin = PointTranslated(Translate(cell->Points()));
484  for (size_t i = 1; i < cell->Size(); ++i)
485  {
486  const PointType& p =
487  PointTranslated(Translate(cell->Points() + i));
488  for (unsigned int j = 0; j < Dim; ++j)
489  {
490  if (pmin[j] > p[j])
491  {
492  pmin[j] = p[j];
493  }
494  else if (pmax[j] < p[j])
495  {
496  pmax[j] = p[j];
497  }
498  }
499  }
500 
501  PointType pdiff = pmax - pmin;
502  unsigned int axis = 0;
503  ScalarType length = pdiff[0];
504  for (unsigned int j = 1; j < Dim; ++j)
505  {
506  if (pdiff[j] > length)
507  {
508  axis = j;
509  length = pdiff[j];
510  }
511  }
512 
513  ScalarType split = (pmax[axis] + pmin[axis]) / 2;
514 
515  CellType* left, *right;
516  left = new CellType;
517  right = new CellType;
518  SplitAlongAxis(*cell, axis, split, left, right); // implemented by TreeData
519 
520  if (left->Size() == cell->Size() || right->Size() == cell->Size())
521  {
522  delete left;
523  delete right;
524  return;
525  }
526  cell->Split(split);
527  cell->Axis(axis);
528  cell->Child(0, left);
529  cell->Child(1, right);
530  }
531 
532  template< class Strategies >
534  AAKdTree< Strategies >::Absolute(ScalarType f) const
535  {
536  if (f < 0)
537  {
538  return -f;
539  }
540  return f;
541  }
542 
543 };
GfxTL::AAKdTree::Build
void Build()
Definition: AAKdTree.hpp:93
GfxTL::sqrt
VectorXD< D, T > sqrt(const VectorXD< D, T > &a)
Definition: VectorXD.h:662
GfxTL::AACube
Definition: AACube.h:11
visionx::armem::pointcloud::PointType
PointType
Definition: constants.h:78
index
uint8_t index
Definition: EtherCATFrame.h:59
c
constexpr T c
Definition: UnscentedKalmanFilterTest.cpp:43
GfxTL::AACube::Center
void Center(Point *c) const
Definition: AACube.hpp:53
GfxTL::AAKdCell
Definition: AAKdTree.h:16
GfxTL::AABox::Split
void Split(unsigned int axis, ScalarType s, AABox< Point > *left, AABox< Point > *right) const
Definition: AABox.hpp:21
GfxTL::AAKdTree::KNearestNeighbors
void KNearestNeighbors(const PointType &p, unsigned int k, std::vector< NN > *neighbors, ScalarType *dist) const
Definition: AAKdTree.hpp:229
armarx::navigation::core::NavigationFrame::Absolute
@ Absolute
GfxTL::AABox::Infinite
void Infinite()
Definition: AABox.hpp:11
Point
Definition: PointCloud.h:21
GfxTL::AAKdCell::ScalarType
Point::ScalarType ScalarType
Definition: AAKdTree.h:23
GfxTL
Definition: AABox.h:8
GfxTL::AAKdCell::AAKdCell
AAKdCell()
Definition: AAKdTree.hpp:7
GfxTL::AAKdCell::Split
ScalarType Split() const
Definition: AAKdTree.hpp:67
GfxTL::AAKdTree::ScalarType
CellType::ScalarType ScalarType
Definition: AAKdTree.h:70
GfxTL::FindFurthestNearestNeighbor
void FindFurthestNearestNeighbor(const NNs &n, size_t size, size_t *worst, ScalarType *worstDist)
Definition: NearestNeighbors.h:117
GfxTL::NearestNeighbor
Definition: NearestNeighbors.h:9
GfxTL::AAKdTree::RefreshWithNewTreeData
void RefreshWithNewTreeData(const AACube< PointType > &bc)
Definition: AAKdTree.hpp:163
GfxTL::AAKdCell::Child
void Child(unsigned int index, ThisType *child)
Definition: AAKdTree.hpp:60
GfxTL::AAKdTree::PointsInSphere
void PointsInSphere(const PointType &center, ScalarType radius, std::vector< size_t > *points) const
Definition: AAKdTree.hpp:123
GfxTL::AAKdCell::operator[]
const ThisType * operator[](unsigned int index) const
Definition: AAKdTree.hpp:47
GfxTL::AACube::Width
ScalarType Width() const
Definition: AACube.hpp:131
GfxTL::AAKdCell::Axis
unsigned int Axis() const
Definition: AAKdTree.hpp:79
GfxTL::AAKdTree::NearestNeighbor
void NearestNeighbor(const PointType &p, size_t *neighbor, ScalarType *dist) const
Definition: AAKdTree.hpp:211
GfxTL::AAKdCell::~AAKdCell
~AAKdCell()
Definition: AAKdTree.hpp:36
GfxTL::AABox
Definition: AABox.h:18
GfxTL::AAKdTree::PointsInAACube
void PointsInAACube(const AACube< PointType > &cube, std::vector< size_t > *points) const
Definition: AAKdTree.hpp:136
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