贝塞尔曲线
· 阅读需 3 分钟
二次贝塞尔曲线
二次贝塞尔曲线的公式为:
我们先来回归一下高中数学,二次函数的标准形式为:
其中, 为二次项系数, 为一次项系数, 为常数项。
二次函数的图像为抛物线,抛物线的顶点坐标为:
我们可以把二次贝塞尔曲线的公式转换为二次函数的标准形式:
拿二阶过程描述如下:
- 将控制点连接起来,得到两条线段;
- 取 t 值,计算出两条线段上的点;
- 将两条线段上的点连接起来,得到一条线段;
- 取 t 值,计算出线段上的点;
- 重复 2、3 步骤,直到 t 值为 1。
高阶的不过是需要多重复几次直到剩一条线段,然后再取 t 值计算出点。
此过程可以用向量表示
程序设计
一般化贝塞尔曲线公式
这个公式是贝塞尔曲线的定义。它描述了如何根据一组控制点 P_i 和一个参数 t 计算贝塞尔曲线上的点 B(t)。
基于多项式的实现
function bezier(points, t) {
const n = points.length - 1;
let x = 0;
let y = 0;
for (let i = 0; i <= n; i++) {
const b = binomial(n, i);
const a = Math.pow(1 - t, n - i);
const c = Math.pow(t, i);
x += b * a * c * points[i].x;
y += b * a * c * points[i].y;
}
return { x, y };
}
function binomial(n, i) {
return factorial(n) / (factorial(i) * factorial(n - i));
}
function factorial(n) {
let result = 1;
for (let i = 1; i <= n; i++) {
result *= i;
}
return result;
}
binomial 这里查看 二项式定理
基于递归实现
function bezier(points, t) {
const n = points.length - 1;
if (n === 0) {
return points[0];
}
const left = bezier(points.slice(0, n), t);
const right = bezier(points.slice(1, n + 1), t);
return {
x: (1 - t) * left.x + t * right.x,
y: (1 - t) * left.y + t * right.y,
};
}
