1 #ifndef GfxTL__KDTREE_HEADER__
2 #define GfxTL__KDTREE_HEADER__
22 template <
class BaseT>
37 m_children[0] = m_children[1] = NULL;
52 return *m_children[i];
58 return *m_children[i];
91 template <
class VectorT>
95 return v[m_splitAxis] <= m_splitValue;
109 unsigned int m_splitAxis;
114 template <
class DataStrategyT>
123 template <
class BaseT>
130 template <
class BuildInformationT>
137 template <
class BuildInformationT>
143 template <
class BuildInformationT>
149 template <
class TraversalInformationT>
156 template <
class TraversalBaseT>
158 public DataStrategyT::template
StrategyBase<BaseT>::template TraversalInformation<
165 template <
class StrategiesT,
170 public StrategiesT::template StrategyBase<
171 MetricT<VectorKernelT<BaseTree<KdTreeCell<typename StrategiesT::CellData>>>>>
175 typedef typename StrategiesT::template StrategyBase<
176 MetricT<VectorKernelT<BaseTree<KdTreeCell<typename StrategiesT::CellData>>>>>
188 return m_createChild;
194 return m_createChild;
198 unsigned int m_createChild;
201 template <
class Po
intT>
223 template <
class GlobalInfoT>
232 m_globalInfo = globalInfo;
238 return *m_globalInfo;
242 const GlobalInfoT* m_globalInfo;
248 typedef std::pair<CellType*, BuildInformation> Pair;
250 if (!BaseType::size())
255 std::deque<Pair> stack(1);
258 stack.back().first = BaseType::Root();
259 InitRootBuildInformation(&stack.back().second);
260 BaseType::InitRoot(stack.back().second, BaseType::Root());
263 Pair& p = stack.back();
266 BaseType::LeaveGlobalBuildInformation(*p.first, p.second);
270 if (BaseType::IsLeaf(*p.first))
272 if (!BaseType::ShouldSubdivide(*p.first, p.second))
277 Subdivide(p.second, p.first);
278 if (BaseType::IsLeaf(*p.first))
286 BaseType::LeaveGlobalBuildInformation(*p.first, p.second);
289 !this->ExistChild(*p.first, p.second.CreateChild()))
291 ++p.second.CreateChild();
298 BaseType::EnterGlobalBuildInformation(*p.first, &p.second);
299 stack.resize(stack.size() + 1);
300 stack.back().first = &(*p.first)[p.second.CreateChild()];
301 InitBuildInformation(
302 *p.first, p.second, p.second.CreateChild(), &stack.back().second);
305 p.second.CreateChild(),
307 &(*p.first)[p.second.CreateChild()]);
308 ++p.second.CreateChild();
315 typedef typename BaseType::template GlobalTraversalInformation<
319 typename BaseType::template TraversalInformation<
322 BaseType::InitRootTraversalInformation(*BaseType::Root(), &ti);
332 template <
class Po
intT,
class DistScalarT,
class ContainerT>
340 DistScalarT sqrRadius,
341 ContainerT* points)
const
343 typedef typename BaseType::template GlobalTraversalInformation<
347 typename BaseType::template TraversalInformation<
353 InitRootTraversalInformation(*BaseType::Root(), &ti);
357 template <
class Po
intT>
360 typedef typename BaseType::template GlobalTraversalInformation<
363 typedef typename BaseType::template TraversalInformation<
383 template <
class Po
intT>
390 template <
class Po
intT,
class DistScalarT,
class ContainerT>
393 DistScalarT sqrRadius,
398 PrivatePointsInBall(p, sqrRadius, points, auxData);
401 template <
class Po
intT,
class LimitedHeapT>
405 typedef typename BaseType::template GlobalTraversalInformation<
408 typedef typename BaseType::template TraversalInformation<
410 TraversalInformation;
416 TraversalInformation ti;
421 BaseType::InitRootTraversalInformation(*BaseType::Root(), &ti);
422 PrivateNearestNeighbors(*BaseType::Root(), ti, neighbors);
423 neighbors->AssertHeap();
426 template <
class Po
intT>
429 typedef typename BaseType::template GlobalTraversalInformation<
432 typedef typename BaseType::template TraversalInformation<
455 template <
class Po
intT>
462 template <
class Po
intT,
class LimitedHeapT>
466 LimitedHeapT* neighbors,
471 PrivateNearestNeighbors(p, auxData, neighbors);
472 neighbors->AssertHeap();
475 template <
class Po
intT>
478 typedef NN<
typename BaseType::template DistanceType<
481 typename BaseType::DereferencedType>
485 template <
class Po
intT,
class EpsilonT,
template <
class>
class ContainerT>
492 ContainerT>* neighbors)
const
494 typedef typename BaseType::template GlobalTraversalInformation<
498 typename BaseType::template TraversalInformation<
505 BaseType::InitRootTraversalInformation(*BaseType::Root(), &ti);
507 neighbors->AssertHeap();
510 template <
class Po
intT>
514 typedef typename BaseType::template GlobalTraversalInformation<
518 typename BaseType::template TraversalInformation<
523 BaseType::InitRootTraversalInformation(*BaseType::Root(), &ti);
524 return Contains(*BaseType::Root(), ti, dref);
529 InitRootBuildInformation(BuildInformation* bi)
531 bi->CreateChild() = 0;
532 BaseType::InitRootBuildInformation(bi);
536 InitBuildInformation(
const CellType& parent,
537 const BuildInformation& parentInfo,
538 unsigned int childIdx,
539 BuildInformation* bi)
541 bi->CreateChild() = 0;
542 BaseType::InitBuildInformation(parent, parentInfo, childIdx, bi);
545 template <
class BuildInformationT>
548 const BuildInformationT& parentInfo,
549 unsigned int childIdx,
550 const BuildInformationT& bi,
553 BaseType::InitCell(parent, parentInfo, childIdx, bi, cell);
556 template <
class TraversalInformationT>
558 InitTraversalInformation(
const CellType& parent,
559 const TraversalInformationT& pTi,
560 unsigned int childIdx,
561 TraversalInformationT* ti)
const
563 ti->Global(&pTi.Global());
564 BaseType::InitTraversalInformation(parent, pTi, childIdx, ti);
567 template <
class TraversalInformationT>
571 typename BaseType::CellRange range;
572 BaseType::GetCellRange(cell, ti, &range);
575 BaseType::InsertBack(range, &cell);
578 bool l = SplitAndInsert(cell, range, &(cell[0]), &(cell[1]));
579 TraversalInformationT cti;
582 UpdateCellWithBack(ti, &(cell[0]));
583 InitTraversalInformation(cell, ti, 0, &cti);
588 UpdateCellWithBack(ti, &(cell[1]));
589 InitTraversalInformation(cell, ti, 1, &cti);
599 BaseType::Remove(
s, &cell);
602 if (BaseType::Remove(cell,
s))
613 Subdivide(BuildInformation& bi,
CellType* cell)
615 BaseType::ComputeSplit(bi, cell);
621 BaseType::SplitData(*cell, *cell, bi, left, right);
622 if (left->Size() == cell->Size())
627 else if (right->Size() == cell->Size())
649 cell->Child(0, left);
650 cell->Child(1, right);
651 if (BaseType::IsLeaf(*cell))
653 cell->Child(0, BaseType::InnerNodeMarker());
657 template <
class TraversalInformationT,
class DistScalarT,
class ContainerT>
661 const TraversalInformationT& ti,
662 ContainerT* points)
const
664 if (BaseType::IsLeaf(cell))
667 typename BaseType::CellRange range;
668 BaseType::GetCellRange(cell, ti, &range);
669 for (
typename BaseType::HandleType h = range.first; h != range.second; ++h)
672 BaseType::SqrDistance(ti.Global().Point(), at(BaseType::Dereference(h)));
675 typename ContainerT::value_type(d, BaseType::Dereference(h)));
679 TraversalInformationT cti;
681 if (BaseType::ExistChild(cell, 0))
683 InitTraversalInformation(cell, ti, 0, &cti);
684 if (BaseType::CellSqrDistance(cell[0], cti) <= sqrRadius)
690 if (BaseType::ExistChild(cell, 1))
692 InitTraversalInformation(cell, ti, 1, &cti);
693 if (BaseType::CellSqrDistance(cell[1], cti) <= sqrRadius)
700 template <
class Po
intT,
class DistScalarT,
class ContainerT>
702 PrivatePointsInBall(
const PointT& p,
703 DistScalarT sqrRadius,
705 PointsInBallAuxData<PointT>* auxData)
const
707 typedef PointsInBallAuxData<PointT> AuxDataType;
708 typedef typename AuxDataType::TraversalInfoType TraversalInfoType;
709 typedef typename TraversalInfoType::GlobalType GlobalInfoType;
710 typedef typename AuxDataType::value_type AuxDataValueType;
711 typedef typename AuxDataType::DistanceType DistanceType;
712 if (!BaseType::Root())
716 auxData->reserve(128);
718 TraversalInfoType ti;
721 BaseType::InitRootTraversalInformation(*BaseType::Root(), &ti);
722 const CellType* current = BaseType::Root();
725 if (BaseType::IsLeaf(*current))
727 typename BaseType::CellRange range;
728 BaseType::GetCellRange(*current, ti, &range);
729 typename BaseType::HandleType h = range.first;
731 for (; h != range.second; ++h)
733 typename ContainerT::value_type nn(
734 BaseType::SqrDistance(p, BaseType::at(BaseType::Dereference(h))),
735 BaseType::Dereference(h));
736 if (nn.sqrDist <= sqrRadius)
738 points->push_back(nn);
742 else if (!BaseType::ExistChild(*current, 0))
744 TraversalInfoType rti;
745 InitTraversalInformation(*current, ti, 1, &rti);
746 if (BaseType::CellSqrDistance(current[1], rti) <= sqrRadius)
748 current = &(*current)[1];
753 else if (!BaseType::ExistChild(*current, 1))
755 TraversalInfoType lti;
756 InitTraversalInformation(*current, ti, 0, <i);
757 if (BaseType::CellSqrDistance((*current)[0], lti) <= sqrRadius)
759 current = &(*current)[0];
766 TraversalInfoType lti, rti;
768 InitTraversalInformation(*current, ti, 0, <i);
769 InitTraversalInformation(*current, ti, 1, &rti);
771 dl = BaseType::CellSqrDistance((*current)[0], lti);
772 dr = BaseType::CellSqrDistance((*current)[1], rti);
777 auxData->push_back(AuxDataValueType(&(*current)[1], rti));
779 current = &(*current)[0];
783 else if (dr <= sqrRadius)
785 current = &(*current)[1];
791 if (!auxData->size())
795 current = auxData->back().m_cell;
796 ti = auxData->back().m_ti;
801 template <
class TraversalInformationT,
class LimitedHeapT>
803 PrivateNearestNeighbors(
const CellType& cell,
804 const TraversalInformationT& ti,
805 LimitedHeapT* neighbors)
const
807 typedef typename LimitedHeapT::value_type NNType;
808 if (BaseType::IsLeaf(cell) || (neighbors->size() + cell.Size() <= neighbors->Limit()))
810 typename BaseType::CellRange range;
811 BaseType::GetCellRange(cell, ti, &range);
812 typename BaseType::HandleType h = range.first;
814 for (; h != range.second; ++h)
816 NNType nn(BaseType::SqrDistance(ti.Global().Point(),
817 BaseType::at(BaseType::Dereference(h))),
818 BaseType::Dereference(h));
819 neighbors->PushHeap(nn);
823 if (!BaseType::ExistChild(cell, 0))
825 TraversalInformationT rti;
826 typename NNType::ScalarType dr;
827 InitTraversalInformation(cell, ti, 1, &rti);
828 dr = BaseType::CellSqrDistance(cell[1], rti);
829 if ((neighbors->size() < neighbors->Limit() || dr <= neighbors->front().sqrDist))
831 PrivateNearestNeighbors(cell[1], rti, neighbors);
835 else if (!BaseType::ExistChild(cell, 1))
837 TraversalInformationT lti;
838 typename NNType::ScalarType dl;
839 InitTraversalInformation(cell, ti, 0, <i);
840 dl = BaseType::CellSqrDistance(cell[0], lti);
841 if ((neighbors->size() < neighbors->Limit() || dl <= neighbors->front().sqrDist))
843 PrivateNearestNeighbors(cell[0], lti, neighbors);
847 TraversalInformationT lti, rti;
849 typename NNType::ScalarType dl, dr;
850 InitTraversalInformation(cell, ti, 0, <i);
851 InitTraversalInformation(cell, ti, 1, &rti);
853 dl = BaseType::CellSqrDistance(cell[0], lti);
854 dr = BaseType::CellSqrDistance(cell[1], rti);
857 if ((neighbors->size() < neighbors->Limit() || dl <= neighbors->front().sqrDist))
859 PrivateNearestNeighbors(cell[0], lti, neighbors);
861 if ((neighbors->size() < neighbors->Limit() || dr <= neighbors->front().sqrDist))
863 PrivateNearestNeighbors(cell[1], rti, neighbors);
868 if ((neighbors->size() < neighbors->Limit() || dr <= neighbors->front().sqrDist))
870 PrivateNearestNeighbors(cell[1], rti, neighbors);
872 if ((neighbors->size() < neighbors->Limit() || dl <= neighbors->front().sqrDist))
874 PrivateNearestNeighbors(cell[0], lti, neighbors);
879 template <
class Po
intT,
class LimitedHeapT>
881 PrivateNearestNeighbors(
const PointT& p,
882 NearestNeighborsAuxData<PointT>* auxData,
883 LimitedHeapT* neighbors)
const
885 typedef NearestNeighborsAuxData<PointT> AuxDataType;
886 typedef typename AuxDataType::TraversalInfoType TraversalInfoType;
887 typedef typename TraversalInfoType::GlobalType GlobalInfoType;
888 typedef typename AuxDataType::value_type AuxDataValueType;
889 if (!BaseType::Root())
893 auxData->reserve(128);
895 TraversalInfoType ti;
898 BaseType::InitRootTraversalInformation(*BaseType::Root(), &ti);
899 const CellType* current = BaseType::Root();
902 typedef typename LimitedHeapT::value_type NNType;
903 if (BaseType::IsLeaf(*current) ||
904 (neighbors->size() + current->Size() <= neighbors->Limit()))
906 typename BaseType::CellRange range;
907 BaseType::GetCellRange(*current, ti, &range);
908 typename BaseType::HandleType h = range.first;
910 for (; h != range.second; ++h)
912 NNType nn(BaseType::SqrDistance(ti.Global().Point(),
913 BaseType::at(BaseType::Dereference(h))),
914 BaseType::Dereference(h));
915 neighbors->PushHeap(nn);
918 else if (!BaseType::ExistChild(*current, 0))
920 TraversalInfoType rti;
921 typename NNType::ScalarType dr;
922 InitTraversalInformation(*current, ti, 1, &rti);
923 dr = BaseType::CellSqrDistance(current[1], rti);
924 if (neighbors->size() < neighbors->Limit() || dr <= neighbors->front().sqrDist)
926 current = &(*current)[1];
931 else if (!BaseType::ExistChild(*current, 1))
933 TraversalInfoType lti;
934 typename NNType::ScalarType dl;
935 InitTraversalInformation(*current, ti, 0, <i);
936 dl = BaseType::CellSqrDistance((*current)[0], lti);
937 if (neighbors->size() < neighbors->Limit() || dl <= neighbors->front().sqrDist)
939 current = &(*current)[0];
946 TraversalInfoType lti, rti;
947 typename NNType::ScalarType dl, dr;
948 InitTraversalInformation(*current, ti, 0, <i);
949 InitTraversalInformation(*current, ti, 1, &rti);
951 dl = BaseType::CellSqrDistance((*current)[0], lti);
952 dr = BaseType::CellSqrDistance((*current)[1], rti);
955 if (neighbors->size() < neighbors->Limit() ||
956 dl <= neighbors->front().sqrDist)
958 auxData->push_back(AuxDataValueType(&(*current)[1], rti, dr));
959 current = &(*current)[0];
963 if ((neighbors->size() < neighbors->Limit() ||
964 dr <= neighbors->front().sqrDist))
966 current = &(*current)[1];
973 if (neighbors->size() < neighbors->Limit() ||
974 dr <= neighbors->front().sqrDist)
976 auxData->push_back(AuxDataValueType(&(*current)[0], lti, dl));
977 current = &(*current)[1];
981 if ((neighbors->size() < neighbors->Limit() ||
982 dl <= neighbors->front().sqrDist))
984 current = &(*current)[0];
993 if (!auxData->size())
997 if (neighbors->size() < neighbors->Limit() ||
998 auxData->back().m_sqrDist <= neighbors->front().sqrDist)
1000 current = auxData->back().m_cell;
1001 ti = auxData->back().m_ti;
1002 auxData->pop_back();
1005 auxData->pop_back();
1010 template <
class TraversalInformationT,
1017 const TraversalInformationT& ti,
1019 LimitedHeap<NNT, std::less<NNT>, ContainerT>* neighbors)
const
1022 if (IsLeaf(cell) || (neighbors->size() + cell.Size() <= neighbors->Limit()))
1024 typename BaseType::CellRange range;
1025 GetCellRange(cell, ti, &range);
1026 typename BaseType::HandleType h = range.first, hend = range.second;
1028 for (; h != hend; ++h)
1030 neighbors->PushHeap(NNType(SqrDistance(ti.Global().Point(), at(Dereference(h))),
1035 TraversalInformationT lti, rti;
1036 InitTraversalInformation(cell, ti, 0, <i);
1037 InitTraversalInformation(cell, ti, 1, &rti);
1039 typename LimitedHeap<NNT, std::less<NNT>, ContainerT>::value_type::ScalarType dl, dr;
1040 dl = CellSqrDistance(cell[0], lti);
1041 dr = CellSqrDistance(cell[1], rti);
1044 if ((neighbors->size() < neighbors->Limit() ||
1045 epsilon * dl <= neighbors->front().sqrDist) &&
1046 BaseType::ExistChild(cell, 0))
1050 if ((neighbors->size() < neighbors->Limit() ||
1051 epsilon * dr <= neighbors->front().sqrDist) &&
1052 BaseType::ExistChild(cell, 1))
1059 if ((neighbors->size() < neighbors->Limit() ||
1060 epsilon * dr <= neighbors->front().sqrDist) &&
1061 BaseType::ExistChild(cell, 1))
1065 if ((neighbors->size() < neighbors->Limit() ||
1066 epsilon * dl <= neighbors->front().sqrDist) &&
1067 BaseType::ExistChild(cell, 0))
1074 template <
class TraversalInformationT>
1077 const TraversalInformationT& ti,
1082 typename BaseType::CellRange range;
1083 GetCellRange(cell, ti, &range);
1084 typename BaseType::HandleType h = range.first, hend = range.second;
1085 for (; h != hend; ++h)
1086 if (at(Dereference(h)) == ti.Global().Point())
1088 *dref = Dereference(h);
1093 if (cell(ti.Global().Point()))
1095 if (!BaseType::ExistChild(cell, 0))
1099 TraversalInformationT lti;
1100 InitTraversalInformation(cell, ti, 0, <i);
1101 return Contains(cell[0], lti, dref);
1105 if (!BaseType::ExistChild(cell, 1))
1109 TraversalInformationT rti;
1110 InitTraversalInformation(cell, rti, 1, &rti);
1111 return Contains(cell[1], rti, dref);