Public
Edited
Dec 25, 2023
Importers
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
// Accepts a real number between 0 and 1 and computes the image of
// that number in the unit square.
// Should be exact if the input is a rational number whose
// denominator is a power of 2.
// Yields an approximation for all other numbers.
function h(t) {
if (t == 0) {
return [0, 0];
} else if (t == 1) {
return [1, 0];
} else if (typeof t == "number" && 0 < t && t < 1) {
let qs = t
.toString(4)
.split(".")[1]
.split("")
.map((q) => parseInt(q));
return h0(qs);
}
}
Insert cell
// Example
h(19 / 64)
Insert cell
// Accepts an array of numbers, denoted qs, that are assumed to represent the
// base four expansion of a real number in the unit interval.
// Thus, each entry in qs should be 0, 1, 2, or 3.
// Returns the image of the number
function h0(qs) {
let cs = qs.map((q, j) => ((-1) ** e(0, j, qs) / 2 ** j) * Math.sign(q));
let x = d3.sum(qs.map((q, j) => cs[j] * ((1 - d(j, qs)) * q - 1))) / 2;
let y = d3.sum(qs.map((q, j) => cs[j] * (1 - d(j, qs) * q))) / 2;
return [x, y];
}
Insert cell
// Example
h0([1, 0, 3])
Insert cell
Insert cell
d = (j, qs) => (e(0, j, qs) + e(3, j, qs)) % 2
Insert cell
Insert cell
function e(k, j, qs) {
let count = 0;
for (let i = 0; i < j; i++) {
if (qs[i] === k) {
count++;
}
}
return count;
}
Insert cell
// Generate the nth level approximation to the curve.
function curve(n, size = 800) {
let pts = d3
.range(0, 1, 1 / 2 ** n)
.concat([1])
.map(function (t) {
let [x, y] = h(t);
return { t, x, y };
});

return Plot.plot({
width: size,
height: size,
inset: 10,
x: { domain: [0, 1], ticks: 8 },
y: { domain: [0, 1], ticks: 8 },
marks: [
Plot.line(pts, { x: "x", y: "y", strokeWidth: 3 }),
Plot.dot(pts, {
fill: "black",
r: 5,
x: "x",
y: "y",
channels: { t: "t" },
tip: true
}),
Plot.frame()
]
});
}
Insert cell
// // This code is used to produce the image in the StackExchange post
// {
// let container = d3.create("div");
// d3.range(12).forEach(function (n) {
// let div = container
// .append("div")
// .style("width", `${width / 4}px`)
// .style("display", "inline-block");
// div.append(() => curve(n, width / 3));
// container.append(() => div.node());
// });

// return container.node();
// }
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