7#ifndef GOOSEEYE_DETAIL_HPP
8#define GOOSEEYE_DETAIL_HPP
23inline size_t atleast_3d_axis(
size_t rank,
size_t axis)
28 size_t end =
static_cast<size_t>(std::round(
double(N - rank) /
double(N)));
44 for (
size_t i = 0; i < axes.size(); ++i) {
45 ret(i) = atleast_3d_axis(rank, axes(i));
59 return atleast_3d_axes(rank, xt::arange<size_t>(rank));
69inline std::vector<size_t> shape(T&& mat)
71 return std::vector<size_t>(mat.shape().cbegin(), mat.shape().cend());
80inline std::vector<size_t> half_shape(
const std::vector<size_t>& shape)
82 std::vector<size_t> ret = shape;
84 for (
size_t i = 0; i < ret.size(); ++i) {
85 ret[i] = (shape[i] - shape[i] % 2) / 2;
100inline std::vector<std::vector<size_t>> pad_width(
const std::vector<size_t>& shape)
102 std::vector<std::vector<size_t>> pad(shape.size(), std::vector<size_t>(2));
104 for (
size_t i = 0; i < shape.size(); ++i) {
105 if (shape[i] % 2 == 0) {
106 pad[i][0] = shape[i] / 2 - 1;
107 pad[i][1] = shape[i] / 2;
110 pad[i][0] = (shape[i] - 1) / 2;
111 pad[i][1] = (shape[i] - 1) / 2;
122inline std::vector<std::vector<size_t>> pad_width(
const T& a)
124 std::vector<size_t> shape(a.shape().cbegin(), a.shape().cend());
125 return pad_width(shape);
141 int ndim =
static_cast<int>(xa.size());
142 std::vector<int> ret;
145 int a[3], s[3], x[3], d[3], in[2], j, i, iin, nnz = 0;
148 for (i = 0; i < 3; i++) {
159 for (i = 0; i < ndim; i++) {
160 a[i] = std::abs((
int)xb[i] - (
int)xa[i]) << 1;
161 s[i] = SIGN((
int)xb[i] - (
int)xa[i]);
166 for (j = 0; j < 3; j++) {
169 for (i = 0; i < 3; i++) {
176 if (a[j] >= std::max(a[in[0]], a[in[1]]))
181 for (i = 0; i < 2; i++)
182 d[in[i]] = a[in[i]] - (a[j] >> 1);
186 for (i = 0; i < ndim; i++)
192 return xt::adapt(ret, {
static_cast<size_t>(nnz),
static_cast<size_t>(ndim)});
194 for (i = 0; i < 2; i++) {
196 x[in[i]] += s[in[i]];
202 for (i = 0; i < 2; i++)
203 d[in[i]] += a[in[i]];
206 return xt::adapt(ret, {
static_cast<size_t>(nnz),
static_cast<size_t>(ndim)});
222 int ndim =
static_cast<int>(xa.size());
223 std::vector<int> ret;
226 double x[3], v[3], t[3], next[3], sign[3];
240 for (i = 0; i < ndim; i++) {
243 ret.push_back(cindex[i]);
245 x[i] = (double)(xa[i]);
246 v[i] = (double)(xb[i] - xa[i]);
251 sign[i] = v[i] / fabs(v[i]);
252 isign[i] = (int)sign[i];
253 next[i] = sign[i] * 0.5;
263 for (iin = 0; iin < nin; iin++) {
265 t[iin] = (next[i] - x[i]) / v[i];
270 for (iin = 1; iin < nin; iin++) {
271 if (t[iin] < t[imin]) {
278 for (iin = 0; iin < nin; iin++) {
279 if (fabs(t[iin] - t[imin]) < 1.e-6) {
280 cindex[in[iin]] += isign[in[iin]];
281 next[in[iin]] += sign[in[iin]];
285 for (i = 0; i < ndim; i++) {
286 ret.push_back(cindex[i]);
290 for (i = 0; i < ndim; i++) {
291 x[i] = xa[i] + v[i] * t[imin];
296 for (i = 0; i < ndim; i++) {
297 if (cindex[i] == xb[i]) {
306 return xt::adapt(ret, {
static_cast<size_t>(nnz),
static_cast<size_t>(ndim)});
322 int ndim =
static_cast<int>(xa.size());
323 std::vector<int> ret;
326 double x[3], v[3], t[3], next[3], sign[3];
340 for (i = 0; i < ndim; i++) {
343 ret.push_back(cindex[i]);
345 x[i] = (double)(xa[i]);
346 v[i] = (double)(xb[i] - xa[i]);
351 sign[i] = v[i] / fabs(v[i]);
352 isign[i] = (int)sign[i];
353 next[i] = sign[i] * 0.5;
363 for (iin = 0; iin < nin; iin++) {
365 t[iin] = (next[i] - x[i]) / v[i];
370 for (iin = 1; iin < nin; iin++) {
371 if (t[iin] < t[imin]) {
378 for (iin = 0; iin < nin; iin++) {
379 if (fabs(t[iin] - t[imin]) < 1.e-6) {
380 cindex[in[iin]] += isign[in[iin]];
381 next[in[iin]] += sign[in[iin]];
383 for (i = 0; i < ndim; i++) {
384 ret.push_back(cindex[i]);
390 for (i = 0; i < ndim; i++) {
391 x[i] = xa[i] + v[i] * t[imin];
396 for (i = 0; i < ndim; i++) {
397 if (cindex[i] == xb[i]) {
406 return xt::adapt(ret, {
static_cast<size_t>(nnz),
static_cast<size_t>(ndim)});
xt::xtensor< T, N > tensor
Fixed (static) rank array.
Toolbox to compute statistics.
@ full
Similar to actual selecting every voxel that is crossed.
array_type::tensor< int, 2 > path(const array_type::tensor< int, 1 > &x0, const array_type::tensor< int, 1 > &x1, path_mode mode=path_mode::Bresenham)
Compute a path between two pixels.