Public
Edited
Feb 10, 2024
Insert cell
Insert cell
draw_bipolar_coordinates();
Insert cell
draw_polar_coordinates();
Insert cell
function draw_bipolar_coordinates() {
const [area, svg] = make_svg();
const xa = -100;
const xb = 100;

for (let i = 2; i <= 9; i++) {
draw_apollonian_circle(svg, xa, xb, 1.0/i);
draw_apollonian_circle(svg, xa, xb, i);
}
let rs = [100, 102, 110, 130, 200, 300, 500, 1000];
for (let r of rs) {
draw_steiner_circle(svg, xa, xb, r, 1);
draw_steiner_circle(svg, xa, xb, r, -1);
}
draw_point(svg, xa); // Point A
draw_point(svg, xb); // Point B
return area.node();
}
Insert cell
function draw_polar_coordinates() {
const [area, svg] = make_svg();
for (let i = 1; i <= 20; i++) {
let r = i * 40;
draw_circle(svg, 0, 0, r)
.attr("stroke", "blue")
.attr("fill", "none");
}
let N = 10;
let R = 1000;
for (let i = 0; i < N; i++) {
let theta = 2*Math.PI/N * i;
let x = Math.cos(theta) * R;
let y = Math.sin(theta) * R;
draw_line(svg, [0, 0], [x, y], "red")
}
return area.node();
}
Insert cell
function draw_apollonian_circle(svg, xa, xb, q) {
const [x1, x2] = get_diameter(xa, xb, q);
const x0 = (x1 + x2) / 2;
const r = Math.abs(x2 - x1) / 2;
const da = Math.abs(x1 - xa);
const db = Math.abs(x1 - xb);
draw_circle(svg, x0, 0, r)
.attr("stroke", "blue")
.attr("fill", "none");
}
Insert cell
function draw_steiner_circle(svg, xa, xb, r, sign) {
let x0 = (xa + xb) / 2;
let b = (xa - xb) / 2;
let h = Math.sqrt(r*r - b*b)
let y0 = sign * h;
draw_circle(svg, x0, y0, r)
.attr("stroke", "red")
.attr("fill", "none");
}
Insert cell
function get_diameter(xa, xb, r) {
const sr = Math.sqrt(r);
const x1 = (xb - xa) * (r - sr)/(r - 1) + xa;
const x2 = (xb - xa) * (r + sr)/(r - 1) + xa;
return [x1, x2];
}
Insert cell
function draw_circle(svg, x0, y0, r) {
return svg.append("circle")
.attr("cx", WIDTH/2 + x0)
.attr("cy", HEIGHT/2 + y0)
.attr("stroke-width", 1)
.attr("r", r);
}
Insert cell
function draw_point(svg, x0) {
draw_circle(svg, x0, 0, 1)
.attr("stroke", "black")
.attr("fill", "black");
}
Insert cell
function make_svg() {
const area = d3.create('div');
const header = area.append('div');
const svg = area.append('svg')
.attr('width', WIDTH)
.attr('height', HEIGHT);
return [area, svg];
}
Insert cell
function draw_line(svg, p1, p2, color) {
let [x1, y1] = p1;
let [x2, y2] = p2;
svg.append("line")
.attr("x1", x1 + WIDTH/2)
.attr("x2", x2 + WIDTH/2)
.attr("y1", y1 + HEIGHT/2)
.attr("y2", y2 + HEIGHT/2)
.attr("stroke-width", 1)
.attr("stroke", color);
}
Insert cell
WIDTH = 1000
Insert cell
HEIGHT = 500
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