kd_tree.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #ifndef LASS_GUARDIAN_OF_INCLUSION_SPAT_KD_TREE_H
00053 #define LASS_GUARDIAN_OF_INCLUSION_SPAT_KD_TREE_H
00054
00055
00056
00057 #include "spat_common.h"
00058
00059 namespace lass
00060 {
00061 namespace spat
00062 {
00063
00064 template <typename ObjectType>
00065 struct KdTreeObjectTraits
00066 {
00067 typedef const ObjectType* TObjectIterator;
00068 typedef const ObjectType& TObjectReference;
00069 typedef ObjectType TPoint;
00070 typedef typename TPoint::TValue TValue;
00071 typedef typename TPoint::TParam TParam;
00072 typedef typename TPoint::TReference TReference;
00073 typedef typename TPoint::TConstReference TConstReference;
00074 enum { dimension = TPoint::dimension };
00075
00076 static const TPoint& position(TObjectIterator object) { return *object; }
00077 };
00078
00079
00080
00081 template
00082 <
00083 class ObjectType,
00084 class ObjectTraits = KdTreeObjectTraits<ObjectType>
00085 >
00086 class KdTree
00087 {
00088 public:
00089
00090 typedef KdTree<ObjectType, ObjectTraits> TSelf;
00091
00092 typedef ObjectType TObject;
00093 typedef ObjectTraits TObjectTraits;
00094
00095 typedef typename TObjectTraits::TObjectIterator TObjectIterator;
00096 typedef typename TObjectTraits::TObjectReference TObjectReference;
00097 typedef typename TObjectTraits::TPoint TPoint;
00098 typedef typename TObjectTraits::TValue TValue;
00099 typedef typename TObjectTraits::TParam TParam;
00100 typedef typename TObjectTraits::TParam TReference;
00101 typedef typename TObjectTraits::TParam TConstReference;
00102
00103 enum { dimension = TObjectTraits::dimension };
00104
00105 class Neighbour
00106 {
00107 public:
00108 Neighbour();
00109 Neighbour(TObjectIterator object, TValue squaredDistance);
00110
00111 TObjectIterator object() const;
00112 TPoint position() const;
00113 TValue squaredDistance() const;
00114
00115 TObjectIterator operator->() const;
00116 TObjectReference operator*() const;
00117 bool operator<(const Neighbour& other) const;
00118 private:
00119 TObjectIterator object_;
00120 TValue squaredDistance_;
00121 };
00122
00123 typedef std::vector<Neighbour> TNeighbourhood;
00124
00125 KdTree();
00126 KdTree(TObjectIterator first, TObjectIterator last);
00127
00128 void reset();
00129 void reset(TObjectIterator first, TObjectIterator last);
00130
00131 Neighbour nearestNeighbour(const TPoint& target) const;
00132 TValue rangeSearch(const TPoint& target, TParam maxRadius, size_t maxCount,
00133 TNeighbourhood& neighbourhood) const;
00134
00135 template <typename OutputIterator>
00136 OutputIterator rangeSearch(const TPoint& target, TParam maxRadius,
00137 OutputIterator first) const;
00138 template <typename RandomIterator>
00139 RandomIterator rangeSearch(const TPoint& target, TParam maxRadius, size_t maxCount,
00140 RandomIterator first) const;
00141
00142 void swap(TSelf& other);
00143 const bool isEmpty() const;
00144 void clear();
00145
00146 const TObjectIterator end() const;
00147
00148 #ifdef LASS_SPAT_KD_TREE_DIAGNOSTICS
00149 void diagnostics();
00150 #endif
00151
00152 private:
00153
00154 typedef std::vector<TObjectIterator> TObjectIterators;
00155 typedef typename TObjectIterators::iterator TIteratorIterator;
00156
00157 typedef unsigned char TAxis;
00158 typedef std::vector<TAxis> TAxes;
00159
00160 enum { dummyAxis_ = TAxis(-1)} ;
00161
00162 class LessDim
00163 {
00164 public:
00165 LessDim(TAxis split): split_(split) {}
00166 bool operator()(const TObjectIterator& a, const TObjectIterator& b) const
00167 {
00168 return TObjectTraits::position(a)[split_] < TObjectTraits::position(b)[split_];
00169 }
00170 private:
00171 TAxis split_;
00172 };
00173
00174 class Node
00175 {
00176 public:
00177 Node(TObjectIterator object, TAxis axis = dummyAxis_): object_(object), axis_(axis) {}
00178 const TObjectIterator& object() const { return object_; }
00179 const TAxis axis() const { return axis_; }
00180 const TPoint position() const { return TObjectTraits::position(object_); }
00181 private:
00182 TObjectIterator object_;
00183 TAxis axis_;
00184 };
00185 typedef std::vector<Node> TNodes;
00186
00187 void buildHeap();
00188 void balance(size_t index, TIteratorIterator first, TIteratorIterator last);
00189 TAxis findSplitAxis(TIteratorIterator first, TIteratorIterator last) const;
00190 void assignNode(size_t index, TObjectIterator object, TAxis splitAxis);
00191 size_t findNode(size_t index, const TPoint& target) const;
00192
00193 void doNearestNeighbour(size_t index, const TPoint& target, Neighbour& best) const;
00194
00195 template <typename OutputIterator>
00196 OutputIterator doRangeSearch(size_t index, const TPoint& target,
00197 TParam squaredRadius, OutputIterator output) const;
00198 template <typename RandomIterator>
00199 RandomIterator doRangeSearch(size_t index, const TPoint& target, TReference squaredRadius,
00200 size_t maxCount, RandomIterator first, RandomIterator last) const;
00201
00202 static TValue squaredDistance(const TPoint& a, const TPoint& b);
00203
00204 TNodes heap_;
00205 TObjectIterator begin_;
00206 TObjectIterator end_;
00207 size_t size_;
00208 };
00209
00210
00211 }
00212
00213 }
00214
00215 #include "kd_tree.inl"
00216
00217 #endif
00218
00219