Public
Edited
Jan 10, 2024
Insert cell
Insert cell
Insert cell
{
let marks1, marks2, plt;

let drawTriangle = (triangle) => {
return [
Plot.line(triangle, {
x: "x",
y: "y",
fx: "class",
fill: "color",
opacity: 0.5
}),
Plot.dot(triangle, {
x: "x",
y: "y",
fx: "class",
fill: "white",
stroke: "color",
strokeWidth: 3,
r: 4
})
];
};

marks1 = drawTriangle(triangle);
marks2 = drawTriangle(translated.filter((d) => d.type === "triangle"));

plt = Plot.plot({
x: { nice: true },
y: { nice: true },
width: width,
color: { legend: true, scheme: "Tableau10" },
grid: true,
aspectRatio: 1.0,
marks: []
.concat(marks1)
.concat(marks2)
.concat([
Plot.dot(points, {
x: "x",
y: "y",
fx: "class",
stroke: "i",
strokeWidth: 2,
r: 5
}),
Plot.link(points, {
x1: "x",
y1: "y",
x2: "bx",
y2: "by",
fx: "class",
stroke: "i"
}),
Plot.dot(points, {
x: "bx",
y: "by",
fx: "class",
fill: "i",
r: 2
})
])
.concat(
Plot.dot(
translated.filter((d) => d.type === "point"),
{ x: "x", y: "y", fx: "class", fill: "i", r: 5 }
)
)
});

return plt;
}
Insert cell
translated = {
let x0 = triangle[0].x,
y0 = triangle[0].y,
dx1 = triangle[1].x - x0,
dx2 = triangle[2].x - x0,
dy1 = triangle[1].y - y0,
dy2 = triangle[2].y - y0,
a = 1 / (dx1 * dy2 - dx2 * dy1),
b = 1 / (dx2 * dy1 - dx1 * dy2),
psi = [
[a * dy2, -a * dx2],
[b * dy1, -b * dx1]
];

let forward = (x, y) => {
let vx = x - x0,
vy = y - y0;
return {
x: psi[0][0] * vx + psi[0][1] * vy,
y: psi[1][0] * vx + psi[1][1] * vy
};
};

let backward = (x, y) => {
let vx = dx1 * x + dx2 * y,
vy = dy1 * x + dy2 * y;
return {
bx: vx + x0,
by: vy + y0
};
};

let nodes = [];

triangle.map(({ x, y, i }) => {
nodes.push(
Object.assign(
{ i, type: "triangle", class: "translated", color: "red" },
forward(x, y)
)
);
});

let obj;
points.map((pnt) => {
obj = Object.assign(
{ i: pnt.i, type: "point", class: "translated" },
forward(pnt.x, pnt.y)
);
nodes.push(obj);
Object.assign(pnt, backward(obj.x, obj.y));
});

return nodes;
}
Insert cell
points = {
button;

let nodes = [],
n = 7,
scaleRadius = d3
.scaleLinear()
.domain([0, n])
.range([0, Math.PI * 2]),
r = 0.5;

for (let i = 0; i < n; ++i) {
nodes.push({
x: r * Math.cos(scaleRadius(i)),
y: r * Math.sin(scaleRadius(i)),
i,
type: "point",
class: "raw"
});
}

return nodes;
}
Insert cell
triangle = {
button;

let nodes = [];

for (let i = 0; i < 3; ++i) {
let k = i === 0 ? 0 : 1;
nodes.push({
x: rnd() * k,
y: rnd() * k,
i,
type: "triangle",
class: "raw",
color: "gray"
});
}

return nodes;
}
Insert cell
rnd = d3.randomNormal()
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