贝兹曲线

在数学的数值分析领域中，贝兹曲线（）是计算机图形学中相当重要的参数曲线。更高维度的广泛化贝兹曲线就称作，其中是一种特殊的实例。
贝兹曲线于1962年，由法国工程师皮埃尔·贝兹（）所广泛发表，他运用贝兹曲线来为汽车的主体进行设计。贝兹曲线最初由于1959年运用德卡斯特里奥演算法开发，以稳定数值的方法求出贝兹曲线。
实例说明.
线性贝兹曲线.
给定点P0、P1，线性贝兹曲线只是一条两点之间的直线。这条线由下式给出：
且其等同于线性插值。
二次方贝兹曲线.
二次方贝兹曲线的路径由给定点P0、P1、P2的函数B（"t"）追踪：
TrueType字型就运用了以贝兹样条组成的二次贝兹曲线。
三次方贝兹曲线.
P0、P1、P2、P3四个点在平面或在三维空间中定义了三次方贝兹曲线。曲线起始于P0走向P1，并从P2的方向来到P3。一般不会经过P1或P2；这两个点只是在那里提供方向资讯。P0和P1之间的间距，决定了曲线在转而趋进P2之前，走向P1方向的「长度有多长」。
曲线的参数形式为：
现代的成象系统，如PostScript、Asymptote和Metafont，运用了以贝兹样条组成的三次贝兹曲线，用来描绘曲线轮廓。
一般化.
formula_4阶贝兹曲线可如下推断。给定点P0、P1、...、Pn，其贝兹曲线即
例如formula_6：
如上公式可如下递归表达：
用formula_8表示由点P0、P1、...、Pn所决定的贝兹曲线。则
用平常话来说，formula_4阶的贝兹曲线，即双formula_11阶贝兹曲线之间的插值。
术语.
一些关于参数曲线的术语，有
即多项式
又称作"n"阶的伯恩斯坦基底多项式，定义00 = 1。
点P"i"称作贝兹曲线的控制点。多边形以带有线的贝兹点连接而成，起始于P0并以P"n"终止，称作贝兹多边形（或控制多边形）。贝兹多边形的凸包（convex hull）包含有贝兹曲线。
构建贝兹曲线.
线性曲线.
线性贝兹曲线函数中的"t"会经过由P0至P1的B（"t"）所描述的曲线。例如当"t=0.25"时，B（"t"）即一条由点P0至P1路径的四分之一处。就像由0至1的连续"t"，B（"t"）描述一条由P0至P1的直线。
二次曲线.
为建构二次贝兹曲线，可以中介点Q0和Q1作为由0至1的"t"：
高阶曲线.
为建构高阶曲线，便需要相应更多的中介点。对于三次曲线，可由线性贝兹曲线描述的中介点Q0、Q1、Q2，和由二次曲线描述的点R0、R1所建构：
对于四次曲线，可由线性贝兹曲线描述的中介点Q0、Q1、Q2、Q3，由二次贝兹曲线描述的点R0、R1、R2，和由三次贝兹曲线描述的点S0、S1所建构：
还可参阅五阶贝兹曲线的构成：
这些运动轨迹使用德卡斯特里奥算法计算出贝塞尔曲线。
升阶.
"n"次贝兹曲线可以转换为一个形状完全相同的"n+1"次贝兹曲线。
这在软体只支援特定阶次的贝兹曲线时很有用。
例如，Cairo只支援三次贝兹曲线，你就可以用升阶的方法在Cairo画出二次贝兹曲线。
我们利用formula_15这个特性来做升阶。我们把曲线方程式中每一项formula_16都乘上 (1 − "t") 或 "t"，让每一项都往上升一阶。以下是将二阶升为三阶的范例
对任何的"n"值，我们都可以使用以下等式
式中formula_21 和 formula_22可以任意挑选。
因此，新的控制点为
应用.
电脑绘图.
由于需要点阵化更精细的解析度时，重新插值（补点）的计算量较小，贝兹曲线被广泛地在计算机图形中用来为平滑曲线建立模型。贝兹曲线是矢量图形文件和相应软件（如PostScript、PDF等）能够处理的唯一曲线，用于光滑地近似其他曲线。
二次和三次贝兹曲线最为常用。
程式范例.
下列程式码为一简单的实际运用范例，展示如何使用C语言标出三次方贝兹曲线。注意，此处仅简单的计算多项式系数，并读尽一系列由0至1的t值；实践中一般不会这么做，递归求解通常会更快速——以更多的记忆体为代价，花费较少的处理器时间。不过直接的方法较易于理解并产生相同结果。以下程式码已使运算更为清晰。实践中的最佳化会先计算系数一次，并在实际计算曲线点的回圈中反复使用。此处每次都会重新计算，损失了效率，但程式码更清楚易读。
曲线的计算可在曲线阵列上将相连点画上直线——点越多，曲线越平滑。
在部分架构中，下以程式码也可由动态规划进行最佳化。举例来说，"dt"是一个常数，"cx" * "t"则等同于每次反复就修改一次常数。经反复应用这种最佳化后，回圈可被重写为没有任何乘法（虽然这个过程不是稳定数值的）。
/*
 产生三次方贝兹曲线的程式码
typedef struct
 float x;
 float y;
Point2D;
 cp在此是四个元素的阵列:
 cp[0]为起始点，或上图中的P0
 cp[1]为第一个控制点，或上图中的P1
 cp[2]为第二个控制点，或上图中的P2
 cp[3]为结束点，或上图中的P3
 t为参数值，0 &lt;= t &lt;= 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结构的阵列。
 呼叫者必须分配足够的记忆体以供输出结果，其为&lt;sizeof(Point2D) numberOfPoints&gt;
void ComputeBezier( Point2D* cp, int numberOfPoints, Point2D* curve )
 float dt;
 int i;
 dt = 1.0 / ( numberOfPoints - 1 );
 for( i = 0; i &lt; numberOfPoints; i++)
 curve[i] = PointOnCubicBezier( cp, i*dt );
另一种贝兹曲线的应用是在动画中，描述物件的运动路径等等。此处，曲线的x、y位置不用来标示曲线，但用来表示图形位置。当用在这种形式时，连续点之间的距离会变的更为重要，且大多不是平均比例。点将会串的更紧密，控制点更接近每一个点，而更为稀疏的控制点会散的更开。如果需要线性运动速度，进一步处理时就需要循所需路径将点平均分散。
多项式表示法.
有时我们可能想要把贝兹曲线表示为多项式，而非比较不直接的伯恩斯坦多项式。使用二项式定理和贝兹曲线的定义，重新整理后可以得到：
此处
计算曲线上的点时需要多次计算formula_26，因此事先计算好formula_27会比较实际；然而要小心高阶曲线可能会缺乏数值稳定性（需使用德卡斯特里奥算法来处理）。注意其空积为1。
有理贝兹曲线.
有理贝兹增加可调节的权重，以提供更近似于随意的形状。分子是加权的伯恩斯坦形式贝兹曲线，而分母是加权的伯恩斯坦多项式的总和。
给定"n" + 1控制点P"i"，有理贝兹曲线可如下描述：
或简单的