Library of Assembled Shared Sources
kd_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::KdTree
46 * @brief a KD tree for point-like objects
47 * @author Bram de Greve [BdG]
48 *
49 * the KD tree does NOT own the objects. You must keep them yourself!
50 */
51
52#ifndef LASS_GUARDIAN_OF_INCLUSION_SPAT_KD_TREE_H
53#define LASS_GUARDIAN_OF_INCLUSION_SPAT_KD_TREE_H
54
55//#define LASS_SPAT_KD_TREE_DIAGNOSTICS
56
57#include "spat_common.h"
58#include "../util/shared_ptr.h"
59
60namespace lass
61{
62namespace spat
63{
64
65template <typename ObjectType, typename IteratorType=const ObjectType*>
66struct KdTreeObjectTraits
67{
68 typedef ObjectType TPoint;
69 typedef IteratorType TObjectIterator;
70 typedef const ObjectType& TObjectReference;
71 typedef typename TPoint::TValue TValue;
72 typedef typename TPoint::TParam TParam;
73 typedef typename TPoint::TReference TReference;
74 typedef typename TPoint::TConstReference TConstReference;
75 enum { dimension = TPoint::dimension };
76
77 static const TPoint& position(TObjectIterator object) { return *object; }
78};
79
80
81
82template
83<
84 class ObjectType,
85 class ObjectTraits = KdTreeObjectTraits<ObjectType>
86>
87class KdTree
88{
89public:
90
92
93 typedef ObjectType TObject;
94 typedef ObjectTraits TObjectTraits;
95
96 typedef typename TObjectTraits::TObjectIterator TObjectIterator;
97 typedef typename TObjectTraits::TObjectReference TObjectReference;
98 typedef typename TObjectTraits::TPoint TPoint;
99 typedef typename TObjectTraits::TValue TValue;
100 typedef typename TObjectTraits::TParam TParam;
101 typedef typename TObjectTraits::TReference TReference;
102 typedef typename TObjectTraits::TConstReference TConstReference;
103
104 enum { dimension = TObjectTraits::dimension };
105
106 class Neighbour
107 {
108 public:
109 Neighbour();
110 Neighbour(TObjectIterator object, TValue squaredDistance);
111
112 TObjectIterator object() const;
113 TPoint position() const;
114 TValue squaredDistance() const;
115
116 TObjectIterator operator->() const;
117 TObjectReference operator*() const;
118 bool operator<(const Neighbour& other) const;
119 private:
120 TObjectIterator object_;
121 TValue squaredDistance_;
122 };
123
124 typedef std::vector<Neighbour> TNeighbourhood;
125
127 KdTree(TObjectIterator first, TObjectIterator last);
128 KdTree(TSelf&& other) noexcept;
129
130 TSelf& operator=(TSelf&& other) noexcept;
131
132 void reset();
133 void reset(TObjectIterator first, TObjectIterator last);
134
135 Neighbour nearestNeighbour(const TPoint& target) const;
136 Neighbour nearestNeighbour(const TPoint& target, TParam maxRadius) const;
137 TValue rangeSearch(const TPoint& target, TParam maxRadius, size_t maxCount,
138 TNeighbourhood& neighbourhood) const;
139
140 template <typename OutputIterator>
141 OutputIterator rangeSearch(const TPoint& target, TParam maxRadius,
142 OutputIterator first) const;
143 template <typename RandomIterator>
144 RandomIterator rangeSearch(const TPoint& target, TParam maxRadius, size_t maxCount,
145 RandomIterator first) const;
146
147 void swap(TSelf& other);
148 bool isEmpty() const;
149 void clear();
150
151 const TObjectIterator end() const;
152
153#ifdef LASS_SPAT_KD_TREE_DIAGNOSTICS
154 void diagnostics();
155#endif
156
157private:
158
159 typedef std::vector<TObjectIterator> TObjectIterators;
160 typedef typename TObjectIterators::iterator TIteratorIterator;
161
162 typedef unsigned char TAxis;
163 typedef std::vector<TAxis> TAxes;
164
165 enum { dummyAxis_ = TAxis(-1)} ;
166
167 class LessDim
168 {
169 public:
170 LessDim(TAxis split): split_(split) {}
171 bool operator()(const TObjectIterator& a, const TObjectIterator& b) const
172 {
173 return TObjectTraits::position(a)[split_] < TObjectTraits::position(b)[split_];
174 }
175 private:
176 TAxis split_;
177 };
178
179 class Node
180 {
181 public:
182 Node(TObjectIterator object, const TPoint& position = TPoint(), TAxis axis = dummyAxis_):
183 position_(position), object_(object), axis_(axis) {}
184 const TObjectIterator& object() const { return object_; }
185 const TPoint& position() const { return position_; }
186 TAxis axis() const { return axis_; }
187 private:
188 TPoint position_;
189 TObjectIterator object_;
190 TAxis axis_;
191 };
192 typedef std::vector<Node> TNodes;
193
194 void buildHeap();
195 void balance(size_t index, TIteratorIterator first, TIteratorIterator last);
196 TAxis findSplitAxis(TIteratorIterator first, TIteratorIterator last) const;
197 void assignNode(size_t index, TObjectIterator object, TAxis splitAxis);
198 size_t findNode(size_t index, const TPoint& target) const;
199
200 void doNearestNeighbour(size_t index, const TPoint& target, Neighbour& best) const;
201
202 template <typename OutputIterator>
203 OutputIterator doRangeSearch(size_t index, const TPoint& target,
204 TParam squaredRadius, OutputIterator output) const;
205 template <typename RandomIterator>
206 RandomIterator doRangeSearch(size_t index, const TPoint& target, TReference squaredRadius,
207 size_t maxCount, RandomIterator first, RandomIterator last) const;
208
209 static TValue squaredDistance(const TPoint& a, const TPoint& b);
210
211 TNodes heap_;
212 std::unique_ptr<TObjectIterator> end_;
213};
214
215
216}
217
218}
219
220#include "kd_tree.inl"
221
222#endif
223
224// EOF
OutputIterator rangeSearch(const TPoint &target, TParam maxRadius, OutputIterator first) const
Find all objects in a radius of maxRadius of target.
Definition kd_tree.inl:297
void clear()
resest the k-d tree to an empty one.
Definition kd_tree.inl:371
KdTree(TObjectIterator first, TObjectIterator last)
Constructs a k-d tree from objects in range [first, last).
Definition kd_tree.inl:80
TValue rangeSearch(const TPoint &target, TParam maxRadius, size_t maxCount, TNeighbourhood &neighbourhood) const
Locates objects within a spherical range around a target position.
Definition kd_tree.inl:239
void swap(TSelf &other)
Swap the representation of two k-d trees.
Definition kd_tree.inl:350
KdTree()
Constructs an empty k-d tree.
Definition kd_tree.inl:69
void reset(TObjectIterator first, TObjectIterator last)
Resets to a new k-d tree of objects in range [first, last).
Definition kd_tree.inl:129
Neighbour nearestNeighbour(const TPoint &target, TParam maxRadius) const
Locates the object that's nearest to a target position, within a maximum range.
Definition kd_tree.inl:152
Neighbour nearestNeighbour(const TPoint &target) const
Locates the object that's nearest to a target position.
Definition kd_tree.inl:141
void reset()
Resets to an empty tree.
Definition kd_tree.inl:117
bool isEmpty() const
returns true if there are no objects in the k-d tree
Definition kd_tree.inl:361
spatial subdivisions, quadtrees, octrees, meshes in 2D and 3D, triangulators, ...
Definition aabb8_tree.h:80
Library for Assembled Shared Sources.
Definition config.h:53