Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tikz_tree_structures_example.cc
Go to the documentation of this file.
1#include <fstream>
2#include <iostream>
3#include <string>
4
5#include <quadtree.H>
7#include <tpl_r_star_tree.H>
8
9using namespace Aleph;
10
11namespace
12{
13
15{
17 pts.append(Point(10, 10));
18 pts.append(Point(20, 30));
19 pts.append(Point(35, 12));
20 pts.append(Point(48, 42));
21 pts.append(Point(60, 18));
22 pts.append(Point(78, 36));
23 pts.append(Point(88, 8));
24 return pts;
25}
26
28{
30 pts.append(Point(2, 2));
31 pts.append(Point(6, 7));
32 pts.append(Point(9, 3));
33 pts.append(Point(13, 8));
34 pts.append(Point(16, 1));
35 pts.append(Point(19, 6));
36 return pts;
37}
38
40{
41 AABBTree tree;
43 entries.append({Rectangle(0, 0, 4, 4), 0});
44 entries.append({Rectangle(3, 2, 9, 7), 1});
45 entries.append({Rectangle(11, 1, 15, 5), 2});
46 entries.append({Rectangle(14, 4, 19, 9), 3});
47 entries.append({Rectangle(6, 8, 10, 12), 4});
48 tree.build(entries);
49 return tree;
50}
51
52// QuadTree exposes its node structure through public accessors
53// (get_root(), QuadNode::get_nw_child()/.../get_se_child(), is_leaf(),
54// get_points_set()) but has no built-in TikZ visualizer, so this example
55// walks it directly to collect leaf regions (by depth) and stored points.
56struct QuadTreeSnapshot
57{
58 Array<Rectangle> leaf_regions;
59 Array<size_t> leaf_depths;
60 Array<Point> points;
61};
62
63void collect_quadtree_rec(QuadNode * node, const size_t depth, QuadTreeSnapshot & snap)
64{
65 if (node == nullptr)
66 return;
67
68 if (node->is_leaf())
69 {
70 snap.leaf_regions.append(Rectangle(node->get_min_x(), node->get_min_y(),
71 node->get_max_x(), node->get_max_y()));
72 snap.leaf_depths.append(depth);
73 for (const Point & p : node->get_points_set())
74 snap.points.append(p);
75 return;
76 }
77
78 collect_quadtree_rec(node->get_nw_child(), depth + 1, snap);
79 collect_quadtree_rec(node->get_ne_child(), depth + 1, snap);
80 collect_quadtree_rec(node->get_sw_child(), depth + 1, snap);
81 collect_quadtree_rec(node->get_se_child(), depth + 1, snap);
82}
83
84QuadTreeSnapshot collect_quadtree(QuadTree & tree)
85{
86 QuadTreeSnapshot snap;
88 return snap;
89}
90
91// Colors cycle by subdivision depth so sibling quadrants at the same depth
92// share a color and successive splits are visually distinguishable.
93std::string depth_color(const size_t depth)
94{
95 static const char * colors[] =
96 {"blue!55", "orange!70!black", "green!55!black", "red!60", "violet!65", "brown!60"};
97 constexpr size_t num_colors = sizeof(colors) / sizeof(colors[0]);
98 return colors[depth % num_colors];
99}
100
102{
103 // Deliberately uneven spread (a dense cluster plus scattered outliers) so
104 // the quadtree subdivides non-uniformly across depths. All coordinates
105 // stay inside [0, 100) since QuadNode::contains() uses a half-open
106 // [min, max) region: a point exactly on the upper/right root boundary
107 // would silently fail to insert.
109 pts.append(Point(12, 15));
110 pts.append(Point(18, 22));
111 pts.append(Point(15, 30));
112 pts.append(Point(22, 12));
113 pts.append(Point(28, 28));
114 pts.append(Point(20, 20));
115 pts.append(Point(70, 75));
116 pts.append(Point(80, 65));
117 pts.append(Point(75, 82));
118 pts.append(Point(85, 88));
119 pts.append(Point(60, 15));
120 pts.append(Point(90, 20));
121 pts.append(Point(45, 60));
122 pts.append(Point(35, 85));
123 pts.append(Point(8, 92));
124 pts.append(Point(95, 5));
125 return pts;
126}
127
129{
131 for (int i = 0; i < 24; ++i)
132 {
133 const int col = i % 6;
134 const int row = i / 6;
135 const Geom_Number x0 = Geom_Number(col * 10 + (i % 3));
136 const Geom_Number y0 = Geom_Number(row * 9 + (i % 2) * 2);
137 rects.append(Rectangle(x0, y0, x0 + 6, y0 + 5));
138 }
139 return rects;
140}
141
142} // namespace
143
144int main(int argc, char * argv[])
145{
146 const std::string output_path =
147 argc > 1 ? argv[1] : "tikz_tree_structures_example.tex";
148
149 std::ofstream out(output_path);
150 if (not out)
151 {
152 std::cerr << "Cannot open output file: " << output_path << '\n';
153 return 1;
154 }
155
156 Tikz_Plane kd_plane(200, 120, 6, 6);
157 kd_plane.put_cartesian_axis();
158 kd_plane.put_coordinate_grid(5, 5, true);
159 kd_plane.enable_auto_legend(true);
160 kd_plane.set_point_radius_mm(0.65);
161
162 const auto kd = KDTreePointSearch::build(make_kd_points(), 0, 0, 100, 50);
163 const auto kd_snap = visualize_kdtree_partitions(kd_plane, kd, true, true);
165 Text(Point(-2, 52),
166 "KD-tree partitions=" + std::to_string(kd_snap.partitions.size())),
167 make_tikz_draw_style("black"),
169
170 Tikz_Plane range_plane(200, 120, 6, 6);
171 range_plane.put_cartesian_axis();
172 range_plane.put_coordinate_grid(2, 2, true);
173 range_plane.enable_auto_legend(true);
174 range_plane.set_point_radius_mm(0.75);
175
178 const Rectangle range_query(5, 2, 15, 7);
181 Text(Point(0, 10),
182 "Range-tree nodes=" + std::to_string(rv.snapshot.nodes.size()) +
183 ", hits=" + std::to_string(rv.query_hits.size())),
184 make_tikz_draw_style("black"),
186
187 Tikz_Plane aabb_plane(200, 120, 6, 6);
188 aabb_plane.put_cartesian_axis();
189 aabb_plane.put_coordinate_grid(2, 2, true);
190 aabb_plane.enable_auto_legend(true);
191
193 const Rectangle aabb_query(2, 1, 8, 6);
196 Text(Point(-1, 13),
197 "AABB nodes=" + std::to_string(av.snapshot.nodes.size()) +
198 ", hits=" + std::to_string(av.query_hit_ids.size())),
199 make_tikz_draw_style("black"),
201
202 // QuadTree: no dedicated visualizer exists yet (unlike KD/Range/AABB
203 // above), so leaf regions are collected by walking the public node API
204 // directly (see collect_quadtree_rec) and drawn colored by subdivision
205 // depth, one wireframe rectangle per leaf.
206 Tikz_Plane quadtree_plane(200, 120, 6, 6);
207 quadtree_plane.put_cartesian_axis();
208 quadtree_plane.put_coordinate_grid(10, 10, true);
209 quadtree_plane.set_point_radius_mm(0.7);
210
212 for (const Point & p : make_quadtree_points())
213 quadtree.insert(p);
214
215 const QuadTreeSnapshot qsnap = collect_quadtree(quadtree);
216 for (size_t i = 0; i < qsnap.leaf_regions.size(); ++i)
217 put_in_plane(quadtree_plane, qsnap.leaf_regions(i),
218 tikz_wire_style(depth_color(qsnap.leaf_depths(i))),
222 Text(Point(-2, 105),
223 "QuadTree leaves=" + std::to_string(qsnap.leaf_regions.size()) +
224 ", points=" + std::to_string(qsnap.points.size())),
225 make_tikz_draw_style("black"),
227
228 // R-tree (Guttman quadratic split) and R*-tree, built from the *same*
229 // rectangles and queried with the same rectangle, so the two split
230 // heuristics can be compared directly: R*-tree typically yields less
231 // node overlap for the same data.
232 Tikz_Plane rtree_plane(200, 120, 6, 6);
233 rtree_plane.put_cartesian_axis();
234 rtree_plane.put_coordinate_grid(10, 10, true);
235
238 {
240 for (size_t i = 0; i < rects.size(); ++i)
241 {
242 rtree.insert(rects(i), static_cast<int>(i));
243 rstar_tree.insert(rects(i), static_cast<int>(i));
244 }
245 }
246 const Rectangle rtree_query(8, 5, 28, 20);
249 Text(Point(-2, 47),
250 "R-tree (Guttman) nodes=" + std::to_string(rt_result.snapshot.nodes.size()) +
251 ", hits=" + std::to_string(rt_result.query_hit_boxes.size())),
252 make_tikz_draw_style("black"),
254
255 Tikz_Plane rstar_plane(200, 120, 6, 6);
256 rstar_plane.put_cartesian_axis();
257 rstar_plane.put_coordinate_grid(10, 10, true);
258
261 Text(Point(-2, 47),
262 "R*-tree nodes=" + std::to_string(rstar_result.snapshot.nodes.size()) +
263 ", hits=" + std::to_string(rstar_result.query_hit_boxes.size())),
264 make_tikz_draw_style("black"),
266
267 out << "\\documentclass[tikz,border=8pt]{standalone}\n"
268 << "\\usepackage{tikz}\n"
269 << "\\begin{document}\n\n";
270
271 kd_plane.draw(out, true);
272 out << "\n\\vspace{4mm}\n\n";
273 range_plane.draw(out, true);
274 out << "\n\\vspace{4mm}\n\n";
275 aabb_plane.draw(out, true);
276 out << "\n\\vspace{4mm}\n\n";
277 quadtree_plane.draw(out, true);
278 out << "\n\\vspace{4mm}\n\n";
279 rtree_plane.draw(out, true);
280 out << "\n\\vspace{4mm}\n\n";
281 rstar_plane.draw(out, true);
282 out << "\n\\end{document}\n";
283
284 std::cout << "Generated " << output_path << '\n';
285 std::cout << "Compile with: pdflatex " << output_path << '\n';
286 return 0;
287}
int main()
size_t size_t int32_t * out
Definition ca-c-api.h:120
size_t row
Definition ca-c-api.h:115
size_t size_t col
Definition ca-c-api.h:116
Axis-aligned bounding box tree for spatial queries.
size_t build(Array< size_t > &idx, const size_t lo, const size_t hi)
Simple dynamic array with automatic resizing and functional operations.
Definition tpl_array.H:138
T & append(const T &data)
Append a copy of data
Definition tpl_array.H:250
Doubly-linked list (defined in tpl_dynList.H).
Definition htlist.H:1155
T & append(const T &item)
Definition htlist.H:1271
static KDTreePointSearch build(const Array< Point > &points, const Geom_Number &xmin, const Geom_Number &ymin, const Geom_Number &xmax, const Geom_Number &ymax)
Build a balanced KD-tree from a point array.
Represents a point with rectangular coordinates in a 2D plane.
Definition point.H:221
Dynamic R-tree indexing axis-aligned rectangles by payload.
Definition tpl_r_tree.H:118
Static 2D range tree for orthogonal range queries.
void build(const DynList< Point > &points)
Build the range tree from a point set.
An axis-aligned rectangle.
Definition point.H:1789
Represents a text string positioned at a 2D point.
Definition point.H:2817
2D TikZ canvas storing geometry objects and emitting LaTeX output.
Definition tikzgeom.H:200
static constexpr int Layer_Default
Definition tikzgeom.H:203
static constexpr int Layer_Overlay
Definition tikzgeom.H:205
Node for QuadTree spatial data structure.
Definition quadnode.H:94
QuadNode *& get_sw_child() noexcept
Get reference to SW child (for reading/writing via SW_CHILD macro).
Definition quadnode.H:369
QuadNode *& get_se_child() noexcept
Get reference to SE child (for reading/writing via SE_CHILD macro).
Definition quadnode.H:372
QuadNode *& get_ne_child() noexcept
Get reference to NE child (for reading/writing via NE_CHILD macro).
Definition quadnode.H:366
const Geom_Number & get_min_y() const noexcept
Get minimum Y coordinate of this region.
Definition quadnode.H:490
const Geom_Number & get_max_y() const noexcept
Get maximum Y coordinate of this region.
Definition quadnode.H:493
const Geom_Number & get_min_x() const noexcept
Get minimum X coordinate of this region.
Definition quadnode.H:484
QuadNode *& get_nw_child() noexcept
Get reference to NW child (for reading/writing via NW_CHILD macro).
Definition quadnode.H:363
bool is_leaf() const noexcept
Check if this node is a leaf (has no children).
Definition quadnode.H:381
const Geom_Number & get_max_x() const noexcept
Get maximum X coordinate of this region.
Definition quadnode.H:487
QuadTree - Hierarchical spatial index for 2D points.
Definition quadtree.H:126
Node * get_root() noexcept
Get the root node.
Definition quadtree.H:451
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_y0_function > > y0(const __gmp_expr< T, U > &expr)
Definition gmpfrxx.h:4113
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
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
AABBTreeQueryVizResult visualize_aabb_tree_query(Tikz_Plane &plane, const AABBTree &tree, const Rectangle &query_rect, const Tikz_Style &node_bbox_style=tikz_wire_style("teal!70!black"), const Tikz_Style &leaf_bbox_style=tikz_wire_style("blue!70"), const Tikz_Style &query_rect_style=tikz_wire_style("red", true), const Tikz_Style &query_hit_style=tikz_wire_style("red"))
Visualize AABB tree with a rectangle query overlay.
RangeTreeQueryVizResult visualize_range_tree_query(Tikz_Plane &plane, const RangeTree2D &tree, const Rectangle &query_rect, const bool draw_points=true, const Tikz_Style &split_style=tikz_wire_style("purple"), const Tikz_Style &point_style=tikz_points_style("black"), const Tikz_Style &query_rect_style=tikz_wire_style("red", true), const Tikz_Style &query_hit_style=tikz_points_style("red"))
Visualize range-tree plus a query rectangle and matching points.
void put_in_plane(Tikz_Plane &plane, const Geom &geom_obj)
Insert any supported geometry type in a Tikz_Plane.
Definition tikzgeom.H:1511
KDTreePointSearch::DebugSnapshot visualize_kdtree_partitions(Tikz_Plane &plane, const KDTreePointSearch &kd_tree, const bool draw_partition_boxes=false, const bool draw_points=true, const Tikz_Style &partition_style=tikz_wire_style("gray!55", true), const Tikz_Style &split_style=tikz_wire_style("blue!70"), const Tikz_Style &point_style=tikz_points_style("red"))
Visualize KD-tree recursive space partitions.
void put_points(Tikz_Plane &plane, const Array< Point > &pts, const Tikz_Style &style=tikz_points_style(), const int layer=Tikz_Plane::Layer_Default)
Inserts all points from an Array<Point> into the plane.
mpq_class Geom_Number
Numeric type used by the geometry module.
Definition point.H:113
RTreeQueryVizResult< Payload, MaxEntries, MinEntries, Variant > visualize_rtree_query(Tikz_Plane &plane, const RTree< Payload, MaxEntries, MinEntries, Variant > &tree, const Rectangle &query_rect, const Tikz_Style &node_bbox_style=tikz_wire_style("teal!70!black"), const Tikz_Style &leaf_bbox_style=tikz_wire_style("blue!70"), const Tikz_Style &entry_bbox_style=tikz_wire_style("gray!55"), const Tikz_Style &query_rect_style=tikz_wire_style("red", true), const Tikz_Style &query_hit_style=tikz_wire_style("red"))
Visualize an R-tree/R*-tree with a rectangle query overlay, highlighting every entry whose bbox inter...
Tikz_Style make_tikz_draw_style(const std::string &draw_color)
Create a basic draw style with a custom color.
Definition tikzgeom.H:172
Tikz_Style tikz_wire_style(const std::string &color="black", const bool dashed=false, const bool with_arrow=false)
Creates a style optimized for wireframe segments and polygons.
Tikz_Style tikz_points_style(const std::string &color="black", const double opacity=-1.0)
Creates a style optimized for point clouds.
QuadTree spatial data structure for efficient 2D point indexing.
Helpers to visualize computational-geometry algorithm results in TikZ.
R*-tree: an R-tree tuned with the Beckmann-Kriegel-Schneider-Seeger heuristics.