- 分析3个锚点的情形
- 选定一个参数 t∈[0,1],在 b 0 b 1 b_0b_1 b0b1线段之上利用t值进行线性插值,得到 b 0 1 = ( 1 − t ) b 0 + b 1 b_0^1=(1-t)b_0+b_1 b01=(1−t)b0+b1
- 在 b 1 b 2 b_1b_2 b1b2上重复操作,得到 b 1 1 b_1^1 b11
- 以 b 0 1 b 1 1 以b_0^1b_1^1 以b01b11作为新锚点序列,进行第二次插值
-
得到的 b 0 2 b_0^2 b02即为3个锚点下的2次贝塞尔曲线上的一点。对所有 t ∈ [ 0 , 1 ] t\in[0,1] t∈[0,1]重复上述的过程,就可以得到一条完整的贝塞尔曲线。n个锚点需要进行n-1次插值,用递归实现。
-
实现代码
Point ins;//记录贝塞尔曲线上的点 void interpolate(std::vector<Point>anchorPoints,float t) { if (anchorPoints.size() == 1) {//递归终止条件,锚点序列大小为1,该点即为曲线上的点 ins=anchorPoints[0]; return; } else {//锚点序列大小>1时,继续进行插值运算,获得新锚点序列 std::vector<Point>next; for (int i = 1; i < anchorPoints.size(); i++) { Point tmp; tmp.x = (1 - t) * anchorPoints[i - 1].x + t * anchorPoints[i].x; tmp.y = (1 - t) * anchorPoints[i - 1].y + t * anchorPoints[i].y; next.push_back(tmp); } interpolate(next,t);//递归 } } std::vector<Point> Bezier(std::vector<Point> anchorPoints) { if (anchorPoints.size() <= 2)return anchorPoints;//一个点时为一点,两个点时为一直线,无需运算 std::vector<Point> result; for (float t = 0; t <= 1; t += 0.001) { interpolate(anchorPoints, t); Point tmp = ins; result.push_back(tmp); } return result; }
结果展示