Published
Edited
Mar 28, 2022
15 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
movement = {
var t = new Date();
while (true) {
let time = (new Date() - t)/1000,
mult1 = Math.sin(time),
mult2 = Math.cos(time);
values.speedx = values.dx.map(d => d * mult1 + 2 * Math.cos(d));
values.speedy = values.dy.map(d => d * mult2 + 2 * Math.sin(d));
values.xpos = values.xpos.map((d,i) => (d + values.speedx[i] + width) % width )
values.ypos = values.ypos.map((d,i) => (d + values.speedy[i] + height) % height )
yield time;
}
}
Insert cell
Insert cell
kernel = function(
xpos,
ypos,
values,
speedx,
speedy,
colorScaleImageData,
distance_type,
radius
) {
var flagDist = -1;
var mindist = radius;
var dist = 0;
var A = 20; // speed look-ahead (for speed-based distance)
var border = 0;

for (var i = 0; i < this.constants.numPoints; i++) {
var x = this.thread.x - xpos[i],
y = this.thread.y - ypos[i];

// show speed arrow
if (
Math.abs(Math.atan2(y, x) - Math.atan2(speedy[i], speedx[i])) < 0.02 &&
x * x + y * y < A * A * (speedy[i] * speedy[i] + speedx[i] * speedx[i])
) {
this.color(1, 0, 0, 1);
continue; // fixed in v2.0.1 😇
}

if (Math.sqrt(x * x + y * y) < 4) {
mindist = 0;
flagDist = 0;
}

// fwd
if (distance_type == 4 || distance_type == 5) {
x = x - A * speedx[i];
y = y - A * speedy[i];
}
// euclidian
if (distance_type != 1) {
dist = Math.sqrt(x * x + y * y);
}
// weighted
if (distance_type == 3 || distance_type == 5) {
dist = dist * (1 + (4 * i) / this.constants.numPoints);
}
// manhattan
if (distance_type == 1) {
dist = Math.abs(x) + Math.abs(y);
}

if (dist < mindist) {
if (mindist - dist < 3) {
border = 1;
} else {
border = 0;
}
mindist = dist;
flagDist = i + 1;
}
}

var value = values[flagDist];
var c = Math.ceil(255 * value);

if (flagDist == 0) {
this.color(0.2, 0.2, 0.2, 1);
} else if (border == 1) {
this.color(1, 1, 1, 1);
} else if (flagDist > 0) {
this.color(
colorScaleImageData[c * 4] / 255,
colorScaleImageData[1 + c * 4] / 255,
colorScaleImageData[2 + c * 4] / 255,
1
);
} else if (flagDist < 0) {
this.color(1, 1, 1, 1);
}
}
Insert cell
render = {
var gpu = new GPU.GPU({ mode: processorType });
return gpu
.createKernel(kernel)
.setConstants({ numPoints: values.values.length })
.setOutput([width, height])
.setGraphical(true);
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more