64 void build(PosAccessor&& get_pos,
int n) {
66 const int total = nx_ * ny_ * nz_;
68 std::fill(count_.begin(), count_.end(), 0);
69 for (
int i = 0; i < n; ++i)
70 ++count_[cell_id_of(get_pos(i))];
73 for (
int c = 0; c < total; ++c)
74 start_[c + 1] = start_[c] + count_[c];
76 std::fill(count_.begin(), count_.end(), 0);
77 for (
int i = 0; i < n; ++i) {
78 const int cid = cell_id_of(get_pos(i));
79 sorted_[start_[cid] + count_[cid]] = i;
86 void query(Scalar px, Scalar py, Scalar pz, F&& f)
const {
87 const int cx = cell_x(px);
88 const int cy = cell_y(py);
89 const int cz = cell_z(pz);
90 for (
int dz = -1; dz <= 1; ++dz) {
91 const int qz = cz + dz;
92 if (qz < 0 || qz >= nz_)
94 for (
int dy = -1; dy <= 1; ++dy) {
95 const int qy = cy + dy;
96 if (qy < 0 || qy >= ny_)
98 for (
int dx = -1; dx <= 1; ++dx) {
99 const int qx = cx + dx;
100 if (qx < 0 || qx >= nx_)
102 const int cid = (qz * ny_ + qy) * nx_ + qx;
103 for (
int k = start_[cid]; k < start_[cid + 1]; ++k)
115 static constexpr int FDX[13] =
116 {-1, 0, 1, -1, 0, 1, -1, 0, 1, -1, 0, 1, 1};
117 static constexpr int FDY[13] =
118 {-1, -1, -1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0};
119 static constexpr int FDZ[13] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0};
121 for (
int cz = 0; cz < nz_; ++cz) {
122 for (
int cy = 0; cy < ny_; ++cy) {
123 for (
int cx = 0; cx < nx_; ++cx) {
124 const int cid = (cz * ny_ + cy) * nx_ + cx;
125 const int beg = start_[cid];
126 const int end = start_[cid + 1];
131 for (
int a = beg; a < end; ++a)
132 for (
int b = a + 1; b < end; ++b)
133 f(sorted_[a], sorted_[b]);
136 for (
int d = 0; d < 13; ++d) {
137 const int ncx = cx + FDX[d];
138 const int ncy = cy + FDY[d];
139 const int ncz = cz + FDZ[d];
140 if (ncx < 0 || ncx >= nx_ || ncy < 0 || ncy >= ny_
141 || ncz < 0 || ncz >= nz_)
143 const int ncid = (ncz * ny_ + ncy) * nx_ + ncx;
144 const int nbeg = start_[ncid];
145 const int nend = start_[ncid + 1];
148 for (
int a = beg; a < end; ++a)
149 for (
int b = nbeg; b < nend; ++b)
150 f(sorted_[a], sorted_[b]);
171 Scalar cs_ = 0, xmin_ = 0, ymin_ = 0, zmin_ = 0;