120 {
124
125 NbBox all;
126 all.SetEmpty();
127 for (
int i = 0; i <
n; ++i)
128 all.Add(getPos(i));
129
130 std::vector<uint64_t> keys(
n), tmp(
n);
131 const double scale = std::max(all.maxx - all.minx, all.maxy - all.miny);
132 const double iscale = (scale > 0.0) ? (65535.0 / scale) : 0.0;
133
134#pragma omp parallel for
135 for (
int i = 0; i <
n; ++i)
136 {
137 const Point2D& p = getPos(i);
138 const uint32_t ix = (uint32_t)((p[0] - all.minx) * iscale);
139 const uint32_t iy = (uint32_t)((p[1] - all.miny) * iscale);
140 keys[i] = ((uint64_t)((
Spread(ix) << 1) |
Spread(iy)) << 32) | (uint32_t)i;
141 }
142
143
144 for (int shift = 32; shift < 64; shift += 8)
145 {
146 size_t cnt[257] = { 0 };
147 for (
int i = 0; i <
n; ++i)
148 ++cnt[((keys[i] >> shift) & 0xFF) + 1];
149 for (int b = 0; b < 256; ++b)
150 cnt[b + 1] += cnt[b];
151 for (
int i = 0; i <
n; ++i)
152 tmp[cnt[(keys[i] >> shift) & 0xFF]++] = keys[i];
153 keys.swap(tmp);
154 }
155
156 for (
int i = 0; i <
n; ++i)
157 {
158 idx[i] = (int)(keys[i] & 0xFFFFFFFFu);
160 }
161
166
168#pragma omp parallel for
170 {
172 b.SetEmpty();
176 }
178 {
180 box[k].Add(
box[2 * k + 1]);
181 }
182 }
std::vector< int > idx
исходные номера точек в порядке сортировки
int firstLeaf
номер первого листа в неявном бинарном дереве (степень двойки)
std::vector< NbBox > box
прямоугольники узлов: корень 1, потомки узла k — 2k и 2k+1
int LeafBegin(int leaf) const
int LeafEnd(int leaf) const
static const int leafSize
static uint32_t Spread(uint32_t v)
std::vector< Point2D > pos
координаты точек в порядке сортировки