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