4 template<
class ValueT,
class BaseT >
7 memset(&_children, NULL,
sizeof(_children));
10 template<
class ValueT,
class BaseT >
12 const KdTreeCell< ValueT, BaseT >& cell)
17 if (cell._children[0])
19 _children[0] =
new KdTreeCell< ValueT, BaseT >(*cell._children[0]);
25 if (cell._children[1])
27 _children[1] =
new KdTreeCell< ValueT, BaseT >(*cell._children[1]);
35 template<
class ValueT,
class BaseT >
38 for (
unsigned int i = 0; i < 2; ++i)
45 template<
class ValueT,
class BaseT >
47 unsigned int index)
const
49 return _children[
index];
52 template<
class ValueT,
class BaseT >
56 return _children[
index];
59 template<
class ValueT,
class BaseT >
63 _children[
index] = child;
66 template<
class ValueT,
class BaseT >
67 const typename KdTreeCell< ValueT, BaseT >::SplitterType&
73 template<
class ValueT,
class BaseT >
74 const typename KdTreeCell< ValueT, BaseT >::BoxType&
75 KdTreeCell< ValueT, BaseT >::Box()
const
80 template<
class Strategies >
85 CellType* root =
new CellType;
88 root->_box.Infinite();
90 Init(range, NULL, root);
92 typedef std::pair< CellType*, CellRange > Pair;
93 std::deque< Pair > stack;
94 stack.push_back(Pair(root, range));
97 Pair p = stack.back();
99 if (ShouldSubdivide(p.second))
101 Subdivide(p.first, p.second);
102 if (IsLeaf(*p.first))
106 for (
unsigned int i = 0; i < CellType::NChildren; ++i)
108 Range(*p.first, p.second, i, &range);
110 stack.push_back(Pair((*p.first)[i], range));
116 template<
class Strategies >
117 void KdTree< Strategies >::Insert(DereferencedType
s)
119 CellType* cell = Root();
126 Init(range, NULL, cell);
128 Insert(cell, range,
s);
131 template<
class Strategies >
132 template<
class ContainerT >
134 unsigned int k, ContainerT* neighbors,
ScalarType* dist)
const
136 *dist = std::numeric_limits< ScalarType >::infinity();
137 neighbors->resize(0);
146 neighbors->reserve(k + 1);
148 if (*dist < std::numeric_limits< ScalarType >::infinity())
154 template<
class Strategies >
155 template<
template<
class >
class ContainerT >
159 *dist = std::numeric_limits< ScalarType >::infinity();
168 NearestNeighborsL(*Root(), range, p, k, neighbors, dist);
175 template<
class Strategies >
176 template<
class ContainerT >
179 ContainerT* neighbors,
ScalarType* sqrDist)
const
181 *sqrDist = std::numeric_limits< ScalarType >::infinity();
182 neighbors->resize(0);
191 neighbors->reserve(k + 1);
193 ApproximateNearestNeighbors(*Root(), range, rootBox, p, k, eps * eps,
199 template<
class Strategies >
200 template<
class ContainerT >
202 ScalarType sqrRadius, ContainerT* points)
const
211 PointsInSphere(*Root(), range, p, sqrRadius, points);
214 template<
class Strategies >
224 return Contains(*Root(), range, p, d);
227 template<
class Strategies >
230 return range.second - range.first > 10;
233 template<
class Strategies >
234 void KdTree< Strategies >::Subdivide(CellType* cell, CellRange range)
236 PointType pmin = cell->_box.Min(), pmax = cell->_box.Max();
251 unsigned int axis = 0;
252 ScalarType length = pdiff[0];
253 for (
unsigned int j = 1; j < Dim; ++j)
255 if (pdiff[j] > length)
262 ScalarType
split = (pmax[axis] + pmin[axis]) / 2;
264 cell->_split.Set(axis,
split);
266 CellType* left, *right;
268 right =
new CellType;
269 Split(cell->_split, range, left, right);
270 if (left->Size() == cell->Size() || right->Size() == cell->Size())
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);
286 cell->_split.Value((right->Box().Min()[cell->_split.Axis()]
287 + left->Box().Max()[cell->_split.Axis()]) / 2);
290 template<
class Strategies >
291 void KdTree< Strategies >::Insert(CellType* cell, CellRange range,
297 BaseType::Insert(range,
s);
298 if (ShouldSubdivide(range))
300 Subdivide(cell, range);
305 BaseType::SplitAndInsert(cell->Split(), range,
s, (*cell)[0],
310 Range(*cell, range, 0, &lr);
311 Insert((*cell)[0], lr,
s);
316 Range(*cell, range, 1, &rr);
317 Insert((*cell)[1], rr,
s);
321 template<
class Strategies >
322 template<
class ContainerT >
325 unsigned int k, ContainerT* neighbors,
ScalarType* dist2)
const
329 HandleType i = range.first, iend = range.second;
330 if (neighbors->size() + cell.Size() <= k)
332 for (; i != iend; ++i)
338 neighbors->push_back(
NN(deref, d2));
340 std::sort(neighbors->begin(), neighbors->end());
341 *dist2 = neighbors->back().sqrDist;
345 for (; i != iend; ++i)
351 if (neighbors->size() < k || d2 <= *dist2)
354 *dist2 = neighbors->back().sqrDist;
360 unsigned int nearerChild, fartherChild;
361 if (cell.Split()(p) <= 0)
375 CellRange childRange;
376 if (neighbors->size() < k || Intersect(cell[nearerChild]->Box(),
379 Range(cell, range, nearerChild, &childRange);
381 box, p, k, neighbors, dist2);
385 if (neighbors->size() < k || Intersect(cell[fartherChild]->Box(),
388 Range(cell, range, fartherChild, &childRange);
390 box, p, k, neighbors, dist2);
394 template<
class Strategies >
395 template<
template<
class >
class ContainerT >
397 const CellRange& range,
const PointType& p,
unsigned int k,
402 HandleType i = range.first, iend = range.second;
403 DereferencedType deref;
404 if (neighbors->
size() + cell.Size() <= k)
406 for (; i != iend; ++i)
408 deref = Dereference(i);
410 p.SqrDistance(at(deref).
Point())));
417 for (; i != iend; ++i)
419 deref = Dereference(i);
421 p.SqrDistance(at(deref).
Point())));
427 unsigned int nearerChild, fartherChild;
428 const CellType* nChild, *fChild;
429 ScalarType splitDist = cell._split(p);
445 CellRange childRange;
449 Range(cell, range, nearerChild, &childRange);
450 NearestNeighborsL(*nChild, childRange, p, k, neighbors,
455 if (neighbors->
size() < k || (splitDist * splitDist < *dist2 &&
456 Intersect(p, *dist2, fChild->_box.Min(), fChild->_box.Max())))
458 Range(cell, range, fartherChild, &childRange);
459 NearestNeighborsL(*fChild, childRange, p, k, neighbors,
464 template<
class Strategies >
465 template<
class ContainerT >
469 ContainerT* neighbors,
ScalarType* sqrDist)
const
473 if (neighbors->size() + cell.Size() <= k)
475 for (HandleType i = range.first; i != range.second; ++i)
481 neighbors->push_back(
NN(deref, d2));
483 std::sort(neighbors->begin(), neighbors->end());
484 *sqrDist = neighbors->back().sqrDist;
488 for (HandleType i = range.first; i != range.second; ++i)
494 if (neighbors->size() < k || d2 <= *sqrDist)
497 *sqrDist = neighbors->back().sqrDist;
503 unsigned int nearerChild, fartherChild;
504 if (cell.Split()(p) <= 0)
518 CellRange childRange;
519 if (neighbors->size() < k || Intersect(cell[nearerChild]->Box(),
520 p, eps * (*sqrDist)))
522 Range(cell, range, nearerChild, &childRange);
523 ApproximateNearestNeighbors(*cell[nearerChild], childRange,
524 box, p, k, eps, neighbors, sqrDist);
528 if (neighbors->size() < k || Intersect(cell[fartherChild]->Box(),
529 p, eps * (*sqrDist)))
531 Range(cell, range, fartherChild, &childRange);
532 ApproximateNearestNeighbors(*cell[fartherChild], childRange,
533 box, p, k, eps, neighbors, sqrDist);
537 template<
class Strategies >
538 template<
class ContainerT >
540 const CellRange& range,
const PointType& p, ScalarType sqrRadius,
541 ContainerT* points)
const
545 for (HandleType i = range.first; i < range.second; ++i)
547 DereferencedType deref = Dereference(i);
548 ScalarType sqrDist = p.SqrDistance(at(deref));
549 if (sqrDist <= sqrRadius)
551 points->push_back(
NN(deref, sqrDist));
557 CellRange childRange;
558 if (Intersect(p, sqrRadius, cell[0]->_box.Min(),
559 cell[0]->_box.Max()))
561 Range(cell, range, 0, &childRange);
562 PointsInSphere(*(cell[0]), childRange, p, sqrRadius, points);
564 if (Intersect(p, sqrRadius, cell[1]->_box.Min(),
565 cell[1]->_box.Max()))
567 Range(cell, range, 1, &childRange);
568 PointsInSphere(*(cell[1]), childRange, p, sqrRadius, points);
573 template<
class Strategies >
579 for (HandleType i = range.first; i < range.second; ++i)
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);
597 template<
class Strategies >
602 pmax = pmin = at(Dereference(range.first));
603 for (HandleType i = range.first + 1; i != range.second; ++i)
606 for (
unsigned int j = 0; j < Dim; ++j)
612 else if (pmax[j] < p[j])
618 cell->_box.Min() = pmin;
619 cell->_box.Max() = pmax;