Uso grafico (animato) delle curve di Bézier

// height=500

let pa;      // punto di partenza della curva
let pb;      // punto finale della curva
let c1;      // 1° punto di controllo
let c2;      // 2° punto di controllo
let c1dist;  // distanza del 1° punto di controllo dall'inizio della curva
let c2dist;  // distanza del 2° punto di controllo dalla fine della curva
let steps;   // numero di cerchi che compongono la curva

function setup() {
    createCanvas(windowWidth, windowHeight);
    pb = createVector();
    c1 = createVector();
    c2 = createVector();
    setupResizable();
    cursor(HAND);
}

function setupResizable() {
//    pa = createVector(width*1.1, height / 2);
    pa = createVector(-width*0.01, height / 2);
    c1dist = width / 3;
    c2dist = width / 6;
    steps = width / 4;
}

function draw() {
    // sposta la punta del ramo
//    pb.x = map(noise(0, frameCount / 800), 0, 1, 0, width / 2);
    pb.x = map(noise(0, frameCount / 800), 0, 1, width / 2, width);
    pb.y = map(noise(1, frameCount / 800), 0, 1, 0, height);

    // muovi i punti di controllo
//    let c1ang = map(noise(2, frameCount / 1000), 0, 1, HALF_PI, PI+HALF_PI);
//    let c2ang = map(noise(3, frameCount / 400), 0, 1, PI+HALF_PI, TWO_PI+HALF_PI);
    let c1ang = map(noise(2, frameCount / 1000), 0, 1, PI+HALF_PI, TWO_PI+HALF_PI);
    let c2ang = map(noise(3, frameCount / 400), 0, 1, HALF_PI, PI+HALF_PI   );
    c1.x = pa.x + cos(c1ang) * c1dist;
    c1.y = pa.y + sin(c1ang) * c1dist;
    c2.x = pb.x + cos(c2ang) * c2dist;
    c2.y = pb.y + sin(c2ang) * c2dist;

    background(255);

    // disegna il ramo
    noStroke();
    fill(148,0,24);
    for (let i = 0; i <= steps; i++) {
        let t = i / steps;
        let x = bezierPoint(pa.x, c1.x, c2.x, pb.x, t);
        let y = bezierPoint(pa.y, c1.y, c2.y, pb.y, t);
        let diam = map(t, 0, 1, 30, 1);  // diametro da 30 a 1 pixel
        circle(x, y, diam);
    }

    // disegna punti di controllo, solo per capire meglio la logica di funzionamento
    if (mouseIsPressed) {
        fill(255, 0, 0);
        circle(c1.x, c1.y, 5);
        circle(c2.x, c2.y, 5);
        stroke(255, 128, 128);
        line(pa.x, pa.y, c1.x, c1.y);
        line(pb.x, pb.y, c2.x, c2.y);
    }
}

function windowResized() {
    resizeCanvas(windowWidth, windowHeight);
    setupResizable();
}

Per vedere i punti di controllo, cliccare sull'area di disegno e mantenere il tasto premuto.