189#include <tclap/CmdLine.h>
198 return os <<
"(" << p.
get_x() <<
", " << p.
get_y() <<
")";
206 cout <<
"\n" << string(60,
'=') <<
endl;
207 cout <<
"QuadTree: Basic Operations" <<
endl;
214 cout <<
"\nCreated QuadTree for region [0, 100] x [0, 100]" <<
endl;
215 cout <<
"Max points per node before split: 4" <<
endl;
217 cout <<
"\n--- Insertion ---" <<
endl;
224 cout <<
"Inserting points:" <<
endl;
225 for (
const auto& p : points)
240 cout <<
" Search " << p <<
": "
241 << (
found ?
"FOUND" :
"not found") <<
endl;
244 cout <<
"\n--- Contains ---" <<
endl;
248 cout <<
"\n--- Removal ---" <<
endl;
250 cout <<
" Removing (50, 50)..." <<
endl;
252 cout <<
" Contains (50, 50) after removal: "
261 cout <<
"\n" << string(60,
'=') <<
endl;
262 cout <<
"QuadTree Structure and Subdivision" <<
endl;
267 cout <<
"\nCreated QuadTree with max 2 points per node" <<
endl;
268 cout <<
"This will force subdivision earlier." <<
endl;
270 cout <<
"\n--- Step-by-step insertion ---" <<
endl;
274 cout <<
"After inserting (25, 25): root has 1 point" <<
endl;
277 cout <<
"After inserting (75, 25): root has 2 points" <<
endl;
280 cout <<
"\nInserting (25, 75) - will trigger subdivision..." <<
endl;
282 cout <<
"Root split into 4 quadrants:" <<
endl;
283 cout <<
" NW: [0, 50] x [0, 50] - contains (25, 25)" <<
endl;
284 cout <<
" NE: [50, 100] x [0, 50] - contains (75, 25)" <<
endl;
285 cout <<
" SW: [0, 50] x [50, 100] - contains (25, 75)" <<
endl;
286 cout <<
" SE: [50, 100] x [50, 100] - empty" <<
endl;
288 cout <<
"\n--- Visualization ---" <<
endl;
289 cout <<
"+----------+----------+" <<
endl;
291 cout <<
"| (25,25) | (75,25) |" <<
endl;
292 cout <<
"+----------+----------+" <<
endl;
294 cout <<
"| (25,75) | (empty) |" <<
endl;
295 cout <<
"+----------+----------+" <<
endl;
296 cout <<
"NW=*, NE=*, SW=*, SE=empty" <<
endl;
304 cout <<
"\n" << string(60,
'=') <<
endl;
305 cout <<
"Practical Example: Geographic Points (Cities)" <<
endl;
312 struct City {
string name;
double x,
y; };
314 {
"New York", 800, 400},
315 {
"Los Angeles", 100, 300},
316 {
"Chicago", 600, 420},
317 {
"Houston", 400, 200},
318 {
"Phoenix", 200, 250},
319 {
"Philadelphia", 780, 410},
320 {
"San Antonio", 350, 180},
321 {
"San Diego", 80, 280},
322 {
"Dallas", 420, 220},
323 {
"San Jose", 60, 370}
333 cout <<
"\n--- Spatial Queries ---" <<
endl;
337 cout <<
"\nLooking for a city at (800, 400)..." <<
endl;
339 cout <<
" Found! (This is New York)" <<
endl;
345 cout <<
"\nSearching for exact point (795, 408)..." <<
endl;
347 cout <<
" Result: " << (result ?
"found" :
"not found (needs exact match)") <<
endl;
355 cout <<
"\n" << string(60,
'=') <<
endl;
356 cout <<
"Practical Example: Game Collision Detection" <<
endl;
359 cout <<
"\nScenario: 2D game with objects in a 800x600 screen" <<
endl;
375 cout <<
"\n--- Collision Query ---" <<
endl;
380 cout <<
"\nChecking for collision with exact position..." <<
endl;
382 cout <<
" COLLISION! Object at player position." <<
endl;
384 cout <<
" No collision at exact position." <<
endl;
387 cout <<
"\nChecking nearby positions for objects:" <<
endl;
391 for (
const auto& pos :
nearby)
397 cout <<
"\n--- Benefits of QuadTree for Games ---" <<
endl;
398 cout <<
"1. Only check objects in player's quadrant region" <<
endl;
399 cout <<
"2. O(log n) average lookup instead of O(n)" <<
endl;
400 cout <<
"3. Scales well with large numbers of objects" <<
endl;
408 cout <<
"\n" << string(60,
'=') <<
endl;
409 cout <<
"Performance Analysis (n = " << n <<
")" <<
endl;
412 QuadTree tree(0, 10000, 0, 10000, 10);
421 for (
int i = 0; i < n; ++i)
424 cout <<
"\nGenerated " << n <<
" random points" <<
endl;
427 auto start = chrono::high_resolution_clock::now();
429 for (
const auto& p : points)
432 auto mid = chrono::high_resolution_clock::now();
436 for (
const auto& p : points)
439 auto end = chrono::high_resolution_clock::now();
441 auto insert_us = chrono::duration_cast<chrono::microseconds>(
mid - start).count();
442 auto search_us = chrono::duration_cast<chrono::microseconds>(end -
mid).count();
447 cout <<
" Found: " <<
found <<
"/" << n <<
" points" <<
endl;
452 cout <<
"\n--- Comparison Note ---" <<
endl;
453 cout <<
"Linear search would require O(" << n <<
") comparisons per query" <<
endl;
454 cout <<
"QuadTree reduces this to O(log n) ~= O(" <<
log2(n) <<
") on average" <<
endl;
462 cout <<
"\n" << string(60,
'=') <<
endl;
474 cout <<
"\nBuilding tree with " << points.
size() <<
" points..." <<
endl;
475 for (
const auto& p : points)
478 cout <<
"\n--- Traversing all nodes ---" <<
endl;
492 string type = node->
is_leaf() ?
"LEAF" :
"INTERNAL";
495 cout <<
" Node (level " <<
LEVEL(node) <<
", " << type;
501 cout <<
"\nTree statistics:" <<
endl;
502 cout <<
" Total nodes: " << node_count <<
endl;
511 TCLAP::CmdLine
cmd(
"QuadTree Spatial Data Structure Example",
' ',
"1.0");
513 TCLAP::ValueArg<int>
nArg(
"n",
"count",
514 "Number of points for performance test",
false, 10000,
"int");
515 TCLAP::SwitchArg
basicArg(
"b",
"basic",
516 "Show basic operations",
false);
517 TCLAP::SwitchArg
structArg(
"s",
"structure",
518 "Show tree structure",
false);
519 TCLAP::SwitchArg
geoArg(
"g",
"geographic",
520 "Show geographic points example",
false);
521 TCLAP::SwitchArg
gameArg(
"c",
"collision",
522 "Show collision detection example",
false);
523 TCLAP::SwitchArg
perfArg(
"p",
"performance",
524 "Run performance analysis",
false);
525 TCLAP::SwitchArg
travArg(
"t",
"traversal",
526 "Show tree traversal",
false);
527 TCLAP::SwitchArg
allArg(
"a",
"all",
528 "Run all demos",
false);
541 int n =
nArg.getValue();
554 cout <<
"=== QuadTree: 2D Spatial Data Structure ===" <<
endl;
555 cout <<
"Hierarchical space partitioning into quadrants" <<
endl;
575 cout <<
"\n=== Summary ===" <<
endl;
576 cout <<
"QuadTree: Efficient 2D spatial indexing" <<
endl;
577 cout <<
"Operations: O(log n) average, O(depth) worst" <<
endl;
578 cout <<
"Use cases: GIS, games, graphics, simulations" <<
endl;
582 catch (TCLAP::ArgException& e)
584 cerr <<
"Error: " << e.error() <<
" for arg " << e.argId() <<
endl;
size_t size() const noexcept
Count the number of elements of the list.
Rectangular point in the plane.
const Geom_Number & get_y() const
Returns y value.
const Geom_Number & get_x() const
Returns x value.
Node for QuadTree spatial data structure.
DynList< Point > & get_points_set() noexcept
Get reference to the points list (for direct manipulation).
bool is_leaf() const noexcept
Check if this node is a leaf (has no children).
QuadTree - Hierarchical spatial index for 2D points.
void for_each(Op &op)
Apply an operation to each node in the tree.
void remove(const Point &p)
Remove a point from the tree.
Point * search(const Point &p) noexcept
Search for a point in the tree.
bool contains(const Point &p) const noexcept
Check if a point is within the tree's region.
Point * insert(Node *&r, const Point &p)
Recursive insert helper.
__gmp_expr< T, __gmp_unary_expr< __gmp_expr< T, U >, __gmp_log2_function > > log2(const __gmp_expr< T, U > &expr)
std::ostream & operator<<(std::ostream &osObject, const Field< T > &rightOp)
DynList< T > maps(const C &c, Op op)
Classic map operation.
QuadTree spatial data structure for efficient 2D point indexing.
void demo_basic_operations()
Demonstrate basic QuadTree operations.
void demo_geographic_points()
Practical example: Geographic Points.
void demo_traversal()
Demonstrate node traversal.
void demo_collision_detection()
Practical example: Game Collision Detection.
void demo_tree_structure()
Demonstrate tree structure.