线段裁剪代码MATLAB.docx
《线段裁剪代码MATLAB.docx》由会员分享,可在线阅读,更多相关《线段裁剪代码MATLAB.docx(10页珍藏版)》请在冰豆网上搜索。
![线段裁剪代码MATLAB.docx](https://file1.bdocx.com/fileroot1/2022-10/12/bdcedd7b-0912-42d7-bc05-455e845d3443/bdcedd7b-0912-42d7-bc05-455e845d34431.gif)
线段裁剪代码MATLAB
四、线段裁剪
%Sutherland_Test.m文件,主文件函数
clearall;
clc;
MainMenu();
%check_callback.m文件,查看图形函数
functioncheck_callback()
%查看原始线段图形回调函数
%lines矩阵共四列,每一列的含义如下:
%端点Ax坐标端点Ay坐标端点Bx坐标端点By坐标
%
lines=getappdata(0,'lines');
ifisempty(lines)
errordlg('当前尚未生成线段,无法显示!
');
return;
end
figure();
holdon;
fori=1:
length(lines(:
1))
plot(lines(i,[1,3]),lines(i,[2,4]));
end
holdoff;
end
%Cohen_Sutherland.m文件,编码裁剪算法
functionLines=Cohen_Sutherland(line,Rectangle)
%编码裁剪算法
%line为线段端点矩阵,共四列,其数据含义如下:
%端点Ax坐标端点Ay坐标端点Bx坐标端点By坐标
%Rectangle为窗口边界值,共四个元素,其含义分别为Xwl,Xwr,Ywb,Ywt。
%
%首先检测参数是否合法
[rowcolumn]=size(line);
ifcolumn<4||length(Rectangle)<4
Lines=[];
fprintf('参数不合法不合法');
return;
end
%
%程序中主要变量说明
%code为线段端点的编码矩阵,两行四列,第一行为点P1的编码,第二行为点P2的编码
%四列的含义为:
D0,D1,D2,D3
%
%依次处理line的各个线段
k=0;
Lines=[];
fori=1:
length(line(:
1))
%取出第i条线段
P1=line(i,[1,2]);
P2=line(i,[3,4]);
%计算斜率
PP=P1-P2;
ifPP
(1)==0
k=inf;
else
k=PP
(2)/PP
(1);
end
finished=false;
while(~finished)
%对点P1和P2进行编码
code=[
P1
(1)(1),P1
(1)>Rectangle
(2),P1
(2)(2)>Rectangle(4);
P2
(1)(1),P2
(1)>Rectangle
(2),P2
(2)(2)>Rectangle(4);
];
%P1,P2,k,code
%进行简取或简弃的判断
test=code(1,:
)|code(2,:
);
%判断是否简取
ifisempty(find(test>0,1))
Lines=[Lines;[P1,P2]];
finished=true;
end
%若当前线段处理完成,则退出
iffinished
break;
end
%判断是否简弃
test=code(1,:
)&code(2,:
);
if~isempty(find(test>0,1))
finished=true;
end
iffinished
break;
end
%确保P1在窗口之外
ifisempty(find(code(1,:
)>0,1))
%交换P1,P2的坐标值和编码
PT=P1;P1=P2;P2=PT;
PT=code(1,:
);code(1,:
)=code(2,:
);code(2,:
)=PT;
end
%从低位开始找编码值为1的地方
D=find(code(1,:
)>0,1);
ifD<=2
%此时P1位于窗口的左边或右边
ifk==0
%若是水平线,则y不变,x变为窗口的左边界或右边界
%且此时k不会等于inf,否则线段处于简弃状态。
P1
(1)=Rectangle(D);
%P1
(2)=Rectangle(find(code(1,[3,4])>0,1));
else
%若线段是斜线,则计算y值,x值变为窗口的左边界或右边界
P1=[Rectangle(D),P1
(2)+k*(Rectangle(D)-P1
(1))];
end
else
%此时P1位于窗口的上方或下方
ifk==inf
%若线段是竖直线,则x不变,y变为窗口的上边界或下边界
%且此时k不会等于0,否则线段将处于简弃状态。
P1
(2)=Rectangle(D);
else
%若线段是斜线,则计算x值,y值变为窗口的上边界或下边界。
P1=[P1
(1)+(Rectangle(D)-P1
(2))/k,Rectangle(D)];
end
end
%对P1和P2重新编码,再次计算。
%P1,P2,k,code
%pause(10);
%scanf(D,'%d');
%inputdlg('');
end
end
%对最终点进行取整运算
%Lines=round(Lines);
end
%DrawOriginalGraph.m文件,绘制原始线段图形函数
functionDrawOriginalGraph()
%绘制原始线段图形函数
%lines矩阵共四列,每一列的含义如下:
%端点Ax坐标端点Ay坐标端点Bx坐标端点By坐标
%
lines=getappdata(0,'lines');
ifisempty(lines)
errordlg('当前尚未生成线段,无法显示!
');
return;
end
figure('name','原始线段图形');
holdon;
fori=1:
length(lines(:
1))
plot(lines(i,[1,3]),lines(i,[2,4]));
end
holdoff;
end
%DrawSutherlandGraph.m文件,绘制编码裁剪算法裁剪后线段函数
functionDrawSutherlandGraph(OriginalLines,Rectangle,SutherlandedLines)
%绘制裁剪前后线段对比图
%OriginalLines是初始线段矩阵,Rectangle是裁剪窗口参数,SutherlandedLines是裁剪后的线段矩阵
%OriginalLines与SutherlandedLines分别有四列,每一列的参数定义相同,如下所示:
%端点Ax坐标端点Ay坐标端点Bx坐标端点By坐标
%Rectangle共四个元素,每个元素的定义分别为Xwl,Xwr,Ywb,Ywt。
figure('name','线段原始图形与裁剪后的对比图');
%在第一个小图里绘制原始线段图形以及裁剪窗口
subplot(2,1,1);
holdon;
%绘制原始线段
fori=1:
length(OriginalLines(:
1))
plot(OriginalLines(i,[1,3]),OriginalLines(i,[2,4]));
end
%绘制裁剪窗口
R=Rectangle;
RLines=[
R
(1),R(3),R
(2),R(3);
R
(2),R(3),R
(2),R(4);
R
(2),R(4),R
(1),R(4);
R
(1),R(4),R
(1),R(3);
];
fori=1:
length(RLines(:
1))
plot(RLines(i,[1,3]),RLines(i,[2,4]),'-r');
end
holdoff;
%在第二个小图里绘制裁剪后的图形及裁剪窗口
subplot(2,1,2);
holdon;
fori=1:
length(SutherlandedLines(:
1))
plot(SutherlandedLines(i,[1,3]),SutherlandedLines(i,[2,4]));
end
%绘制裁剪窗口
fori=1:
length(RLines(:
1))
plot(RLines(i,[1,3]),RLines(i,[2,4]),'-r');
end
holdoff;
end
%generate_callback.m文件,
functiongenerate_callback()
%生成线段回调函数
%
prompt={'输入线段条数','线段端点x坐标最大值','线段端点y坐标最大值'};%设置提示字符串
title='生成线段';%设置标题
numline=1;%指定输入数据行数
defdata={'20','100','100'};%指定数据的默认值
Resize='on';%设置对话框大小为可调节的
answer=inputdlg(prompt,title,numline,defdata,Resize);
%若用户点击“取消”键,则直接退出
ifisempty(answer)
return;
end
%将输入对话框的输入值转化为浮点数
data=str2num(char(answer));
lines=GenerateLines(round(data
(1)),data
(2),data(3));
setappdata(0,'lines',lines);
answer=questdlg('是否查看已生成的线段','提问对话框','是','否','是');
%answer,strcmp(answer,'是')
ifstrcmp(answer,'是')
%绘制原始线段图形
DrawOriginalGraph();
end
end
%GenereateLines.m文件,随机生成线段函数
functionLines=GenerateLines(count,MaxX,MaxY)
%随机生成count条线段,以矩阵Lines返回。
%MaxX是线段端点x坐标的最大值,MaxY是线段端点y坐标最大值
%Lines矩阵共四列,每一列的含义如下:
%端点Ax坐标端点Ay坐标端点Bx坐标端点By坐标
%
%line=rand(count,4);
line(:
[1,3])=rand(count,2)*MaxX;
line(:
[2,4])=rand(count,2)*MaxY;
Lines=line;
end
%MainMenu.m文件,这界面函数
functionMainMenu()
%程序主菜单界面
%
leftbase=0;
bottombase=-50;
%初始化线段矩阵lines
setappdata(0,'lines',[]);
figure();
uicontrol('Style','pushbutton','string','生成线段','position',[200+leftbase350+bottombase10050],...
'callback','generate_callback');
uicontrol('Style','pushbutton','string','裁剪','position',[200+leftbase280+bottombase10050],...