裁剪参考代码.doc_第1页
裁剪参考代码.doc_第2页
裁剪参考代码.doc_第3页
裁剪参考代码.doc_第4页
裁剪参考代码.doc_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

参考代码:1、直线的裁剪 SutherlandCohen算法Sutherland_Cohen(float x0, float y0, float x2, float y2)unsigned int c,c1,c2; float x,y,wx,wy; bool accept=false, done=false; c1=EnCode(x0,y0); c2=EnCode(x2,y2); do if (c1|c2)=0) accept=true; done=true; else if(c1&c2)!=0)done=true; else c=c1; if(c=0) c=c2; /求位于窗口外的点 wx=x2-x0; wy=y2-y0; if (c&8)=8) x=x0+wx*(wyt-y0)/wy; y=wyt; else if (c&4)=4) x=x0+wx*(wyb-y0)/wy; y=wyb; else if (c&1)=1) y=y0+wy*(wxl-x0)/wx; x=wxl; else y=y0+wy*(wxr-x0)/wx; x=wxr; if (c = c1) /表明c1!=0,起始点不在窗口内,将交点作为新的起点重复判断步骤; x0 = x; y0 = y; c1 = EnCode(x0, y0); else /终点不在窗口内,交点作为新的终点 x2 = x; y2 = y; c2 = EnCode(x2, y2); while(done=false); if (accept=true) drawLine(int(x0), int(y0), int(x2), int(y2)/绘制裁剪出的线段 EnCode(float LinePx, float LinePy)unsigned int RC=0;if(LinePxwxr)RC=RC | RIGHT;if(LinePywyt)RC=RC | TOP;return RC; 中点分割算法MidPoint(float xx0, float yy0, float xx2, float yy2)int RC0,RC1,RC;float x,y;bool accept=false;RC0=EnCode(xx0,yy0);RC1=EnCode(xx2,yy2);if(RC0|RC1)=0)/简取之accept=true; else if(RC0&RC1)!=0)/简弃之 accept=false;return;elseif(RC0=0|RC1=0)/一个顶点在窗口里面,一个顶点在窗口外面if(RC0=0)/P0点在窗口内,P1点在窗口外MidClip(xx0,yy0,&xx2,&yy2,true);else/P1点在窗口内,P0点在窗口外MidClip(xx2,yy2,&xx0,&yy0,false);else/两个点都在窗口外面,将进行拆分,始终可以拆分成两段直线。离P0点近的为false,离P1点近的为truex=(xx0+xx2)/2;y=(yy0+yy2)/2;RC=EnCode(x,y);while(RC!=0)/中点落在窗口外面if(RC0&RC)=0)/中点P和P0点跨越窗口时,P点和P1点肯定位于窗口之外,舍去PP1xx2=x,yy2=y;RC1=RC;else/中点在P0侧,舍去PP0点xx0=x,yy0=y;RC0=RC;x=(xx0+xx2)/2;y=(yy0+yy2)/2;RC=EnCode(x,y);/RC=0,中点在窗口内,以中点分为两段可以裁剪了MidClip(x,y,&xx0,&yy0,false);MidClip(x,y,&xx2,&yy2,true); accept=true;if(accept=true) drawLine(int(x0), int(y0), int(x2), int(y2)/绘制裁剪出的线段MidClip(float P0x, float P0y, float *P1x, float *P1y, bool flag)float x,y;/中点坐标int RCT0,RCT1,RCT;RCT0=EnCode(P0x,P0y);RCT1=EnCode(*P1x,*P1y);x=(P0x+*P1x)/2;y=(P0y+*P1y)/2;RCT=EnCode(x,y);while(fabs(x-P0x)1e-6|fabs(y-P0y)1e-6)if(RCT=0)/中点也在窗口内,则P=P0P0x=x;P0y=y;RCT0=RCT;else/否则舍弃P1点*P1x=x;*P1y=y;RCT1=RCT;x=(P0x+*P1x)/2;y=(P0y+*P1y)/2;RCT=EnCode(x,y);*P1x=x;*P1y=y;/*if(flag=true)xx2=x;yy2=y;elsexx0=x,yy0=y;*/ 梁友栋-Barsky算法ClipTest(float u, float v, float *tmax, float *tmin)/裁剪测试函数 /顺序左右下上float t;int ReturnValue=TRUE;if(u*tmin)ReturnValue=FALSE;else if(t*tmax)*tmax=t;elseif(u0.0)/内部到外部,计算终点处的tmint=v/u;if(t*tmax)ReturnValue=FALSE;else if(t*tmin)*tmin=t;else/平行于窗口边界的直线if(v0.0)/直线在窗口外可直接删除ReturnValue=FALSE;return(ReturnValue);BarskyClip(float x1, float y1, float x2, float y2)/裁剪函数float tmax,tmin,dx,dy;dx=x2-x1;dy=y2-y1;tmax=0.0,tmin=1.0;/窗口边界的左、右、下、上顺序裁剪直线if(ClipTest(-dx,x1-wxl,&tmax,&tmin)/n1,左边界u1x,v1x1wxlif(ClipTest(dx,wxr-x1,&tmax,&tmin)/n2,右边界u2x,v2wxrx1if(ClipTest(-dy,y1-wyb,&tmax,&tmin)/n3,下边界u3y,v3y1-wybif(ClipTest(dy,wyt-y1,&tmax,&tmin)/n4,上边界u4y,v4wyt-y1if(tmin0.0)/判断直线的起点x1+=tmax*dx;y1+=tmax*dy;drawLine(int(x0), int(y0), int(x2), int(y2)/绘制裁剪出的线段2、多边形的裁剪int ClipByEdgn(float *cinpointsx, float *cinpointsy, int cinnum, int inoutflag, int winedge) float sx,sy; int coutnum=0; /为裁剪后新多边形顶点数bool f; sx = cinpointsxcinnum-1; sy = cinpointsycinnum-1; /为裁剪前旧多边形最后一个顶点坐标 switch(inoutflag)case LEFT:if (sx = winedge) f = 0 ;/前一点在内 if (sx winedge) f = 1 ;/ 前一点在外 for(int i=0; i= winedge) /当前点在内 if (f = 1) /前一点在外 clippointsxcoutnum = winedge; /交点为新点, clippoints为输出点 clippointsycoutnum = sy + (cinpointsyi - sy) * (winedge - sx) / (cinpointsxi - sx); coutnum = coutnum + 1; f = 0; /当前点作为下一点的前一点(在内) clippointsxcoutnum = cinpointsxi; clippointsycoutnum = cinpointsyi; coutnum = coutnum + 1; /当前点为新点 else /当前点在外 if (f = 0) /前一点在内 clippointsxcoutnum = winedge; / 交点为新点 clippointsycoutnum = sy + (cinpointsyi - sy) * (winedge - sx) / (cinpointsxi - sx); coutnum = coutnum + 1; f = 1; sx = cinpointsxi; sy = cinpointsyi; break;case RIGHT:if (sx winedge) f = 1 ;/ 前一点在外 for(int i=0; icinnum; i+) if (cinpointsxi = winedge) f = 0 ;/前一点在内 if (sy winedge) f = 1 ;/ 前一点在外 for(int i=0; i= winedge) /当前点在内 if (f = 1) /前一点在外 clippointsycoutnum = winedge; /交点为新点 clippointsxcoutnum = sx + (cinpointsxi - sx) * (winedge - sy) / (cinpointsyi - sy); coutnum = coutnum + 1; f = 0; /当前点作为下一点的前一点(在内) clippointsxcoutnum = cinpointsxi; clippointsycoutnum = cinpointsyi; coutnum = coutnum + 1; /当前点为新点 else /当前点在外 if (f = 0) /前一点在内 clippointsycoutnum = winedge; / 交点为新点 clippointsxcoutnum = sx + (cinpointsxi - sx) * (winedge - sy) / (cinpointsyi - sy); coutnum = coutnum + 1; f = 1; sx = cinpointsxi; sy = cinpointsyi; break;case TOP:if (sy winedge) f = 1 ;/ 前一点在外 for(int i=0; icinnum; i+) if (cinpointsyi = winedge) /当前点在内 if (f = 1) /前一点在外 clippointsycoutnum = winedge; /交点为新点 clippointsxcoutnum = sx + (cinpointsxi - sx) * (winedge - sy) / (cinpointsyi - sy); coutnum = coutnum + 1; f = 0; /当前点作为下一点的前一点(在内) clippointsxcoutnum = cinpointsxi; clippointsycoutnum = cinpointsyi; coutnum = coutnum + 1;

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论