贝塞尔曲线的公式
贝塞尔曲线的动态图
该网址包含了简单的一阶二阶三阶曲线的公式.
贝塞尔曲线可以表示如下:
B
(
t
)
=
∑
i
=
0
n
C
i
n
(
1
−
t
)
n
−
i
t
i
P
i
B(t) = \sum_{i=0}^{n}C_i^{n}(1-t)^{n-i}t^iP_i
B(t)=i=0∑nCin(1−t)n−itiPi
其中
C
i
n
=
n
!
i
!
(
n
−
i
)
!
C_i^n =\frac{n!}{i!(n-i)!}
Cin=i!(n−i)!n! 是数学中排列的意思。
- 给出N个点,可以得到一条贝塞尔曲线,曲线的起始点和给出的N个点的起始点重合,其他部分一般不重合
- 有N个点时,中间的N-2个点为控制点,生成的曲线称为N-1阶曲线。
- P i P_i Pi是第i个点,从0数起
- 假设t=0:0.01:1,当t从0变化到1时,会有101个结果,利用这101个结果绘画出来的曲线就是贝塞尔曲线
贝塞尔曲线matlab代码
function bezier( vertices )
%BEZIER 绘制Bezier曲线
Dim=size(vertices,1);%二位或者三维空间
NumPoint=size(vertices,2)-1;%点的个数
t=0:0.001:1;
x=[];y=[];z=[];
if Dim==2
x=(1-t).^(NumPoint)*vertices(1,1);
y=(1-t).^(NumPoint)*vertices(2,1);
for j=1:NumPoint
w=factorial(NumPoint)/(factorial(j)*factorial(NumPoint-j))*(1-t).^(NumPoint-j).*t.^(j);
x=x+w*vertices(1,j+1);y=y+w*vertices(2,j+1);
end
plot(vertices(1,:),vertices(2,:),'b');
hold on;grid on;
axis tight;
xlabel('X');ylabel('Y');
plot(x,y,'r');
end
if Dim==3
x=(1-t).^(NumPoint)*vertices(1,1);
y=(1-t).^(NumPoint)*vertices(2,1);
z=(1-t).^(NumPoint)*vertices(3,1);
for j=1:NumPoint
w=factorial(NumPoint)/(factorial(j)*factorial(NumPoint-j))*(1-t).^(NumPoint-j).*t.^(j);
x=x+w*vertices(1,j+1);y=y+w*vertices(2,j+1);z=z+w*vertices(3,j+1);
end
plot3(vertices(1,:),vertices(2,:),vertices(3,:),'b');
hold on;grid on;
axis tight;
%axis([0.5,1.5,0.5,1.5,0,0.7]);
xlabel('X');ylabel('Y');zlabel('Z');
plot3(x,y,z,'r');
view(3);
end
end
example
v = [1 3; 3 7;7 2;9 6;13 3;15,4]'; % 注意这里有个转置符号
bezier(v);
贝塞尔曲线C++代码
#pragma once
#include <cmath>
#include <map>
using namespace std;
struct Point
{
double x;
double y;
Point() {}
Point(double x_, double y_) :x(x_), y(y_) {}
};
int factorial(int n)
{
if (n == 0)
return 1;
return n * factorial(n - 1);
}
// vertics 控制点
// yp 贝塞尔得到的结果点
// num 贝塞尔函数中t的取值个数 =num+1,控制曲线内点的个数
bool bezier(vector<Point> vertices, vector<Point> & yp, int num=10)
{
if (vertices.size() < 2)
return false;
int NumPoint = vertices.size() - 1;
int t_num = num + 1;
vector<double> t(t_num); // 滑动t来产生数据
vector<double> x(t_num);
vector<double> y(t_num);
vector<double> w(t_num); //每一段的长度
for (int i = 0; i < t_num - 1; i++)
t[i + 1] = t[i] + 1.0/num;
for (int i = 0; i < t_num; i++)
{
x[i] = pow(1 - t[i], NumPoint)*vertices[0].x;
y[i] = pow(1 - t[i], NumPoint)*vertices[0].y;
}
for (int j = 1; j <= NumPoint; j++)
{
for (int k = 0; k < t_num; k++)
{
w[k] = factorial(NumPoint) / (factorial(j) * factorial(NumPoint - j))* pow(1 - t[k], NumPoint - j)*pow(t[k], j);
x[k] = x[k] + w[k] * vertices[j].x;
y[k] = y[k] + w[k] * vertices[j].y;
}
}
yp.clear();
yp.resize(t_num);
for (int i = 0; i < t_num; i++)
{
yp[i].x = x[i];
yp[i].y = y[i];
}
return true;
}