Published unlisted
Edited
May 23, 2022
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
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
circular = {
const width = 400;
const height = 400;
const c = DOM.context2d(width, height);

const center = [150, 150];
const r = 120;
const tickSize = 3;
const rectX = 20;
const rectY = 20;
const rectW = 100;
const rectH = 100;

c.fillStyle = "rgba(200, 200, 200, 0.5)";
c.fillRect(rectX, rectY, rectW, rectH);

// draw center
c.strokeStyle = "black";
c.beginPath();
c.moveTo(center[0], center[1] - tickSize);
c.lineTo(center[0], center[1] + tickSize);
c.closePath();
c.stroke();
c.beginPath();
c.moveTo(center[0] - tickSize, center[1]);
c.lineTo(center[0] + tickSize, center[1]);
c.closePath();
c.stroke();

// Draw arc
c.fillStyle = "none";
c.strokeStyle = "black";
c.beginPath();
c.arc(center[0], center[1], r, Math.PI, (Math.PI * 3) / 2);
c.stroke();
c.closePath();

// https://mathworld.wolfram.com/Circle-LineIntersection.html
// moves x1,y1,x2,y2 to be relative to cx cy.
const findIntersections = (x1, y1, x2, y2, cx, cy, r) => {
let dx = x2 - cx - (x1 - cx);
let dy = y2 - cy - (y1 - cy);
let dr = Math.sqrt(dx * dx + dy * dy);
let dd = (x1 - cx) * (y2 - cy) - (x2 - cx) * (y1 - cy);

const sgn = (v) => {
return v < 0 ? -1 : 1;
};

let delta = r * r * dr * dr - dd * dd;
if (delta < 0) {
return [];
}

let ix1 =
(dd * dy + sgn(dy) * dx * Math.sqrt(r * r * dr * dr - dd * dd)) /
(dr * dr) +
cx;
let iy1 =
(-dd * dx + Math.abs(dy) * Math.sqrt(r * r * dr * dr - dd * dd)) /
(dr * dr) +
cy;
let ix2 =
(dd * dy - sgn(dy) * dx * Math.sqrt(r * r * dr * dr - dd * dd)) /
(dr * dr) +
cx;
let iy2 =
(-dd * dx - Math.abs(dy) * Math.sqrt(r * r * dr * dr - dd * dd)) /
(dr * dr) +
cy;

let intersections = [];
if (x1 <= ix1 && ix1 <= x2 && y1 <= iy1 && iy1 <= y2) {
intersections.push([ix1, iy1]);
}
if (x1 <= ix2 && ix2 <= x2 && y1 <= iy2 && iy2 <= y2) {
intersections.push([ix2, iy2]);
}

return intersections;
};

// https://mathworld.wolfram.com/Circle-LineIntersection.html
let edges = [
[rectX, rectY, rectX + rectW, rectY],
[rectX, rectY, rectX, rectY + rectH],
[rectX + rectW, rectY, rectX + rectW, rectY + rectH],
[rectX, rectY + rectH, rectX + rectW, rectY + rectH]
];
for (let edge of edges) {
const intersections = findIntersections(
edge[0],
edge[1],
edge[2],
edge[3],
center[0],
center[1],
r
);
for (let i of intersections) {
c.fillStyle = "red";
c.fillRect(i[0] - 2, i[1] - 2, 4, 4);
}
}

// const x = Math.sqrt(
// r * r - (rectY + yEdge - center[1]) * (rectY + yEdge - center[1])
// );
// c.fillStyle = "red";
// let intersectX = center[0] > rectX + xEdge ? center[0] - x : center[0] + x;
// c.fillRect(intersectX, rectY + yEdge - 2, 4, 4);

// const y = Math.sqrt(
// r * r - (rectX + xEdge - center[0]) * (rectX + xEdge - center[0])
// );
// c.fillStyle = "blue";
// let intersectY = center[1] > rectY + yEdge ? center[1] - y : center[1] + y;
// c.fillRect(rectX + xEdge, intersectY - 2, 4, 4);

return c.canvas;
}
Insert cell
Insert cell
Insert cell
Plot.rect(
sizesSorted,
Plot.bin({ fillOpacity: "count" }, { x: "bearing", y: "area" })
).plot()
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
turfjs = require("@turf/turf")
Insert cell
tilebelt = import("https://cdn.skypack.dev/@mapbox/tilebelt")
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