xxxxxxxxxx
75
function gasket(t) {
const x0 = 0,
y0 = 0,
r0 = 1,
b0 = -1 / r0;
const x1 = (1 + t) / 2,
y1 = 0,
r1 = r0 - Math.sqrt(x1 * x1 + y1 * y1),
b1 = 1 / r1;
const x2 = -r1,
y2 = y1,
r2 = x1,
b2 = 1 / r2;
const c0 = [x0, x0, b0];
const c1 = [x1, y1, b1];
const c2 = [x2, y2, b2];
const b3 = solve(b0, b1, b2);
const c3 = [
solve(b0 * x0, b1 * x1, b2 * x2, 2) / b3,
solve(b0 * y0, b1 * y1, b2 * y2, 2) / b3,
b3
];
return [
c0, c1, c2, c3,
circles(c0, c1, c2, c3),
circles(c3, c1, c2, c0),
circles(c0, c2, c3, c1),
circles(c0, c1, c3, c2)
];
}
function* circles(c0, c1, c2, c3) {
const c = innerSoddy(c0, c1, c2, c3);
if (Math.abs(c[2]) > 200)
return;
yield c;
yield* circles(c0, c1, c, c2);
yield* circles(c1, c, c2, c0);
yield* circles(c2, c, c0, c1);
}
function innerSoddy([x0, y0, b0], [x1, y1, b1], [x2, y2, b2], [x3, y3, b3]) {
const b = 2 * (b0 + b1 + b2) - b3;
return [
(2 * (b0 * x0 + b1 * x1 + b2 * x2) - b3 * x3) / b,
(2 * (b0 * y0 + b1 * y1 + b2 * y2) - b3 * y3) / b,
b
];
}
function solve(x, y, z, offset = 0) {
const b = x + y + z;
const c = x * x + y * y + z * z - b * b / 2 - offset;
return Math.sqrt(Math.max(0, b * b - 2 * c)) + b;
}
const dim = 400
const half = dim / 2
function setup() {
createCanvas(dim, dim);
scale(dim / 2)
}
function draw() {
background(255);
translate(dim / 2, dim / 2)
noFill()
const factor = dim / 2.1
for (const [x, y, c] of gasket(0)) {
const r = Math.abs(1 / c);
circle(x * factor, y * factor, r * factor * 2);
}
noLoop()
}