SourceXtractorPlusPlus
0.22
SourceXtractor++, the next generation SExtractor
Loading...
Searching...
No Matches
SEUtils
SEUtils
_impl
QuadTree.icpp
Go to the documentation of this file.
1
17
18
#include <cassert>
19
#include <algorithm>
// For std::find
20
21
namespace
SourceXtractor
{
22
23
template
<
typename
T>
24
QuadTree<T>::QuadTree
(
size_t
capacity) :
m_capacity
(capacity),
m_is_divided
(false) {
25
}
26
27
template
<
typename
T>
28
QuadTree<T>::QuadTree
(
const
QuadTree
& tree) {
29
m_capacity
= tree.
m_capacity
;
30
m_is_divided
= tree.
m_is_divided
;
31
m_min
= tree.
m_min
;
32
m_max
= tree.
m_max
;
33
m_data
= tree.
m_data
;
34
for
(
int
i = 0; i<4; i++) {
35
m_sub_trees
[i] = tree.
m_sub_trees
[i];
36
}
37
}
38
39
template
<
typename
T>
40
void
QuadTree<T>::add
(
const
T& data) {
41
if
(
m_is_divided
) {
42
auto
c = Coord {
Traits::getCoord
(data, 0),
Traits::getCoord
(data, 1) };
43
44
while
(!
isContained
(c)) {
45
expand
(c);
46
}
47
48
auto
quad =
getQuadrant
(c);
49
if
(
m_sub_trees
[quad] ==
nullptr
) {
50
m_sub_trees
[quad] =
std::make_shared<QuadTree>
(
m_capacity
);
51
m_sub_trees
[quad]->m_min =
getQuadrantMin
(quad);
52
m_sub_trees
[quad]->m_max =
getQuadrantMax
(quad);
53
}
54
m_sub_trees
[quad]->add(data);
55
}
else
{
56
addLocally(data);
57
if
(m_data.size() >= m_capacity) {
58
split();
59
}
60
}
61
}
62
63
template
<
typename
T>
64
void
QuadTree<T>::remove
(
const
T& data) {
65
if
(
m_is_divided
) {
66
auto
c =
Coord
{
Traits::getCoord
(data, 0),
Traits::getCoord
(data, 1) };
67
auto
quad =
getQuadrant
(c);
68
if
(
m_sub_trees
[quad] !=
nullptr
) {
69
m_sub_trees
[quad]->remove(data);
70
}
71
}
else
{
72
auto
it =
std::find
(
m_data
.begin(),
m_data
.end(), data);
73
if
(it !=
m_data
.end()) {
74
m_data
.erase(it);
75
}
76
}
77
}
78
79
template
<
typename
T>
80
std::vector<T>
QuadTree<T>::getPointsWithinRange
(
Coord
c,
double
range)
const
{
81
auto
range_sq = range * range;
82
if
(
m_is_divided
) {
83
std::vector<T>
points;
84
for
(
int
i=0; i<4; i++) {
85
if
(
m_sub_trees
[i] !=
nullptr
) {
86
// compare range with distance to closest corner of subtree
87
auto
dx_sq =
std::min
((c.
x
-
m_sub_trees
[i]->m_min.x) * (c.
x
-
m_sub_trees
[i]->m_min.x),
88
(c.
x
-
m_sub_trees
[i]->m_max.x) * (c.
x
-
m_sub_trees
[i]->m_max.x));
89
auto
dy_sq =
std::min
((c.
y
-
m_sub_trees
[i]->m_min.y) * (c.
y
-
m_sub_trees
[i]->m_min.y),
90
(c.
y
-
m_sub_trees
[i]->m_max.y) * (c.
y
-
m_sub_trees
[i]->m_max.y));
91
if
(dx_sq + dy_sq <= range_sq) {
92
auto
subtree_points =
m_sub_trees
[i]->getPointsWithinRange(c, range);
93
points.
insert
(points.
end
(), subtree_points.begin(), subtree_points.end());
94
}
95
}
96
}
97
return
points;
98
}
else
{
99
std::vector<T>
points;
100
std::copy_if
(
m_data
.begin(),
m_data
.end(),
std::back_inserter
(points),
101
[c, range_sq](
const
T& point) {
102
auto pc = Coord { Traits::getCoord(point, 0), Traits::getCoord(point, 1) };
103
return (pc.x - c.
x
) * (pc.x - c.
x
) + (pc.y - c.
y
) * (pc.y - c.
y
) <= range_sq;
104
});
105
return
points;
106
}
107
}
108
109
template
<
typename
T>
110
void
QuadTree<T>::addLocally
(
const
T& data) {
111
assert(!
m_is_divided
);
112
113
auto
c =
Coord
{
Traits::getCoord
(data, 0),
Traits::getCoord
(data, 1) };
114
115
if
(
m_data
.empty()) {
116
m_min
.x =
m_max
.x = c.x;
117
m_min
.y =
m_max
.y = c.y;
118
}
else
{
119
m_min
.x =
std::min
(
m_min
.x, c.x);
120
m_min
.y =
std::min
(
m_min
.y, c.y);
121
m_max
.x =
std::max
(
m_max
.x, c.x);
122
m_max
.y =
std::max
(
m_max
.y, c.y);
123
}
124
125
m_data
.push_back(data);
126
}
127
128
template
<
typename
T>
129
void
QuadTree<T>::split
() {
130
assert(!
m_is_divided
);
131
132
m_is_divided
=
true
;
133
// expands to a square
134
m_max
.x =
std::max
(
m_max
.x,
m_min
.x + (
m_max
.y -
m_min
.y));
135
m_max
.y =
std::max
(
m_max
.y,
m_min
.y + (
m_max
.x -
m_min
.x));
136
137
for
(
auto
& d :
m_data
) {
138
add
(d);
139
}
140
m_data
.clear();
141
}
142
143
template
<
typename
T>
144
void
QuadTree<T>::expand
(
Coord
c) {
145
assert(
m_is_divided
&& !
isContained
(c));
146
147
auto
clone =
std::make_shared<QuadTree<T>
>(*this);
148
149
if
(c.
x
<
m_min
.x) {
150
m_min
.x -= (
m_max
.x -
m_min
.x);
151
}
else
{
152
m_max
.x += (
m_max
.x -
m_min
.x);
153
}
154
if
(c.
y
<
m_min
.y) {
155
m_min
.y -= (
m_max
.y -
m_min
.y);
156
}
else
{
157
m_max
.y += (
m_max
.y -
m_min
.y);
158
}
159
160
auto
quad =
getQuadrant
({ (clone->m_min.x + clone->m_max.x) / 2.0, (clone->m_min.y + clone->m_max.y) / 2.0 });
161
m_sub_trees
[quad] = clone;
162
for
(
size_t
i=0; i<4; i++) {
163
if
(i != quad) {
164
m_sub_trees
[i] =
nullptr
;
165
}
166
}
167
}
168
169
template
<
typename
T>
170
size_t
QuadTree<T>::getQuadrant
(
Coord
c)
const
{
171
size_t
quadrant = 0;
172
if
(c.
x
>= (
m_min
.x +
m_max
.x) / 2.0) {
173
quadrant += 1;
174
}
175
if
(c.
y
>= (
m_min
.y +
m_max
.y) / 2.0) {
176
quadrant += 2;
177
}
178
return
quadrant;
179
}
180
181
template
<
typename
T>
182
bool
QuadTree<T>::isContained
(
Coord
c)
const
{
183
return
c.
x
>=
m_min
.x && c.
x
<=
m_max
.x && c.
y
>=
m_min
.y && c.
y
<=
m_max
.y;
184
}
185
186
template
<
typename
T>
187
typename
QuadTree<T>::Coord
QuadTree<T>::getQuadrantMin
(
size_t
quadrant)
const
{
188
return
{
189
quadrant & 1 ? (
m_max
.x +
m_min
.x) / 2.0 :
m_min
.x,
190
quadrant & 2 ? (
m_max
.y +
m_min
.y) / 2.0 :
m_min
.y
191
};
192
}
193
194
template
<
typename
T>
195
typename
QuadTree<T>::Coord
QuadTree<T>::getQuadrantMax
(
size_t
quadrant)
const
{
196
return
{
197
quadrant & 1 ?
m_max
.x : (
m_max
.x +
m_min
.x) / 2.0,
198
quadrant & 2 ?
m_max
.y : (
m_max
.y +
m_min
.y) / 2.0
199
};
200
}
201
202
203
}
std::back_inserter
T back_inserter(T... args)
SourceXtractor::QuadTree::remove
void remove(const T &data)
Definition
QuadTree.icpp:64
SourceXtractor::QuadTree::m_is_divided
bool m_is_divided
Definition
QuadTree.h:59
SourceXtractor::QuadTree::getPointsWithinRange
std::vector< T > getPointsWithinRange(Coord c, double range) const
Definition
QuadTree.icpp:80
SourceXtractor::QuadTree< std::shared_ptr< SourceXtractor::MoffatGrouping::SourceInfo > >::isContained
bool isContained(Coord c) const
Definition
QuadTree.icpp:182
SourceXtractor::QuadTree::split
void split()
Definition
QuadTree.icpp:129
SourceXtractor::QuadTree::m_max
Coord m_max
Definition
QuadTree.h:60
SourceXtractor::QuadTree::m_sub_trees
std::shared_ptr< QuadTree< T > > m_sub_trees[4]
Definition
QuadTree.h:62
SourceXtractor::QuadTree< std::shared_ptr< SourceXtractor::MoffatGrouping::SourceInfo > >::expand
void expand(Coord c)
Definition
QuadTree.icpp:144
SourceXtractor::QuadTree< std::shared_ptr< SourceXtractor::MoffatGrouping::SourceInfo > >::getQuadrantMax
Coord getQuadrantMax(size_t quadrant) const
Definition
QuadTree.icpp:195
SourceXtractor::QuadTree::m_capacity
size_t m_capacity
Definition
QuadTree.h:57
SourceXtractor::QuadTree::add
void add(const T &data)
Definition
QuadTree.icpp:40
SourceXtractor::QuadTree::addLocally
void addLocally(const T &data)
Definition
QuadTree.icpp:110
SourceXtractor::QuadTree::m_min
Coord m_min
Definition
QuadTree.h:60
SourceXtractor::QuadTree< std::shared_ptr< SourceXtractor::MoffatGrouping::SourceInfo > >::getQuadrantMin
Coord getQuadrantMin(size_t quadrant) const
Definition
QuadTree.icpp:187
SourceXtractor::QuadTree::QuadTree
QuadTree(size_t capacity=100)
Definition
QuadTree.icpp:24
SourceXtractor::QuadTree< std::shared_ptr< SourceXtractor::MoffatGrouping::SourceInfo > >::getQuadrant
size_t getQuadrant(Coord c) const
Definition
QuadTree.icpp:170
SourceXtractor::QuadTree::m_data
std::vector< T > m_data
Definition
QuadTree.h:61
std::copy_if
T copy_if(T... args)
std::vector::end
T end(T... args)
std::find
T find(T... args)
std::vector::insert
T insert(T... args)
std::make_shared
T make_shared(T... args)
std::max
T max(T... args)
std::min
T min(T... args)
SourceXtractor
Definition
Aperture.h:30
SourceXtractor::QuadTreeTraits::getCoord
static double getCoord(const T &t, size_t index)
SourceXtractor::QuadTree::Coord
Definition
QuadTree.h:36
SourceXtractor::QuadTree::Coord::y
double y
Definition
QuadTree.h:37
SourceXtractor::QuadTree::Coord::x
double x
Definition
QuadTree.h:37
std::vector
Generated by
1.13.2