Begtostudy(白途思)'s Professional Technology Blog

欢迎访问begtostudy的专业知识博客!主要是专业技术和算法为主。
  首页  :: 联系 :: 订阅 订阅  :: 管理

贝塞尔曲线

Posted on 2010-07-08 08:45  白途思  阅读(1189)  评论(0编辑  收藏  举报

贝塞尔曲线又称贝兹曲线或贝济埃曲线,一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成,节点是可拖动的支点,线段像可伸缩的皮筋,我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的。如下图:

0b14ad1956fc9d5643a9ade9

贝塞尔曲线是应用于二维图形应用程序的数学曲线。曲线的定义有四个点:起始点、终止点(也称锚点)以及两个相互分离的中间点。滑动两个中间点,贝塞尔曲线的形状会发生变化。二十世纪六十年代晚期,Pierre Bézier应用数学方法为雷诺公司的汽车制造业描绘出了贝塞尔曲线。

贝塞尔曲线就是这样的一条曲线,它是依据四个位置任意的点坐标绘制出的一条光滑曲线。在历史上,研究贝塞尔曲线的人最初是按照已知曲线参数方程来确定四个点的思路设计出这种矢量曲线绘制法。贝塞尔曲线的有趣之处更在于它的“皮筋效应”~也就是说,随着点有规律地移动,曲线将产生皮筋伸引一样的变换,带来视觉上的冲击。1962年,法国数学家 Pierre Bézier第一个研究了这种矢量绘制曲线的方法,并给出了详细的计算公式,因此按照这样的公式绘制出来的曲线就用他的姓氏来命名~是为贝塞尔曲线。

建构贝塞尔曲线

1、线性曲线

线性贝塞尔曲线演示动画,t in [0,1]
线性贝塞尔曲线函数中的 t 会经过由 P0 至 P1 的 B(t) 所描述的曲线。例如当 t=0.25 时,B(t) 即一条由点 P0 至 P1 路径的四分之一处。就像由 0 至 1 的连续 t,B(t) 描述一条由 P0 至 P1 的直线。如下图所示:

Bezier_1_big
线性贝塞尔曲线演示动画,t in [0,1]

2、二次曲线

为建构二次贝塞尔曲线,可以中介点 Q0 和 Q1 作为由 0 至 1 的 t:

由 P0 至 P1 的连续点 Q0,描述一条线性贝塞尔曲线。
由 P1 至 P2 的连续点 Q1,描述一条线性贝塞尔曲线。
由 Q0 至 Q1 的连续点 B(t),描述一条二次贝塞尔曲线。

Bezier_2_big

二次贝塞尔曲线的结构

Bezier_2_big

二次贝塞尔曲线演示动画,t in [0,1]

3、三阶曲线

为建构高阶曲线,便需要相应更多的中介点。对于三次曲线,可由线性贝塞尔曲线描述的中介点 Q0、Q1、Q2,和由二次曲线描述的点 R0、R1 所建构:

Bezier_3_big

三次贝塞尔曲线的结构

Bezier_3_big

三次贝塞尔曲线演示动画,t in [0,1]

4、四次曲线

对于四次曲线,可由线性贝塞尔曲线描述的中介点 Q0、Q1、Q2、Q3,由二次贝塞尔曲线描述的点 R0、R1、R2,和由三次贝塞尔曲线描述的点 S0、S1 所建构:

Bezier_4_big

四次贝塞尔曲线的结构

Bezier_4_big

四次贝塞尔曲线演示动画,t in [0,1]

5、五阶贝塞尔曲线

BezierCurve

五阶贝塞尔曲线的构成。

代码演示:

C++ 产生三次方贝塞尔曲线的代码

/*
 產生三次方貝茲曲線的程式碼
*/
 
typedef struct
{
    float x;
    float y;
}
Point2D;
 
/*
 cp 在此是四個元素的陣列:
 cp[0] 為起始點,或上圖中的 P0
 cp[1] 為第一個控制點,或上圖中的 P1
 cp[2] 為第二個控制點,或上圖中的 P2
 cp[3] 為結束點,或上圖中的 P3
 t 為參數值,0 <= t <= 1
*/
 
Point2D PointOnCubicBezier( Point2D* cp, float t )
{
    float   ax, bx, cx;
    float   ay, by, cy;
    float   tSquared, tCubed;
    Point2D result;
 
    /* 計算多項式係數 */
 
    cx = 3.0 * (cp[1].x - cp[0].x);
    bx = 3.0 * (cp[2].x - cp[1].x) - cx;
    ax = cp[3].x - cp[0].x - cx - bx;
 
    cy = 3.0 * (cp[1].y - cp[0].y);
    by = 3.0 * (cp[2].y - cp[1].y) - cy;
    ay = cp[3].y - cp[0].y - cy - by;
 
    /* 計算位於參數值 t 的曲線點 */
 
    tSquared = t * t;
    tCubed = tSquared * t;
 
    result.x = (ax * tCubed) + (bx * tSquared) + (cx * t) + cp[0].x;
    result.y = (ay * tCubed) + (by * tSquared) + (cy * t) + cp[0].y;
 
    return result;
}
 
/*
 ComputeBezier 以控制點 cp 所產生的曲線點,填入 Point2D 結構的陣列。
 呼叫者必須分配足夠的記憶體以供輸出結果,其為 <sizeof(Point2D) numberOfPoints>
*/
 
void ComputeBezier( Point2D* cp, int numberOfPoints, Point2D* curve )
{
    float   dt;
    int	    i;
 
    dt = 1.0 / ( numberOfPoints - 1 );
 
    for( i = 0; i < numberOfPoints; i++)
        curve[i] = PointOnCubicBezier( cp, i*dt );
}

在Blend中设计WPF和Silverlight时,我们会经常看到下面方式,设置使用的就是三次方贝塞尔曲线

image

参考资料:

贝塞尔曲线
http://zh.wikipedia.org/zh-cn/%E8%B2%9D%E8%8C%B2%E6%9B%B2%E7%B7%9A

贝塞尔曲线
http://baike.baidu.com/view/60154.htm

二次贝塞尔曲线实例
http://www.flashas.net/as/20091015/4624.html

 

 

原帖:http://ghj1976.spaces.live.com/blog/cns!F5D0FA8B5536921!794.entry?wa=wsignin1.0&sa=124109162

前往Begtostudy的编程知识博客(CSDN)