Published
Edited
Dec 7, 2021
Importers
4 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
base_digit_set([
[2, 0],
[0, 2]
])
Insert cell
Insert cell
{
let A = [
[2, 0],
[0, 2]
];
let AInv = math.inv(A);
let IFS = new IteratedFunctionSystem(
base_digit_set(A).map((d) => new AffineFunction([AInv, d]))
);

return IFS.render_deterministic({
colors: true,
max_depth: 1,
init: [
[0, 0],
[2, 0],
[2, 2],
[0, 2]
],
axes: true,
padding: 20
});
}
Insert cell
Insert cell
{
let A = [
[2, 0],
[0, 2]
];
let AInv = math.inv(A);
let IFS = new IteratedFunctionSystem(
[
[0, 0],
[1, 0],
[0, 1],
[-1, -1]
].map((d) => new AffineFunction([AInv, d]))
);
return IFS.render_deterministic({
colors: true,
max_depth: 6,
init: [
[0, 0],
[2, 0],
[2, 2],
[0, 2]
],
axes: true,
padding: 20
});

return IFS.render_stochastic({
colors: true,
n: 100000,
image_width: width < 800 ? width : 800
});
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
let A = [
[2, -1],
[1, 1]
];
let AInv = math.inv(A);
let IFS = new IteratedFunctionSystem(
base_digit_set(A).map((d) => new AffineFunction([AInv, d]))
);

return IFS.render_deterministic({
fill_colors: true,
stroke_colors: "match",
max_depth: 8,
init: [
[0, 0],
[2, 1],
[1, 2],
[-1, 1]
]
});
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
{
let A = [
[2, -1],
[1, 1]
];
let AInv = math.inv(A);
let B = [
[0, 1],
[2 / math.sqrt(3), -1 / math.sqrt(3)]
];
AInv = math.multiply(B, AInv, math.inv(B));
let IFS = new IteratedFunctionSystem(
base_digit_set(A).map(
(d) => new AffineFunction([AInv, math.multiply(B, d)])
)
);
return IFS.render_deterministic({
fill_colors: true,
stroke_colors: "match",
max_depth: 8,
extent: [
[-0.5, 2.2],
[-0.7, 2]
],
padding: 0,
init: [
[0, 0],
[2, 1],
[1, 2],
[-1, 1]
].map((xy) => math.multiply(B, xy))
});
}
Insert cell
Insert cell
function digit_pic(A, opts = {}) {
let { s = 0.04, w = width < 500 ? width : 500 } = opts;
let u = [A[0][0], A[1][0]];
let v = [A[0][1], A[1][1]];

let xmin = d3.min([u[0], v[0], 0, u[0] + v[0]]);
let xmax = d3.max([u[0], v[0], 0, u[0] + v[0]]);
let ymin = d3.min([u[1], v[1], 0, u[1] + v[1]]);
let ymax = d3.max([u[1], v[1], 0, u[1] + v[1]]);
let aspect = (ymax - ymin) / (xmax - xmin);
let h = w * aspect;

let tu = math.atan2(u[1], u[0]);
let tv = math.atan2(v[1], v[0]);

let digit_set = base_digit_set(A);

return Plot.plot({
width: w,
height: h,
marks: [
Plot.line([u, [0, 0], v], { stroke: "black", strokeWidth: 3 }),
Plot.line([u, [u[0] + v[0], u[1] + v[1]], v], {
strokeDasharray: [3, 5]
}),
Plot.line(
[
[0, -s],
[2 * s, 0],
[0, s]
].map(shift(u).compose(rotate(tu)).f),
{ fill: "black" }
),
Plot.line(
[
[0, -s],
[2 * s, 0],
[0, s]
].map(shift(v).compose(rotate(tv)).f),
{ fill: "black" }
),
Plot.dot(digit_set, { r: 4, fill: "black" })
]
});
}
Insert cell
function base_digit_set(A) {
let eps = 10 ** -8;
let left_of_line = ([cx, cy], [[ax, ay], [bx, by]]) =>
(bx - ax) * (cy - ay) - (cx - ax) * (by - ay) > 0;
let left_of_or_on_line = ([cx, cy], [[ax, ay], [bx, by]]) =>
(bx - ax) * (cy - ay) - (cx - ax) * (by - ay) > -eps;

let u = [A[0][0], A[1][0]];
let v = [A[0][1], A[1][1]];
if (left_of_line(u, [[0, 0], v])) {
[u, v] = [v, u];
}
let [ux, uy] = u;
let [vx, vy] = v;

let xs = [0, ux, vx, ux + vx];
let xmin = d3.min(xs);
let xmax = d3.max(xs);
let ys = [0, uy, vy, uy + vy];
let ymin = d3.min(ys);
let ymax = d3.max(ys);

let nominations = d3
.range(xmin, xmax + 1)
.map((x) => d3.range(ymin, ymax + 1).map((y) => [x, y]))
.flat();

return nominations.filter(
(w) =>
left_of_or_on_line(w, [[0, 0], u]) &&
left_of_line(w, [u, [ux + vx, uy + vy]]) &&
left_of_line(w, [[ux + vx, uy + vy], v]) &&
left_of_or_on_line(w, [v, [0, 0]])
);
}
Insert cell
math = require("mathjs")
Insert cell
import {
AffineFunction,
IteratedFunctionSystem,
shift,
rotate
// degree
} from "@mcmcclur/iteratedfunctionsystem-class"
Insert cell
import { DigraphIFS } from "@mcmcclur/digraphifs-class"
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