三階貝塞爾曲線擬合1/2正弦

三階貝塞爾曲線擬合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.1415926
int 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.000008
10.3, -0.000014
12.0, -0.000022
13.8, -0.000032
15.5, -0.000045
17.2, -0.000061
19.0, -0.000080
20.7, -0.000102
22.4, -0.000127
24.2, -0.000155
25.9, -0.000186
27.6, -0.000220
29.4, -0.000256
31.1, -0.000294
32.9, -0.000335
34.6, -0.000376
36.4, -0.000419
38.2, -0.000462
39.9, -0.000505
41.7, -0.000547
43.5, -0.000587
45.3, -0.000625
47.0, -0.000660
48.8, -0.000692
50.6, -0.000719
52.4, -0.000741
54.3, -0.000756
56.1, -0.000766
57.9, -0.000768
59.7, -0.000762
61.6, -0.000749
63.4, -0.000727
65.2, -0.000697
67.1, -0.000659
69.0, -0.000612
70.8, -0.000559
72.7, -0.000498
74.6, -0.000433
76.5, -0.000364
78.4, -0.000293
80.3, -0.000222
82.2, -0.000155
84.2, -0.000095
86.1, -0.000046
88.0, -0.000012
90.0, 0.000000
max_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軟件,使得方便排版文章中使用的公式和曲線。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章