您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 管理学资料 > 多边形裁剪的Sutherland—Hodgman算法(计算机图形学)
多边形裁剪的Sutherland—Hodgman算法1.Sutherland—Hodgman多边形裁剪算法思想该算法的基本思想是每次用窗口的一条边界及其延长线来裁剪多边形的各边。多边形通常由它的顶点序列来表示,经过裁剪规则针对某条边界裁剪后,结果形成新的顶点序列,又留待下条边界进行裁剪,…,直到窗口的所有边界都裁剪完毕,算法形成最后的顶点序列,才是结果多边形(它可能构成一个或多个多边形)。当多边形一个顶点Pi相对于窗口某条边界及其延长线进行剪裁时,不外乎下列四种情况(即裁剪规则):1、顶点Pi在内侧,前一顶点Pi-1也在内侧,则将Pi纳入新的顶点序列;2、顶点Pi在内侧,前一顶点Pi-1在外侧,则先求交点Q,再将Q、Pi依次纳入新的顶点序列;3、顶点Pi在外侧,前一顶点Pi-1在内侧,则先求交点Q,再将Q纳入新的顶点序列;4、顶点Pi与前一顶点Pi-1均在外侧,则顶点序列中不增加新的顶点。2.Sutherland—Hodgman多边形裁剪算法步骤考虑多边形相对于一条边界及其延长线进行裁剪的算法:1.从主函数得到待裁剪多边形的顶点序列P[][2]、顶点序列数n、窗口一条边界参数xl(假如为矩形窗口的左边界);2.赋初值:将顶点序列中的最后一个顶点赋给前一顶点S;设置初始标志flag:if(S在边界内侧)flag=0;elseflag=1;设新的顶点序列数j=0;3.对多边形各顶点进行裁剪规则处理,结果放入新的多边形顶点序列Q[][2]中:for(对第一个顶点直到最后一个顶点,逐一处理){if(Pi在边界内侧){if(flag!=0){flag=0;求交点并放入新的多边形顶点序列Qj中;j++;}将当前顶点放入新的多边形顶点序列Qj中:Qj=Pi;j++;}else{if(flag==0){flag=1;求交点并放入新的多边形顶点序列Qj中;j++;}}将当前顶点赋给S:S=Pi;}4.做返回准备:将新的多边形顶点序列Q又逐一放回原多边形顶点序列P中:P=Q;将新的多边形顶点数j放回原多边形顶点数n中:n=j;////////////////////////////////////////////////////////////////////////////////////////-----多边形裁剪的Sutherland—Hodgman算法---------///////////////////////////////////////////////////////////////////////////////////////voidCMyClip_AView::ClipedgeL(CPointpolypoint[],CPointclipwindow[],UINTpolynum)/*其中参数polypoint[]为多边形顶点,clipwindow[]为裁剪窗口顶点,polynum为多边形顶点数目*/{//找出裁剪窗口边界longxl,xr,yt,yb;UINTi;xl=clipwindow[0].x;xr=clipwindow[0].x;yt=clipwindow[0].y;yb=clipwindow[0].y;for(i=1;i=4;i++){if(xlclipwindow[i].x)xl=clipwindow[i].x;if(xrclipwindow[i].x)xr=clipwindow[i].x;if(ybclipwindow[i].y)yb=clipwindow[i].y;if(ytclipwindow[i].y)yt=clipwindow[i].y;}//CPointB[Polygon_Num],C[Polygon_Num];UINTm_nA,m_nB;intx,y;longtem1,tem2;m_nA=polynum;/*记载原始多边形顶点顶点个数*/m_nB=0;/*记载新生成多边形顶点顶点个数*/for(i=0;im_nA;i++){if(polypoint[i].xxl&&polypoint[i+1].xxl)/*判断的多边形边两个端点都在外部,不做处理*/{continue;/*如果是这种情况,那么就对继续对下一条多边形边作判断,也就是说下面的判断不用做了*/}if(polypoint[i].x=xl&&polypoint[i+1].x=xl)/*边两个端点都在内部,保留*//*因为每个保留的点在数组中只出现一次,且下一次判断时第二个端点一定会要取到,因此只保留的两个点中的第一个*/{B[m_nB].x=polypoint[i].x;B[m_nB].y=polypoint[i].y;m_nB=m_nB+1;continue;}if(polypoint[i].xxl&&polypoint[i+1].x=xl)/*边两个端点起点在外部,终点在内部,求交点,然后交点,终点都应该送入临时数组*/{/*保留交点*/x=xl;tem1=(xl-polypoint[i].x);//tem2=(xl-x1)*dy/dx+y1;//y/x=dy/dx----y=x*dy/dxtem2=tem1*(polypoint[i+1].y-polypoint[i].y)/(polypoint[i+1].x-polypoint[i].x)+polypoint[i].y;y=tem2;B[m_nB].x=x;B[m_nB].y=y;m_nB=m_nB+1;continue;}if(polypoint[i].x=xl&&polypoint[i+1].xxl)/*起点在内部,终点在外,求交点,然后起点,交点送入临时数组*/{/*保留内部点*/B[m_nB].x=polypoint[i].x;B[m_nB].y=polypoint[i].y;m_nB=m_nB+1;/*保留交点*/x=xl;tem1=(xl-polypoint[i].x);tem2=tem1*(polypoint[i+1].y-polypoint[i].y)/(polypoint[i+1].x-polypoint[i].x)+polypoint[i].y;y=tem2;B[m_nB].x=x;B[m_nB].y=y;m_nB=m_nB+1;continue;}}//把第一个点的数据拷贝到最后//形成裁剪后的多边形if(i==m_nA){B[m_nB]=B[0];}//下------------------m_nA=0;for(i=0;im_nB;i++){if(B[i].yyb&&B[i+1].yyb)//两个点全在下方{continue;//下一条边}if(B[i].y=yb&&B[i+1].y=yb)//p1,p2都在yb上方{C[m_nA].x=B[i].x;C[m_nA].y=B[i].y;m_nA++;continue;}if(B[i].yyb&&B[i+1].y=yb)//p1在下,P2在上,留交点,外->内{y=yb;tem1=yb-B[i].y;//tem2=x1+(yb-y1)*dx/dytem2=tem1*(B[i+1].x-B[i].x)/(B[i+1].y-B[i].y)+B[i].x;x=tem2;C[m_nA].x=x;C[m_nA].y=y;m_nA++;continue;}if(B[i].y=yb&&B[i+1].yyb)//p1在上方,P2在下方,留P1和交点,内-外{//savep1C[m_nA].x=B[i].x;C[m_nA].y=B[i].y;m_nA++;//留交点y=yb;tem1=yb-B[i].y;//tem2=x1+(yb-y1)*dx/dytem2=tem1*(B[i+1].x-B[i].x)/(B[i+1].y-B[i].y)+B[i].x;x=tem2;C[m_nA].x=x;C[m_nA].y=y;m_nA++;continue;}}//形成第二次裁剪多边形if(i==m_nB){C[m_nA]=C[0];}//右------------------m_nB=0;for(i=0;im_nA;i++){if(C[i].xxr&&C[i+1].xxr)//P1,P2都在右方--gonext{continue;}if(C[i].x=xr&&C[i+1].x=xr)//P1,P2都在左方,留P1{B[m_nB].x=C[i].x;B[m_nB].y=C[i].y;m_nB++;continue;}if(C[i].xxr&&C[i+1].x=xr)//P1在右方,P2在左方,留交点{x=xr;tem1=C[i].x-xr;tem2=C[i].y-tem1*(C[i+1].y-C[i].y)/(C[i+1].x-C[i].x);y=tem2;B[m_nB].x=x;B[m_nB].y=y;m_nB++;continue;}if(C[i].x=xr&&C[i+1].xxr)//P1在内,P2在外,留P1和交点{//savep1B[m_nB].x=C[i].x;B[m_nB].y=C[i].y;m_nB++;//save交点x=xr;tem1=C[i].x-xr;tem2=C[i].y-tem1*(C[i+1].y-C[i].y)/(C[i+1].x-C[i].x);y=tem2;B[m_nB].x=x;B[m_nB].y=y;m_nB++;continue;}}//三次裁剪后的新多边形if(i==m_nA){B[m_nB]=B[0];}//上-------------------m_nA=0;for(i=0;im_nB;i++){if(B[i].yyt&&B[i+1].yyt)//p1,p2都在上方,next{continue;}if(B[i].y=yt&&B[i+1].y=yt)//p1,p2都在下方,留P1{C[m_nA].x=B[i].x;C[m_nA].y=B[i].y;m_nA++;continue;}if(B[i].yyt&&B[i+1].y=yt)//P1在上方,P2在下方外->内,留交点{y=yt;tem1=B[i].y-yt;//tem2=x1+(yb-y1)*dx/dytem2=B[i].x-tem1*(B[i+1].x-B[i].x)/(B[i+1].y-B[i].y);x=tem2;C[m_nA].x=x;C[m_nA].y=y;m_nA++;continue;}if(B[i].y=yt&&B[i+1].yyt)//P1在下方,P2在上方,内->外,留P1和交点{//savep1,,,C[m_nA].x=B[i].x;C[m_nA].y=B[i].y;m_nA++;//save交点y=yt;tem1=B[i].y-yt;//tem2=x1+(yb-y1)*dx/dytem2=B[i].x-tem1*(B[i+1].x-B[i].x)/(B[i+1].y-B[i].y);x=tem2;C[m_nA].x=x;C[m_nA].y=y;m_nA++;continue;}}//形成裁剪后的多边形if(i==m_nB){C[m_nA]=C[0];}CClientDCdc(this);CPentempen;tempen.CreatePen(PS_SOLID,1,RGB(255,0,0));dc.SelectObject(tempen);dc.MoveTo(C[0]);for(i=1;i=m_nA;i++){dc.LineTo(C[i]);}}//.....
本文标题:多边形裁剪的Sutherland—Hodgman算法(计算机图形学)
链接地址:https://www.777doc.com/doc-5636936 .html