貝塞爾曲線生成及測試


玩過ps的同學,應該用過一個鋼筆工具。

而鋼筆產生的就是貝塞爾曲線。還有這里來體驗一下:

https://myst729.github.io/bezier-curve/

 

Bezier曲線分為一次/二次/三次/多次貝塞爾曲線,之所以這么分是為了更好的理解其中的內涵。

一次貝塞爾曲線(線性Bezier),實際上就是一條連接兩點的直線段。
二次貝塞爾曲線,就是兩點間的一條拋物線,利用一個控制點來控制拋物線的形狀。
三次貝塞爾曲線,則需要一個起點,一個終點,兩個控制點來控制曲線的形狀。
實例如下:在http://cubic-bezier.com/#.42,0,1,1的地方體驗一下。

一階曲線。

 

二階的貝塞爾曲線是這樣畫出來的。

 

 

而多階的是這樣的。

 

 

那二階的計算公式,其中 0<=t<=1。

  二階的計算點的公式: P0*(1-t)^2 + 2*P1*t(1-t) + P2*t^2 =P,其中P0為起始點,P1為控制點,P2為終點。那我們用matlab仿真,代碼如下:

%% 起始點
startx=1;
starty=1;
%% 終止點
endx=10;
endy=0;
%% 控制點
cont1x=5;
cont1y=1;
%% 生成曲線
pointnum=100;%步數
t=1/(pointnum-1);
for i=1:pointnum-1
    x= startx*(1-i*t)^2 + cont1x*2*i*t*(1-i*t) + endx*(i*t)^2;
    y= starty*(1-i*t)^2 + cont1y*2*i*t*(1-i*t) + endy*(i*t)^2;
    hold on;
    plot(x,y,'.');
end

plot(startx,starty,'*')
plot(endx,endy,'*')
plot(cont1x,cont1y,'*')

 

 四個點的話就是兩個控制點 p1,p2,另外兩個就是起點和終點p0,p3。

公式為: P = P0*(1-t)^3 +3*P1*t*(1-t)^2+3*P2*(1-t)*t^2+P3*t^3 。

 

C++代碼如下:

struct Point_Float
{
    float x;
    float y;
};

float MetaComputing(float p0, float p1, float p2, float p3, float t)
{
    // 方法一:
    float a, b, c;
    float tSquare, tCube;
    // 計算多項式系數
    c = 3.0 * (p1 - p0);
    b = 3.0 * (p2 - p1) - c;
    a = p3 - b - c - p0;

    // 計算t位置的點
    tSquare = t * t;
    tCube   = t * tSquare;
    return (a * tCube) + (b * tSquare) + (c * t) + p0;

    // 方法二: 原始的三次方公式
    //  float n = 1.0 - t;
    //  return n*n*n*p0 + 3.0*p1*t*n*n + 3.0*p2*t*t*n + p3*t*t*t;
}

float MetaComputing(float p0, float p1, float p2, float t)
{
    // 方法一:
    float a, b, c;
    float tmin;
    // 計算多項式系數
    c = p0;
    b = 2.0 * p1;
    a = p2;

    // 計算t位置的點
    tmin = 1-t;
    return (tmin*tmin*c) + (tmin*t*b) + (t*t*a);

}

Point_Float PointOnTrieBezier(Point_Float* cp, float t)
{
    Point_Float tPoint;
    tPoint.x = MetaComputing(cp[0].x, cp[1].x, cp[2].x, cp[3].x, t);
    tPoint.y = MetaComputing(cp[0].y, cp[1].y, cp[2].y, cp[3].y, t);
    return tPoint;
}

Point_Float PointOnCubeBezier(Point_Float* cp, float t)
{
    Point_Float tPoint;
    tPoint.x = MetaComputing(cp[0].x, cp[1].x, cp[2].x, t);
    tPoint.y = MetaComputing(cp[0].y, cp[1].y, cp[2].y, t);
    return tPoint;
}

 

 

參考資料:    

http://blog.csdn.net/cdnight/article/details/48468653

https://www.cnblogs.com/cheneasternsun/p/5941438.html

http://blog.csdn.net/devillixin/article/details/39896355


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM