4 template <
class ValueT,
class BaseT>
7 memset(&_children, NULL,
sizeof(_children));
10 template <
class ValueT,
class BaseT>
12 BaseT(cell), _split(cell._split), _box(cell._box)
14 if (cell._children[0])
16 _children[0] =
new KdTreeCell<ValueT, BaseT>(*cell._children[0]);
22 if (cell._children[1])
24 _children[1] =
new KdTreeCell<ValueT, BaseT>(*cell._children[1]);
32 template <
class ValueT,
class BaseT>
35 for (
unsigned int i = 0; i < 2; ++i)
42 template <
class ValueT,
class BaseT>
43 const KdTreeCell<ValueT, BaseT>*
46 return _children[
index];
49 template <
class ValueT,
class BaseT>
50 KdTreeCell<ValueT, BaseT>*
53 return _children[
index];
56 template <
class ValueT,
class BaseT>
60 _children[
index] = child;
63 template <
class ValueT,
class BaseT>
64 const typename KdTreeCell<ValueT, BaseT>::SplitterType&
70 template <
class ValueT,
class BaseT>
71 const typename KdTreeCell<ValueT, BaseT>::BoxType&
72 KdTreeCell<ValueT, BaseT>::Box()
const
77 template <
class Strategies>
83 CellType* root =
new CellType;
86 root->_box.Infinite();
88 Init(range, NULL, root);
90 typedef std::pair<CellType*, CellRange> Pair;
91 std::deque<Pair> stack;
92 stack.push_back(Pair(root, range));
95 Pair p = stack.back();
97 if (ShouldSubdivide(p.second))
99 Subdivide(p.first, p.second);
100 if (IsLeaf(*p.first))
104 for (
unsigned int i = 0; i < CellType::NChildren; ++i)
106 Range(*p.first, p.second, i, &range);
108 stack.push_back(Pair((*p.first)[i], range));
114 template <
class Strategies>
116 KdTree<Strategies>::Insert(DereferencedType
s)
118 CellType* cell = Root();
125 Init(range, NULL, cell);
127 Insert(cell, range,
s);
130 template <
class Strategies>
131 template <
class ContainerT>
135 ContainerT* neighbors,
138 *dist = std::numeric_limits<ScalarType>::infinity();
139 neighbors->resize(0);
148 neighbors->reserve(k + 1);
150 if (*dist < std::numeric_limits<ScalarType>::infinity())
156 template <
class Strategies>
157 template <
template <
class>
class ContainerT>
162 ScalarType* dist)
const
164 *dist = std::numeric_limits<ScalarType>::infinity();
173 NearestNeighborsL(*Root(), range, p, k, neighbors, dist);
180 template <
class Strategies>
181 template <
class ContainerT>
186 ContainerT* neighbors,
189 *sqrDist = std::numeric_limits<ScalarType>::infinity();
190 neighbors->resize(0);
199 neighbors->reserve(k + 1);
201 ApproximateNearestNeighbors(*Root(), range, rootBox, p, k, eps * eps, neighbors, sqrDist);
206 template <
class Strategies>
207 template <
class ContainerT>
210 ScalarType sqrRadius,
211 ContainerT* points)
const
220 PointsInSphere(*Root(), range, p, sqrRadius, points);
223 template <
class Strategies>
233 return Contains(*Root(), range, p, d);
236 template <
class Strategies>
240 return range.second - range.first > 10;
243 template <
class Strategies>
245 KdTree<Strategies>::Subdivide(CellType* cell, CellRange range)
247 PointType pmin = cell->_box.Min(), pmax = cell->_box.Max();
262 unsigned int axis = 0;
263 ScalarType length = pdiff[0];
264 for (
unsigned int j = 1; j < Dim; ++j)
266 if (pdiff[j] > length)
273 ScalarType
split = (pmax[axis] + pmin[axis]) / 2;
275 cell->_split.Set(axis,
split);
277 CellType *left, *right;
279 right =
new CellType;
280 Split(cell->_split, range, left, right);
281 if (left->Size() == cell->Size() || right->Size() == cell->Size())
289 cell->Child(0, left);
290 cell->Child(1, right);
291 CellRange childRange;
292 Range(*cell, range, 0, &childRange);
293 Init(childRange, cell, left);
294 Range(*cell, range, 1, &childRange);
295 Init(childRange, cell, right);
298 (right->Box().Min()[cell->_split.Axis()] + left->Box().Max()[cell->_split.Axis()]) / 2);
301 template <
class Strategies>
303 KdTree<Strategies>::Insert(CellType* cell, CellRange range, DereferencedType
s)
308 BaseType::Insert(range,
s);
309 if (ShouldSubdivide(range))
311 Subdivide(cell, range);
316 BaseType::SplitAndInsert(cell->Split(), range,
s, (*cell)[0], (*cell)[1], &left);
320 Range(*cell, range, 0, &lr);
321 Insert((*cell)[0], lr,
s);
326 Range(*cell, range, 1, &rr);
327 Insert((*cell)[1], rr,
s);
331 template <
class Strategies>
332 template <
class ContainerT>
339 ContainerT* neighbors,
344 HandleType i = range.first, iend = range.second;
345 if (neighbors->size() + cell.Size() <= k)
347 for (; i != iend; ++i)
353 neighbors->push_back(
NN(deref, d2));
355 std::sort(neighbors->begin(), neighbors->end());
356 *dist2 = neighbors->back().sqrDist;
360 for (; i != iend; ++i)
366 if (neighbors->size() < k || d2 <= *dist2)
369 *dist2 = neighbors->back().sqrDist;
375 unsigned int nearerChild, fartherChild;
376 if (cell.Split()(p) <= 0)
390 CellRange childRange;
391 if (neighbors->size() < k || Intersect(cell[nearerChild]->Box(), p, *dist2))
393 Range(cell, range, nearerChild, &childRange);
404 if (neighbors->size() < k ||
405 Intersect(cell[fartherChild]->Box() , p, *dist2))
407 Range(cell, range, fartherChild, &childRange);
418 template <
class Strategies>
419 template <
template <
class>
class ContainerT>
422 const CellRange& range,
426 ScalarType* dist2)
const
430 HandleType i = range.first, iend = range.second;
431 DereferencedType deref;
432 if (neighbors->
size() + cell.Size() <= k)
434 for (; i != iend; ++i)
436 deref = Dereference(i);
444 for (; i != iend; ++i)
446 deref = Dereference(i);
447 neighbors->
PushHeap(NN(deref, p.SqrDistance(at(deref).
Point())));
453 unsigned int nearerChild, fartherChild;
454 const CellType *nChild, *fChild;
455 ScalarType splitDist = cell._split(p);
471 CellRange childRange;
475 Range(cell, range, nearerChild, &childRange);
476 NearestNeighborsL(*nChild, childRange, p, k, neighbors, dist2);
480 if (neighbors->
size() < k || (splitDist * splitDist < *dist2 &&
481 Intersect(p, *dist2, fChild->_box.Min(), fChild->_box.Max())))
483 Range(cell, range, fartherChild, &childRange);
484 NearestNeighborsL(*fChild, childRange, p, k, neighbors, dist2);
488 template <
class Strategies>
489 template <
class ContainerT>
497 ContainerT* neighbors,
502 if (neighbors->size() + cell.Size() <= k)
504 for (HandleType i = range.first; i != range.second; ++i)
510 neighbors->push_back(
NN(deref, d2));
512 std::sort(neighbors->begin(), neighbors->end());
513 *sqrDist = neighbors->back().sqrDist;
517 for (HandleType i = range.first; i != range.second; ++i)
523 if (neighbors->size() < k || d2 <= *sqrDist)
526 *sqrDist = neighbors->back().sqrDist;
532 unsigned int nearerChild, fartherChild;
533 if (cell.Split()(p) <= 0)
547 CellRange childRange;
548 if (neighbors->size() < k || Intersect(cell[nearerChild]->Box(), p, eps * (*sqrDist)))
550 Range(cell, range, nearerChild, &childRange);
551 ApproximateNearestNeighbors(*cell[nearerChild],
562 if (neighbors->size() < k ||
563 Intersect(cell[fartherChild]->Box() , p, eps * (*sqrDist)))
565 Range(cell, range, fartherChild, &childRange);
566 ApproximateNearestNeighbors(*cell[fartherChild],
577 template <
class Strategies>
578 template <
class ContainerT>
581 const CellRange& range,
583 ScalarType sqrRadius,
584 ContainerT* points)
const
588 for (HandleType i = range.first; i < range.second; ++i)
590 DereferencedType deref = Dereference(i);
591 ScalarType sqrDist = p.SqrDistance(at(deref));
592 if (sqrDist <= sqrRadius)
594 points->push_back(
NN(deref, sqrDist));
600 CellRange childRange;
601 if (Intersect(p, sqrRadius, cell[0]->_box.Min(), cell[0]->_box.Max()))
603 Range(cell, range, 0, &childRange);
604 PointsInSphere(*(cell[0]), childRange, p, sqrRadius, points);
606 if (Intersect(p, sqrRadius, cell[1]->_box.Min(), cell[1]->_box.Max()))
608 Range(cell, range, 1, &childRange);
609 PointsInSphere(*(cell[1]), childRange, p, sqrRadius, points);
614 template <
class Strategies>
617 const CellRange range,
623 for (HandleType i = range.first; i < range.second; ++i)
635 unsigned int nearerChild = cell.Split()(p) <= 0 ? 0 : 1;
636 CellRange childRange;
637 Range(cell, range, nearerChild, &childRange);
638 return Contains(*cell[nearerChild], childRange, p, d);
641 template <
class Strategies>
646 pmax = pmin = at(Dereference(range.first));
647 for (HandleType i = range.first + 1; i != range.second; ++i)
650 for (
unsigned int j = 0; j < Dim; ++j)
656 else if (pmax[j] < p[j])
662 cell->_box.Min() = pmin;
663 cell->_box.Max() = pmax;