Library of Assembled Shared Sources
quad_tree.h
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2024 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43
44
45/** @class lass::spat::QuadTree
46 * A spatial container for generic objects. The object needs a traits class which
47 * contains the necessary functions to perform the quad tree management for the
48 * particular ObjectType. The traits class needs as a basis the following interface:
49 * <tt>
50 * static TAabb aabb(const TSimplePolygon3D& iP);
51 * static bool contains( const TSimplePolygon3D& iP, const TPoint& point)
52 * </tt>
53 * The above functions are only examples. The dimensionality of the primitives must
54 * match but can be of any order. So the quad tree can be used to classify in
55 * 2 and 3 dimensions. In three dimensions the more common name is OctTree.
56 *
57 * Higher level divisions can in theory be supported but the dimensional specific
58 * part must be reimplemented. Altough this is only 2 functions and could be written
59 * generally this is not yet available.
60 *
61 * @brief a Quad tree for general objects
62 * @author Tom De Muer [TDM]
63 */
64
65#ifndef LASS_GUARDIAN_OF_INCLUSION_SPAT_QUAD_TREE_H
66#define LASS_GUARDIAN_OF_INCLUSION_SPAT_QUAD_TREE_H
67
68#include "spat_common.h"
70#include "split_heuristics.h"
72#include "../util/allocator.h"
73
74namespace lass
75{
76namespace spat
77{
78
79template
80<
81 typename ObjectType,
82 typename ObjectTraits = DefaultObjectTraits<ObjectType>,
83 typename SplitHeuristics = DefaultSplitHeuristics
84>
85class QuadTree:
86 public SplitHeuristics, util::NonCopyable, private impl::QuadTreeHelper<ObjectTraits, typename ObjectTraits::TPoint>
87{
88public:
89
90 typedef QuadTree<ObjectType, ObjectTraits, SplitHeuristics> TSelf;
91 typedef ObjectType TObjectType;
92 typedef ObjectTraits TObjectTraits;
93 typedef SplitHeuristics TSplitHeuristics;
94
95 typedef typename TObjectTraits::TObjectIterator TObjectIterator;
96 typedef typename TObjectTraits::TObjectReference TObjectReference;
97 typedef typename TObjectTraits::TAabb TAabb;
98 typedef typename TObjectTraits::TRay TRay;
99 typedef typename TObjectTraits::TPoint TPoint;
100 typedef typename TObjectTraits::TVector TVector;
101 typedef typename TObjectTraits::TValue TValue;
102 typedef typename TObjectTraits::TParam TParam;
103 typedef typename TObjectTraits::TReference TReference;
104 typedef typename TObjectTraits::TConstReference TConstReference;
105 typedef typename TObjectTraits::TInfo TInfo;
106
107 static constexpr size_t dimension = TObjectTraits::dimension;
108 static constexpr size_t defaultMaxObjectsPerLeaf = 10;
109 static constexpr size_t defaultMaxDepth = 10;
110
111 class Neighbour
112 {
113 public:
114 Neighbour() {}
115 Neighbour(TObjectIterator object, TValue squaredDistance):
116 object_(object), squaredDistance_(squaredDistance) {}
117 TObjectIterator object() const { return object_; }
118 TValue squaredDistance() const { return squaredDistance_; }
119 TObjectIterator operator->() const { return object_; }
120 TObjectReference operator*() const { return TObjectTraits::object(object_); }
121 bool operator<(const Neighbour& other) const { return squaredDistance_ < other.squaredDistance_; }
122 bool operator==(const Neighbour& other) const { return object_ == other.object_; }
123 private:
124 TObjectIterator object_;
125 TValue squaredDistance_;
126 };
127
128 QuadTree(const TSplitHeuristics& heuristics = TSplitHeuristics(defaultMaxObjectsPerLeaf, defaultMaxDepth));
129 QuadTree(const TAabb& aabb, const TSplitHeuristics& heuristics = TSplitHeuristics(defaultMaxObjectsPerLeaf, defaultMaxDepth));
130 QuadTree(const TAabb& aabb, TObjectIterator end, const TSplitHeuristics& heuristics = TSplitHeuristics(defaultMaxObjectsPerLeaf, defaultMaxDepth));
131 QuadTree(TObjectIterator first, TObjectIterator last, const TSplitHeuristics& heuristics = TSplitHeuristics(defaultMaxObjectsPerLeaf, defaultMaxDepth));
132 QuadTree(TSelf&& other) noexcept;
133 ~QuadTree();
134
135 TSelf& operator=(TSelf&& other) noexcept;
136
137 void reset();
138 void reset(TObjectIterator first, TObjectIterator last);
139
140 /** return true if any of the objects contains point.
141 *
142 * Required :
143 * <tt>static bool ObjectTypeTraits::contains( const Object& object, const TPoint& point, const TInfo* info );</tt>
144 */
145 bool contains(const TPoint& p, const TInfo* info = 0) const;
146
147 /** find objects containing point and write them to the output iterator.
148 *
149 * Required :
150 * <tt>static bool ObjectTypeTraits::contains( const Object& object, const TPoint& point, const TInfo* info );</tt>
151 */
152 template <typename OutputIterator>
153 OutputIterator find(const TPoint& p, OutputIterator result, const TInfo* info = 0) const;
154
155 template <typename OutputIterator>
156 OutputIterator find(const TAabb& box, OutputIterator result, const TInfo* info = 0) const;
157
158 template <typename OutputIterator>
159 OutputIterator find(const TRay& ray, TParam minT, TParam maxT, OutputIterator result, const TInfo* info = 0) const;
160
161 const TObjectIterator intersect(const TRay& ray, TReference t, TParam tMin = 0,
162 const TInfo* info = 0) const;
163
164 bool intersects(const TRay& ray, TParam tMin = 0,
165 TParam maxT = std::numeric_limits<TValue>::infinity(), const TInfo* info = 0) const;
166
167 const Neighbour nearestNeighbour(const TPoint& point, const TInfo* info = 0) const;
168
169 template <typename RandomIterator>
170 RandomIterator rangeSearch(const TPoint& center, TParam maxRadius, size_t maxCount,
171 RandomIterator first, const TInfo* info = 0) const;
172
173 /** contains. Returns the number of object that returned sFront on all the lines
174 * provided in the iFrustum vector and _adds_ them to the vector oObjects. An example
175 * of use is frustum culling.
176 *
177 * Required :
178 * <tt>static bool ObjectTypeTraits::contains( const Object& object, const TPoint& point );</tt>
179 */
180 //size_t visible( const std::vector<TSeparator>& iFrustum, std::vector<ObjectType*>& oObjects ) const;
181
182 void add(TObjectIterator object);
183 void remove(TObjectIterator object);
184 size_t objectCount() const;
185
186 const TAabb& aabb() const;
187
188 /** depth. Returns the depth of the tree */
189 size_t depth() const;
190 const TValue averageDepth() const;
191 bool isEmpty() const;
192
193 void swap(QuadTree& other);
194 const TObjectIterator end() const;
195
196private:
197
198 static constexpr size_t numChildren = 1 << dimension;
199
200 typedef std::vector<TObjectIterator> TObjectIterators;
201
203 8192,
206 >
207 > TNodesAllocator;
208
209 struct QuadNode
210 {
211 TAabb bounds;
212 TObjectIterators data; /**< the list containing the data */
213 QuadNode *children; /**< 0 = NW, 1 = NE, 2 = SE, 3 = SW for quadtrees */
214
215 QuadNode(const TAabb& bounds, TNodesAllocator& allocator);
216 ~QuadNode();
217
218 void add(TObjectIterator object, const TSplitHeuristics& heuristics, size_t level = 0, bool mayDecompose = true);
219 bool remove(TObjectIterator object);
220
221 bool isLeaf() const { return !children; }
222 const TPoint center() const;
223 const TValue sqrDistance(const TPoint& point) const;
224 size_t objectCount() const; /**< number of objects in this node and all its children */
225 size_t depth() const; /**< depth of the child tree */
226 const TValue averageDepth() const;
227 void decompose(const TSplitHeuristics& heuristics, size_t level = 0); /**< split the current node into 4 children */
228 void absorb(); /**< absorb all children into the current node */
229
230 private:
231
232 TNodesAllocator& allocator_;
233 void makeChildren();
234 void deleteChildren(size_t count);
235 };
236
237 const TObjectIterator doIntersect(const QuadNode& node,
238 const TRay& ray, TReference t, TParam tMin, const TInfo* info,
239 const TVector& tNear, const TVector& tFar, const TPoint& support, const TVector& invDir, size_t flipMask) const;
240
241 bool doIntersects(const QuadNode& node,
242 const TRay& ray, TParam tMin, TParam tMax, const TInfo* info,
243 const TVector& tNear, const TVector& tFar, const TPoint& support, const TVector& invDir, size_t flipMask) const;
244
245 template <typename OutputIterator>
246 OutputIterator doFind(const QuadNode& node,
247 const TAabb& box, OutputIterator result, const TInfo* info) const;
248
249 template <typename OutputIterator>
250 OutputIterator doFind(const QuadNode& node,
251 const TRay& ray, TParam tMin, TParam tMax, OutputIterator result, const TInfo* info,
252 const TVector& tNear, const TVector& tFar, const TPoint& support, const TVector& invDir, size_t flipMask) const;
253
254 void doNearestNeighbour(const QuadNode& node,
255 const TPoint& point, const TInfo* info, Neighbour& best) const;
256
257 template <typename RandomIterator>
258 RandomIterator doRangeSearch(const QuadNode& node,
259 const TPoint& target, TReference squaredRadius, size_t maxCount, RandomIterator first, RandomIterator last, const TInfo* info) const;
260
261 TAabb aabb_;
262 QuadNode* root_;
263 TObjectIterator end_;
264 std::unique_ptr<TNodesAllocator> nodesAllocator_;
265 size_t numObjects_;
266};
267
268
269
270}
271}
272
273#include "quad_tree.inl"
274
275#endif
276
277// EOF
void add(TObjectIterator object)
contains.
QuadTree(const TAabb &aabb, TObjectIterator end, const TSplitHeuristics &heuristics=TSplitHeuristics(defaultMaxObjectsPerLeaf, defaultMaxDepth))
empty quadtree with fixed bounding box and end iterator.
OutputIterator find(const TAabb &box, OutputIterator result, const TInfo *info=0) const
OutputIterator find(const TPoint &p, OutputIterator result, const TInfo *info=0) const
find objects containing point and write them to the output iterator.
QuadTree(const TAabb &aabb, const TSplitHeuristics &heuristics=TSplitHeuristics(defaultMaxObjectsPerLeaf, defaultMaxDepth))
empty quadtree with fixed bounding box
Definition quad_tree.inl:94
size_t depth() const
depth.
OutputIterator find(const TRay &ray, TParam minT, TParam maxT, OutputIterator result, const TInfo *info=0) const
TSelf & operator=(TSelf &&other) noexcept
move constructor
QuadTree(TSelf &&other) noexcept
move constructor
QuadTree(TObjectIterator first, TObjectIterator last, const TSplitHeuristics &heuristics=TSplitHeuristics(defaultMaxObjectsPerLeaf, defaultMaxDepth))
quadtree from objects, with computed bounding box
bool contains(const TPoint &p, const TInfo *info=0) const
return true if any of the objects contains point.
fixes a variable-size allocator to one size.
Definition allocator.h:398
A simple fixed-size block allocator.
Definition allocator.h:979
use as base class if derived should not be copyable
spatial subdivisions, quadtrees, octrees, meshes in 2D and 3D, triangulators, ...
Definition aabb8_tree.h:80
Library for Assembled Shared Sources.
Definition config.h:53
default traits for objects to be stored in spatial subdivision trees