三阶贝塞尔曲线拟合1/4圆
根据贝塞尔曲线的知识,我们知道三阶贝塞尔曲线的参数方程如下,其中A、B、C、D为四个控制点坐标,P(t)表示曲线上的每一点。
因为要模拟1/4圆,所以通过P(0)和P(1)的切线方向,应该按照下图所示位置安放。其中AB为水平方向,DC为垂直方向,并且线段长度|AB| = |DC| = h。
那么这个问题实际上,就转换为计算出合理的h值,使得半径|OJ| = 1,也即J点刚好在圆弧上。
根据贝塞尔曲线的对称性,不难想出J点在P(0.5)处,代入公式即可求得:
同样的结论,也可以直接由贝塞尔曲线的几何图形特征来推定,也即:
所以也可以再次确认P(0.5)和J是同一点。
代入四个控制点坐标A(0, 1),B(h, 1),C(1, h)和D(1, 0),可以求解P(0.5)点坐标如下:
根据圆形方程定义,可以拟出下面方程:
从而求解出h的值为:
所以,可以最终求解出三阶贝塞尔曲线模拟1/4圆的参数方程P(t)定义如下:
另一方面,该方程描述的曲线与真实1/4圆有多大差异呢?下面就针对这个问题进行数值求解。
采用t = 0.0到1.0,步进值0.01,求解每个点到原点的距离与半径1的差异。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> double bezier3(double a, double b, double c, double d, double t) { double nt = 1.0 - t; double nt2 = nt * nt; double nt3 = nt * nt * nt; double t2 = t * t; double t3 = t * t * t; return (a * nt3 + b * 3.0 * nt2 * t + c * 3.0 * nt * t2 + d * t3); } int main() { double t, a; double d, e; double max_e = 0.0, min_e = 1.0; double x, y; double h = (sqrt(2) - 1.0) * 4.0 / 3.0; for(t = 0.0; t < 1.01; t+=0.01) { x = bezier3(0, h, 1, 1, t); y = bezier3(1, 1, h, 0, t); d = sqrt(x * x + y * y); e = d - 1.0; a = atan2(y, x); a = a * 180.0 / 3.1415926; if(max_e < e) max_e = e; if(min_e > e) min_e = e; printf("%4.1f, %f\n", a, e); } printf("max_e = %f, min_e = %f\n", max_e, min_e); return 0; }
输出结果如下:
90.0, 0.000000 89.1, 0.000003 88.1, 0.000010 87.2, 0.000022 86.2, 0.000037 85.3, 0.000054 84.4, 0.000073 83.4, 0.000092 82.5, 0.000113 81.6, 0.000133 80.7, 0.000153 79.7, 0.000172 78.8, 0.000190 77.9, 0.000206 77.0, 0.000221 76.1, 0.000234 75.2, 0.000246 74.3, 0.000255 73.4, 0.000263 72.5, 0.000268 71.6, 0.000271 70.7, 0.000273 69.8, 0.000272 68.9, 0.000269 68.0, 0.000265 67.1, 0.000259 66.2, 0.000251 65.3, 0.000242 64.4, 0.000232 63.5, 0.000220 62.6, 0.000208 61.8, 0.000194 60.9, 0.000181 60.0, 0.000166 59.1, 0.000152 58.2, 0.000137 57.3, 0.000123 56.5, 0.000108 55.6, 0.000094 54.7, 0.000081 53.8, 0.000068 52.9, 0.000056 52.0, 0.000045 51.2, 0.000035 50.3, 0.000026 49.4, 0.000018 48.5, 0.000012 47.6, 0.000007 46.8, 0.000003 45.9, 0.000001 45.0, 0.000000 44.1, 0.000001 43.2, 0.000003 42.4, 0.000007 41.5, 0.000012 40.6, 0.000018 39.7, 0.000026 38.8, 0.000035 38.0, 0.000045 37.1, 0.000056 36.2, 0.000068 35.3, 0.000081 34.4, 0.000094 33.5, 0.000108 32.7, 0.000123 31.8, 0.000137 30.9, 0.000152 30.0, 0.000166 29.1, 0.000181 28.2, 0.000194 27.4, 0.000208 26.5, 0.000220 25.6, 0.000232 24.7, 0.000242 23.8, 0.000251 22.9, 0.000259 22.0, 0.000265 21.1, 0.000269 20.2, 0.000272 19.3, 0.000273 18.4, 0.000271 17.5, 0.000268 16.6, 0.000263 15.7, 0.000255 14.8, 0.000246 13.9, 0.000234 13.0, 0.000221 12.1, 0.000206 11.2, 0.000190 10.3, 0.000172 9.3, 0.000153 8.4, 0.000133 7.5, 0.000113 6.6, 0.000092 5.6, 0.000073 4.7, 0.000054 3.8, 0.000037 2.8, 0.000022 1.9, 0.000010 0.9, 0.000003 -0.0, 0.000000 max_e = 0.000273, min_e = 0.000000
从输出结果分析可以看到,误差均为向着圆弧外凸,0度到45度一段,45度到90度一段。
在0度、45度和90度为最小误差0.000000,在19.3度和70.7度达到最大误差为0.000273,基本上非常接近1/4圆弧了。
以上,即为三阶贝塞尔曲线模拟1/4圆弧的全部内容。
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-09 16:51:31