Published
Edited
Nov 25, 2018
1 fork
14 stars
Insert cell
Insert cell
Insert cell
Insert cell
canvas = {
const height = 600;
const context = DOM.context2d(width, height);
const radius = Math.min(width, height) / 2 - 2;
const P = polygon(n, radius);
const a = p * -Math.PI * (1 / 2 - 1 / n);
context.translate(width / 2, height / 2);

context.beginPath();
context.moveTo(...P[0]);
for (let i = 1; i < n; ++i) {
context.lineTo(...P[i]);
}
context.closePath();
for (let i = n - 1; i >= 0; --i) {
const [p0, p1] = lineRotate(P[i], P[(i + 1) % n], a);
const [p2, p3] = lineRotate(P[(i + 1) % n], P[(i + 2) % n], a);
const p4 = lineLineIntersect(p0, p1, p2, p3);
if (i === n - 1) context.moveTo(...p4);
else context.lineTo(...p4);
}
context.closePath();
context.fillStyle = "#ddd";
context.fill();
context.lineWidth = 1.5;
context.stroke();

context.beginPath();
for (let i = 0; i < n; ++i) {
const [p0, p1] = lineRotate(P[i], P[(i + 1) % n], a);
const [p2, p3] = lineRotate(P[(i + 1) % n], P[(i + 2) % n], a);
context.moveTo(...p2);
context.lineTo(...lineLineIntersect(p0, p1, p2, p3));
}
context.lineWidth = 1;
context.strokeStyle = "#555";
context.stroke();

yield context.canvas;
}
Insert cell
function polygon(n, radius) {
const polygon = [[0, radius]];
for (let i = 1; i < n; ++i) {
const angle = i / n * 2 * Math.PI;
const x = radius * Math.sin(angle);
const y = radius * Math.cos(angle);
polygon.push([x, y]);
}
return polygon;
}
Insert cell
function lineLineIntersect([x0, y0], [x1, y1], [x2, y2], [x3, y3]) {
const x02 = x0 - x2, y02 = y0 - y2;
const x10 = x1 - x0, y10 = y1 - y0;
const x32 = x3 - x2, y32 = y3 - y2;
const t = (x32 * y02 - y32 * x02) / (y32 * x10 - x32 * y10);
return [x0 + t * x10, y0 + t * y10];
}
Insert cell
function lineRotate([x0, y0], [x1, y1], angle) {
const dx = x1 - x0, dy = y1 - y0;
const ca = Math.cos(angle), sa = Math.sin(angle);
return [[x0, y0], [x0 + ca * dx - sa * dy, y0 + sa * dx + ca * dy]];
}
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