outlineHorizontalPaths = (
{ source, target, sizes = [5, 5], bias = 1, limit = 1 },
construction = []
) => {
let [x1, y1] = source;
let [x2, y2] = target;
if (x2 < x1) {
[x1, y1, x2, y2] = [x2, y2, x1, y1];
}
const xmid = (x1 + x2) / 2;
const w = (Math.abs(x2 - x1) / 2) * limit;
const sizeSum = sizes.reduce((acc, v) => acc + v, 0);
const v = vec2.sub([], [x2, y2], [x1, y1]);
const vp = vec2.normalize([], [v[1], -v[0]]);
let ds = sizeSum / 2;
let curves = [];
for (let s of [0, ...sizes]) {
ds -= s;
const u = vec2.scale([], vp, ds);
const y1a = y1 - ds;
const y2a = y2 - ds;
const dx = Math.max(-w, Math.min(w, u[0]));
const x1a = bias * (xmid + dx - x1) + x1;
const x2a = bias * (xmid + dx - x2) + x2;
curves.push([
[x1, y1a],
[x1a, y1a],
[x2a, y2a],
[x2, y2a]
]);
}
let paths = [];
const coord = (p) => p[0] + "," + p[1];
for (let i = 0; i < sizes.length; i++) {
let [a, b, c, d] = curves[i];
let path =
"M" + coord(a) + "C" + coord(b) + "," + coord(c) + "," + coord(d);
[d, c, b, a] = curves[i + 1];
path +=
"L" + coord(a) + "C" + coord(b) + "," + coord(c) + "," + coord(d) + "Z";
paths.push(path);
}
construction.splice(0, 0, ...curves);
return paths;
}