Published
Edited
May 29, 2022
2 forks
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
// draw bg
ctx.fillStyle = palette.bg;
ctx.fillRect(0, 0, width, height);

drawPts(ctx, twoDData, { fill: palette.fg });
}
Insert cell
function drawPts(ctx, data, opts = {}) {
const { fill, r } = Object.assign(
{
fill: "#fff",
r: 0.75
},
opts
);
ctx.beginPath();
ctx.fillStyle = fill;
const marginX = 0;
data.forEach((pt) => {
const [u, v] = pt.position;

const x = width / 2 + math.lerp(0, width / 2, u) / aspectRatio;
const y = height / 2 + math.lerp(0, height / 2, v);
ctx.moveTo(x, y);
ctx.arc(x, y, r, 0, 2 * Math.PI);
});
ctx.fill();
}
Insert cell
threeDData = {
const count = 9;
let pts = math
.linspace(count, true)
.flatMap((w) =>
math
.linspace(count, true)
.flatMap((v) =>
math
.linspace(count, true)
.map((u) => [2 * u - 1, 2 * v - 1, 2 * w - 1])
)
);

pts = pts.map((pt) => GLVec3.rotateY([], pt, [0, 0, 0], rotY * Math.PI));
pts = pts.map((pt) => GLVec3.rotateX([], pt, [0, 0, 0], rotX * Math.PI));
pts = pts.map((pt) => GLVec3.scale([], pt, math.lerp(0.25, 1.25, zoom)));

return pts;
}
Insert cell
twoDData = {
return threeDData
.map((vec3) => {
const vec3Projected = projectPointOnPlane(vec3, projectionPlane);
const distToProjectPlane = distance(vec3, vec3Projected);

const [u, v, w] = vec3Projected;

if (u < -aspectRatio || u > aspectRatio) return false;
if (v < -1 || v > 1) return false;
if (distToProjectPlane > frustum) return false;
if (projectionPlane[2] < w) return false;

return {
position: [u, v]
};
})
.filter(Boolean);
}
Insert cell
Insert cell
palette = ({
bg: `hsl(0,0%,5%)`,
fg: `hsl(0,0%,95%)`,
debug: `hsl(300, 100%, 50%)`
})
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