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
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 #ifndef LASS_GUARDIAN_OF_INCLUSION_SPAT_QUAD_TREE_H
00066 #define LASS_GUARDIAN_OF_INCLUSION_SPAT_QUAD_TREE_H
00067
00068 #include "spat_common.h"
00069 #include "impl/quad_tree_helper.h"
00070
00071 namespace lass
00072 {
00073 namespace spat
00074 {
00075
00076 template
00077 <
00078 class ObjectType,
00079 class ObjectTraits = DefaultObjectTraits<ObjectType>
00080 >
00081 class QuadTree: private impl::QuadTreeHelper<ObjectTraits, ObjectTraits::dimension>
00082 {
00083 public:
00084
00085 typedef QuadTree<ObjectType, ObjectTraits> TSelf;
00086 typedef ObjectType TObjectType;
00087 typedef ObjectTraits TObjectTraits;
00088
00089 typedef typename TObjectTraits::TObjectIterator TObjectIterator;
00090 typedef typename TObjectTraits::TObjectReference TObjectReference;
00091 typedef typename TObjectTraits::TAabb TAabb;
00092 typedef typename TObjectTraits::TRay TRay;
00093 typedef typename TObjectTraits::TPoint TPoint;
00094 typedef typename TObjectTraits::TVector TVector;
00095 typedef typename TObjectTraits::TValue TValue;
00096 typedef typename TObjectTraits::TParam TParam;
00097 typedef typename TObjectTraits::TReference TReference;
00098 typedef typename TObjectTraits::TConstReference TConstReference;
00099 typedef typename TObjectTraits::TInfo TInfo;
00100
00101 enum { dimension = TObjectTraits::dimension };
00102
00103 class Neighbour
00104 {
00105 public:
00106 Neighbour() {}
00107 Neighbour(TObjectIterator object, TValue squaredDistance):
00108 object_(object), squaredDistance_(squaredDistance) {}
00109 TObjectIterator object() const { return object_; }
00110 TValue squaredDistance() const { return squaredDistance_; }
00111 TObjectIterator operator->() const { return object_; }
00112 TObjectReference operator*() const { return TObjectTraits::object(object_); }
00113 bool operator<(const Neighbour& other) const { return squaredDistance_ < other.squaredDistance_; }
00114 bool operator==(const Neighbour& other) const { return object_ == other.object_; }
00115 private:
00116 TObjectIterator object_;
00117 TValue squaredDistance_;
00118 };
00119
00120
00121
00122
00123
00124 QuadTree(size_t maxSize = 100, size_t maxLevel = 10);
00125
00126
00127
00128 QuadTree(TObjectIterator first, TObjectIterator last, size_t maxSize = 10, size_t maxLevel = 10);
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 ~QuadTree();
00143
00144 void reset();
00145 void reset(TObjectIterator first, TObjectIterator last);
00146
00147
00148
00149
00150
00151
00152 const bool contains(const TPoint& p, const TInfo* info = 0) const;
00153
00154
00155
00156
00157
00158
00159 template <typename OutputIterator>
00160 OutputIterator find(const TPoint& p, OutputIterator result, const TInfo* info = 0) const;
00161
00162 const TObjectIterator intersect(const TRay& ray, TReference t, TParam tMin = 0,
00163 const TInfo* info = 0) const;
00164
00165 const bool intersects(const TRay& ray, TParam tMin = 0,
00166 TParam maxT = std::numeric_limits<TValue>::infinity(), const TInfo* info = 0) const;
00167
00168 const Neighbour nearestNeighbour(const TPoint& point, const TInfo* info = 0) const;
00169
00170 template <typename RandomIterator>
00171 RandomIterator rangeSearch(const TPoint& center, TParam maxRadius, size_t maxCount,
00172 RandomIterator first, const TInfo* info = 0) const;
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 void add(TObjectIterator object);
00184 size_t objectCount() const;
00185
00186 const TAabb& aabb() const;
00187
00188
00189 const size_t depth() const;
00190 const TValue averageDepth() const;
00191
00192 void swap(QuadTree& other);
00193 const TObjectIterator end() const;
00194
00195 private:
00196 enum { subNodeCount = 1 << dimension };
00197 typedef std::vector<TObjectIterator> TObjectIterators;
00198 struct QuadNode
00199 {
00200 QuadNode *node[subNodeCount];
00201 TPoint center;
00202 TVector extents;
00203 TObjectIterators data;
00204 bool leaf;
00205
00206 QuadNode(const TPoint& aCenter, const TVector& aExtents);
00207 ~QuadNode();
00208
00209 void add(TObjectIterator object, size_t maxSize, size_t maxLevel, size_t level = 0, bool mayDecompose = true);
00210
00211 size_t objectCount() const;
00212 size_t depth() const;
00213 const TValue averageDepth() const;
00214 void decompose(size_t maxSize, size_t maxLevel, size_t level = 0);
00215 void absorb();
00216
00217 TAabb aabb() const;
00218 };
00219
00220 const TObjectIterator doIntersect(const QuadNode* node, const TRay& ray, TReference t, TParam tMin,
00221 const TInfo* info, const TVector& tNear, const TVector& tFar, size_t flipMask) const;
00222 const bool doIntersects(const QuadNode* node, const TRay& ray, TParam tMin, TParam tMax,
00223 const TInfo* info, const TVector& tNear, const TVector& tFar, size_t flipMask) const;
00224 void doNearestNeighbour(const QuadNode* node, const TPoint& point, const TInfo* info,
00225 Neighbour& best) const;
00226 template <typename RandomIterator>
00227 RandomIterator doRangeSearch(const QuadNode* node, const TPoint& target, TReference squaredRadius,
00228 size_t maxCount, RandomIterator first, RandomIterator last, const TInfo* info) const;
00229
00230 TAabb aabb_;
00231 QuadNode* root_;
00232 TObjectIterator end_;
00233 size_t maxSize_;
00234 size_t maxLevel_;
00235 };
00236
00237
00238
00239 }
00240 }
00241
00242 #include "quad_tree.inl"
00243
00244 #endif
00245
00246