41#ifndef CPUNEIGHBORTREE_H
42#define CPUNEIGHBORTREE_H
60 minx =
miny = std::numeric_limits<double>::infinity();
61 maxx =
maxy = -std::numeric_limits<double>::infinity();
82 return std::numeric_limits<double>::infinity();
85 return dx * dx + dy * dy;
92 return std::numeric_limits<double>::infinity();
93 const double dx = std::max(0.0, std::max(
minx - p[0], p[0] -
maxx));
94 const double dy = std::max(0.0, std::max(
miny - p[1], p[1] -
maxy));
95 return dx * dx + dy * dy;
127 for (
int i = 0; i <
n; ++i)
130 std::vector<uint64_t> keys(
n), tmp(
n);
132 const double iscale = (scale > 0.0) ? (65535.0 / scale) : 0.0;
134#pragma omp parallel for
135 for (
int i = 0; i <
n; ++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;
144 for (
int shift = 32; shift < 64; shift += 8)
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];
156 for (
int i = 0; i <
n; ++i)
158 idx[i] = (int)(keys[i] & 0xFFFFFFFFu);
168#pragma omp parallel for
180 box[k].Add(
box[2 * k + 1]);
190 const double R2 = R * R;
196 const int k = stack[--top];
197 if (
box[k].Dist2(q) >= R2)
203 stack[top++] = 2 * k + 1;
204 stack[top++] = 2 * k;
213 v = (v | (v << 8)) & 0x00FF00FF;
214 v = (v | (v << 4)) & 0x0F0F0F0F;
215 v = (v | (v << 2)) & 0x33333333;
216 v = (v | (v << 1)) & 0x55555555;
Заголовочный файл с описанием класса Point2D.
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
void Build(int n_, F getPos)
Построение дерева; getPos(i) возвращает координаты i-й точки
void CollectLeaves(const NbBox &q, double R, std::vector< int > &leaves) const
Список листьев, прямоугольники которых находятся на расстоянии меньше R от прямоугольника q.
static const int leafSize
static uint32_t Spread(uint32_t v)
const NbBox & LeafBox(int leaf) const
std::vector< Point2D > pos
координаты точек в порядке сортировки
double Dist2(const Point2D &p) const
Квадрат расстояния до точки
void Add(const Point2D &p)
double Dist2(const NbBox &b) const
Квадрат расстояния до другого прямоугольника (для пустого — бесконечность).