计算机图形学实验指导书--实验2使用线段剪裁
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
计算机图形学实验指导书--实验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
#include
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;
else
m=(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 code[0]=1; else if(x>xw_max) code[1]=1; if(y>yw_max) code[3]=1; else if(y 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;