function koch_like_curve(size_factor, n, opts = {}) {
let { width = 900 } = opts;
let axiom = [{ symbol: "F", step: 1, level: 0 }];
let productions = {
F: ({ part }) => [
{
symbol: "F",
step: size_factor(part.level) * part.step,
level: part.level + 1
},
{ symbol: "r", theta: Math.acos(1 / (2 * size_factor(part.level)) - 1) },
{
symbol: "F",
step: size_factor(part.level) * part.step,
level: part.level + 1
},
{
symbol: "r",
theta: -2 * Math.acos(1 / (2 * size_factor(part.level)) - 1)
},
{
symbol: "F",
step: size_factor(part.level) * part.step,
level: part.level + 1
},
{ symbol: "r", theta: Math.acos(1 / (2 * size_factor(part.level)) - 1) },
{
symbol: "F",
step: size_factor(part.level) * part.step,
level: part.level + 1
}
]
};
let lsys = new LSystem({
axiom,
productions
});
lsys.iterate(n);
let instructions = lsys.getRaw();
let pts = [[0, 0]];
let dir = [1, 0];
instructions.forEach(function (o) {
if (o.symbol == "F") {
let [x0, y0] = pts.slice(-1)[0];
let x1 = x0 + o.step * dir[0];
let y1 = y0 + o.step * dir[1];
pts.push([x1, y1]);
} else if (o.symbol == "r") {
dir = r(o.theta)(dir);
}
});
let aspect = 0.54 / 1.04;
return Plot.plot({
x: { domain: [-0.02, 1.02] },
y: { domain: [-0.02, 0.52] },
width: width,
height: width * aspect,
margin: 0,
marks: [Plot.line(pts)]
});
function r(theta) {
return ([x, y]) => [
Math.cos(theta) * x - Math.sin(theta) * y,
Math.sin(theta) * x + Math.cos(theta) * y
];
}
}