三阶贝塞尔曲线拟合1/2正弦

来源:互联网 发布:软件 win7 开机启动 编辑:程序博客网 时间:2024/06/02 14:47

三阶贝塞尔曲线拟合1/2正弦


根据贝塞尔曲线的知识,我们知道三阶贝塞尔曲线的参数方程如下,其中A、B、C、D为四个控制点坐标,P(t)表示曲线上的每一点。



因为要模拟1/2正弦,所以通过P(0)和P(1)的切线方向,应该按照下图所示位置安放。

其中AB为水平向左方向,DC为水平向右方向,并且线段长度|AB| = |DC| = h。

那么这个问题实际上,就转换为计算出合理的h值,使得曲线(原点)中点处的斜率为1。



根据P(t)定义,求得三阶贝塞尔曲线的导数为:


根据贝塞尔曲线的对称性,不难想出P(0.5)在原点处,代入公式即可求得:

代入四个控制点坐标A(-PI/2, -1),B(-PI/2 + h, 1),C(PI/2 - h, 1)和D(PI/2, 1),可以求解P'(0.5)的值如下:


根据正弦曲线在原点处的斜率为1可知,P'(0.5)表示的斜率为1,从而拟出下面方程:

从而求解出h的值为:


所以,可以最终求解出三阶贝塞尔曲线模拟1/2正弦的参数方程P(t)定义如下:



另一方面,该方程描述的曲线与真实1/2正弦有多大差异呢?下面就针对这个问题进行数值求解。

采用t = 0.0到1.0,步进值0.01,求解-PI/2到PI/2的每个点到正弦曲线的数值差异。

#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);}#define PI 3.1415926int main(){        double t, a;        double d, e;        double max_e = 0.0, min_e = 1.0;        double x, y;        double h = PI - 2.0;        for(t = 0.0; t < 1.01; t+=0.01)        {                x = bezier3(-PI / 2.0, -PI / 2.0 + h, PI / 2.0 - h, PI / 2.0, t);                y = bezier3(-1, -1, 1, 1, t);                d = sin(x);                e = y - d;                a = x * 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-88.0, 0.000012-86.1, 0.000046-84.2, 0.000095-82.2, 0.000155-80.3, 0.000222-78.4, 0.000293-76.5, 0.000364-74.6, 0.000433-72.7, 0.000498-70.8, 0.000559-69.0, 0.000612-67.1, 0.000659-65.2, 0.000697-63.4, 0.000727-61.6, 0.000749-59.7, 0.000762-57.9, 0.000768-56.1, 0.000766-54.3, 0.000756-52.4, 0.000741-50.6, 0.000719-48.8, 0.000692-47.0, 0.000660-45.3, 0.000625-43.5, 0.000587-41.7, 0.000547-39.9, 0.000505-38.2, 0.000462-36.4, 0.000419-34.6, 0.000376-32.9, 0.000335-31.1, 0.000294-29.4, 0.000256-27.6, 0.000220-25.9, 0.000186-24.2, 0.000155-22.4, 0.000127-20.7, 0.000102-19.0, 0.000080-17.2, 0.000061-15.5, 0.000045-13.8, 0.000032-12.0, 0.000022-10.3, 0.000014-8.6, 0.000008-6.9, 0.000004-5.2, 0.000002-3.4, 0.000001-1.7, 0.000000 0.0, 0.000000 1.7, -0.000000 3.4, -0.000001 5.2, -0.000002 6.9, -0.000004 8.6, -0.00000810.3, -0.00001412.0, -0.00002213.8, -0.00003215.5, -0.00004517.2, -0.00006119.0, -0.00008020.7, -0.00010222.4, -0.00012724.2, -0.00015525.9, -0.00018627.6, -0.00022029.4, -0.00025631.1, -0.00029432.9, -0.00033534.6, -0.00037636.4, -0.00041938.2, -0.00046239.9, -0.00050541.7, -0.00054743.5, -0.00058745.3, -0.00062547.0, -0.00066048.8, -0.00069250.6, -0.00071952.4, -0.00074154.3, -0.00075656.1, -0.00076657.9, -0.00076859.7, -0.00076261.6, -0.00074963.4, -0.00072765.2, -0.00069767.1, -0.00065969.0, -0.00061270.8, -0.00055972.7, -0.00049874.6, -0.00043376.5, -0.00036478.4, -0.00029380.3, -0.00022282.2, -0.00015584.2, -0.00009586.1, -0.00004688.0, -0.00001290.0, 0.000000max_e = 0.000768, min_e = -0.000768

从输出结果分析可以看到,误差在-90度到0度为上浮,在0度到90度为下浮。

在-90度、0度和90度为最小误差0.000000,在-57.9度和57.9度达到最大误差为0.000768,基本上非常接近1/2正弦了。


以上,即为三阶贝塞尔曲线模拟1/2正弦的全部内容。

感谢Grapher和GeoGebra软件,使得方便排版文章中使用的公式和曲线。

0 0
原创粉丝点击