直线裁剪算法研究(Cohen-Sutherland算法和Liang-Barsky算法)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

直线裁剪算法研究

摘要:直线裁剪是计算机图形学中的一个重要技术,在对常见的直经线裁剪的算法分析的基础上,针对Cohen-Sutherland算法和Liang-Barsky算法进行了分析研究。并对两种算法了计算直线与窗口边界的交点时,进行了有效有比较。

关键词:裁剪;算法;Cohen-Sutherland;Liang-Barsky;

1 引言

直线是图形系统中使用最多的一个基本元素。所以对于直线段的裁剪算法是被研究最深入的一类算法,目前在矩形窗口的直线裁剪算法中,出现了许多有效的算法。其中比较著名的有:Cohen-Sutherland算法、中点分割算法、Liang-Ba rsky算法、Sobkow-Pospisil-Yang算法,及Nicholl-Lee-Ncholl算法等。

2 直线裁剪的基本原理

图1所示的为直线与窗口边界之间可能出现的几种关系。可以通过检查直线的两个端点是否在窗口之内确定如何对此直线裁剪。如果一直线的两个端点均在窗口边界之内(如图1中P5到P6的直线),则此直线应保留。如果一条直线的一个端点在窗口外(如P9)另一个点在窗口内(如P10),则应从直线与边界的交点(P9)处裁剪掉边界之外的线段。如果直线的两个端点均在边界外,则可分为两种情况:一种情况是该直线全部在窗口之外;另一种情况是直线穿过两个窗口边界。图中从P3到P4的直线属于前一种情况,应全部裁剪掉;从P7到P8的直线属于后一种情况,应保留P7到P8的线段,其余部分均裁剪掉。

图1直线相对干窗口边界的栽剪

直线裁剪算法应首先确定哪些直线全部保留或全部裁剪,剩下的即为部分裁剪的直线。对于部分裁剪的直线则首先要求出这些直线与窗口边界的交点,把从交点开始在边界外的部分裁剪掉。一个复杂的画面中可能包含有几千条直线,为了提高算法效率,加快裁剪速度,应当采用计算量较小的算法求直线与窗口边界的交点。

3 cohen-sutherland直线裁剪算法

Cohen-Sutherland算法的大意是:对于每条线段P1P2,分为3种情况处理。

①若P1P2完全在窗口内,则显示该线段P1P2,简称“取”之。

②若P1P2明显在窗口外,则丢弃该线段,简称“弃”之。

③若线段既不满足“取”的条件,也不满足“弃”的条件,则把线段分为两段。其中

一段完全在窗口外,可弃之。然后对另一段重复上述处理。

1.区域码及其建立

Cohen-Sutherland直线裁剪算法的核心是把所有直线的端点均分配一个表示其相对

位置的4位二进制代码。此代码称为区域码。区域码按照端点与窗口边界的相对位置编码,

即区域码的4位分别代表端点位于窗口的上、下、左、右。区域码从右到左的各位所代表

的坐标区如下所示:

位 4 3 2 1

坐标区上下右左

上述各位中某位为1,则表示点位于此坐标区。窗口周围各坐标区的区域码如图2所

示。由图2可见,位于窗中内的点,其区域码应为0000,位于窗口左下方的点,其区域

码应为0101,其余类推。

区域码各位的值可以通过对端点坐标(x,y)与窗口边界的比较求得。如果x

则区域码的第一位为1,其余各位的确定与此相似。现在的计算机语言都可以进行位操作,

因此,可以通过以下步骤建立区域码:

①计算出端点坐标与窗口边界的差。

②按计算出的各个差的符号把区域码的相应位置为0或1,即

区域码的第一位置为(x-x wmin)的符号位;

区域码的第二位置为(x wmin-x)的符号位;

区域码的第三位置为(y-y wmin)的符号位;

图2 区域码区域码的第四位置为(y wmin-y)的符号位。

2.区域码裁剪算法

对所有直线的端点都建立了区域码之后,就可按区域码判断直线在窗口之内或窗口

之外。这可分为如下几种情况:

①若一直线的两个端点的区域码均为0000则此直线在窗口边界之内,应子保留。

②若一直线的两个端点的区域码的同一位同时为1,则此直线全部在窗口边界之外,

应子裁剪。例如,若一直线的一个端点的区域码为1001,另一个端点的区域码为0101,

则此两端点的区域码的第一位均为1,说明此两端点均在窗口边界之左,因此,直线在窗

口边界之外,应予裁剪。可用将直线两个端点的区域码进行与操作的方法,判断直线是否

在窗口之外,若与操作的结果为0000则两端点的区域码任何位均不同时为1,此直线不一定被裁剪。

③以上两种情况之外的直线,有可能穿过窗口,也有可能不穿过窗口,如图87所示。图中所示的两条直线都不符合情况②的要求,但一条直线(P 1P 2)穿过窗口,另一直线(P 3P 4)不守过窗口。对这类直线可以进行如下处理:取窗口外的一个端点与窗口边界比较以确定可排除直线的哪一部分,然后,把直线剩下的部分与其他边界比较,这样一直到直线全部被排除或确定直线的哪一部分在窗口之内为止。可按“左、右、下、上”的次序建立检查直线端点与窗口边界关系的算法。

下面介绍对图3所示的两条直线进行处理的过程。从直线P 1P 2的下端点P 1开始,依次检查窗口的左、上、右及下边界,可发现此点在窗口之下(因为区域码的第三位为1)。然后求得直线与下边界的交点P 1排除线段P 1 P 1这样直线就缩短为P 1 P 2。因为P 2在边界之外,将此端点与各边界比较,可发现此端点在窗口上面。计算出交点P 2线段P 1P 2保留下来。这样就完成了对这条线的处理并开始处理下一直线P 3 P 4。端点P 3在窗口之左,可计算出交点3P '讲裁剪掉线段33P P '。检查43P P '的区域码,可发现直线的这一剩余部分在窗口之下故也可排除。

由于窗口边界均平行于坐标轴,所以直线与窗口边界的交点可以用直线方程的各参数很方便地求出,对于一条端点坐标为()11,y x 及()22,y x 的直线,其与一垂直边界的交点的y 坐标可以用下式计算:

()11x x m y y -+=

这里互的取值可取x 或m ax w x ,斜率m 可用公式()()1212x x y y m --=计算。同样地,与水平边界交点的x 坐标可用下式计算:

()m y y x x 11-+=

这里y 的值可取几m in w y 或m ax w y 。

下面是区域码直线裁剪算法的C 语言描述,其中每个端点的区域码用4元素布尔数组表示。

区域码直线裁剪算法代码

Void Line_Clipping(x1,y1,x2,y2,xw_xmin,yw_ymin,xw_max,yw_max) float x1,y1,x2,y2,xw_xmin,yw_ymin,xw_max,xw_max,yw_max; /*()11,y x 和()22,y x 是线段端点坐标*/ {

Int draw,done;

Int code1,code2,code; float x,y;

Draw=FALSE; done=FALSE;

code1=get_code(x1,y1,xw_xmin,yw_ymin,xw_max,yw_max);

code2=get_code(x2,y2,xw_xmin,yw_ymin,xw_max,yw_max);

相关文档
最新文档