贝塞尔曲线
贝塞尔曲线(Bézier curve),又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线。一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的。
在数学的数值分析领域中,贝塞尔曲线是电脑图形学中相当重要的参数曲线。
📐 数学公式
可以使用数学公式来描述贝塞尔曲线。 正如我们所看到的——实际上不需要知道,大多数人只是通过鼠标移动点来绘制曲线。 但如果你喜欢数学——就在这里。 给定控制点 Pi 的坐标:第一个控制点的坐标为 P1 = (x1, y1),第二个:P2 = (x2, y2),依此类推,曲线坐标由依赖于参数的方程来描述。 t 是步长,范围 [0,1]。 2 个控制点曲线的公式: P = (1-t) • P1 + t • P2 3 个控制点曲线的公式: P = (1−t)² • P1 + 2(1−t)t • P2 + t² • P3 4 个控制点曲线的公式: P = (1−t)³ • P1 + 3(1−t)² • t • P2 + 3(1−t)t² • P3 + t³ • P4 这些是向量方程。 换句话说,我们可以用x和y代替P来得到对应的坐标。 例如,3 点曲线由计算如下的点 (x,y) 形成: x = (1−t)² • x1 + 2(1−t)t • x2 + t² • x3 y = (1−t)² • y1 + 2(1−t)t • y2 + t² • y3
📌 JavaScript
参考代码:index.js
/** * 贝塞尔曲线点的坐标计算 * @param {Number} t - 步长 * @param {Object} p0 - 点的 x 和 y 坐标 * @param {Object} p1 - 点的 x 和 y 坐标 * @param {Object} p2 - 点的 x 和 y 坐标 * @param {Object} p3 - 点的 x 和 y 坐标 * @returns {Object} 返回经过计算后的点的坐标 */ export function bezier(t, p0, p1, p2, p3) { const cX = 3 * (p1.x - p0.x), bX = 3 * (p2.x - p1.x) - cX, aX = p3.x - p0.x - cX - bX; const cY = 3 * (p1.y - p0.y), bY = 3 * (p2.y - p1.y) - cY, aY = p3.y - p0.y - cY - bY; const x = (aX * Math.pow(t, 3)) + (bX * Math.pow(t, 2)) + (cX * t) + p0.x; const y = (aY * Math.pow(t, 3)) + (bY * Math.pow(t, 2)) + (cY * t) + p0.y; return { x: x, y: y }; }
测试:test.js
import { bezier } from './index'; /** * canvas画布上返回一条贝塞尔曲线 */ function draw() { /* step 指定了贝塞尔曲线分为 100断(步长) */ const step = 0.01, p0 = { x: 10, y: 10 }, p1 = { x: 50, y: 100 }, p2 = { x: 150, y: 200 }, p3 = { x: 200, y: 75 }, ctx = document.createElement('canvas').getContext('2d'); ctx.width = 500; ctx.height = 500; document.body.appendChild(ctx.canvas); ctx.moveTo(p0.x, p0.y); for (let i = 0; i < 1; i += step) { const p = bezier(i, p0, p1, p2, p3); ctx.lineTo(p.x, p.y); } ctx.stroke(); } draw();