(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],...
'callback','sutherland_callback');
uicontrol('Style','pushbutton','string','查看原始线段图形','position',[200+leftbase210+bottombase10050],...
'callback','check_callback');
end
%sutherland_callback.m文件
functionsutherland_callback()
%裁剪算法回调函数
%
lines=getappdata(0,'lines');
ifisempty(lines)
errordlg('当前尚未生成线段!
\n请先生成线段','错误提示');
return;
end
whiletrue
prompt={'窗口参数Xwl','窗口参数Xwr','窗口参数Ywb','窗口参数Ywt'};%设置提示字符串
title='窗口参数';%设置标题
numline=1;%指定输入数据行数
defdata={'0','1000','0','1000'};%指定数据的默认值
Resize='on';%设置对话框大小为可调节的
answer=inputdlg(prompt,title,numline,defdata,Resize);
%若用户点击了“取消”键,则直接退出。
ifisempty(answer)
return;
end
data=str2num(char(answer));
ifdata
(1)>data
(2)||data(3)>data(4)
errordlg('窗口参数必须满足Xwl<=Ywr且Ywb<=Ywt','错误提示');
else
break;
end
end
%
%开始进行裁剪
SutherlandedLines=Cohen_Sutherland(lines,data);
answer=questdlg('裁剪已完成!
是否查看裁剪效果?
','询问','是','否','是');
ifstrcmp(answer,'是')
DrawSutherlandGraph(lines,data,SutherlandedLines);
end
end