/** * Returns a bezier curve that starts and ends at the given `t` parameters. * * @param ps a quadratic bezier curve given as an ordered array of its * control point coordinates, e.g. `[[0,0], [1,1], [2,1]]` * @param tS the `t` parameter where the resultant bezier should start * @param tE the `t` parameter where the resultant bezier should end * * @internal */ function fromTo2( ps: number[][], tS: number, tE: number): number[][] { if (tS === 0) { if (tE === 1) { return ps; } return splitLeft2(ps, tE); } if (tE === 1) { return splitRight2(ps, tS); } return splitAtBoth2(ps, tS, tE); } /** * Returns a bezier curve that starts at the given t parameter and ends * at `t === 1`. * * @param ps a quadratic bezier curve given as an ordered array of its * control point coordinates, e.g. `[[0,0], [1,1], [2,1]]` * @param t the `t` parameter where the resultant bezier should start * * @internal */ function splitRight2( ps: number[][], t: number): number[][] { // -------------------------------------------------------- // const [[x0, y0], [x1, y1], [x2, y2]] = ps; const p0 = ps[0]; const p1 = ps[1]; const p2 = ps[2]; const x0 = p0[0]; const y0 = p0[1]; const x1 = p1[0]; const y1 = p1[1]; const x2 = p2[0]; const y2 = p2[1]; // -------------------------------------------------------- const tt = t*t; const xA = x0 - x1; const xB = x2 - x1; const yA = y0 - y1; const yB = y2 - y1; return [ [tt*(xA + xB) - (2*t*xA - x0), // xx0, split point x tt*(yA + yB) - (2*t*yA - y0)], // yy0, split point y [t*xB + x1, // xx1 t*yB + y1], // yy1 p2 ]; } /** * Returns a bezier curve that starts at `t === 0` and ends at the given `t` * parameter. * * @param ps a quadratic bezier curve given as an ordered array of its * control point coordinates, e.g. `[[0,0], [1,1], [2,1]]` * @param t the `t` parameter where the resultant bezier should end * * @internal */ function splitLeft2( ps: number[][], t: number): number[][] { // -------------------------------------------------------- // const [[x0, y0], [x1, y1], [x2, y2]] = ps; const p0 = ps[0]; const p1 = ps[1]; const p2 = ps[2]; const x0 = p0[0]; const y0 = p0[1]; const x1 = p1[0]; const y1 = p1[1]; const x2 = p2[0]; const y2 = p2[1]; // -------------------------------------------------------- const tt = t*t; const xA = x0 - x1; const yA = y0 - y1; return [ p0, [-t*xA + x0, // xx1 -t*yA + y0], // yy1 [tt*(xA + (x2 - x1)) - (2*t*xA - x0), // xx2 - split point x tt*(yA + (y2 - y1)) - (2*t*yA - y0)] // yy2 - split point y ]; } /** * Returns a bezier curve that starts and ends at the given `t` parameters. * * @param ps a quadratic bezier curve given as an ordered array of its * control point coordinates, e.g. `[[0,0], [1,1], [2,1]]` * @param tS the `t` parameter where the resultant bezier should start * @param tE the `t` parameter where the resultant bezier should end * * @internal */ function splitAtBoth2( ps: number[][], tS: number, tE: number): number[][] { // -------------------------------------------------------- // const [[x0, y0], [x1, y1], [x2, y2]] = ps; const p0 = ps[0]; const p1 = ps[1]; const p2 = ps[2]; const x0 = p0[0]; const y0 = p0[1]; const x1 = p1[0]; const y1 = p1[1]; const x2 = p2[0]; const y2 = p2[1]; // -------------------------------------------------------- const ttS = tS*tS; const ttE = tE*tE; const tStE = tS*tE; const xA = x0 - x1; const xB = x2 - x1; const xC = xA + xB; const yA = y0 - y1; const yB = y2 - y1; const yC = yA + yB; const xx0 = ttS*xC - (2*tS*xA - x0); const xx1 = tStE*xC - (xA*(tE + tS) - x0); const xx2 = ttE*xC - (2*tE*xA - x0); const yy0 = ttS*yC - (2*tS*yA - y0); const yy1 = tStE*yC - (yA*(tE + tS) - y0); const yy2 = ttE*yC - (2*tE*yA - y0); return [[xx0, yy0], [xx1, yy1], [xx2, yy2]]; } export { fromTo2 }