SourceXtractorPlusPlus
1.0.3
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
for
(
int
i=0; i<4; i++) {
68
if
(
m_sub_trees
[i] !=
nullptr
&&
m_sub_trees
[i]->
isContained
(c)) {
69
m_sub_trees
[i]->remove(data);
70
}
71
}
72
}
else
{
73
auto
it =
std::find
(
m_data
.begin(),
m_data
.end(), data);
74
if
(it !=
m_data
.end()) {
75
m_data
.erase(it);
76
}
77
}
78
}
79
80
template
<
typename
T>
81
std::vector<T>
QuadTree<T>::getPointsWithinRange
(
Coord
c,
double
range)
const
{
82
auto
range_sq = range * range;
83
if
(
m_is_divided
) {
84
std::vector<T>
points;
85
for
(
int
i=0; i<4; i++) {
86
if
(
m_sub_trees
[i] !=
nullptr
) {
87
// compare range with distance to closest corner of subtree
88
auto
dx_sq =
std::min
((c.
x
-
m_sub_trees
[i]->m_min.x) * (c.
x
-
m_sub_trees
[i]->m_min.x),
89
(c.
x
-
m_sub_trees
[i]->m_max.x) * (c.
x
-
m_sub_trees
[i]->m_max.x));
90
auto
dy_sq =
std::min
((c.
y
-
m_sub_trees
[i]->m_min.y) * (c.
y
-
m_sub_trees
[i]->m_min.y),
91
(c.
y
-
m_sub_trees
[i]->m_max.y) * (c.
y
-
m_sub_trees
[i]->m_max.y));
92
if
(dx_sq + dy_sq <= range_sq) {
93
auto
subtree_points =
m_sub_trees
[i]->getPointsWithinRange(c, range);
94
points.
insert
(points.
end
(), subtree_points.begin(), subtree_points.end());
95
}
96
}
97
}
98
return
points;
99
}
else
{
100
std::vector<T>
points;
101
std::copy_if
(
m_data
.begin(),
m_data
.end(),
std::back_inserter
(points),
102
[c, range_sq](
const
T& point) {
103
auto pc = Coord { Traits::getCoord(point, 0), Traits::getCoord(point, 1) };
104
return (pc.x - c.
x
) * (pc.x - c.
x
) + (pc.y - c.
y
) * (pc.y - c.
y
) <= range_sq;
105
});
106
return
points;
107
}
108
}
109
110
template
<
typename
T>
111
void
QuadTree<T>::addLocally
(
const
T& data) {
112
assert(!
m_is_divided
);
113
114
auto
c =
Coord
{
Traits::getCoord
(data, 0),
Traits::getCoord
(data, 1) };
115
116
if
(
m_data
.empty()) {
117
m_min
.x =
m_max
.x = c.x;
118
m_min
.y =
m_max
.y = c.y;
119
}
else
{
120
m_min
.x =
std::min
(
m_min
.x, c.x);
121
m_min
.y =
std::min
(
m_min
.y, c.y);
122
m_max
.x =
std::max
(
m_max
.x, c.x);
123
m_max
.y =
std::max
(
m_max
.y, c.y);
124
}
125
126
m_data
.push_back(data);
127
}
128
129
template
<
typename
T>
130
void
QuadTree<T>::split
() {
131
assert(!
m_is_divided
);
132
133
m_is_divided
=
true
;
134
// expands to a square
135
m_max
.x =
std::max
(
m_max
.x,
m_min
.x + (
m_max
.y -
m_min
.y));
136
m_max
.y =
std::max
(
m_max
.y,
m_min
.y + (
m_max
.x -
m_min
.x));
137
138
for
(
auto
& d :
m_data
) {
139
add
(d);
140
}
141
m_data
.clear();
142
}
143
144
template
<
typename
T>
145
void
QuadTree<T>::expand
(
Coord
c) {
146
assert(
m_is_divided
&& !
isContained
(c));
147
148
auto
clone =
std::make_shared<QuadTree<T>
>(*this);
149
150
if
(c.
x
<
m_min
.x) {
151
m_min
.x -= (
m_max
.x -
m_min
.x);
152
}
else
{
153
m_max
.x += (
m_max
.x -
m_min
.x);
154
}
155
if
(c.
y
<
m_min
.y) {
156
m_min
.y -= (
m_max
.y -
m_min
.y);
157
}
else
{
158
m_max
.y += (
m_max
.y -
m_min
.y);
159
}
160
161
auto
quad =
getQuadrant
({ (clone->m_min.x + clone->m_max.x) / 2.0, (clone->m_min.y + clone->m_max.y) / 2.0 });
162
m_sub_trees
[quad] = clone;
163
for
(
size_t
i=0; i<4; i++) {
164
if
(i != quad) {
165
m_sub_trees
[i] =
nullptr
;
166
}
167
}
168
}
169
170
template
<
typename
T>
171
size_t
QuadTree<T>::getQuadrant
(
Coord
c)
const
{
172
size_t
quadrant = 0;
173
if
(c.
x
>= (
m_min
.x +
m_max
.x) / 2.0) {
174
quadrant += 1;
175
}
176
if
(c.
y
>= (
m_min
.y +
m_max
.y) / 2.0) {
177
quadrant += 2;
178
}
179
return
quadrant;
180
}
181
182
template
<
typename
T>
183
bool
QuadTree<T>::isContained
(
Coord
c)
const
{
184
return
c.
x
>=
m_min
.x && c.
x
<=
m_max
.x && c.
y
>=
m_min
.y && c.
y
<=
m_max
.y;
185
}
186
187
template
<
typename
T>
188
typename
QuadTree<T>::Coord
QuadTree<T>::getQuadrantMin
(
size_t
quadrant)
const
{
189
return
{
190
quadrant & 1 ? (
m_max
.x +
m_min
.x) / 2.0 :
m_min
.x,
191
quadrant & 2 ? (
m_max
.y +
m_min
.y) / 2.0 :
m_min
.y
192
};
193
}
194
195
template
<
typename
T>
196
typename
QuadTree<T>::Coord
QuadTree<T>::getQuadrantMax
(
size_t
quadrant)
const
{
197
return
{
198
quadrant & 1 ?
m_max
.x : (
m_max
.x +
m_min
.x) / 2.0,
199
quadrant & 2 ?
m_max
.y : (
m_max
.y +
m_min
.y) / 2.0
200
};
201
}
202
203
204
}
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:81
SourceXtractor::QuadTree< std::shared_ptr< SourceXtractor::MoffatGrouping::SourceInfo > >::isContained
bool isContained(Coord c) const
Definition
QuadTree.icpp:183
SourceXtractor::QuadTree::split
void split()
Definition
QuadTree.icpp:130
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:145
SourceXtractor::QuadTree< std::shared_ptr< SourceXtractor::MoffatGrouping::SourceInfo > >::getQuadrantMax
Coord getQuadrantMax(size_t quadrant) const
Definition
QuadTree.icpp:196
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:111
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:188
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:171
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.15.0