Published
Edited
Jan 8, 2022
4 forks
Importers
50 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
resistanceCircle = R => [R / (R + 1), 0, 1 / (R + 1)]
Insert cell
Insert cell
reactanceCircle = X => [1, 1 / X, 1 / Math.abs(X)]
Insert cell
Insert cell
function circleCircleIntersect([ax, ay, ar], [bx, by, br]) {
const dx = bx - ax, dy = by - ay, d = Math.hypot(dx, dy);
const x = (dx * dx + dy * dy - br * br + ar * ar) / (2 * d);
const y = Math.sign(ay) * Math.sqrt(ar * ar - x * x);
return [ax + (dx * x + dy * y) / d, ay + (dy * x - dx * y) / d];
}
Insert cell
Insert cell
function smith([R, X]) {
if (isNaN(X) || isNaN(R)) return;
if (R === Infinity || Math.abs(X) === Infinity) return [1, 0];
if (X === 0) return [(R - 1) / (R + 1), 0];
return circleCircleIntersect(reactanceCircle(X), resistanceCircle(R));
}
Insert cell
Insert cell
Insert cell
function smithInvert([x, y]) {
if (Math.hypot(x, y) > 1) return;
return [
(1 - x ** 2 - y ** 2) / (x ** 2 - 2 * x + y ** 2 + 1),
2 * y / ((x - 1) ** 2 + y ** 2)
];
}
Insert cell
Insert cell
function resistanceArc(R, X1, X2) {
const r = scale(1 / (R + 1));
const [x1, y1] = transform(smith([R, X1]));
const [x2, y2] = transform(smith([R, X2]));
if (Math.sign(X1) !== Math.sign(X2)) {
const [x0, y0] = transform(smith([R, 0]));
return `
M${x1},${y1}
A${r},${r} 0 0,${0 < X1 ? 0 : 1} ${x0},${y0}
A${r},${r} 0 0,${X2 < 0 ? 0 : 1} ${x2},${y2}
`;
}
return `
M${x1},${y1}
A${r},${r} 0 0,${X2 < X1 ? 0 : 1} ${x2},${y2}
`;
}
Insert cell
function reactanceArc(X, R1, R2) {
const [x1, y1] = transform(smith([R1, X]));
const [x2, y2] = transform(smith([R2, X]));
if (X === 0) {
return `
M${x1},${y1}
L${x2},${y2}
`;
}
const r = scale(1 / Math.abs(X));
return `
M${x1},${y1}
A${r},${r} 0 0,${X < 0 ? 1 : 0} ${x2},${y2}
`;
}
Insert cell
Insert cell
function transform([x, y]) {
return [(x + 1) * (width / 2 - margin) + margin, (1 - y) * (width / 2 - margin) + margin];
}
Insert cell
function transformInvert([x, y]) {
return [(x - margin) / (width / 2 - margin) - 1, 1 - (y - margin) / (width / 2 - margin)];
}
Insert cell
function scale(r) {
return (width / 2 - margin) * r;
}
Insert cell
width = 975
Insert cell
margin = 20
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