Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
quadnode.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
44# ifndef QUADNODE_H
45# define QUADNODE_H
46
47# include <htlist.H>
48# include <point.H>
49# include <ah-errors.H>
50
51using namespace Aleph;
52
53# define PARENT(p) ((p)->get_parent())
54# define NW_CHILD(p) ((p)->get_nw_child())
55# define NE_CHILD(p) ((p)->get_ne_child())
56# define SW_CHILD(p) ((p)->get_sw_child())
57# define SE_CHILD(p) ((p)->get_se_child())
58# define COLOR(p) ((p)->get_color())
59# define LEVEL(p) ((p)->get_level())
60
94{
95public:
96
104 enum class Color
105 {
106 White,
107 Gray,
108 Black,
110 };
111
120 enum class Quad
121 {
122 NW,
123 NE,
124 SW,
125 SE,
127 };
128
133 enum class Side
134 {
135 North,
136 South,
137 East,
138 West,
140 };
141
142private:
144
150
152 unsigned long level;
153
154 // Region boundaries
159
161 static QuadNode * get_north_neighbor(QuadNode * v) noexcept
162 {
163 if (PARENT(v) == nullptr)
164 return nullptr;
165
166 if (v->is_sw_child())
167 return NW_CHILD(PARENT(v));
168
169 if (v->is_se_child())
170 return NE_CHILD(PARENT(v));
171
173
174 if (u == nullptr or u->is_leaf())
175 return u;
176 else if (v->is_nw_child())
177 return SW_CHILD(u);
178 else
179 return SE_CHILD(u);
180 }
181
183 static QuadNode * get_south_neighbor(QuadNode * v) noexcept
184 {
185 if (PARENT(v) == nullptr)
186 return nullptr;
187
188 if (v->is_nw_child())
189 return SW_CHILD(PARENT(v));
190
191 if (v->is_ne_child())
192 return SE_CHILD(PARENT(v));
193
195
196 if (u == nullptr or u->is_leaf())
197 return u;
198 else if (v->is_sw_child())
199 return NW_CHILD(u);
200 else
201 return NE_CHILD(u);
202 }
203
205 static QuadNode * get_east_neighbor(QuadNode * v) noexcept
206 {
207 if (PARENT(v) == nullptr)
208 return nullptr;
209
210 if (v->is_nw_child())
211 return NE_CHILD(PARENT(v));
212
213 if (v->is_sw_child())
214 return SE_CHILD(PARENT(v));
215
217
218 if (u == nullptr or u->is_leaf())
219 return u;
220 else if (v->is_ne_child())
221 return NW_CHILD(u);
222 else
223 return SW_CHILD(u);
224 }
225
227 static QuadNode * get_west_neighbor(QuadNode * v) noexcept
228 {
229 if (PARENT(v) == nullptr)
230 return nullptr;
231
232 if (v->is_ne_child())
233 return NW_CHILD(PARENT(v));
234
235 if (v->is_se_child())
236 return SW_CHILD(PARENT(v));
237
239
240 if (u == nullptr or u->is_leaf())
241 return u;
242 else if (v->is_nw_child())
243 return NE_CHILD(u);
244 else
245 return SE_CHILD(u);
246 }
247
249 static void get_neighbors_by_side(QuadNode * node,
250 const Side & side,
252 {
253 if (node == nullptr)
254 return;
255
256 if (node->is_leaf())
257 {
258 neighbors.append(node);
259 return;
260 }
261
262 switch(side)
263 {
264 case Side::West:
267 break;
268 case Side::East:
271 break;
272 case Side::North:
275 break;
276 case Side::South:
279 break;
280 default:
281 ah_domain_error_if(true) << "Invalid side value";
282 }
283}
284
286static size_t count_points(QuadNode * node) noexcept
287{
288 if (node == nullptr)
289 return 0;
290
291 if (node->is_leaf())
292 return node->points.size();
293
294 size_t num_points = 0;
295
300
301 return num_points;
302}
303
304public:
305
308 : points(), parent(nullptr), nw_child(nullptr), ne_child(nullptr),
309 sw_child(nullptr), se_child(nullptr), color(Color::White), level(0),
310 min_x(0), max_x(0), min_y(0), max_y(0)
311 {
312 // Empty
313 }
314
325 const Geom_Number & _min_y, const Geom_Number & _max_y,
326 QuadNode * _parent = nullptr)
327 : points(), parent(_parent), nw_child(nullptr), ne_child(nullptr),
328 sw_child(nullptr), se_child(nullptr), color(Color::White), level(0),
330 {
332 << "QuadNode bounds must define a non-empty region";
333 }
334
335 QuadNode(const QuadNode &) = delete;
336
346 const Geom_Number & _max_x,
347 const Geom_Number & _min_y,
348 const Geom_Number & _max_y)
349 {
351 << "QuadNode bounds must define a non-empty region";
352
353 min_x = _min_x;
354 max_x = _max_x;
355 min_y = _min_y;
356 max_y = _max_y;
357 }
358
361
364
367
370
373
376
378 [[nodiscard]] unsigned long & get_level() noexcept { return level; }
379
381 [[nodiscard]] bool is_leaf() const noexcept { return color != Color::Gray; }
382
385 {
386 if (parent == nullptr)
387 return false;
388 return NW_CHILD(parent) == this;
389 }
390
393 {
394 if (parent == nullptr)
395 return false;
396 return NE_CHILD(parent) == this;
397 }
398
401 {
402 if (parent == nullptr)
403 return false;
404 return SW_CHILD(parent) == this;
405 }
406
409 {
410 if (parent == nullptr)
411 return false;
412 return SE_CHILD(parent) == this;
413 }
414
423 [[nodiscard]] bool contains(const Point & p) const noexcept
424 {
425 return p.get_x() >= min_x and p.get_x() < max_x and
426 p.get_y() >= min_y and p.get_y() < max_y;
427 }
428
438 [[nodiscard]] QuadNode * get_child_to(const Point & p) const
439 {
440 assert(nw_child != nullptr);
441 assert(ne_child != nullptr);
442 assert(sw_child != nullptr);
443 assert(se_child != nullptr);
444
446 << "This node does not contain that point";
447
448 if (nw_child->contains(p))
449 return nw_child;
450
451 if (ne_child->contains(p))
452 return ne_child;
453
454 if (sw_child->contains(p))
455 return sw_child;
456
457 if (se_child->contains(p))
458 return se_child;
459
460 return nullptr; // To avoid compiler warnings
461 }
462
471 Point & add_point(const Point & p)
472 {
473 color = Color::Black;
474 return points.append(p);
475 }
476
479 {
480 return count_points(this);
481 }
482
485
488
491
494
497
500
503
506
514 [[nodiscard]] Point * search_point(const Point & p) noexcept
515 {
516 for (Point & point : points)
517 {
518 if (point == p)
519 return &point;
520 }
521 return nullptr;
522 }
523
529 bool remove_point(const Point & p)
530 {
531 for (DynList<Point>::iterator it(points); it.has_curr(); it.next_ne())
532 {
533 const Point & curr = it.get_curr_ne();
534
535 if (curr == p)
536 {
537 it.del();
538 if (points.is_empty())
539 color = Color::White;
540 return true;
541 }
542 }
543 return false;
544 }
545
548 {
549 points.empty();
550 color = Color::White;
551 }
552
578
581
587 template <class Op>
588 void for_each_point(Op & op)
589 {
590 for (Point & point : points)
591 op(point);
592 };
593
595 template <class Op>
596 void for_each_point(Op && op = Op())
597 {
599 }
600
601 QuadNode & operator = (const QuadNode &) = delete;
602};
603
604# endif // QUADNODE_H
Exception handling system with formatted messages for Aleph-w.
#define ah_domain_error_if(C)
Throws std::domain_error if condition holds.
Definition ah-errors.H:527
Doubly-linked list (defined in tpl_dynList.H).
Definition htlist.H:1155
Represents a point with rectangular coordinates in a 2D plane.
Definition point.H:221
Node for QuadTree spatial data structure.
Definition quadnode.H:94
DynList< QuadNode * > get_neighbors()
Find all adjacent leaf nodes.
Definition quadnode.H:560
Color & get_color() noexcept
Get reference to color (for reading/writing via COLOR macro).
Definition quadnode.H:375
Side
Cardinal directions for neighbor navigation.
Definition quadnode.H:134
@ South
Southern neighbor.
@ North
Northern neighbor.
@ East
Eastern neighbor.
@ West
Western neighbor.
bool is_sw_child() const noexcept
Check if this node is the SW child of its parent.
Definition quadnode.H:400
static QuadNode * get_east_neighbor(QuadNode *v) noexcept
Find the eastern neighbor of a node.
Definition quadnode.H:205
QuadNode(const Geom_Number &_min_x, const Geom_Number &_max_x, const Geom_Number &_min_y, const Geom_Number &_max_y, QuadNode *_parent=nullptr)
Construct a node with specified region bounds.
Definition quadnode.H:324
static size_t count_points(QuadNode *node) noexcept
Recursively count all points in a subtree.
Definition quadnode.H:286
QuadNode *& get_sw_child() noexcept
Get reference to SW child (for reading/writing via SW_CHILD macro).
Definition quadnode.H:369
Geom_Number min_y
Minimum Y coordinate.
Definition quadnode.H:157
QuadNode *& get_se_child() noexcept
Get reference to SE child (for reading/writing via SE_CHILD macro).
Definition quadnode.H:372
static QuadNode * get_west_neighbor(QuadNode *v) noexcept
Find the western neighbor of a node.
Definition quadnode.H:227
static void get_neighbors_by_side(QuadNode *node, const Side &side, DynList< QuadNode * > &neighbors)
Recursively collect leaf neighbors on a given side.
Definition quadnode.H:249
bool contains(const Point &p) const noexcept
Check if a point is contained in this node's region.
Definition quadnode.H:423
unsigned long & get_level() noexcept
Get reference to level (for reading/writing via LEVEL macro).
Definition quadnode.H:378
Geom_Number get_height() const noexcept
Get height of this region.
Definition quadnode.H:499
Geom_Number max_x
Maximum X coordinate.
Definition quadnode.H:156
static QuadNode * get_south_neighbor(QuadNode *v) noexcept
Find the southern neighbor of a node.
Definition quadnode.H:183
bool is_ne_child() const noexcept
Check if this node is the NE child of its parent.
Definition quadnode.H:392
Geom_Number max_y
Maximum Y coordinate.
Definition quadnode.H:158
QuadNode *& get_ne_child() noexcept
Get reference to NE child (for reading/writing via NE_CHILD macro).
Definition quadnode.H:366
QuadNode() noexcept
Default constructor - creates a white (empty) node.
Definition quadnode.H:307
const Geom_Number & get_min_y() const noexcept
Get minimum Y coordinate of this region.
Definition quadnode.H:490
bool is_se_child() const noexcept
Check if this node is the SE child of its parent.
Definition quadnode.H:408
const Geom_Number & get_max_y() const noexcept
Get maximum Y coordinate of this region.
Definition quadnode.H:493
void for_each_point(Op &&op=Op())
Apply operation to each point (rvalue reference version).
Definition quadnode.H:596
QuadNode * ne_child
Northeast child.
Definition quadnode.H:147
Geom_Number min_x
Minimum X coordinate.
Definition quadnode.H:155
void empty() noexcept
Remove all points from this node and mark it as White.
Definition quadnode.H:547
Geom_Number get_mid_x() const noexcept
Get midpoint X coordinate.
Definition quadnode.H:502
QuadNode * parent
Parent node (nullptr for root)
Definition quadnode.H:145
QuadNode * get_child_to(const Point &p) const
Find which child node should contain a given point.
Definition quadnode.H:438
DynList< Point > & get_points_set() noexcept
Get reference to the points list (for direct manipulation).
Definition quadnode.H:580
Geom_Number get_mid_y() const noexcept
Get midpoint Y coordinate.
Definition quadnode.H:505
Quad
Quadrant directions for child nodes.
Definition quadnode.H:121
@ SW
Southwest quadrant.
@ NW
Northwest quadrant.
@ NE
Northeast quadrant.
@ SE
Southeast quadrant.
const Geom_Number & get_min_x() const noexcept
Get minimum X coordinate of this region.
Definition quadnode.H:484
QuadNode * sw_child
Southwest child.
Definition quadnode.H:148
Geom_Number get_width() const noexcept
Get width of this region.
Definition quadnode.H:496
bool is_nw_child() const noexcept
Check if this node is the NW child of its parent.
Definition quadnode.H:384
static QuadNode * get_north_neighbor(QuadNode *v) noexcept
Find the northern neighbor of a node.
Definition quadnode.H:161
QuadNode *& get_nw_child() noexcept
Get reference to NW child (for reading/writing via NW_CHILD macro).
Definition quadnode.H:363
QuadNode & operator=(const QuadNode &)=delete
Point & add_point(const Point &p)
Add a point to this node.
Definition quadnode.H:471
void set_region(const Geom_Number &_min_x, const Geom_Number &_max_x, const Geom_Number &_min_y, const Geom_Number &_max_y)
Set the region boundaries for this node.
Definition quadnode.H:345
unsigned long level
Depth in the tree (0 for root)
Definition quadnode.H:152
Point * search_point(const Point &p) noexcept
Search for a point in this node.
Definition quadnode.H:514
void for_each_point(Op &op)
Apply operation to each point in this node.
Definition quadnode.H:588
QuadNode(const QuadNode &)=delete
QuadNode * se_child
Southeast child.
Definition quadnode.H:149
bool is_leaf() const noexcept
Check if this node is a leaf (has no children).
Definition quadnode.H:381
DynList< Point > points
Points stored in this node (only for leaves)
Definition quadnode.H:143
bool remove_point(const Point &p)
Remove a point from this node.
Definition quadnode.H:529
Color color
Node state (White/Gray/Black)
Definition quadnode.H:151
size_t get_num_points() noexcept
Get total number of points in this subtree.
Definition quadnode.H:478
const Geom_Number & get_max_x() const noexcept
Get maximum X coordinate of this region.
Definition quadnode.H:487
Color
Node color states for quadtree nodes.
Definition quadnode.H:105
@ White
Empty leaf node.
@ Gray
Internal node with children.
@ Black
Leaf node with points.
QuadNode *& get_parent() noexcept
Get reference to parent node (for reading/writing via PARENT macro).
Definition quadnode.H:360
QuadNode * nw_child
Northwest child.
Definition quadnode.H:146
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
Singly linked list implementations with head-tail access.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
and
Check uniqueness with explicit hash + equality functors.
2D point and geometric utilities.
#define PARENT(p)
Definition quadnode.H:53
#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