计算机图形学(六)多边形裁剪Sutherland-Hodgeman算法讲解与源代码

因为最近CSDN上传资源出现问题,无法上传,等可以上传之后再给出下载地址。

源码下载:点我下载

首先讲一下算法的原理:

Sutherland-Hodgeman算法:
基本思想是一次用窗口的一条边裁剪多边形。
考虑窗口的一条边以及延长线构成的裁剪线,该线把平面分成两个部分:可见一侧;不可见一侧。
多边形的各条边的两端点S、P。它们与裁剪线的位置关系只有四种,

如图:

S、P与裁剪线的位置关系 对于情况(1)仅输出顶点P;情况(2)输出0个顶点;情况(3)输出线段SP与裁剪线的交点I;情况(4)输出线段SP与裁剪线的交点I和终点P 

上述算法仅用一条裁剪边对多边形进行裁剪,得到一个顶点序列,作为下一条裁剪边处理过程的输入。
 
对于每一条裁剪边,只是判断点在窗口哪一侧改变求线段SP与裁剪边的交点的算法。

算法的实现过程还是比较复杂的。

代码过程:

1首先画一个多边形,然后记录边数和边的2个顶点。

2.运行算法。

算法的实现:

 

 
  1. typedef struct 

  2. {

  3. int x;

  4. int y;

  5. }Vertex;

  6. typedef  struct   

  7. {   

  8. int   xmin;    

  9. int   xmax;    

  10. int   ymin;    

  11. int   ymax;   

  12. }   

  13. rectangle;

 
  1. typedef Vertex Edge[2];

  2. typedef Vertex VertexArray[MAX];

  3. VertexArray InVertexArray;

  4. VertexArray OutVertexArray;

  5. Edge ClipBoundary[4];

  6. rectangle rect1;

  7. int InLength;

  8. int OutLength;


 

 

 

 
  1. void CClipingView::InitClipBoundary(rectangle rect1)

  2. {

  3. //InitRectangle();

  4. ClipBoundary[0][0].y=YT;

  5. ClipBoundary[0][0].x=XL;

  6. ClipBoundary[0][1].y=YT;

  7. ClipBoundary[0][1].x=XR;

  8. ClipBoundary[1][0].x=XR;

  9. ClipBoundary[1][0].y=YT;

  10. ClipBoundary[1][1].x=XR;

  11. ClipBoundary[1][1].y=YB;

  12. ClipBoundary[2][0].x=XR;

  13. ClipBoundary[2][0].y=YB;

  14. ClipBoundary[2][1].x=XL;

  15. ClipBoundary[2][1].y=YB;

  16. ClipBoundary[3][0].x=XL;

  17. ClipBoundary[3][0].y=YB;

  18. ClipBoundary[3][1].x=XL;

  19. ClipBoundary[3][1].y=YT;

  20. }

 
  1. void CClipingView::SutherlandHodgmanPolygonClip(int InLength, VertexArray InVertexArray, int *OutLength, VertexArray OutVertexArray, Edge ClipBoundary)

  2. {

  3. Vertex  *s,*p,I;   

  4.     int j;   

  5.     *OutLength=0;   

  6.     s=&(InVertexArray[InLength-1]);   

  7.     for(j=0;j<InLength;j++)   

  8.     {   

  9.         p=&(InVertexArray[j]);   

  10.         if(Inside(p,ClipBoundary))   

  11.         {   

  12.             if(Inside(s,ClipBoundary))   

  13.                 Output(p,OutLength,OutVertexArray);   

  14.             else   

  15.             {   

  16.                 Intersect(s,p,ClipBoundary,&I);   

  17.                 Output(&I,OutLength,OutVertexArray);   

  18.                 Output(p,OutLength,OutVertexArray);   

  19.             }   

  20.         }   

  21.         else   

  22.             if(Inside(s,ClipBoundary))   

  23.             {   

  24.                 Intersect(s,p,ClipBoundary,&I);   

  25.                 Output(&I,OutLength,OutVertexArray);   

  26.             }   

  27.         s=p;   

  28.     }  

  29. }

 
  1. bool CClipingView::Inside(Vertex *textVertex, Edge ClipBoundary)

  2. {

  3. if(ClipBoundary[1].x>ClipBoundary[0].x)//裁剪边为窗口的下边   

  4.     {   

  5.         if(textVertex->y>=ClipBoundary[0].y)   

  6.             return TRUE;   

  7.     }   

  8.     else    

  9.         if(ClipBoundary[1].x<ClipBoundary[0].x)//裁剪边为窗口的上边   

  10.         {   

  11.             if(textVertex->y<=ClipBoundary[0].y)   

  12.                 return TRUE;   

  13.         }   

  14.         else   

  15.             if(ClipBoundary[1].y>ClipBoundary[0].y)//裁剪边为窗口的右边   

  16.             {   

  17.                 if(textVertex->x<=ClipBoundary[0].x)   

  18.                     return TRUE;   

  19.             }   

  20.             else    

  21.                 if(ClipBoundary[1].y<ClipBoundary[0].y)//裁剪边为窗口的左边   

  22.                 {   

  23.                         if(textVertex->x>=ClipBoundary[0].x)   

  24.                         return TRUE;   

  25.                 }   

  26.     return FALSE; 

  27. }

 
  1. void CClipingView::Intersect(Vertex *s, Vertex *p, Edge ClipBoundary, Vertex *I)

  2. {

  3. if(ClipBoundary[0].y==ClipBoundary[1].y)   

  4.     {              

  5.         I->y=ClipBoundary[0].y;         

  6.         I->x=s->x+(ClipBoundary[0].y-s->y)*(p->x-s->x)/(p->y-s->y);       

  7.     }   

  8.     else   

  9.     {      

  10.         I->x=ClipBoundary[0].x;        

  11.         I->y=s->y+(ClipBoundary[0].x-s->x)*(p->y-s->y)/(p->x-s->x);   

  12.     }  

}

 

 

 
  1. void CClipingView::All_SutherlandHodgmanPolygonClip()

  2. {

  3. int i;

  4. InitClipBoundary(rect1);

  5. SutherlandHodgmanPolygonClip(InLength,InVertexArray,&OutLength,OutVertexArray,ClipBoundary[0]);//裁剪边为下

  6. InLength=OutLength;

  7. for(i=0;i<=OutLength-1;i++)

  8. {

  9. InVertexArray[i].x=OutVertexArray[i].x;

  10. InVertexArray[i].y=OutVertexArray[i].y;

  11. }

  12. OutLength=0;

  13. SutherlandHodgmanPolygonClip(InLength,InVertexArray,&OutLength,OutVertexArray,ClipBoundary[1]);//裁剪边为右

  14. InLength=OutLength;

  15. for(i=0;i<=OutLength-1;i++)

  16. {

  17. InVertexArray[i].x=OutVertexArray[i].x;

  18. InVertexArray[i].y=OutVertexArray[i].y;

  19. }

  20. OutLength=0;

  21. SutherlandHodgmanPolygonClip(InLength,InVertexArray,&OutLength,OutVertexArray,ClipBoundary[2]);//裁剪边为上

  22. InLength=OutLength;

  23. for(i=0;i<=OutLength-1;i++)

  24. {

  25. InVertexArray[i].x=OutVertexArray[i].x;

  26. InVertexArray[i].y=OutVertexArray[i].y;

  27. }

  28. OutLength=0;

  29. SutherlandHodgmanPolygonClip(InLength,InVertexArray,&OutLength,OutVertexArray,ClipBoundary[3]);

  30. InitPloygon2();

  31. //Invalidate();

  32. }


其中只给出了一些核心的算法和数据结构。

 

想要了解更多可以下载我的源码时时的运行或进行DeBug来查看代码的具体情况。

如果有什么不多的地方还请指出。让我们一起学习,一起进步。谢谢。

  • 3
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值