多边形裁剪算法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
多边形裁剪的 Sutherland — Hodgman 算法
1>. Sutherland — Hodgman 多边形裁剪算法思想 该算法的基本思想是每次用窗口的一条边界及其延长线来裁剪多边形的各边。 多边形通常由 它的顶点序列来表示, 经过裁剪规则针对某条边界裁剪后, 结果形成新的顶点序列, 又留待 下条边界进行裁剪,…,直到窗口的所有边界都裁剪完毕,算法形成最后的顶点序列, 才是 结果多边形(它可能构成一个或多个多边形) 当多边形一个顶点 裁剪规则): 1 、顶点
2、 顶点 列;
3、 顶点
4、 顶点 Pi 在内侧, Pi 在内
侧, O
Pi 相对于窗口某条边界及其延长线进行剪裁时, 不外乎下列四种情况 (即 前一顶点 前一顶点 前一顶点 Pi-1 也在内侧,则将 Pi 纳入新的顶点序列; Pi-1在外侧,则先求交点 Q ,再将Q 、Pi 依次纳入新的顶点序 Pi 在外侧, Pi 与前一顶点 Pi-1 均在外侧,则顶点序列中不增加新的顶点。
Pi-1在内侧,则先求交点 Q ,再将Q 纳入新的顶点序列; 2>. Sutherland — Hodgman 多边形裁剪算法步骤 考虑多边形相对于一条边界及其延长线进行裁剪的算法: 1.从主函数得到待裁剪多边形的顶点序列 P[][2]、顶点序列数n 、窗口一条边界参数 xl (假 如为矩形窗口的左边界) ; 2.赋初值:将顶点序列中的最后一个顶点赋给前一顶点 设置初始标志 flag :
if (S 在边界内侧 )flag=0; else flag=1 ; 设新的顶点序列数 j=0; 3.对多边形各顶点进行裁剪规则处理,结果放入新的多边形顶点序列 for (对第一个顶点直到最后一个顶点, { if
(Pi 在边界内侧 ) {
if (flag!=0) { flag=0; 求交点并放入新的多边形顶点序列 逐一处理) Qj 中;
S ;
Q[][2]
中: 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 算法
///////////////////////////////////////////////////////////////////////////////////// void CMyClip_AView::ClipedgeL(CPoint polypoint[], CPoint clipwindow[], UINT polynum) /*其中参数polypoint[] 为多边形顶点,clipwindow[] 为裁剪窗口顶点,polynum 为多边形顶点数目*/
//找出裁剪窗口边界
long xl,xr,yt,yb;
UINT i;
xl=clipwindow[0].x;
xr=clipwindow[0].x;
yt=clipwindow[0].y;
yb=clipwindow[0].y;
for(i=1;i<=4;i++)
{
if(xl>clipwindow[i].x) xl=clipwindow[i].x;
if(xr xr=clipwindow[i].x; if(yb>clipwindow[i].y) yb=clipwindow[i].y; if(yt // CPoint B[Polygon_Num],C[Polygon_Num]; UINT m_nA,m_nB; int x,y; long tem1,tem2; m_nA=polynum;/* 记载原始多边形顶点顶点个数 */ m_nB=0;/* 记载新生成多边形顶点顶点个数 */ for(i=0;i { if(polypoint[i].x 部,不做处理 */ { 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].x 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/dx 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(polypoint[i].x>=xl && polypoint[i+1].x { /* 保留内部点 */ 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); 边两个端点都在内部,保留 */ 且下一次判断时第二个端点一 边两个端点起点在外部,终点在 */ 起点在内部, 终点在外, 求交点,