OPAL (Object Oriented Parallel Accelerator Library) 2024.2
OPAL
QuadTree.cpp
Go to the documentation of this file.
2
3#include <iostream>
4#include <list>
5#include <memory>
6#include <utility>
7#include <vector>
8
9namespace mslang {
11 level_m(right.level_m),
12 objects_m(right.objects_m.begin(),
13 right.objects_m.end()),
14 bb_m(right.bb_m),
15 nodes_m()
16 {
17 if (!right.nodes_m.empty()) {
18 for (unsigned int i = 0; i < 4u; ++ i) {
19 nodes_m.emplace_back(new QuadTree(*right.nodes_m[i]));
20 }
21 }
22 }
23
25 // for (std::shared_ptr<Base> &obj: objects_m)
26 // obj.reset();
27
28 objects_m.clear();
29 nodes_m.clear();
30 }
31
33 objects_m.clear();
34 nodes_m.clear();
35 }
36
37 void QuadTree::operator=(const QuadTree &right) {
38 level_m = right.level_m;
39 objects_m.insert(objects_m.end(),
40 right.objects_m.begin(),
41 right.objects_m.end());
42 bb_m = right.bb_m;
43
44 if (!nodes_m.empty()) nodes_m.clear();
45
46 if (!right.nodes_m.empty()) {
47 for (unsigned int i = 0; i < 4u; ++ i) {
48 nodes_m.emplace_back(new QuadTree(*right.nodes_m[i]));
49 }
50 }
51 }
52
53 void QuadTree::transferIfInside(std::list<std::shared_ptr<Base> > &objs) {
54 for (std::shared_ptr<Base> &obj: objs) {
55 if (bb_m.isInside(obj->bb_m)) {
56 objects_m.emplace_back(std::move(obj));
57 }
58 }
59
60 objs.remove_if([](const std::shared_ptr<Base> obj) { return !obj; });
61 }
62
64 double X[] = {bb_m.center_m[0] - 0.5 * bb_m.width_m,
65 bb_m.center_m[0],
66 bb_m.center_m[0] + 0.5 * bb_m.width_m};
67 double Y[] = {bb_m.center_m[1] - 0.5 * bb_m.height_m,
68 bb_m.center_m[1],
69 bb_m.center_m[1] + 0.5 * bb_m.height_m};
70
71 bool allEmpty = true;
72
73 nodes_m.reserve(4);
74 for (unsigned int i = 0; i < 4u; ++ i) {
75 nodes_m.emplace_back(new QuadTree(level_m + 1,
76 BoundingBox2D(Vector_t({X[i / 2], Y[i % 2], 0.0}),
77 Vector_t({X[i / 2 + 1], Y[i % 2 + 1], 0.0}))));
78
79 nodes_m.back()->transferIfInside(objects_m);
80
81 if (!nodes_m.back()->objects_m.empty()) {
82 allEmpty = false;
83 }
84 }
85
86 if (allEmpty) {
87 nodes_m.clear();
88 return;
89 }
90
91 for (unsigned int i = 0; i < 4u; ++ i) {
92 nodes_m[i]->buildUp();
93 }
94 }
95
96 void QuadTree::writeGnuplot(std::ostream &out) const {
97 out << "# level: " << level_m << ", size: " << objects_m.size() << std::endl;
98 bb_m.writeGnuplot(out);
99 out << "# num holes: " << objects_m.size() << std::endl;
100 out << std::endl;
101
102 if (!nodes_m.empty()) {
103 for (unsigned int i = 0; i < 4u; ++ i) {
104 nodes_m[i]->writeGnuplot(out);
105 }
106 }
107 }
108
109 bool QuadTree::isInside(const Vector_t &R) const {
110 if (!nodes_m.empty()) {
111 Vector_t X = R - bb_m.center_m;
112 unsigned int idx = (X[1] < 0.0 ? 0: 1);
113 idx += (X[0] < 0.0 ? 0: 2);
114
115 if (nodes_m[idx]->isInside(R)) {
116 return true;
117 }
118 }
119
120 for (const std::shared_ptr<Base> & obj: objects_m) {
121 if (obj->isInside(R)) {
122 return true;
123 }
124 }
125
126 return false;
127 }
128
129 void QuadTree::getDepth(unsigned int &d) const {
130 if (!nodes_m.empty()) {
131 for (const auto & node: nodes_m) {
132 node->getDepth(d);
133 }
134 } else {
135 if ((unsigned int)level_m > d) d = level_m;
136 }
137 }
138}
PartBunchBase< T, Dim >::ConstIterator end(PartBunchBase< T, Dim > const &bunch)
PartBunchBase< T, Dim >::ConstIterator begin(PartBunchBase< T, Dim > const &bunch)
#define X(arg)
Definition fftpack.cpp:106
bool isInside(const Vector_t &X) const
virtual void writeGnuplot(std::ostream &out) const
void getDepth(unsigned int &d) const
Definition QuadTree.cpp:129
std::vector< std::shared_ptr< QuadTree > > nodes_m
Definition QuadTree.h:16
void writeGnuplot(std::ostream &out) const
Definition QuadTree.cpp:96
void transferIfInside(std::list< std::shared_ptr< Base > > &objs)
Definition QuadTree.cpp:53
void operator=(const QuadTree &right)
Definition QuadTree.cpp:37
bool isInside(const Vector_t &R) const
Definition QuadTree.cpp:109
BoundingBox2D bb_m
Definition QuadTree.h:15
std::list< std::shared_ptr< Base > > objects_m
Definition QuadTree.h:14
Vektor< double, 3 > Vector_t
Definition Vektor.h:6