一、 实验目的:
直线段的裁剪:编码裁剪算法,中点分割裁剪算法。
二、实验内容:
//BasicGraph.cpp
//请将下列裁剪程序补充完整,并用注释说明是何种裁剪算法
void Encode (int x,int y,int *code,int XL,int XR,int YB,int YT) {
//请将此程序补充完整 int c=0;
if(x else if(x>XR) c=c|RIGHT; if(y //编码裁剪算法: void C_S_Line(POINT &p1,POINT &p2,int XL,int XR,int YB,int YT) { //请将此程序补充完整 int x1,x2,y1,y2,x,y,code1,code2,code; x1=p1.x; x2=p2.x; y1=p1.y; y2=p2.y; Encode(x1,y1,&code1,XL,XR,YB,YT); Encode(x2,y2,&code2,XL,XR,YB,YT); while(code1!=0||code2!=0) { if((code1&code2)!=0) return; code=code1; if(code1==0) code=code2; if((LEFT&code)!=0) {x=XL;y=y1+(y2-y1)*(XL-x1)/(x2-x1);} else if((RIGHT&code)!=0) {x=XR;y=y1+(y2-y1)*(XR-x1)/(x2-x1);} if((BOTTOM&code)!=0) {y=YB;x=x1+(x2-x1)*(YB-y1)/(y2-y1);} else if((TOP&code)!=0) {y=YT;x=x1+(x2-x1)*(YT-y1)/(y2-y1);} if(code==code1) {x1=x;y1=y;Encode(x,y,&code1,XL,XR,YB,YT);} else {x2=x;y2=y;Encode(x,y,&code2,XL,XR,YB,YT);} } p1.x=x1;p1.y=y1;p2.x=x2;p2.y=y2; } int IsInArea(POINT point,int XL,int XR,int YB,int YT) { //请将此程序补充完整 if(point.x>=XL && point.x<=XR && point.y>YB && point.y else return 0; } int NotIntersect(POINT begin,POINT end,int XL,int XR,int YB,int YT) { //请将此程序补充完整 int maxx,maxy,minx,miny; maxx=(begin.x>end.x)?begin.x:end.x; minx=(begin.x if(maxx //中点裁剪算法: POINT ClipMid(POINT begin,POINT end,int XL,int XR,int YB,int YT) { //请将此程序补充完整 POINT mid,temp; if(IsInArea(begin,XL,XR,YB,YT)) temp=begin; else if(NotIntersect(begin,end,XL,XR,YB,YT)) temp=begin; else { mid.x=(begin.x+end.x)/2;mid.y=(begin.y+end.y)/2; if(abs(mid.x-end.x)<=1&& abs(mid.y-end.y)<=1) temp=mid; else { if(NotIntersect(begin,mid,XL,XR,YB,YT)) temp=ClipMid(mid,end,XL,XR,YB,YT); else temp=ClipMid(begin,mid,XL,XR,YB,YT); } } return temp; } //Liang-Barsky直线裁剪算法: void ClipParameter(POINT &p1,POINT &p2,int XL,int XR,int YB,int YT) { float u1=0.0,u2=1.0; float dx=p2.x-p1.x,dy=p2.y-p1.y; if(clipTest(-dx,p1.x-XL,&u1,&u2)) if(clipTest(dx,XR-p1.x,&u1,&u2)) if(clipTest(-dy,p1.y-YB,&u1,&u2)) if(clipTest(dy,YT-p1.y,&u1,&u2)) { if(u2<1.0) { p2.x=p1.x+u2*dx; p2.y=p1.y+u2*dy; } if(u1>0.0) { p1.x=p1.x+u1*dx; p1.y=p1.y+u1*dy; } } } int clipTest(float p,float q,float *u1,float *u2) { float r; int remainFlag=1; if(p<0.0) { r=q/p; if(r>*u2) remainFlag=0; else if(r>*u1) *u1=r; } else if(p>0.0) { r=q/p; if(r<*u1) remainFlag=0; else if(r<*u2) *u2=r; } else //*p=0 if(q<0.0) remainFlag=0; return remainFlag; } //逐边裁剪算法: //typedef struct tRes { int yes,isIn; POINT pout;} Res; Res TestIntersect(int edge,int type,POINT p1,POINT p2) {//判断p2是否在所裁剪的窗边edge的内侧,是否与p1点分别在窗边edge的异侧 float dx,dy,m; Res res;int isIn=0,yes=0;POINT pout; dy=p2.y-p1.y;dx=p2.x-p1.x;m=dy/dx; switch(type) { case 1: /*right*/ if(p2.x<=edge){isIn=1;if(p1.x>edge)yes=1;} else if(p1.x<=edge)yes=1;break; case 2: /*bottom*/ if(p2.y>=edge){isIn=1;if(p1.y if(p2.x>=edge){isIn=1;if(p1.x if(p2.y<=edge){isIn=1;if(p1.y>edge)yes=1;} else if(p1.y<=edge)yes=1; default: break; } if(yes) { if((type==1) || (type==3)) { pout.x=edge;pout.y=p1.y+m*(pout.x-p1.x);} if((type==2) || (type==4)) { pout.y=edge;pout.x=p1.x+(pout.y-p1.y)/m;} } res.isIn=isIn;res.yes=yes;res.pout=pout; return res; } int clipSingleEdge(int edge,int type,int nin,POINT pin[50],POINT pout[50]) /*对多边形pin与窗边edge进行裁剪,返回裁剪后的多边形pout及点数*/ { int i,k=0;POINT p;Res res; p.x=pin[nin-1].x;p.y=pin[nin-1].y; for(i=0;i res=TestIntersect(edge,type,p,pin[i]); if(res.yes) { pout[k].x=res.pout.x;pout[k].y=res.pout.y;k++;} if(res.isIn) { pout[k].x=pin[i].x;pout[k].y=pin[i].y;k++;} p.x=pin[i].x;p.y=pin[i].y; } return k; } void ClipEdgePolygon(POINT ps[50],int &n,int XL,int XR,int YB,int YT) { /*对多边形ps进行逐边裁剪*/ int n1=0,n2=0; POINT pt[50]; n1=clipSingleEdge(XR,1,n,ps,pt); n2=clipSingleEdge(YB,2,n1,pt,ps); n1=clipSingleEdge(XL,3,n2,ps,pt); n2=clipSingleEdge(YT,4,n1,pt,ps); n=n2; } //多边形编码裁剪算法: void ClipEncodePolygon(POINT ps[50],int &n,int XL,int XR,int YB,int YT) { POINT tp[50]; int k=0,m; int code1,code2,code; int x,y; for(int i=0;i Encode(ps[i].x,ps[i].y,&code1,XL,XR,YB,YT); Encode(ps[i+1].x,ps[i+1].y,&code2,XL,XR,YB,YT); code=code1;m=i; for(int j=0;j<2;j++) { if((code1 & code2)!=0) //线段两端都在窗口外的同一侧 { switch(code) { case 1:x=XL;y=ps[m].y;break; case 2:x=XR;y=ps[m].y;break; case 4:x=ps[m].x;y=YB;break; case 5:x=XL;y=YB;break; case 6:x=XR;y=YB;break;