Auxiliary figures:
// cubic interpolation by the four values in 0, 1/3, 2/3 and 1
function cerp(y1, y2, y3, y4, x) {
    const a = -9*y1/2 + 27*y2/2 - 27*y3/2 + 9*y4/2;
    const b = 9*y1 - 45*y2/2 + 18*y3 - 9*y4/2;
    const c = -11*y1/2 + 9*y2 - 9*y3/2 + y4;
    const d = y1;
    return a*x*x*x + b*x*x + c*x + d;
}

function cl_transform(points, x, y) {
    const x1 = lerp(points[0][0], points[1][0], x);
    const x2 = lerp(points[2][0], points[3][0], x);
    const x3 = lerp(points[4][0], points[5][0], x);
    const x4 = lerp(points[6][0], points[7][0], x);
    const x_transformed = cerp(x1, x2, x3, x4, y);
    const y1 = lerp(points[0][1], points[1][1], x);
    const y2 = lerp(points[2][1], points[3][1], x);
    const y3 = lerp(points[4][1], points[5][1], x);
    const y4 = lerp(points[6][1], points[7][1], x);
    const y_transformed = cerp(y1, y2, y3, y4, y);
    return [x_transformed, y_transformed];
}