Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
quadtree.H
Go to the documentation of this file.
1
2/*
3 Aleph_w
4
5 Data structures & Algorithms
6 version 2.0.0b
7 https://github.com/lrleon/Aleph-w
8
9 This file is part of Aleph-w library
10
11 Copyright (c) 2002-2026 Leandro Rabindranath Leon
12
13 Permission is hereby granted, free of charge, to any person obtaining a copy
14 of this software and associated documentation files (the "Software"), to deal
15 in the Software without restriction, including without limitation the rights
16 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 copies of the Software, and to permit persons to whom the Software is
18 furnished to do so, subject to the following conditions:
19
20 The above copyright notice and this permission notice shall be included in all
21 copies or substantial portions of the Software.
22
23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 SOFTWARE.
30*/
31
32
45# ifndef QUADTREE_H
46# define QUADTREE_H
47
48# include <quadnode.H>
49
126{
127public:
128 using Node = QuadNode;
129
130private:
132
135
143 void split(Node * node)
144 {
145 assert(node->is_leaf()); // Only applies to leaf nodes
146
147 size_t next_level = LEVEL(node) + 1;
148
149 NW_CHILD(node) =
150 new QuadNode(node->get_min_x(), node->get_mid_x(),
151 node->get_min_y(), node->get_mid_y(), node);
152 LEVEL(NW_CHILD(node)) = next_level;
153
154 NE_CHILD(node) =
155 new QuadNode(node->get_mid_x(), node->get_max_x(),
156 node->get_min_y(), node->get_mid_y(), node);
157 LEVEL(NE_CHILD(node)) = next_level;
158
159 SW_CHILD(node) =
160 new QuadNode(node->get_min_x(), node->get_mid_x(),
161 node->get_mid_y(), node->get_max_y(), node);
162 LEVEL(SW_CHILD(node)) = next_level;
163
164 SE_CHILD(node) =
165 new QuadNode(node->get_mid_x(), node->get_max_x(),
166 node->get_mid_y(), node->get_max_y(), node);
167 LEVEL(SE_CHILD(node)) = next_level;
168
169 COLOR(node) = Node::Color::Gray;
170
171 DynList<Point> & points = node->get_points_set();
172
173 while (not points.is_empty())
174 {
175 Point point = points.remove_first();
176
177 QuadNode * child = node->get_child_to(point);
178
179 child->add_point(point);
180 }
181 }
182
190 void join(Node * node)
191 {
192 assert(not node->is_leaf()); // node is not a leaf
193 // All four children of node must be leaves
194 assert(NW_CHILD(node)->is_leaf());
195 assert(NE_CHILD(node)->is_leaf());
196 assert(SW_CHILD(node)->is_leaf());
197 assert(SE_CHILD(node)->is_leaf());
198
199 DynList<Point> & points = node->get_points_set();
200
201 DynList<Point> & nw_points = NW_CHILD(node)->get_points_set();
202
203 while(not nw_points.is_empty())
204 points.append(nw_points.remove_first());
205
206 auto & ne_points = NE_CHILD(node)->get_points_set();
207
208 while(not ne_points.is_empty())
209 points.append(ne_points.remove_first());
210
211 auto & sw_points = SW_CHILD(node)->get_points_set();
212
213 while(not sw_points.is_empty())
214 points.append(sw_points.remove_first());
215
216 auto & se_points = SE_CHILD(node)->get_points_set();
217
218 while(not se_points.is_empty())
219 points.append(se_points.remove_first());
220
221 delete NW_CHILD(node);
222 NW_CHILD(node) = nullptr;
223
224 delete NE_CHILD(node);
225 NE_CHILD(node) = nullptr;
226
227 delete SW_CHILD(node);
228 SW_CHILD(node) = nullptr;
229
230 delete SE_CHILD(node);
231 SE_CHILD(node) = nullptr;
232
234 }
235
237 Point * insert(Node *& r, const Point & p)
238 {
239 assert(r->contains(p));
240
241 if (r->is_leaf())
242 {
244 return &r->add_point(p);
245 else
246 split(r);
247 }
248
249 Node * node = r->get_child_to(p);
250
251 return insert(node, p);
252 }
253
255 void empty(Node *& r) noexcept
256 {
257 if (r == nullptr)
258 return;
259
260 empty(NW_CHILD(r));
261 empty(NE_CHILD(r));
262 empty(SW_CHILD(r));
263 empty(SE_CHILD(r));
264
265 delete r;
266 r = nullptr;
267 }
268
270 template <class Op>
271 void operate_on_nodes(Node * r, Op & op)
272 {
273 if (r == nullptr)
274 return;
275
276 op(r);
277
282 }
283
285 void copy_tree(QuadNode * src, QuadNode *& tgt,
286 QuadNode * tgt_parent = nullptr)
287 {
288 if (src == nullptr)
289 return;
290
291 tgt = new QuadNode(src->get_min_x(), src->get_max_x(),
292 src->get_min_y(), src->get_max_y(), tgt_parent);
293
294 tgt->get_points_set() = src->get_points_set();
295
296 COLOR(tgt) = COLOR(src);
297 LEVEL(tgt) = LEVEL(src);
298
299 copy_tree(NW_CHILD(src), NW_CHILD(tgt), tgt);
300 copy_tree(NE_CHILD(src), NE_CHILD(tgt), tgt);
301 copy_tree(SW_CHILD(src), SW_CHILD(tgt), tgt);
302 copy_tree(SE_CHILD(src), SE_CHILD(tgt), tgt);
303 }
304
305public:
306
314 {
315 // Empty
316 }
317
326 QuadTree(const Geom_Number & min_x, const Geom_Number & max_x,
327 const Geom_Number & min_y, const Geom_Number & max_y,
328 const size_t & _max_num_points_per_node = 1)
329 : root(new Node(min_x, max_x, min_y, max_y)),
331 {
332 // Empty
333 }
334
344
350 : root(tree.root), max_num_points_per_node(tree.max_num_points_per_node)
351 {
352 tree.root = nullptr;
353 }
354
361 {
362 if (this == &tree)
363 return *this;
364
365 empty(root);
367 copy_tree(tree.root, root);
368
369 return *this;
370 }
371
377 QuadTree & operator = (QuadTree && tree) noexcept
378 {
379 if (this != &tree)
380 {
381 empty(root);
382 root = tree.root;
383 max_num_points_per_node = tree.max_num_points_per_node;
384 tree.root = nullptr;
385 }
386 return *this;
387 }
388
391 {
392 empty(root);
393 }
394
397 {
398 return root;
399 }
400
403 {
404 return root;
405 }
406
412
418
424 [[nodiscard]] bool contains(const Point & p) const noexcept
425 {
426 return root->contains(p);
427 }
428
437 Point * insert(const Point & p)
438 {
439 if (not root->contains(p))
440 return nullptr;
441
442 return insert(root, p);
443 }
444
451 Point * insert(const Geom_Number & x, const Geom_Number & y)
452 {
453 return insert(Point(x, y));
454 }
455
461 [[nodiscard]] Point * search(const Point & p) noexcept
462 {
463 if (not root->contains(p))
464 return nullptr;
465
466 Node * aux = root;
467
468 while (not aux->is_leaf())
469 aux = aux->get_child_to(p);
470
471 return aux->search_point(p);
472 }
473
479 [[nodiscard]] Node * search_container_node(const Point & p) noexcept
480 {
481 if (not root->contains(p))
482 return nullptr;
483
484 Node * aux = root;
485
486 while (not aux->is_leaf())
487 aux = aux->get_child_to(p);
488
489 if (aux->search_point(p) == nullptr)
490 return nullptr;
491
492 return aux;
493 }
494
502 void remove(const Point & p)
503 {
504 Node * aux = root;
505
506 while (not aux->is_leaf())
507 aux = aux->get_child_to(p);
508
509 if (not aux->remove_point(p))
510 return;
511
512 Node * parent = PARENT(aux);
513
514 if (parent == nullptr)
515 return;
516
517 if (NW_CHILD(parent)->get_num_points() +
518 NE_CHILD(parent)->get_num_points() +
519 SW_CHILD(parent)->get_num_points() +
520 SE_CHILD(parent)->get_num_points() <= max_num_points_per_node)
521 join(parent);
522 }
523
525 void empty()
526 {
531 root->empty();
532 }
533
541 template <class Op>
542 void for_each(Op & op)
543 {
545 }
546
548 template <class Op>
549 void for_each(Op && op = Op())
550 {
552 }
553};
554
555# endif // QUADTREE_H
#define PARENT(p)
Definition Dijkstra.H:123
#define LEVEL(p)
Definition btreepic.C:373
Dynamic singly linked list with functional programming support.
Definition htlist.H:1423
T & append(const T &item)
Append a new item by copy.
Definition htlist.H:1562
constexpr bool is_empty() const noexcept
Return true if list is empty.
Definition htlist.H:523
Node for QuadTree spatial data structure.
Definition quadnode.H:94
bool contains(const Point &p) const noexcept
Check if a point is contained in this node's region.
Definition quadnode.H:417
const Geom_Number & get_min_y() const noexcept
Get minimum Y coordinate of this region.
Definition quadnode.H:484
const Geom_Number & get_max_y() const noexcept
Get maximum Y coordinate of this region.
Definition quadnode.H:487
void empty() noexcept
Remove all points from this node and mark it as White.
Definition quadnode.H:539
Geom_Number get_mid_x() const noexcept
Get midpoint X coordinate.
Definition quadnode.H:496
QuadNode * get_child_to(const Point &p) const
Find which child node should contain a given point.
Definition quadnode.H:432
DynList< Point > & get_points_set() noexcept
Get reference to the points list (for direct manipulation).
Definition quadnode.H:572
Geom_Number get_mid_y() const noexcept
Get midpoint Y coordinate.
Definition quadnode.H:499
const Geom_Number & get_min_x() const noexcept
Get minimum X coordinate of this region.
Definition quadnode.H:478
Point & add_point(const Point &p)
Add a point to this node.
Definition quadnode.H:465
Point * search_point(const Point &p) noexcept
Search for a point in this node.
Definition quadnode.H:508
bool is_leaf() const noexcept
Check if this node is a leaf (has no children).
Definition quadnode.H:375
bool remove_point(const Point &p)
Remove a point from this node.
Definition quadnode.H:523
size_t get_num_points() noexcept
Get total number of points in this subtree.
Definition quadnode.H:472
const Geom_Number & get_max_x() const noexcept
Get maximum X coordinate of this region.
Definition quadnode.H:481
@ White
Empty leaf node.
@ Gray
Internal node with children.
@ Black
Leaf node with points.
QuadTree - Hierarchical spatial index for 2D points.
Definition quadtree.H:126
size_t max_num_points_per_node
Maximum points per leaf node before splitting.
Definition quadtree.H:134
void empty(Node *&r) noexcept
Recursively delete all nodes.
Definition quadtree.H:255
~QuadTree()
Destructor - frees all nodes.
Definition quadtree.H:390
void for_each(Op &op)
Apply an operation to each node in the tree.
Definition quadtree.H:542
QuadTree(const Geom_Number &min_x, const Geom_Number &max_x, const Geom_Number &min_y, const Geom_Number &max_y, const size_t &_max_num_points_per_node=1)
Construct a quadtree with specified region and capacity.
Definition quadtree.H:326
void for_each(Op &&op=Op())
Apply operation to each node (rvalue reference version).
Definition quadtree.H:549
void remove(const Point &p)
Remove a point from the tree.
Definition quadtree.H:502
QuadTree()
Default constructor - creates an uninitialized tree.
Definition quadtree.H:312
Point * search(const Point &p) noexcept
Search for a point in the tree.
Definition quadtree.H:461
Node * search_container_node(const Point &p) noexcept
Find the leaf node containing a point.
Definition quadtree.H:479
Point * insert(const Geom_Number &x, const Geom_Number &y)
Insert a point given by coordinates.
Definition quadtree.H:451
void copy_tree(QuadNode *src, QuadNode *&tgt, QuadNode *tgt_parent=nullptr)
Deep copy a tree structure.
Definition quadtree.H:285
const Node * get_root() const noexcept
Get the root node (const version).
Definition quadtree.H:402
void split(Node *node)
Subdivide a leaf node into four children.
Definition quadtree.H:143
void operate_on_nodes(Node *r, Op &op)
Apply operation to all nodes in the tree.
Definition quadtree.H:271
QuadTree(const QuadTree &tree)
Copy constructor - creates a deep copy of the tree.
Definition quadtree.H:339
QuadTree(QuadTree &&tree) noexcept
Move constructor - transfers ownership.
Definition quadtree.H:349
bool contains(const Point &p) const noexcept
Check if a point is within the tree's region.
Definition quadtree.H:424
Point * insert(Node *&r, const Point &p)
Recursive insert helper.
Definition quadtree.H:237
size_t get_max_num_points_per_node() const noexcept
Get the maximum points per leaf node.
Definition quadtree.H:414
QuadTree & operator=(const QuadTree &tree)
Copy assignment operator - creates a deep copy.
Definition quadtree.H:360
void join(Node *node)
Merge four child nodes back into their parent.
Definition quadtree.H:190
Point * insert(const Point &p)
Insert a point into the tree.
Definition quadtree.H:437
void set_max_num_points_per_node(const size_t &_max_num_points_per_node) noexcept
Set the maximum points per leaf node.
Definition quadtree.H:408
Node * get_root() noexcept
Get the root node.
Definition quadtree.H:396
Node * root
Root node of the tree.
Definition quadtree.H:131
void empty()
Remove all points from the tree, keeping only the root.
Definition quadtree.H:525
static mpfr_t y
Definition mpfr_mul_d.c:3
static bool is_leaf(BinNode< std::string > *p) noexcept
Definition Huffman.H:111
DynList< T > maps(const C &c, Op op)
Classic map operation.
QuadTree node implementation for spatial data structures.
#define COLOR(p)
Definition quadnode.H:58
#define SE_CHILD(p)
Definition quadnode.H:57
#define NE_CHILD(p)
Definition quadnode.H:55
#define NW_CHILD(p)
Definition quadnode.H:54
#define SW_CHILD(p)
Definition quadnode.H:56