Published
Edited
Feb 8, 2021
1 fork
7 stars
Insert cell
Insert cell
Insert cell
path = toothPath + axlePath
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
size = 2 * (radius + padding)
Insert cell
Insert cell
toothDepth = Math.min(
(toothScale * (2.0 * Math.PI * radius)) / numTeeth,
radius / 2
)
Insert cell
Insert cell
toothAngles = {
const angleDelta = (2 * Math.PI) / numTeeth / 4;
const angleWidener = toothDepth / (radius - toothDepth) / 2;
const tooth = [0, 1, 2 - angleWidener, 3 + angleWidener];
return Array.from({ length: numTeeth }).flatMap((v, i) => {
return tooth.map(v => (v + 4 * i) * angleDelta);
});
}
Insert cell
Insert cell
corners = toothAngles.map((angle, index) => {
let r = index % 4 < 2 ? radius : radius - toothDepth;
return [Math.cos(angle), Math.sin(angle)].map(v =>
(v * r + radius + padding).toFixed(2)
);
})
Insert cell
Insert cell
toothPath = corners.slice(1).reduce((p, corner) => {
p += "L" + corner.join();
return p;
}, "M" + corners[0].join()) + "z"
Insert cell
Insert cell
axleRadius = Math.max(0, radius - toothDepth - ringScale * toothDepth)
Insert cell
axleStart = [padding + radius + axleRadius, padding + radius].map(v =>
v.toFixed(3)
)
Insert cell
arcParams = {
let r = axleRadius.toFixed(3);
let endAngle = Math.PI * 1.999;
let [x, y] = [Math.cos(endAngle), -Math.sin(endAngle)]
.map(v => padding + radius + v * axleRadius)
.map(v => v.toFixed(3));
return [r, r, 0, 1, 0, x, y];
}
Insert cell
axlePath = "M" + axleStart.join() + "A" + arcParams.join() + "z"
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