这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战
1 引言
直线裁剪算法中较为著名的有Cohen-Sutherland算法,即基于编码的裁剪方法
本文将基于直线裁剪算法,对二维坐标系中不同情况的直线裁剪进行分析、运用与推广
2 思路
总体思路流程图如下:
-
简取与简弃是两种较为简单的情况,而复杂情况的裁剪有几个需注意的问题:
- 对于2个交点的情况,则取计算交点后的两点连线,即可得到裁剪后的直线
- 对于1个交点的情况,“新”直线必定有一个端点在矩形裁剪框内,而另一个端点则需判断矩形边界的x(或y)与原直线外部端点的x(或y)坐标大小
-
关于交点的计算,思路如下:
- 首先构造一个4行3列的零矩阵
- 分别根据四个方向的编码值,获取x,y坐标,
- 第3列用于记录交点是否为实交点,实为1,虚为0
- 最后将矩阵作为返回值
3 过程
3.1 主函数Cohen.m
首先绘制直线、裁剪框,并计算两端点编码
分别对简取、简弃、复杂情况进行判断
%简弃
if code1(1)+code2(1)>1||code1(2)+code2(2)>1||code1(3)+code2(3)>1||code1(4)+code2(4)>1
figure('Name','简弃')
quyu(x1,x2,y1,y2);
%简取
elseif code1(1)==0&&code1(2)==0&&code1(3)==0&&code1(4)==0&&code2(1)==0&&code2(2)==0&&code2(3)==0&&code2(4)==0
figure('Name','简取')
hold on;
plot(xx,yy);
quyu(x1,x2,y1,y2);
hold off;
最后在一个新窗口绘制裁剪后直线,便于与原图形对比
3.2 求交点的函数jiaoDian.m
首先获取并记录交点
jd=zeros(4,3);
%求交点
k=(dy2-dy1)/(dx2-dx1); %直线斜率
yzuo=k*(x1-dx1)+dy1;
jd(1,1)=x1;jd(1,2)=yzuo;
% 其他方位同理
求直线端点坐标较大、小值
%求直线端点坐标较大、小值
xx=[dx1 dx2];yy=[dy1 dy2];
xmax=max(xx);ymax=max(yy);
xmin=min(xx);ymin=min(yy);
再分左、右、下、上4种情况判断交点是否为实
3.3 求编码的函数code.m
Code=zeros(1,4);
if dx<x1
Code(1,4)=1;
elseif dy<y1
Code(1,2)=1;
% 依此类推
end
3.4 获取裁剪框的函数quyu.m
默认x1,y1比x2,y2小,否则将抛出一个错误:x1是左边线,不能大于x2
3.5 绘制矩形的函数juxing.m
专门写了一个绘制矩形的函数,1个矩形可以看作4条直线的组合
4 结果
由于裁剪情况较多,故此处仅展示直线与窗口有1个交点与2个交点的情况,更多示例及完整代码请见Cohen(gitee.com)