advectBatch = {
let orderp, orderq, p, q, batch;
const random = d3.randomNormal();
const { hypot } = Math;
return function advectBatch(values, target, n, epsilon) {
const l = values.length / 4;
if (!(p && p.length === l)) {
p = new Float32Array(l);
q = new Float32Array(l);
batch = new Float32Array(values.length);
orderp = new Uint32Array(l);
orderq = new Uint32Array(l);
for (let i = 0; i < l; i++) orderp[i] = orderq[i] = i;
}
batch.fill(0);
for (let s = 1; s < n; s++) {
let x = random(),
y = random(),
z = random(),
norm = 1 / hypot(x, y, z);
x *= norm;
y *= norm;
z *= norm;
p = project_pixels(values, x, y, z, p);
q = project_pixels(target, x, y, z, q);
orderp.sort((i, j) => p[i] - p[j]);
orderq.sort((i, j) => q[i] - q[j]);
for (let k = 0; k < l; k++) {
const i = orderp[k],
j = orderq[k];
const b = q[j] - p[i];
batch[4 * i + 0] += b * x;
batch[4 * i + 1] += b * y;
batch[4 * i + 2] += b * z;
}
}
let energy = 0;
for (let i = 0; i < batch.length; i++) {
values[i] += batch[i] * epsilon;
energy += Math.abs(batch[i]);
}
return energy;
};
}