Public
Edited
Apr 9, 2023
1 star
Insert cell
Insert cell
Insert cell
Insert cell
shapes.find((s) => s.type === "obtuse")?.subdivide()
Insert cell
shapes = {
let size = 10;
let rv = Array.from(
{ length: 10 },
(d, i) =>
new RobinsonTriangle({
type: "acute",
points: [
{ x: 0, y: 0 },
{
x: Math.cos((TAU / 10) * i) * size,
y: Math.sin((TAU / 10) * i) * size
},
{
x: Math.cos((TAU / 10) * (i + 1)) * size,
y: Math.sin((TAU / 10) * (i + 1)) * size
}
]
})
).map((s, i) => (i % 2 ? s.flip() : s));
for (let i = 0; i < depth; i++) {
rv = rv.flatMap((s, j) => s.subdivide());
}
return rv;
}
Insert cell
class RobinsonTriangle {
constructor({ points, type, depth = 0 }) {
this.type = type;
this.points = points;
this.depth = depth;
}

get path() {
let [a, b, c] = this.points;
return lineGen([b, a, c]);
}

get svg() {
let [a, b, c] = this.points;
let strokeWidth = 0.1 * Math.pow(0.87, depth);
return htl.svg`<g>
<path d="${lineGen([b, a, c])}" fill="${this.color}"></path>
<path
d="${lineGen([b, c])}"
fill="none"
stroke="${this.color}"
stroke-width="${strokeWidth}"
></path>
<path
d="${lineGen([b, a, c])}"
fill="none"
stroke="white"
stroke-width="${strokeWidth}"
></path>
</g>`;
}

get color() {
return this.type === "acute" ? "steelblue" : "rgb(160,40,5)";
}

flip() {
let [a, b, c] = this.points;
return new RobinsonTriangle({ type: this.type, points: [a, c, b] });
}

subdivide() {
let [a, b, c] = this.points;

if (this.type === "acute") {
let p = lerpxy(a, b, 1 / PHI);
return [
new RobinsonTriangle({
type: "acute",
points: [c, p, b],
depth: this.depth + 1
}),
new RobinsonTriangle({
type: "obtuse",
points: [p, c, a],
depth: this.depth + 1
})
];
} else {
let q = lerpxy(b, a, 1 / PHI);
let r = lerpxy(b, c, 1 / PHI);
return [
new RobinsonTriangle({
type: "obtuse",
points: [r, c, a],
depth: this.depth + 1
}),
new RobinsonTriangle({
type: "obtuse",
points: [q, r, b],
depth: this.depth + 1
}),
new RobinsonTriangle({
type: "acute",
points: [r, q, a],
depth: this.depth + 1
})
];
}
}
}
Insert cell
lineGen = d3.line().x(d => d.x).y(d => d.y)
Insert cell
deg = (d) => d / 360 * TAU
Insert cell
Insert cell
lerp = (a, b, t) => a + (b - a) * t
Insert cell
lerpxy = (p1, p2, t) => ({ x: lerp(p1.x, p2.x, t), y: lerp(p1.y, p2.y, t) })
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