ZLayout EDA Library v1.0.0
Advanced Electronic Design Automation Layout Library with Bilingual Documentation
Loading...
Searching...
No Matches
quadtree.hpp
Go to the documentation of this file.
1
5
6#pragma once
7
10#include <vector>
11#include <memory>
12#include <functional>
13#include <string>
14#include <mutex>
15#include <algorithm>
16
17namespace zlayout {
18namespace spatial {
19
27template<typename T>
29public:
30 using ObjectType = T;
31 using BoundingBoxFunc = std::function<geometry::Rectangle(const T&)>;
32
34 std::vector<T> objects;
35 std::unique_ptr<QuadTreeNode> children[4];
36 bool divided;
37 size_t capacity;
38 size_t max_depth;
39 size_t depth;
40
49 size_t capacity = 10,
50 size_t max_depth = 8,
51 size_t depth = 0);
52
59 bool insert(const T& object, const BoundingBoxFunc& get_bbox);
60
67 std::vector<T> query_range(const geometry::Rectangle& range,
68 const BoundingBoxFunc& get_bbox) const;
69
76 std::vector<T> query_point(const geometry::Point& point,
77 const BoundingBoxFunc& get_bbox) const;
78
82 size_t size() const;
83
87 void clear();
88
92 bool is_divided() const { return divided; }
93
97 std::vector<T> get_all_objects() const;
98
99private:
103 void subdivide();
104
108 bool intersects_boundary(const T& object, const BoundingBoxFunc& get_bbox) const;
109};
110
119template<typename T>
120class QuadTree {
121public:
122 using ObjectType = T;
123 using BoundingBoxFunc = std::function<geometry::Rectangle(const T&)>;
124
125private:
126 std::unique_ptr<QuadTreeNode<T>> root;
127 BoundingBoxFunc get_bounding_box;
128 size_t object_count;
129 size_t capacity;
130 size_t max_depth;
131 bool collect_statistics;
132 mutable std::mutex tree_mutex; // For thread-safe operations
133
134public:
143 BoundingBoxFunc get_bbox,
144 size_t capacity = 10,
145 size_t max_depth = 8);
146
152 bool insert(const T& object);
153
159 std::vector<T> query_range(const geometry::Rectangle& range) const;
160
166 std::vector<T> query_point(const geometry::Point& point) const;
167
174 std::vector<T> query_nearby(const T& target, double distance) const;
175
180 std::vector<std::pair<T, T>> find_potential_intersections() const;
181
187 std::vector<std::pair<T, T>> find_intersections(
188 std::function<bool(const T&, const T&)> collision_func) const;
189
193 size_t size() const { return object_count; }
194
198 bool empty() const { return object_count == 0; }
199
203 void clear();
204
208 struct Statistics {
214 double tree_efficiency; // objects / total_nodes
215 };
216
220 Statistics get_statistics() const;
221
225 const QuadTreeNode<T>* get_root() const { return root.get(); }
226
230 void rebuild(size_t new_capacity, size_t new_max_depth);
231
237 bool remove(const T& object);
238
245 bool update(const T& old_object, const T& new_object);
246
252 size_t batch_insert(const std::vector<T>& objects);
253
259 size_t batch_remove(const std::vector<T>& objects);
260
264 class Iterator {
265 private:
266 const QuadTree* tree;
267 std::vector<T> objects;
268 size_t current_index;
269
270 public:
271 Iterator(const QuadTree* tree, bool is_end = false);
272
273 const T& operator*() const;
274 const T* operator->() const;
276 bool operator!=(const Iterator& other) const;
277 bool operator==(const Iterator& other) const;
278 };
279
283 Iterator begin() const;
284
288 Iterator end() const;
289
295 bool contains(const T& object) const;
296
301 std::vector<T> get_all_objects() const;
302
309 std::vector<T> query_circle(const geometry::Point& center, double radius) const;
310
317 std::vector<T> query_k_nearest(const T& target, size_t k) const;
318
323 void optimize();
324
338 double fill_factor; // percentage of nodes that are at capacity
339 std::vector<size_t> objects_per_level; // objects at each depth level
340 };
341
345 DetailedStatistics get_detailed_statistics() const;
346
352 bool merge(const QuadTree& other);
353
359 std::vector<std::unique_ptr<QuadTree>> split_by_regions(
360 const std::vector<geometry::Rectangle>& regions) const;
361
366 bool validate() const;
367
371 std::string to_string() const;
372
377 void set_statistics_collection(bool enable) { collect_statistics = enable; }
378
383 double get_load_factor() const;
384
385private:
389 bool remove_from_node(QuadTreeNode<T>* node, const T& object);
390
394 void collect_all_objects(const QuadTreeNode<T>* node, std::vector<T>& objects) const;
395
399 void find_k_nearest_recursive(const QuadTreeNode<T>* node, const T& target,
400 size_t k, std::vector<std::pair<T, double>>& candidates) const;
401
405 void calculate_detailed_statistics_recursive(const QuadTreeNode<T>* node,
406 DetailedStatistics& stats) const;
407
411 bool validate_node(const QuadTreeNode<T>* node) const;
412
416 void node_to_string(const QuadTreeNode<T>* node, std::string& result,
417 const std::string& indent = "") const;
418};
419
420// Specialized QuadTree for common geometric types
421
426
431
435std::unique_ptr<RectangleQuadTree> create_rectangle_quadtree(
436 const geometry::Rectangle& boundary,
437 size_t capacity = 10,
438 size_t max_depth = 8);
439
443std::unique_ptr<PointQuadTree> create_point_quadtree(
444 const geometry::Rectangle& boundary,
445 size_t capacity = 10,
446 size_t max_depth = 8);
447
448// Template implementation (must be in header for template instantiation)
449
450template<typename T>
459
460template<typename T>
461bool QuadTreeNode<T>::insert(const T& object, const BoundingBoxFunc& get_bbox) {
462 // Check if object fits in this boundary
463 if (!intersects_boundary(object, get_bbox)) {
464 return false;
465 }
466
467 // If we have space and haven't subdivided, add it here
468 if (objects.size() < capacity && !divided) {
469 objects.push_back(object);
470 return true;
471 }
472
473 // If we can still subdivide, do so
474 if (!divided && depth < max_depth) {
475 subdivide();
476 }
477
478 // Try to insert into children
479 if (divided) {
480 for (int i = 0; i < 4; ++i) {
481 if (children[i]->insert(object, get_bbox)) {
482 return true;
483 }
484 }
485 // If no child could contain it, store it at this level
486 objects.push_back(object);
487 return true;
488 } else {
489 // No more subdivisions possible, store here
490 objects.push_back(object);
491 return true;
492 }
493}
494
495template<typename T>
497 const BoundingBoxFunc& get_bbox) const {
498 std::vector<T> result;
499
500 // Check if this node intersects with query range
501 if (!boundary.intersects(range)) {
502 return result;
503 }
504
505 // Check objects in this node
506 for (const auto& object : objects) {
507 geometry::Rectangle obj_bbox = get_bbox(object);
508 if (obj_bbox.intersects(range)) {
509 result.push_back(object);
510 }
511 }
512
513 // Recursively check children
514 if (divided) {
515 for (int i = 0; i < 4; ++i) {
516 auto child_results = children[i]->query_range(range, get_bbox);
517 result.insert(result.end(), child_results.begin(), child_results.end());
518 }
519 }
520
521 return result;
522}
523
524template<typename T>
526 const BoundingBoxFunc& get_bbox) const {
527 std::vector<T> result;
528
529 // Check if point is in this boundary
530 if (!boundary.contains_point(point)) {
531 return result;
532 }
533
534 // Check objects in this node
535 for (const auto& object : objects) {
536 geometry::Rectangle obj_bbox = get_bbox(object);
537 if (obj_bbox.contains_point(point)) {
538 result.push_back(object);
539 }
540 }
541
542 // Recursively check children
543 if (divided) {
544 for (int i = 0; i < 4; ++i) {
545 auto child_results = children[i]->query_point(point, get_bbox);
546 result.insert(result.end(), child_results.begin(), child_results.end());
547 }
548 }
549
550 return result;
551}
552
553template<typename T>
554void QuadTreeNode<T>::subdivide() {
555 double x = boundary.x;
556 double y = boundary.y;
557 double w = boundary.width / 2.0;
558 double h = boundary.height / 2.0;
559
560 // Create four child nodes (NW, NE, SW, SE)
561 children[0] = std::make_unique<QuadTreeNode>(
562 geometry::Rectangle(x, y + h, w, h), capacity, max_depth, depth + 1);
563 children[1] = std::make_unique<QuadTreeNode>(
564 geometry::Rectangle(x + w, y + h, w, h), capacity, max_depth, depth + 1);
565 children[2] = std::make_unique<QuadTreeNode>(
566 geometry::Rectangle(x, y, w, h), capacity, max_depth, depth + 1);
567 children[3] = std::make_unique<QuadTreeNode>(
568 geometry::Rectangle(x + w, y, w, h), capacity, max_depth, depth + 1);
569
570 divided = true;
571}
572
573template<typename T>
574bool QuadTreeNode<T>::intersects_boundary(const T& object, const BoundingBoxFunc& get_bbox) const {
575 return boundary.intersects(get_bbox(object));
576}
577
578template<typename T>
579size_t QuadTreeNode<T>::size() const {
580 size_t count = objects.size();
581 if (divided) {
582 for (int i = 0; i < 4; ++i) {
583 count += children[i]->size();
584 }
585 }
586 return count;
587}
588
589template<typename T>
591 objects.clear();
592 if (divided) {
593 for (int i = 0; i < 4; ++i) {
594 children[i].reset();
595 }
596 divided = false;
597 }
598}
599
600template<typename T>
601std::vector<T> QuadTreeNode<T>::get_all_objects() const {
602 std::vector<T> result = objects;
603 if (divided) {
604 for (int i = 0; i < 4; ++i) {
605 auto child_objects = children[i]->get_all_objects();
606 result.insert(result.end(), child_objects.begin(), child_objects.end());
607 }
608 }
609 return result;
610}
611
612template<typename T>
614 BoundingBoxFunc get_bbox,
615 size_t capacity,
616 size_t max_depth)
617 : root(std::make_unique<QuadTreeNode<T>>(boundary, capacity, max_depth, 0)),
618 get_bounding_box(get_bbox),
619 object_count(0),
620 capacity(capacity),
621 max_depth(max_depth),
622 collect_statistics(true) {
623 // Initialize other members
624}
625
626template<typename T>
627bool QuadTree<T>::insert(const T& object) {
628 std::lock_guard<std::mutex> lock(tree_mutex);
629
630 if (root->insert(object, get_bounding_box)) {
631 object_count++;
632 return true;
633 }
634 return false;
635}
636
637template<typename T>
638std::vector<T> QuadTree<T>::query_range(const geometry::Rectangle& range) const {
639 std::lock_guard<std::mutex> lock(tree_mutex);
640
641 return root->query_range(range, get_bounding_box);
642}
643
644template<typename T>
645std::vector<T> QuadTree<T>::query_point(const geometry::Point& point) const {
646 std::lock_guard<std::mutex> lock(tree_mutex);
647
648 return root->query_point(point, get_bounding_box);
649}
650
651template<typename T>
652std::vector<T> QuadTree<T>::query_nearby(const T& target, double distance) const {
653 // Implementation of query_nearby method
654 // This is a placeholder and should be implemented
655 return std::vector<T>();
656}
657
658template<typename T>
659std::vector<std::pair<T, T>> QuadTree<T>::find_potential_intersections() const {
660 // Implementation of find_potential_intersections method
661 // This is a placeholder and should be implemented
662 return std::vector<std::pair<T, T>>();
663}
664
665template<typename T>
666std::vector<std::pair<T, T>> QuadTree<T>::find_intersections(
667 std::function<bool(const T&, const T&)> collision_func) const {
668 // Implementation of find_intersections method
669 // This is a placeholder and should be implemented
670 return std::vector<std::pair<T, T>>();
671}
672
673template<typename T>
675 std::lock_guard<std::mutex> lock(tree_mutex);
676
677 root->clear();
678 object_count = 0;
679}
680
681template<typename T>
683 std::lock_guard<std::mutex> lock(tree_mutex);
684
685 Statistics stats = {};
686 stats.total_nodes = 1; // Assuming a single root node
687 stats.total_objects = object_count;
688 stats.max_depth_reached = 1; // Assuming a single level tree
689
690 return stats;
691}
692
693template<typename T>
694void QuadTree<T>::rebuild(size_t new_capacity, size_t new_max_depth) {
695 // Implementation of rebuild method
696 // This is a placeholder and should be implemented
697}
698
699template<typename T>
700bool QuadTree<T>::remove(const T& object) {
701 std::lock_guard<std::mutex> lock(tree_mutex);
702
703 if (remove_from_node(root.get(), object)) {
704 object_count--;
705 return true;
706 }
707 return false;
708}
709
710template<typename T>
711bool QuadTree<T>::remove_from_node(QuadTreeNode<T>* node, const T& object) {
712 if (!node) return false;
713
714 // Try to remove from this node's objects
715 auto it = std::find(node->objects.begin(), node->objects.end(), object);
716 if (it != node->objects.end()) {
717 node->objects.erase(it);
718 return true;
719 }
720
721 // Try to remove from children
722 if (node->divided) {
723 for (int i = 0; i < 4; ++i) {
724 if (remove_from_node(node->children[i].get(), object)) {
725 return true;
726 }
727 }
728 }
729
730 return false;
731}
732
733template<typename T>
734bool QuadTree<T>::update(const T& old_object, const T& new_object) {
735 std::lock_guard<std::mutex> lock(tree_mutex);
736
737 if (remove(old_object)) {
738 return insert(new_object);
739 }
740 return false;
741}
742
743template<typename T>
744size_t QuadTree<T>::batch_insert(const std::vector<T>& objects) {
745 std::lock_guard<std::mutex> lock(tree_mutex);
746
747 size_t success_count = 0;
748 for (const auto& object : objects) {
749 if (root->insert(object, get_bounding_box)) {
750 object_count++;
751 success_count++;
752 }
753 }
754 return success_count;
755}
756
757template<typename T>
758size_t QuadTree<T>::batch_remove(const std::vector<T>& objects) {
759 std::lock_guard<std::mutex> lock(tree_mutex);
760
761 size_t success_count = 0;
762 for (const auto& object : objects) {
763 if (remove_from_node(root.get(), object)) {
764 object_count--;
765 success_count++;
766 }
767 }
768 return success_count;
769}
770
771template<typename T>
773 return Iterator(this, false);
774}
775
776template<typename T>
778 return Iterator(this, true);
779}
780
781template<typename T>
782bool QuadTree<T>::contains(const T& object) const {
783 geometry::Rectangle bbox = get_bounding_box(object);
784 auto candidates = query_range(bbox);
785 return std::find(candidates.begin(), candidates.end(), object) != candidates.end();
786}
787
788template<typename T>
789std::vector<T> QuadTree<T>::get_all_objects() const {
790 std::lock_guard<std::mutex> lock(tree_mutex);
791
792 std::vector<T> result;
793 collect_all_objects(root.get(), result);
794 return result;
795}
796
797template<typename T>
798void QuadTree<T>::collect_all_objects(const QuadTreeNode<T>* node, std::vector<T>& objects) const {
799 if (!node) return;
800
801 objects.insert(objects.end(), node->objects.begin(), node->objects.end());
802
803 if (node->divided) {
804 for (int i = 0; i < 4; ++i) {
805 collect_all_objects(node->children[i].get(), objects);
806 }
807 }
808}
809
810template<typename T>
811std::vector<T> QuadTree<T>::query_circle(const geometry::Point& center, double radius) const {
812 // Query square region first, then filter by distance
813 geometry::Rectangle search_area(center.x - radius, center.y - radius,
814 2 * radius, 2 * radius);
815 auto candidates = query_range(search_area);
816
817 std::vector<T> result;
818 for (const auto& candidate : candidates) {
819 geometry::Rectangle bbox = get_bounding_box(candidate);
820 geometry::Point candidate_center = bbox.center();
821
822 if (center.distance_to(candidate_center) <= radius) {
823 result.push_back(candidate);
824 }
825 }
826
827 return result;
828}
829
830template<typename T>
831std::vector<T> QuadTree<T>::query_k_nearest(const T& target, size_t k) const {
832 std::vector<std::pair<T, double>> candidates;
833 find_k_nearest_recursive(root.get(), target, k, candidates);
834
835 // Sort by distance and return top k
836 std::sort(candidates.begin(), candidates.end(),
837 [](const auto& a, const auto& b) { return a.second < b.second; });
838
839 std::vector<T> result;
840 for (size_t i = 0; i < std::min(k, candidates.size()); ++i) {
841 result.push_back(candidates[i].first);
842 }
843
844 return result;
845}
846
847template<typename T>
848void QuadTree<T>::find_k_nearest_recursive(const QuadTreeNode<T>* node, const T& target,
849 size_t k, std::vector<std::pair<T, double>>& candidates) const {
850 if (!node) return;
851
852 geometry::Rectangle target_bbox = get_bounding_box(target);
853
854 // Check objects in this node
855 for (const auto& object : node->objects) {
856 if (object == target) continue; // Skip self
857
858 geometry::Rectangle obj_bbox = get_bounding_box(object);
859 double distance = target_bbox.distance_to(obj_bbox);
860 candidates.emplace_back(object, distance);
861 }
862
863 // Recursively check children
864 if (node->divided) {
865 for (int i = 0; i < 4; ++i) {
866 find_k_nearest_recursive(node->children[i].get(), target, k, candidates);
867 }
868 }
869}
870
871template<typename T>
873 auto stats = get_detailed_statistics();
874
875 // Determine optimal parameters based on current data
876 size_t optimal_capacity = std::max(1UL, object_count / stats.total_nodes);
877 size_t optimal_depth = std::max(1UL, stats.max_depth_reached);
878
879 // Rebuild with optimal parameters
880 rebuild(optimal_capacity, optimal_depth);
881}
882
883template<typename T>
885 DetailedStatistics stats = {};
886 stats.objects_per_level.resize(20, 0); // Assume max 20 levels
887
888 calculate_detailed_statistics_recursive(root.get(), stats);
889
890 if (stats.leaf_nodes > 0) {
891 stats.average_objects_per_leaf = static_cast<double>(stats.total_objects) / stats.leaf_nodes;
892 }
893
894 if (stats.total_nodes > 0) {
895 stats.tree_efficiency = static_cast<double>(stats.total_objects) / stats.total_nodes;
896 }
897
898 stats.memory_usage_bytes = stats.total_nodes * sizeof(QuadTreeNode<T>) +
899 stats.total_objects * sizeof(T);
900
901 return stats;
902}
903
904template<typename T>
905void QuadTree<T>::calculate_detailed_statistics_recursive(const QuadTreeNode<T>* node,
906 DetailedStatistics& stats) const {
907 if (!node) return;
908
909 stats.total_nodes++;
910 stats.total_objects += node->objects.size();
911 stats.max_depth_reached = std::max(stats.max_depth_reached, node->depth);
912
913 if (node->depth < stats.objects_per_level.size()) {
914 stats.objects_per_level[node->depth] += node->objects.size();
915 }
916
917 if (!node->divided) {
918 stats.leaf_nodes++;
919 if (stats.min_depth_reached == 0 || node->depth < stats.min_depth_reached) {
920 stats.min_depth_reached = node->depth;
921 }
922 } else {
923 stats.internal_nodes++;
924 for (int i = 0; i < 4; ++i) {
925 calculate_detailed_statistics_recursive(node->children[i].get(), stats);
926 }
927 }
928}
929
930template<typename T>
932 return validate_node(root.get());
933}
934
935template<typename T>
936bool QuadTree<T>::validate_node(const QuadTreeNode<T>* node) const {
937 if (!node) return true;
938
939 // Check that all objects fit within boundary
940 for (const auto& object : node->objects) {
941 geometry::Rectangle bbox = get_bounding_box(object);
942 if (!node->boundary.intersects(bbox)) {
943 return false;
944 }
945 }
946
947 // Check children
948 if (node->divided) {
949 for (int i = 0; i < 4; ++i) {
950 if (!validate_node(node->children[i].get())) {
951 return false;
952 }
953 }
954 }
955
956 return true;
957}
958
959template<typename T>
960std::string QuadTree<T>::to_string() const {
961 std::string result = "QuadTree Structure:\n";
962 node_to_string(root.get(), result);
963 return result;
964}
965
966template<typename T>
967void QuadTree<T>::node_to_string(const QuadTreeNode<T>* node, std::string& result,
968 const std::string& indent) const {
969 if (!node) return;
970
971 result += indent + "Node: " + std::to_string(node->objects.size()) + " objects\n";
972
973 if (node->divided) {
974 for (int i = 0; i < 4; ++i) {
975 result += indent + " Child " + std::to_string(i) + ":\n";
976 node_to_string(node->children[i].get(), result, indent + " ");
977 }
978 }
979}
980
981template<typename T>
983 if (object_count == 0) return 0.0;
984
985 auto stats = get_statistics();
986 size_t total_capacity = stats.total_nodes * capacity;
987 return static_cast<double>(object_count) / total_capacity;
988}
989
990} // namespace spatial
991} // namespace zlayout
2D point with high-precision coordinates and utility methods
Definition point.hpp:23
double x
X coordinate.
Definition point.hpp:25
double y
Y coordinate.
Definition point.hpp:26
double distance_to(const Point &other) const
Calculate Euclidean distance to another point.
Definition point.cpp:56
Axis-aligned rectangle for bounding boxes and simple EDA components.
Definition rectangle.hpp:26
Point center() const
Get center point of rectangle.
Definition rectangle.cpp:68
bool intersects(const Rectangle &other) const
Check if this rectangle intersects with another rectangle.
bool contains_point(const Point &point) const
Check if point is inside rectangle (inclusive of boundary)
Definition rectangle.cpp:89
double distance_to(const Rectangle &other) const
Calculate minimum distance to another rectangle.
Iterator support for tree traversal.
Definition quadtree.hpp:264
Iterator(const QuadTree *tree, bool is_end=false)
bool operator!=(const Iterator &other) const
bool operator==(const Iterator &other) const
Quadtree spatial index for efficient range and intersection queries.
Definition quadtree.hpp:120
bool insert(const T &object)
Insert object into quadtree.
Definition quadtree.hpp:627
const QuadTreeNode< T > * get_root() const
Get root node (for visualization/debugging)
Definition quadtree.hpp:225
void clear()
Clear all objects from tree.
Definition quadtree.hpp:674
std::vector< T > get_all_objects() const
Get all objects in tree as vector.
Definition quadtree.hpp:789
bool empty() const
Check if tree is empty.
Definition quadtree.hpp:198
std::string to_string() const
Get tree as string representation (for debugging)
Definition quadtree.hpp:960
bool contains(const T &object) const
Check if object exists in tree.
Definition quadtree.hpp:782
size_t batch_remove(const std::vector< T > &objects)
Batch remove multiple objects efficiently.
Definition quadtree.hpp:758
std::function< geometry::Rectangle(const T &)> BoundingBoxFunc
Definition quadtree.hpp:123
size_t size() const
Get total number of objects in tree.
Definition quadtree.hpp:193
std::vector< T > query_range(const geometry::Rectangle &range) const
Query objects in rectangular range.
Definition quadtree.hpp:638
std::vector< T > query_k_nearest(const T &target, size_t k) const
Get k nearest neighbors to target object.
Definition quadtree.hpp:831
QuadTree(const geometry::Rectangle &boundary, BoundingBoxFunc get_bbox, size_t capacity=10, size_t max_depth=8)
Constructor.
Definition quadtree.hpp:613
Statistics get_statistics() const
Calculate tree statistics.
Definition quadtree.hpp:682
bool update(const T &old_object, const T &new_object)
Update object position (remove and re-insert)
Definition quadtree.hpp:734
void optimize()
Optimize tree structure for better performance This rebuilds the tree with better parameters based on...
Definition quadtree.hpp:872
DetailedStatistics get_detailed_statistics() const
Get detailed statistics about tree structure.
Definition quadtree.hpp:884
std::vector< std::pair< T, T > > find_intersections(std::function< bool(const T &, const T &)> collision_func) const
Find intersecting objects using efficient spatial queries.
Definition quadtree.hpp:666
void rebuild(size_t new_capacity, size_t new_max_depth)
Rebuild tree with new parameters.
Definition quadtree.hpp:694
Iterator end() const
Get iterator to end of tree.
Definition quadtree.hpp:777
void set_statistics_collection(bool enable)
Enable/disable statistics collection.
Definition quadtree.hpp:377
bool merge(const QuadTree &other)
Merge another quadtree into this one.
bool remove(const T &object)
Remove object from tree.
Definition quadtree.hpp:700
std::vector< std::unique_ptr< QuadTree > > split_by_regions(const std::vector< geometry::Rectangle > &regions) const
Split tree into multiple subtrees based on spatial regions.
double get_load_factor() const
Get current load factor of the tree.
Definition quadtree.hpp:982
std::vector< T > query_circle(const geometry::Point &center, double radius) const
Get objects within circular range.
Definition quadtree.hpp:811
std::vector< T > query_point(const geometry::Point &point) const
Query objects containing a specific point.
Definition quadtree.hpp:645
bool validate() const
Validate tree structure integrity.
Definition quadtree.hpp:931
size_t batch_insert(const std::vector< T > &objects)
Batch insert multiple objects efficiently.
Definition quadtree.hpp:744
std::vector< std::pair< T, T > > find_potential_intersections() const
Find all potentially intersecting pairs of objects.
Definition quadtree.hpp:659
Iterator begin() const
Get iterator to beginning of tree.
Definition quadtree.hpp:772
std::vector< T > query_nearby(const T &target, double distance) const
Find objects within distance of target object.
Definition quadtree.hpp:652
A node in the quadtree structure.
Definition quadtree.hpp:28
std::vector< T > objects
Objects stored in this node.
Definition quadtree.hpp:34
std::function< geometry::Rectangle(const T &)> BoundingBoxFunc
Definition quadtree.hpp:31
size_t depth
Current depth in tree.
Definition quadtree.hpp:39
bool is_divided() const
Check if this node has been subdivided.
Definition quadtree.hpp:92
std::unique_ptr< QuadTreeNode > children[4]
Child nodes (NW, NE, SW, SE)
Definition quadtree.hpp:35
std::vector< T > query_range(const geometry::Rectangle &range, const BoundingBoxFunc &get_bbox) const
Query objects in a rectangular range.
Definition quadtree.hpp:496
void clear()
Clear all objects and children.
Definition quadtree.hpp:590
size_t size() const
Get total number of objects in this subtree.
Definition quadtree.hpp:579
bool divided
Whether this node has been subdivided.
Definition quadtree.hpp:36
size_t max_depth
Maximum subdivision depth.
Definition quadtree.hpp:38
std::vector< T > query_point(const geometry::Point &point, const BoundingBoxFunc &get_bbox) const
Query objects containing a specific point.
Definition quadtree.hpp:525
QuadTreeNode(const geometry::Rectangle &boundary, size_t capacity=10, size_t max_depth=8, size_t depth=0)
Constructor.
Definition quadtree.hpp:451
geometry::Rectangle boundary
Spatial boundary of this node.
Definition quadtree.hpp:33
std::vector< T > get_all_objects() const
Get all objects in this subtree.
Definition quadtree.hpp:601
size_t capacity
Maximum objects before subdivision.
Definition quadtree.hpp:37
bool insert(const T &object, const BoundingBoxFunc &get_bbox)
Insert object into this node or appropriate child.
Definition quadtree.hpp:461
QuadTree< geometry::Point > PointQuadTree
QuadTree specialized for Point objects (using Point as both object and bounding box)
Definition quadtree.hpp:430
QuadTree< geometry::Rectangle > RectangleQuadTree
QuadTree specialized for Rectangle objects.
Definition quadtree.hpp:425
std::unique_ptr< RectangleQuadTree > create_rectangle_quadtree(const geometry::Rectangle &boundary, size_t capacity=10, size_t max_depth=8)
Create QuadTree for rectangles with default bounding box function.
std::unique_ptr< PointQuadTree > create_point_quadtree(const geometry::Rectangle &boundary, size_t capacity=10, size_t max_depth=8)
Create QuadTree for points with default bounding box function.
Main namespace for ZLayout library.
Definition component.hpp:20
2D Point class for geometric calculations
Axis-aligned rectangle class for bounding boxes and simple components.
Get tree statistics for performance analysis.
Definition quadtree.hpp:208