Interactive demonstration on how a closed path is calculated and plotted.
Move the black dots on the blue line with your mouse/finger.
// array of points that lie on the Bezier path let A = ; // resulting control points conveniently located here // B = ; // coefficients for a 5 point closed path const N = 5; const c0 = 3.0 / 11.0; const c1 = -1.0 / 11.0; const c2 = 1.0 / 11.0; const c3 = -3.0 / 11.0; const c4 = 1; // calculate B[] control points let B = [ { x: A[1].x*c0 + A[2].x*c1 + A[3].x*c2 + A[4].x*c3 + A[0].x*c4 , y: A[1].y*c0 + A[2].y*c1 + A[3].y*c2 + A[4].y*c3 + A[0].y*c4 }, { x: A[2].x*c0 + A[3].x*c1 + A[4].x*c2 + A[0].x*c3 + A[1].x*c4 , y: A[2].y*c0 + A[3].y*c1 + A[4].y*c2 + A[0].y*c3 + A[1].y*c4 }, { x: A[3].x*c0 + A[4].x*c1 + A[0].x*c2 + A[1].x*c3 + A[2].x*c4 , y: A[3].y*c0 + A[4].y*c1 + A[0].y*c2 + A[1].y*c3 + A[2].y*c4 }, { x: A[4].x*c0 + A[0].x*c1 + A[1].x*c2 + A[2].x*c3 + A[3].x*c4 , y: A[4].y*c0 + A[0].y*c1 + A[1].y*c2 + A[2].y*c3 + A[3].y*c4 }, { x: A[0].x*c0 + A[1].x*c1 + A[2].x*c2 + A[3].x*c3 + A[4].x*c4 , y: A[0].y*c0 + A[1].y*c1 + A[2].y*c2 + A[3].y*c3 + A[4].y*c4 } ]; // mirror to C[] control point for (let i = 0; i < 5; i++) { C[i].x = 2 * A[(i + 1) % 5].x - B[(i + 1) % 5].x; C[i].y = 2 * A[(i + 1) % 5].y - B[(i + 1) % 5].y; }