您好,欢迎访问三七文档
直线裁剪算法研究摘要:直线裁剪是计算机图形学中的一个重要技术,在对常见的直经线裁剪的算法分析的基础上,针对Cohen-Sutherland算法和Liang-Barsky算法进行了分析研究。并对两种算法了计算直线与窗口边界的交点时,进行了有效有比较。关键词:裁剪;算法;Cohen-Sutherland;Liang-Barsky;1引言直线是图形系统中使用最多的一个基本元素。所以对于直线段的裁剪算法是被研究最深入的一类算法,目前在矩形窗口的直线裁剪算法中,出现了许多有效的算法。其中比较著名的有:Cohen-Sutherland算法、中点分割算法、Liang-Barsky算法、Sobkow-Pospisil-Yang算法,及Nicholl-Lee-Ncholl算法等。2直线裁剪的基本原理图1所示的为直线与窗口边界之间可能出现的几种关系。可以通过检查直线的两个端点是否在窗口之内确定如何对此直线裁剪。如果一直线的两个端点均在窗口边界之内(如图1中P5到P6的直线),则此直线应保留。如果一条直线的一个端点在窗口外(如P9)另一个点在窗口内(如P10),则应从直线与边界的交点(P9)处裁剪掉边界之外的线段。如果直线的两个端点均在边界外,则可分为两种情况:一种情况是该直线全部在窗口之外;另一种情况是直线穿过两个窗口边界。图中从P3到P4的直线属于前一种情况,应全部裁剪掉;从P7到P8的直线属于后一种情况,应保留P7到P8的线段,其余部分均裁剪掉。图1直线相对干窗口边界的栽剪直线裁剪算法应首先确定哪些直线全部保留或全部裁剪,剩下的即为部分裁剪的直线。对于部分裁剪的直线则首先要求出这些直线与窗口边界的交点,把从交点开始在边界外的部分裁剪掉。一个复杂的画面中可能包含有几千条直线,为了提高算法效率,加快裁剪速度,应当采用计算量较小的算法求直线与窗口边界的交点。3cohen-sutherland直线裁剪算法Cohen-Sutherland算法的大意是:对于每条线段P1P2,分为3种情况处理。①若P1P2完全在窗口内,则显示该线段P1P2,简称“取”之。②若P1P2明显在窗口外,则丢弃该线段,简称“弃”之。③若线段既不满足“取”的条件,也不满足“弃”的条件,则把线段分为两段。其中一段完全在窗口外,可弃之。然后对另一段重复上述处理。1.区域码及其建立Cohen-Sutherland直线裁剪算法的核心是把所有直线的端点均分配一个表示其相对位置的4位二进制代码。此代码称为区域码。区域码按照端点与窗口边界的相对位置编码,即区域码的4位分别代表端点位于窗口的上、下、左、右。区域码从右到左的各位所代表的坐标区如下所示:位4321坐标区上下右左上述各位中某位为1,则表示点位于此坐标区。窗口周围各坐标区的区域码如图2所示。由图2可见,位于窗中内的点,其区域码应为0000,位于窗口左下方的点,其区域码应为0101,其余类推。区域码各位的值可以通过对端点坐标(x,y)与窗口边界的比较求得。如果xxwmin,则区域码的第一位为1,其余各位的确定与此相似。现在的计算机语言都可以进行位操作,因此,可以通过以下步骤建立区域码:①计算出端点坐标与窗口边界的差。②按计算出的各个差的符号把区域码的相应位置为0或1,即区域码的第一位置为(x-xwmin)的符号位;区域码的第二位置为(xwmin-x)的符号位;区域码的第三位置为(y-ywmin)的符号位;区域码的第四位置为(ywmin-y)的符号位。2.区域码裁剪算法对所有直线的端点都建立了区域码之后,就可按区域码判断直线在窗口之内或窗口之外。这可分为如下几种情况:①若一直线的两个端点的区域码均为0000则此直线在窗口边界之内,应子保留。②若一直线的两个端点的区域码的同一位同时为1,则此直线全部在窗口边界之外,应子裁剪。例如,若一直线的一个端点的区域码为1001,另一个端点的区域码为0101,则此两端点的区域码的第一位均为1,说明此两端点均在窗口边界之左,因此,直线在窗口边界之外,应予裁剪。可用将直线两个端点的区域码进行与操作的方法,判断直线是否图2区域码在窗口之外,若与操作的结果为0000则两端点的区域码任何位均不同时为1,此直线不一定被裁剪。③以上两种情况之外的直线,有可能穿过窗口,也有可能不穿过窗口,如图87所示。图中所示的两条直线都不符合情况②的要求,但一条直线(P1P2)穿过窗口,另一直线(P3P4)不守过窗口。对这类直线可以进行如下处理:取窗口外的一个端点与窗口边界比较以确定可排除直线的哪一部分,然后,把直线剩下的部分与其他边界比较,这样一直到直线全部被排除或确定直线的哪一部分在窗口之内为止。可按“左、右、下、上”的次序建立检查直线端点与窗口边界关系的算法。下面介绍对图3所示的两条直线进行处理的过程。从直线P1P2的下端点P1开始,依次检查窗口的左、上、右及下边界,可发现此点在窗口之下(因为区域码的第三位为1)。然后求得直线与下边界的交点P1排除线段P1P1这样直线就缩短为P1P2。因为P2在边界之外,将此端点与各边界比较,可发现此端点在窗口上面。计算出交点P2线段P1P2保留下来。这样就完成了对这条线的处理并开始处理下一直线P3P4。端点P3在窗口之左,可计算出交点3P讲裁剪掉线段33PP。检查43PP的区域码,可发现直线的这一剩余部分在窗口之下故也可排除。由于窗口边界均平行于坐标轴,所以直线与窗口边界的交点可以用直线方程的各参数很方便地求出,对于一条端点坐标为11,yx及22,yx的直线,其与一垂直边界的交点的y坐标可以用下式计算:11xxmyy这里互的取值可取x或maxwx,斜率m可用公式1212xxyym计算。同样地,与水平边界交点的x坐标可用下式计算:myyxx11这里y的值可取几minwy或maxwy。下面是区域码直线裁剪算法的C语言描述,其中每个端点的区域码用4元素布尔数组表示。区域码直线裁剪算法代码VoidLine_Clipping(x1,y1,x2,y2,xw_xmin,yw_ymin,xw_max,yw_max)floatx1,y1,x2,y2,xw_xmin,yw_ymin,xw_max,xw_max,yw_max;/*11,yx和22,yx是线段端点坐标*/{Intdraw,done;Intcode1,code2,code;floatx,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);while(!Done){if(code1==0&&code==2){draw=TRUE;done=TRUE;}elseif(code1&code2!=0)done=TRUE;else{If(code1!=0)code=code1;elsecode=code2;if(code&TOP!=0){y=yw_ymax;x=x1+(y-y1)*(x2-x1)/(y2-y1);}elseif(code&BOTTOM!=0){y=yw_ymin;x=x1+(y-y1)*(x2-x1)/(y2-y1);}elseif(code&RTGHT!=0){x=xw_xmax;y=y1+(x-x1)*(y2-y1)/(x2-x1);}elseif(code&LIFT!=0){x=xw_xmin;y=y1+(x-x1)*(y2-y1)/(x2-x1);}if(code==code1){x1=x;y1=y;code1=get_code{x1,y1,xw_xmin,yw_ymin,xw_max,yw_max};}else{x2=x;y2=y;code2=get_code{x2,y2,xw_xmin,yw_ymin,xw_max,yw_max};}If(draw)Draw_Line(x1,y1,x2,y2);}intget_code(x,y,xw_xmin,yw_ymin,xw_max,yw_max)floatx,y,xw_xmin,yw_ymin,xw_max,yw_max;{intcode;code=0;if(yyw_ymax)code|=TOP;elseif(yyw_ymin)code|=BOTTOM;if(xxw_xmax)code|=RIGHT;elseif(xxw_xmin)code|=LEFT;returncode;}4Liang-Barsky算法Liang(梁友栋)-Barsky算法又称为参数方程法。首先写出端点11,yx及22,yx之间连线的参数方程如下:xuxuxxxx1121yuyuyyyy1121其中,1212,yyyxxx。参数u可取01之间的值,坐标yx,表示此范围内的u值定义的直线上的一个点。当u=0时,11,,yxyx,直线的另一端u=0时,22,,yxyx。我们发现,如果直线上的某点处于yx,及minmin,wwyx及maxmax,wwyx所定义的窗口之内,则满足以下条:minwx≤xux1≤maxwxminwy≤yuy1≤maxwy这四个不等式可以表示为:kup≤kq,k=1,2,3,4其中,参数qp,定义为;,1xpmin11wxxq,2xp1max2xxqw,3ypmin13wyyq,4yp1max4yyqw按照直线与窗口边界的相对位置,可分为以下几种倩况。①任何一条与窗口边界平行的直线,其0kp,此处k值表示取哪一个边界(k=1,2,3及4,分别相应于左、右、下及上边界)。如果对某一k值,还满足0kq,则此直线完全在边界外,可不进一步考虑;如果kq≥0,则此与边界平行的直线在边界内。②如果0kq,则情况较复杂。此时,可把直线按从11,yx到22,yx连线方向作为正向,将此直线无限延伸,同时把各窗口边界也无限延伸(见图3);然后分以下两种情况讨论:a当0kq时,则是由窗口外发出的一条直线的无限延伸线进入相应窗口边界的无限延伸线的内部。b当0kq时,情况相反。即直线的延伸线是由窗口边界延伸线的内部到外部。以图3中的直线1L为例,说明以上两种情况。表1.1给出1L的延伸线相对于4个边界延伸线的方向及kq取值。表1.1直线方向与kP取值边界kP取值方向交点左0121xxxp由外到内1u右0122xxxp由内到外下0123yyyp由外到内上0124yyyp由内到外2u当0kq时,可以用下式计算出一参数u,此u值应于直线延伸线与窗口边界k的延伸线的交点:kkpqu对于每条直线,可计算出一对u值(1u及2u),由此两参数可判断直线是如何裁剪的。其中,1u的值可由从窗口边界外发出进人窗口边界之内的直线(0kP)所涉及的窗口边界确定。对于这些窗口边界,可计算出各kkkpqr,取各kr中最大值即为回1u,2u可由图3直线与窗口边界的相对位置自窗口边界内发出至窗口边界外的直线(0kP)所涉及的窗口边界确定,同样可计算出这些窗口边界的kr值,取各kr中的最小值即为2u。如果21uu,则此直线全部在窗口外而可排除:否则,此直线在窗口内,可由1u及2u计算出彼裁剪直线的端点。图3中标出直线1L及2L相应于1u及2u的与边界的交点。1L的12uu,则1L彼裁剪,并可由1u及2u计算出裁剪点;而2L的21uu,则此直线全部彼排除。此算法可用以下过程表示。此过程中开始把交点参数置为01u及12u。对每一窗口边界计算出相应的p及q值,然后用函数CliPtest由参数p及q决定此直线能否彼排除或者决定交点参数是否要调整。当0p时,用参数r修改1u值:当0p时,用参数r修改2u值。如果最后的结果为21uu,则排除此直线;否则,只有当新
本文标题:直线裁剪算法研究(Cohen-Sutherland算法和Liang-Barsky算法)
链接地址:https://www.777doc.com/doc-5824270 .html