五、贝切尔曲线拼接
%BezierTest.m文件,这是主文件
clear all;
clc;
leftbase=10;
bottombase=10;
figure();
uicontrol('Style','pushbutton','string','绘制Bezier曲线并连接','position',[200+leftbase
200+bottombase 150 60],...
'callback','bezier_callback');
%mainfunction.m文件,这是这界面函数
function mainfunction()
%主函数
%获取两条被切尔曲线的控制点
prompt={'P0 x坐标','P0 y坐标','P1 x坐标','P1 y坐标','P2 x坐标','P2 y坐标','P3 x坐标','P3 y坐
标'};%设置提示字符串
title='第一条Bezier曲线控制点坐标';%设置标题
numline=1;%指定输入数据行数
defdata={'0','0','0','3','1','5','2','3'};%指定数据的默认值
Resize='on';%设置对话框大小为可调节的
answer=inputdlg(prompt,title,numline,defdata,Resize);
%将输入的cell类型数据转换为整数
data=str2num(char(answer));
%检测用户是否点击了取消按钮
if length(data)<8
return ;
end
BP1=[];
for i=1:4
BP1=[BP1;[data(2*i-1),data(2*i)]];
end
prompt={'Q1 x坐标','Q1 y坐标','Q2 x坐标','Q2 y坐标','Q3 x坐标','Q3 y坐标','比例因子a'};%
设置提示字符串
title='第二条Bezier曲线控制点坐标';%设置标题
defdata={'3','2','4','4','3','5','1'};%指定数据的默认值
answer=inputdlg(prompt,title,numline,defdata,Resize);
data=str2num(char(answer));
%检测用户是否点击了取消按钮
if length(data)<6
return ;
end
a=abs(data(7));%比例因子;
%P2,P3,Q0,Q1四点按顺序处于同一条直线上,即有Q0=Q1-a(P3-P2)
BP2(1,:)=(BP1(3,:)-BP1(4,:))*a;
for i=1:3
BP2=[BP2;[data(2*i-1),data(2*i)]];
end
BP2(1,:)=BP2(1,:)+BP2(2,:);
%下面计算两条Bezier曲线的点坐标
t=[0:0.01:1]';%参数矩阵
Point1=GetBezier(t,BP1);
Point2=GetBezier(t,BP2);
figure();
%绘制两条Bezier曲线,并实现连接
subplot(2,1,1);
%title('两条Bezier曲线');
hold on;
scatter(Point1(:,1),Point1(:,2),'.g');
scatter(Point2(:,1),Point2(:,2),'.b');
%绘制控制线
for i=1:3
CP1=[BP1(i,:);BP1(i+1,:)];
CP2=[BP2(i,:);BP2(i+1,:)];
plot(CP1(:,1),CP1(:,2),'--r','LineWidth',2);
plot(CP2(:,1),CP2(:,2),'--r','LineWidth',2);
end
hold off;
%title('两条Bezier曲线');
%绘制两条Bezier曲线的连接后曲线
%对第二条Bezier曲线做偏移trans,使其第一个控制点Q0与P3重合
trans=BP1(4,:)-BP2(1,:);
%BP3=BP2+trans;
BP3(:,1)=BP2(:,1)+trans(:,1);
BP3(:,2)=BP2(:,2)+trans(:,2);
Point3(:,1)=Point2(:,1)+trans(:,1);
Point3(:,2)=Point2(:,2)+trans(:,2);
subplot(2,1,2);
hold on;
scatter(Point1(:,1),Point1(:,2),'.g');
scatter(Point3(:,1),Point3(:,2),'.b');
%绘制控制线
for i=1:3
CP1=[BP1(i,:);BP1(i+1,:)];
CP2=[BP3(i,:);BP3(i+1,:)];
plot(CP1(:,1),CP1(:,2),'--r','LineWidth',2);
plot(CP2(:,1),CP2(:,2),'--r','LineWidth',2);
end
hold off;
%title('连接后的Bezier曲线');
end
%GetBezier.m文件,这是计算贝切尔曲线点坐标函数
function [Point]=GetBezier(t,P)
%t为参数矩阵,共一列。
%P为控制点坐标矩阵,每一行为一个点的x,y,坐标
[row,column]=size(t);
T(:,4)=ones(row,column);
for i=4:-1:2
T(:,i-1)=T(:,i).*t;
end
M=[
-1,3,-3,1;
3,-6,3,0;
-3,3,0,0;
1,0,0,0;
];
Point=T*M*P;
end
%bezier_callback.m文件。
function bezier_callback()
mainfunction;
end