189#include <tclap/CmdLine.h>
198 cout <<
"\n" << string(60,
'=') <<
endl;
199 cout <<
"QuadTree: Basic Operations" <<
endl;
200 cout << string(60,
'=') <<
endl;
206 cout <<
"\nCreated QuadTree for region [0, 100] x [0, 100]" <<
endl;
207 cout <<
"Max points per node before split: 4" <<
endl;
209 cout <<
"\n--- Insertion ---" <<
endl;
216 cout <<
"Inserting points:" <<
endl;
217 for (
const auto& p : points)
220 cout <<
" Inserted " << p <<
endl;
223 cout <<
"\n--- Search ---" <<
endl;
232 cout <<
" Search " << p <<
": "
233 << (found ?
"FOUND" :
"not found") <<
endl;
236 cout <<
"\n--- Contains ---" <<
endl;
237 cout <<
" Contains (25, 25): " << (tree.
contains(
Point(25, 25)) ?
"yes" :
"no") <<
endl;
238 cout <<
" Contains (99, 99): " << (tree.
contains(
Point(99, 99)) ?
"yes" :
"no") <<
endl;
240 cout <<
"\n--- Removal ---" <<
endl;
242 cout <<
" Removing (50, 50)..." <<
endl;
244 cout <<
" Contains (50, 50) after removal: "
253 cout <<
"\n" << string(60,
'=') <<
endl;
254 cout <<
"QuadTree Structure and Subdivision" <<
endl;
255 cout << string(60,
'=') <<
endl;
259 cout <<
"\nCreated QuadTree with max 2 points per node" <<
endl;
260 cout <<
"This will force subdivision earlier." <<
endl;
262 cout <<
"\n--- Step-by-step insertion ---" <<
endl;
266 cout <<
"After inserting (25, 25): root has 1 point" <<
endl;
269 cout <<
"After inserting (75, 25): root has 2 points" <<
endl;
272 cout <<
"\nInserting (25, 75) - will trigger subdivision..." <<
endl;
274 cout <<
"Root split into 4 quadrants:" <<
endl;
275 cout <<
" NW: [0, 50] x [0, 50] - contains (25, 25)" <<
endl;
276 cout <<
" NE: [50, 100] x [0, 50] - contains (75, 25)" <<
endl;
277 cout <<
" SW: [0, 50] x [50, 100] - contains (25, 75)" <<
endl;
278 cout <<
" SE: [50, 100] x [50, 100] - empty" <<
endl;
280 cout <<
"\n--- Visualization ---" <<
endl;
281 cout <<
"+----------+----------+" <<
endl;
282 cout <<
"| * | * |" <<
endl;
283 cout <<
"| (25,25) | (75,25) |" <<
endl;
284 cout <<
"+----------+----------+" <<
endl;
285 cout <<
"| * | |" <<
endl;
286 cout <<
"| (25,75) | (empty) |" <<
endl;
287 cout <<
"+----------+----------+" <<
endl;
288 cout <<
"NW=*, NE=*, SW=*, SE=empty" <<
endl;
296 cout <<
"\n" << string(60,
'=') <<
endl;
297 cout <<
"Practical Example: Geographic Points (Cities)" <<
endl;
298 cout << string(60,
'=') <<
endl;
304 struct City {
string name;
double x,
y; };
306 {
"New York", 800, 400},
307 {
"Los Angeles", 100, 300},
308 {
"Chicago", 600, 420},
309 {
"Houston", 400, 200},
310 {
"Phoenix", 200, 250},
311 {
"Philadelphia", 780, 410},
312 {
"San Antonio", 350, 180},
313 {
"San Diego", 80, 280},
314 {
"Dallas", 420, 220},
315 {
"San Jose", 60, 370}
318 cout <<
"\nInserting " <<
cities.size() <<
" cities..." <<
endl;
322 cout <<
" " <<
city.name <<
" at (" <<
city.x <<
", " <<
city.y <<
")" <<
endl;
325 cout <<
"\n--- Spatial Queries ---" <<
endl;
329 cout <<
"\nLooking for a city at (800, 400)..." <<
endl;
331 cout <<
" Found! (This is New York)" <<
endl;
333 cout <<
" Not found" <<
endl;
337 cout <<
"\nSearching for exact point (795, 408)..." <<
endl;
339 cout <<
" Result: " << (result ?
"found" :
"not found (needs exact match)") <<
endl;
347 cout <<
"\n" << string(60,
'=') <<
endl;
348 cout <<
"Practical Example: Game Collision Detection" <<
endl;
349 cout << string(60,
'=') <<
endl;
351 cout <<
"\nScenario: 2D game with objects in a 800x600 screen" <<
endl;
363 cout <<
"\nPlacing " <<
objects.size() <<
" game objects..." <<
endl;
367 cout <<
"\n--- Collision Query ---" <<
endl;
369 Point player(410, 305);
370 cout <<
"Player at " << player <<
endl;
372 cout <<
"\nChecking for collision with exact position..." <<
endl;
374 cout <<
" COLLISION! Object at player position." <<
endl;
376 cout <<
" No collision at exact position." <<
endl;
379 cout <<
"\nChecking nearby positions for objects:" <<
endl;
383 for (
const auto& pos :
nearby)
386 cout <<
" " << pos <<
": " << (
collision ?
"COLLISION" :
"clear") <<
endl;
389 cout <<
"\n--- Benefits of QuadTree for Games ---" <<
endl;
390 cout <<
"1. Only check objects in player's quadrant region" <<
endl;
391 cout <<
"2. O(log n) average lookup instead of O(n)" <<
endl;
392 cout <<
"3. Scales well with large numbers of objects" <<
endl;
400 cout <<
"\n" << string(60,
'=') <<
endl;
401 cout <<
"Performance Analysis (n = " << n <<
")" <<
endl;
402 cout << string(60,
'=') <<
endl;
404 QuadTree tree(0, 10000, 0, 10000, 10);
413 for (
int i = 0; i < n; ++i)
416 cout <<
"\nGenerated " << n <<
" random points" <<
endl;
419 auto start = chrono::high_resolution_clock::now();
421 for (
const auto& p : points)
424 auto mid = chrono::high_resolution_clock::now();
428 for (
const auto& p : points)
431 auto end = chrono::high_resolution_clock::now();
433 auto insert_us = chrono::duration_cast<chrono::microseconds>(
mid - start).count();
434 auto search_us = chrono::duration_cast<chrono::microseconds>(end -
mid).count();
436 cout <<
"\nResults:" <<
endl;
437 cout <<
" Insert " << n <<
" points: " <<
insert_us <<
" us" <<
endl;
438 cout <<
" Search " << n <<
" points: " <<
search_us <<
" us" <<
endl;
439 cout <<
" Found: " << found <<
"/" << n <<
" points" <<
endl;
440 cout <<
" Avg insert: " << (
insert_us * 1000.0 / n) <<
" ns/point" <<
endl;
441 cout <<
" Avg search: " << (
search_us * 1000.0 / n) <<
" ns/point" <<
endl;
444 cout <<
"\n--- Comparison Note ---" <<
endl;
445 cout <<
"Linear search would require O(" << n <<
") comparisons per query" <<
endl;
446 cout <<
"QuadTree reduces this to O(log n) ~= O(" <<
log2(n) <<
") on average" <<
endl;
454 cout <<
"\n" << string(60,
'=') <<
endl;
455 cout <<
"Tree Traversal" <<
endl;
456 cout << string(60,
'=') <<
endl;
466 cout <<
"\nBuilding tree with " << points.size() <<
" points..." <<
endl;
467 for (
const auto& p : points)
470 cout <<
"\n--- Traversing all nodes ---" <<
endl;
484 string type = node->
is_leaf() ?
"LEAF" :
"INTERNAL";
487 cout <<
" Node (level " <<
LEVEL(node) <<
", " << type;
493 cout <<
"\nTree statistics:" <<
endl;
494 cout <<
" Total nodes: " << node_count <<
endl;
503 TCLAP::CmdLine
cmd(
"QuadTree Spatial Data Structure Example",
' ',
"1.0");
505 TCLAP::ValueArg<int>
nArg(
"n",
"count",
506 "Number of points for performance test",
false, 10000,
"int");
507 TCLAP::SwitchArg
basicArg(
"b",
"basic",
508 "Show basic operations",
false);
509 TCLAP::SwitchArg
structArg(
"s",
"structure",
510 "Show tree structure",
false);
511 TCLAP::SwitchArg
geoArg(
"g",
"geographic",
512 "Show geographic points example",
false);
513 TCLAP::SwitchArg
gameArg(
"c",
"collision",
514 "Show collision detection example",
false);
515 TCLAP::SwitchArg
perfArg(
"p",
"performance",
516 "Run performance analysis",
false);
517 TCLAP::SwitchArg
travArg(
"t",
"traversal",
518 "Show tree traversal",
false);
519 TCLAP::SwitchArg
allArg(
"a",
"all",
520 "Run all demos",
false);
533 int n =
nArg.getValue();
546 cout <<
"=== QuadTree: 2D Spatial Data Structure ===" <<
endl;
547 cout <<
"Hierarchical space partitioning into quadrants" <<
endl;
567 cout <<
"\n=== Summary ===" <<
endl;
568 cout <<
"QuadTree: Efficient 2D spatial indexing" <<
endl;
569 cout <<
"Operations: O(log n) average, O(depth) worst" <<
endl;
570 cout <<
"Use cases: GIS, games, graphics, simulations" <<
endl;
574 catch (TCLAP::ArgException& e)
576 cerr <<
"Error: " << e.error() <<
" for arg " << e.argId() <<
endl;
Represents a point with rectangular coordinates in a 2D plane.
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)
and
Check uniqueness with explicit hash + equality functors.
Divide_Conquer_DP_Result< Cost > divide_and_conquer_partition_dp(const size_t groups, const size_t n, Transition_Cost_Fn transition_cost, const Cost inf=dp_optimization_detail::default_inf< Cost >())
Optimize partition DP using divide-and-conquer optimization.
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.