Public
Edited
Nov 11, 2022
1 fork
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
canvas = {
const context = DOM.context2d(width, height);

const opacityPostfix = (k = 2) =>
("0" + parseInt((255 / repeat) * k).toString(16)).slice(-2);

var pathPoints;

// Background
{
// context.fillStyle = "hsl(216deg 100% 13%)";
// context.fillRect(0, 0, width, height);
context.canvas.style.background = "hsl(216deg 50% 13%)";
}

// Draw points
{
function draw(pts, yOffset = 0, radius = 5, k = 2) {
const maxV = d3.max(pts, (e) => e.v);

pts.map((pts) => {
const { x, y, v } = pts;

(context.fillStyle =
d3.color(colorMap(v / maxV)).hex() + opacityPostfix(k)),
context.beginPath(),
context.arc(
constants.xScale(x),
constants.yScale(y + yOffset),
radius,
0,
Math.PI * 2
),
context.fill();
});
}

const radius = width / constants.numX / 3;

if (showGridToggle) {
draw(data.points, 0, radius / 2, 3);
}

pathList.map((path) => {
pathPoints = path.map((str) => {
return data.map[str];
});
draw(pathPoints, 0, radius);
});
}

// Draw ground truth
{
context.strokeStyle = "#ff0000" + "80";
context.lineWidth = 3;
context.beginPath();

context.moveTo(constants.xScale(0), constants.yScale(0));
// context.lineTo(constants.xScale(0.2), constants.yScale(0.3));

const r = 1,
n = 100;
const thetaScale = d3
.scaleLinear()
.domain([0, n * 2])
.range([0, Math.PI * 2]);
var x, y, theta;
for (let i = 0; i < n + 1; ++i) {
theta = thetaScale(i);
x = (r * (theta - Math.sin(theta))) / Math.PI;
y = (r * (1 - Math.cos(theta))) / 2;
context.lineTo(constants.xScale(x), constants.yScale(y));
}

context.stroke();
}

return context.canvas;
}
Insert cell
points
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
points = data.points
Insert cell
path = mkPath(mkLinks(data.points, data.map))
Insert cell
pathList = {
const t = new Date();
const lst = [...new Array(repeat)];
const pathLst = lst.map((e) => mkPath(mkLinks(data.points, data.map)));
constants["simulationTime"] = new Date() - t;
return pathLst;
}
Insert cell
function mkPath(links) {
const { numX, numY } = constants;
return dijkstra.find_path(links, "0-0", ij2str(numX, numY));
}
Insert cell
Insert cell
data = {
const { numX, numY } = constants;

const points = [];
const map = {};

var pnt, x, y, v, dt;

// Build dataset with points and map
for (let i = 0; i < numX + 1; ++i) {
for (let j = 0; j < numY + 1; ++j) {
x = i / numX;
y = j / numY;
v = computeV(y);
dt = v === 0 ? 100 : 1 / v;

pnt = {
i,
j,
x,
y,
dt,
v
};

map[ij2str(i, j)] = pnt;

points.push(pnt);
}
}

return { points, map };
}
Insert cell
function str2ij(str) {
const pair = str.split("-").map((e) => parseInt(e));
return { i: pair[0], j: pair[1] };
}
Insert cell
function ij2str(i, j) {
return i + '-' + j
}
Insert cell
function computeV(h) {
const { mass, gravity } = constants;
const v = Math.sqrt(2 * h * gravity);
return v;
}
Insert cell
constants = {
return {
sqrt2: Math.sqrt(2),
mass: 1,
gravity: 9.8,
numX: numX,
numY: parseInt((numX / width) * height),
xScale: d3.scaleLinear().domain([-0.1, 1.1]).range([0, width]),
yScale: d3.scaleLinear().domain([-0.1, 1.1]).range([0, height])
};
}
Insert cell
g = 9.8
Insert cell
height = (width * 9) / 16
Insert cell
Insert cell
Insert cell
dijkstra = require("https://bundle.run/dijkstrajs@1.0.2")
Insert cell
d3 = require("d3")
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