贝塞尔曲线的生成

贝塞尔曲线的公式

贝塞尔曲线的动态图
该网址包含了简单的一阶二阶三阶曲线的公式.

贝塞尔曲线可以表示如下:
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=0nCin(1t)nitiPi
其中 C i n = n ! i ! ( n − i ) ! C_i^n =\frac{n!}{i!(n-i)!} Cin=i!(ni)!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;
}
result

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值