Sutherland-Hodgman算法(多边形裁剪)

Sutherland-Hodgman算法

Sutherland-Hodgman算法也叫逐边裁剪法,该算法是萨瑟兰德(I.E.Sutherland)和霍德曼(Hodgman)在1974年提出的。这种算法采用了分割处理、逐边裁剪的方法。

一,基本思想:

一次用窗口的一条边裁剪多边形。

考虑窗口的一条边以及延长线构成的裁剪线该线把平面分成两个部分:可见一侧;不可见一侧。多边形的各条边的两端点S、P。它们与裁剪线的位置关系只有四种

情况(1)仅输出1个顶点P;

情况(2)输出0个顶点;

情况(3)输出线段SP与裁剪线的1个交点I;

情况(4)输出线段SP与裁剪线的1个交点I和1个终点P

二、算法实现:

  1、已知:多边形顶点数组src,顶点个数n,
       定义新多边形顶点数组dest。

  2、赋初值:用变量flag来标识:
          0表示在内侧,1表示在外侧。

3、对多边形的n条边进行处理,对当前点号的考虑为:0~n-1。
   for(i=0;i<n;i++)
   {
    if(当前第i个顶点是否在边界内侧?)

  {
     if(flag!=0) /*前一个点在外侧吗?*/
     {
      flag=0;/*从外到内的情况,将标志置0,作为下一次循环的前一点标志*/
      (dest + j) =求出交点; /*将交点dest放入新多边形*/

j++;
     }
     
     (dest + j)= (src + i); /*将当前点srci放入新多边形*/

j++;
    }
    else
    {
     if(flag==0) /*前一个点在内侧吗?*/
     {
      flag=1;/*从内到外的情况,将标志置1,作为下一次循环的前一点标志*/
      (dest + j) =求出交点; /*将交点dest放入新多边形*/

j++;
     }
    }
    s= (src + i); /*将当前点作为下次循环的前一点*/
   }

三,算法特点:

  Sutherland-Hodgeman多边形裁剪算法具有一般性,被裁剪多边形可以是任意凸多边形或凹多边形,裁剪窗口不局限于矩形,可以是任意凸多边形。
  上面的算法是多边形相对窗口的一条边界进行裁剪的实现,对于窗口的每一条边界依次调用该算法程序,并将前一次裁剪的结果多边形作为下一次裁剪时的被裁剪多边形,即可得到完整的多边形裁剪程序。

  1. //点在有向线段那侧
  2. /*
  3. 向量叉积法
  4.   为简单计,测试点表示为P点。假设窗口边界方向为顺时针,如图中所示,对于其中任一边界向量,从向量起点A向终点B看过去:
  5.   如果被测试点P在该边界线右边(即内侧),AB×AP的方向与X-Y平面垂直并指向屏幕里面,即右手坐标系中Z轴的负方向。
  6.   反过来,如果P在该边界线的左边(即外侧),这时AB×AP的方向与X-Y平面垂直并指向屏幕外面,即右手坐标系中Z轴的正方向。
  7.   设:点P(x,y)、点A(xA,yA)、点B(xB,yB),
  8.     向量AB={(xB-xA),(yB-yA)},
  9.     向量AP={(x-xA),(y-yA)},
  10.   那么AB×AP的方向可由下式的符号来确定:
  11. V=(xB-xA)·(y-yA)-(x-xA)·(yB-yA)(3-14)
  12.   因此,当V≤0时,P在边界线内侧;
  13.      而V>0时,P在边界线外侧。
  14. */
  15. staticint_RtInSide(RtVectorvector,RtPointpoint)
  16. {
  17. return(vector.ep.x-vector.sp.x)*(point.y-vector.sp.y)-(vector.ep.y-vector.sp.y)*(point.x-vector.sp.x);
  18. }
  19. //多边形点必须是顺时针方向
  20. intrtPrunePSH(RtPoint*src,intnum,RtPoint**dest,int*total)
  21. {
  22. inti=0,j=0,k=-1,flag=0;
  23. RtPointstart,stop;//被剪裁多边形
  24. RtPointsp,ep;//剪裁窗口
  25. RtPoint*temp=NULL;
  26. temp=(RtPoint*)malloc(sizeof(RtPoint)*3*(*total));
  27. if(temp==NULL)return-1;
  28. sp=*(src+num-1);
  29. for(i=0;i<num;i++)//剪裁窗口
  30. {
  31. ep=*(src+i);
  32. start=*((*dest)+*total-1);
  33. flag=_RtInSide(rtVector(sp,ep),start)>0?0:1;
  34. for(j=0;j<*total;j++)//被剪裁的多边形
  35. {
  36. stop=*((*dest)+j);
  37. if(_RtInSide(rtVector(sp,ep),stop)<=0)//当前第i个顶点是否在边界内侧
  38. {
  39. if(flag==0)/*前一个点在外侧吗?*/
  40. {
  41. flag=1;/*从外到内的情况,将标志置0,作为下一次循环的前一点标志*/
  42. k++;
  43. CRtPoint<double>point;
  44. CRtPoint<int>st(sp.x,sp.y),et(ep.x,ep.y);
  45. CRtLine<int>v1(st,et);
  46. st.SetData(start.x,start.y);
  47. et.SetData(stop.x,stop.y);
  48. CRtLine<int>v2(st,et);
  49. v2.Intersect(v1,point);
  50. (temp+k)->x=point[0];/*将交点放入新多边形*/
  51. (temp+k)->y=point[1];
  52. }
  53. k++;
  54. *(temp+k)=stop;/*将当前点pi放入新多边形*/
  55. }
  56. else
  57. {
  58. if(0!=flag)/*前一个点在内侧吗?*/
  59. {
  60. flag=0;/*从内到外的情况,将标志置1,作为下一次循环的前一点标志*/
  61. k++;
  62. CRtPoint<double>point;
  63. CRtPoint<int>st(sp.x,sp.y),et(ep.x,ep.y);
  64. CRtLine<int>v1(st,et);
  65. st.SetData(start.x,start.y);
  66. et.SetData(stop.x,stop.y);
  67. CRtLine<int>v2(st,et);
  68. v2.Intersect(v1,point);
  69. (temp+k)->x=point[0];/*将交点放入新多边形*/
  70. (temp+k)->y=point[1];
  71. }
  72. }
  73. start=stop;/*将当前点作为下次循环的前一点*/
  74. }
  75. sp=ep;
  76. *total=k+1;
  77. memcpy(*dest,temp,sizeof(RtPoint)*(*total));
  78. k=-1;
  79. }
  80. return0;
  81. }

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Sutherland-Hodgeman多边形裁剪算法是一种计算机图形学中常用的算法,用于将一个多边形裁剪成另一个多边形。该算法的基本思想是将待裁剪的多边形按照裁剪边界的每条边进行切割,得到被裁剪后的多边形。该算法的优点是简单易懂,适用于任意多边形的裁剪。 ### 回答2: Sutherland-Hodgeman(苏瑟兰-霍吉曼)多边形裁剪算法是一种常用于计算机图形学中的算法,用于裁剪一个多边形并输出一个新的多边形。 该算法是基于对多边形的顶点进行逐个的处理的,处理结果就是新的多边形的顶点集合。在处理的过程中,每个顶点都要被分类为来自于裁剪区域内部或外部,以便将相应的线段保存下来。 Sutherland-Hodgeman算法的核心是,对于原多边形的每条边,找到与裁剪区域相交的部分,并且将相交的部分记录在输出多边形的顶点列表中。同时,如果原多边形的一条边完全位于裁剪区域的内部,那么这条边完全被保留下来,加入输出多边形的顶点列表中。 在进行多边形裁剪时,Sutherland-Hodgeman算法需要两个多边形,裁剪多边形和剪切多边形。首先,裁剪多边形的边缘被考虑,与剪切多边形的边缘相交的部分被加入输出多边形的边缘集合中,而被裁剪的部分不加入。其次,保留在之前阶段的边缘被检查,如果一个顶点在裁剪多边形之外,则该点被裁剪,如果其在裁剪多边形内,则该顶点被保留。 总之,Sutherland-Hodgeman算法可用于多边形的裁剪,它是非常高效而且直观的算法。在实际的计算机图形学应用中,这一算法通常与其他技术一起使用,以便更好地增强裁剪效果。 ### 回答3: Sutherland-Hodgeman多边形裁剪算法是一种用于计算二维多边形裁剪算法,它通过剪裁多边形的每个边来实现。它分为四个步骤:初始化、裁剪边、填充裁剪后的多边形、输出裁剪后的多边形。 首先,该算法将窗口边缘与多边形边缘相交的点作为剪裁边缘。具体操作是将多边形的每一条边与窗口的每一条边相交,得到一系列相交点。这些交点分别按照一定顺序排列,根据绕射规则找到多边形上的顶点并将其保存。 其次,算法通过将相邻的顶点与裁剪窗口的边缘相交交叉点连接,形成一个多边形外观。通过这种连结方式裁剪后,新生成的多边形被覆盖使用新的顶点,作为下一个窗口边缘和多边形边缘的交点。 然后,把新的多边形用填色算法填充成新的多边形。 最后,将裁剪后的多边形输出。 这种算法的优点在于它容易实现,简单易懂,并且在计算时只需要使用基本的几何定理。这种算法可以很容易地扩展到三维空间,因为它在处理多边形时只使用了它们在二维平面上的投影。然而,它的缺点也很明显:它不能处理多边形内部的裁剪,因为它的操作只考虑了顶点和边缘。定义复合窗体可以用具有几何意义的复合形来覆盖该不足之处。另外,如果多边形密集附近,一些顶点可能在相邻的边缘中出现,导致产生奇怪的视觉效果。这种问题可以通过对算法进行修改来解决。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值