当前位置:文档之家› 计算机图形学实验指导书--实验2使用线段剪裁

计算机图形学实验指导书--实验2使用线段剪裁

计算机图形学实验指导书--实验2使用线段剪裁实验2使用线段剪裁Cohen——sutherland算法一.实验目的及要求根据Cohen——sutherland算法,掌握直线剪裁的程序设计方法。

注意,不能使用语言库中的画圆函数。

二.理论基础将不需要裁剪的直线挑出,并删去其中在窗外的直线,然后对其余直线,逐条与窗框求交点,并将窗框外的部分删去。

采用Cohen-Sutherland 直线剪裁的算法一区域编码为基础,将窗口及周围的八个方向以4位的二进制数进行编码。

4个位分代表窗外上,下,左右的编码值。

三、算法分析1. Cohen—SutherLand直线裁剪算法裁剪的实质,就是决定图形中那些点、线段、文字、以及多边形在窗口之内。

Cohen—SutherLand直线裁剪算法的基本大意是:对于每条线段P1P2,分为三种情况处理。

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

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

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

其中一段完全在窗口外,可弃之。

然后对另一段重复上述处理。

为了使计算机能够快速地判断一条线段与窗口属何种关系,采用如下的编码方法。

延长窗口的边,把未经裁剪的图形区域分为9个区,每个区具有一个四位代码,即四位二进制数,从左到右各位依次表示上、下、左、右。

裁剪一条线段时,先求出端点P1P2所在的区号code1和code2。

若code1=0且code2=0,则说明P1和P2均在窗口内,那么整条线段也比在窗口内,应取之。

若code1和code2经按位与运算后的结果code1&code2不为0,则说明两个端点同在窗口的上方、下方、左方或右方。

若上述两种条件均不成立,则按第三种情况处理,求出线段与窗口某边的交点,在交点处把线段一分为二,其中必有一段完全在窗口外,可以弃之。

再对另一段重复进行上述处理。

计算线段与窗口边界(或其延长线)的交点,属于线段与直线求交问题。

在实现本算法时,不必把线段与每条窗口边界依次求交,只要按顺序检测到端点区码的某位不为0时,才把线段与对应的窗口边界进行求交。

四、提示代码#include<stdio.h>#include<graphics.h>void initgr(void) /* BGI初始化*/{int gd = DETECT, gm = 0; /* 和gd = VGA,gm = VGAHI是同样效果*/registerbgidriver(EGAVGA_driver);/* 注册BGI驱动后可以不需要.BGI文件的支持运行*/initgraph(&gd, &gm, "");}clip_a_line(x1,y1,x2,y2,xw_min,xw_max,yw_min,yw_max){int i,code1[4],code2[4],done,display;float m;int x11,x22,y11,y22,mark;done=0;display=0;while(done==0){x11=x1;x22=x2;y11=y1;y22=y2;encode(x1,y1,code1,xw_min,xw_max,yw_min,yw_max);encode(x2,y2,code2,xw_min,xw_max,yw_min,yw_max);if(accept(code1,code2)){done=1;display=1;break;}else if(reject(code1,code2)){done=1;break;}mark=swap_if_needed(code1,code2);if(mark==1){x1=x22;x2=x11;y1=y22;y2=y11;}if(x2==x1)m=-1;elsem=(float)(y2-y1)/(float)(x2-x1);if(code1[2]){x1+=(yw_min-y1)/m;y1=yw_min;}else if(code1[3]){x1-=(y1-yw_max)/m;y1=yw_max;}else if(code1[0]){y1-=(x1-xw_min)*m;x1=xw_min;}else if(code1[1]){y1+=(xw_max-x1)*m;x1=xw_max;}}if(display==1){line(x1,y1,x2,y2);printf("The result is:(x1,y1)=(%d,%d)\n",x1,y1);printf("The result is:(x2,y2)=(%d,%d)\n",x2,y2);}}int encode(int x,int y,int code[],int xw_min,int xw_max,int yw_min,int yw_max){int i;for(i=0;i<4;i++)code[i]=0;if(x<xw_min)code[0]=1;else if(x>xw_max)code[1]=1;if(y>yw_max)code[3]=1;else if(y<yw_min)code[2]=1;return(0);}int accept(int code1[],int code2[]){int i,flag;flag=1;for(i=0;i<4;i++){if((code1[i]==1) || (code2[i]==1)){flag=0;break;}}return(flag);}int reject(int code1[],int code2[]){int i,flag;flag=0;for(i=0;i<4;i++){if((code1[i]==1) && (code2[i]==1)){flag=1;break;}}return(flag);}int swap_if_needed(int code1[],int code2[]) {int i,flag1,flag2,tmp;flag1=1;for(i=0;i<4;i++)if(code1[i]==1){flag1=0;break;}flag2=1;for(i=0;i<4;i++)if(code2[i]==1){flag2=0;break;}if((flag1==0) && (flag2==0))return(0);if((flag1==1) && (flag2==0)){for(i=0;i<4;i++){tmp=code1[i];code1[i]=code2[i];code2[i]=tmp;}return(1);}return(0);}void main(){int x1,x2,y1,y2,xw_min,xw_max,yw_min,yw_max;initgr();printf("Please input the bottom boundary(xw_min,yw_min):\n"); scanf("%d,%d",&xw_min,&yw_min);printf("Please input the top boundary(xw_max,yw_max):\n");scanf("%d,%d",&xw_max,&yw_max);setcolor(GREEN);line(xw_min,yw_min,xw_max,yw_min);line(xw_min,yw_max,xw_max,yw_max);line(xw_min,yw_min,xw_min,yw_max);line(xw_max,yw_min,xw_max,yw_max);getch();printf("Please input the position of the first point(x1,y1):\n"); scanf("%d,%d",&x1,&y1);printf("Please input the position of the first point(x2,y2):\n"); scanf("%d,%d",&x2,&y2);setcolor(YELLOW);line(x1,y1,x2,y2);getch();cleardevice();setcolor(GREEN);line(xw_min,yw_min,xw_max,yw_min);line(xw_min,yw_max,xw_max,yw_max);line(xw_min,yw_min,xw_min,yw_max);line(xw_max,yw_min,xw_max,yw_max);setcolor(RED);clip_a_line(x1,y1,x2,y2,xw_min,xw_max,yw_min,yw_max); outtextxy(50,50,"Cohen-SutherLand!");getch();closegraph();}。

相关主题