Sutherland-Hodgeman多边形裁剪算法思想:

  每次用窗口的一条边界(包括延长线)对要裁剪的多边形进行裁剪,裁剪时,顺序地测试多边形各顶点,保留边界内侧的顶点,删除外侧的顶点,同时,适时地插入新的顶点:即交点和窗口顶点,从而得到一个新的多边形顶点序列。

  然后以此新的顶点序列作为输入,相对第二条窗边界线进行裁剪,又得到一个更新的多边形顶点序列。

  依次下去,相对于第三条、第四条边界线进行裁剪,最后输出的多边形顶点序列即为所求的裁剪好了的多边形。如下图所示。

新的多边形顶点序列产生规则:

  在用窗口一条边界及其延长线裁剪一个多边形时,该边界线把平面分成两个部分:一部分称为边界内侧;另一部分称为边界外侧。

  如下图所示,依序考虑多边形的各条边。假设当前处理的多边形的边为SP(箭头表示顺序关系,S为前一点,P为当前点),边SP与裁剪线的位置关系只有下面四种情况:

  1. S在外侧,P在内侧。则交点 I、当前点P保存到新多边形中。                                                                    
  2. S、P均在内侧,则当前点P保存到新多边形中。                                                                                      
  3. S在内侧,P在外侧。则交点 I 保存到新多边形中。                                                                                 
  4. S、P均在外侧。则没有点被保存到新多边形中。                                                                         

核心代码:

def poly_clip(self, rect):print(len(self.vertex_pts))vsold = copy.deepcopy(self.vertex_pts)vsnew = []'''对左边界进行操作'''flag = 1 #前一个点S的内外标志,用变量flag来标识:0表示在内侧,1表示在外侧。vp1 = vsold.pop(0)if (vp1.x() >= rect.left()):flag = 0vsold.append(vp1)for i in range(len(vsold)):# 对于左边界,判断第i个顶点是否在边界内vp2 = vsold.pop(0)#当前第i个顶点在边界内侧if (vp2.x() >= rect.left()):if flag!=0: #前一个点在外侧flag = 0 #将标志置0,作为下一次循环的前一点标志vsnew.append(QPoint(rect.left(),vp2.y() + (vp1.y() - vp2.y()) * (rect.left() - vp2.x()) / (vp1.x() - vp2.x())))vsnew.append(vp2)#当前第i个顶点在边界外侧else:if flag == 0: #前一个点在内侧flag = 1 #将标志置0,作为下一次循环的前一点标志vsnew.append(QPoint(rect.left(),vp2.y() + (vp1.y() - vp2.y()) * (rect.left() - vp2.x()) / (vp1.x() - vp2.x())))vp1=vp2 #将当前点作为下次循环的前一点'''对上边界进行操作'''vsold = copy.deepcopy(vsnew)vsnew = copy.deepcopy([])flag = 1vp1 = vsold.pop(0)if (vp1.y() >= rect.top()):flag = 0vsold.append(vp1)for i in range(len(vsold)):vp2 = vsold.pop(0)if (vp2.y() >= rect.top()):if flag != 0:flag = 0vsnew.append(QPoint(vp2.x() + (vp1.x() - vp2.x()) * (rect.top() - vp2.y()) / (vp1.y() - vp2.y()), rect.top()))vsnew.append(vp2)else:if flag == 0:flag = 1vsnew.append(QPoint(vp2.x() + (vp1.x() - vp2.x()) * (rect.top() - vp2.y()) / (vp1.y() - vp2.y()), rect.top()))vp1 = vp2'''对右边界进行操作'''vsold = copy.deepcopy(vsnew)vsnew = copy.deepcopy([])flag = 1vp1 = vsold.pop(0)if (vp1.x() <= rect.right()):flag = 0vsold.append(vp1)for i in range(len(vsold)):vp2 = vsold.pop(0)if (vp2.x() <= rect.right()):if flag != 0:flag = 0vsnew.append(QPoint(rect.right(), vp2.y() + (vp1.y() - vp2.y()) * (rect.right() - vp2.x()) / (vp1.x() - vp2.x())))vsnew.append(vp2)else:if flag == 0:flag = 1vsnew.append(QPoint(rect.right(), vp2.y() + (vp1.y() - vp2.y()) * (rect.right() - vp2.x()) / (vp1.x() - vp2.x())))vp1 = vp2'''对下边界进行操作'''vsold = copy.deepcopy(vsnew)vsnew = copy.deepcopy([])flag = 1vp1 = vsold.pop(0)if (vp1.y() <= rect.bottom()):flag = 0vsold.append(vp1)for i in range(len(vsold)):vp2 = vsold.pop(0)if (vp2.y() <= rect.bottom()):if flag != 0:flag = 0vsnew.append(QPoint(vp2.x() + (vp1.x() - vp2.x()) * (rect.bottom() - vp2.y()) / (vp1.y() - vp2.y()),rect.bottom()))vsnew.append(vp2)else:if flag == 0:flag = 1vsnew.append(QPoint(vp2.x() + (vp1.x() - vp2.x()) * (rect.bottom() - vp2.y()) / (vp1.y() - vp2.y()),rect.bottom()))vp1 = vp2polyclip = QPolygon(vsnew)return polyclip

算法特点:

  Sutherland-Hodgeman多边形裁剪算法具有一般性,被裁剪多边形可以是任意凸多边形或凹多边形,裁剪窗口不局限于矩形,可以是任意凸多边形(这里代码中我只用矩形举例,大家可以踊跃尝试)。

加上UI界面实现效果:

PS: 如需参考完整代码,请移步:  https://download.csdn.net/download/qq_42185999/11958148  进行下载

Sutherland-Hodgeman 逐次裁剪法(多边形裁剪)相关推荐

  1. 【学习记录】图片行列切割与子图行列拼接之中央裁剪法

    写在前面 :本博客仅作记录学习之用,部分图片来自网络,如需使用请注明出处,同时如有侵犯您的权益,请联系删除! 文章目录 前言 分割与拼接 拼接问题 分割和拼接的用途 函数实现 切割函数 拼接函数 中央 ...

  2. java实现线段裁剪算法,多边形裁剪算法java

    Weiler-Atherton 任意多边形裁剪 Sutherland-Hodgeman 算法解决了裁剪窗口为凸多边形窗口的问题,但一些应用需要涉及 任意多边形窗口(含凹多边形窗口)的裁剪.Weiler ...

  3. 多边形裁剪一:Sutherland-Hodgman算法

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

  4. 计算机图形学 多边形裁剪

    多边形裁剪 多边形裁剪 Sutherland Hodgeman多边形裁剪 新点的产生与旧点的保留及其二者的输出确定 第一点S在不可见侧,第二点P在可见侧 第一点S和第二点P都在可见侧 第一点S在可见侧 ...

  5. 图形学学习笔记4——平面图形裁剪

    平面图形裁剪 基础概念 空间中的图形尺寸任意,显示设备尺寸有限,如何判断图形哪些部分在显示区外,哪些部分在显示区内这一过程就是对图形的裁剪. 当有大量图形需要显示时,裁剪就很耗时,在软件裁剪速度无法达 ...

  6. 计算机图形学 裁剪算法

    裁剪算法 直线裁剪算法 暴力裁剪法 点的裁剪 线的裁剪 判断直线段与窗口的关系 三个算法 Cohen Sutherland算法/编码裁剪算法--通过二进制编码及运算,对直线与窗口的关系进行分类. 处理 ...

  7. 关闭裁剪功能_4个图片裁剪技巧,瞬间看出Word大神与小白的差距!

    当我们用Word对长篇文档进行排版的时候,难免会插入一些图片,有时插入的图片大小尺寸不符合要求,就需要我们手动去裁剪调整.今天,这篇文章主要是介绍文档排版时,图片大小尺寸的设置方法,非常实用哦!Wor ...

  8. 多边形分解成三角形算法, 耳切法

    https://blog.csdn.net/zzq61974/article/details/87635763 https://www.cnblogs.com/xignzou/p/3721494.ht ...

  9. PCL实现选框裁剪点云

    PCL实现选框裁剪点云 需求:在屏幕上点击画出多边形,裁剪对应框内的点云. 实现:按"x" 绘制多边形 再按"x"裁剪 实现算法来自 PCL裁剪之多边形裁剪 一 ...

最新文章

  1. 使用W3C XML Schema
  2. android Anr Input类型系统源码解析
  3. h5的语义化部分_H5 部分新语义化标签
  4. string包含某个字符串_Tcl字符串操作基础2
  5. 车牌识别系统,并语音读出识别结果,MATLAB仿真
  6. 两大主流Web服务器之分析与对比
  7. 使用Infinispan创建自己的Drools和jBPM持久性
  8. 查询结果取交集_Elasticsearch 查询过程中的 prefilter 原理
  9. mysql varchar 效率_由MySQL中char和varchar效率想到的
  10. 酷安电脑版_2020年末 平板电脑购买推荐
  11. Spring强制使用CGLIB代理事务
  12. vue list数组合并和插入数据
  13. Numpy根据某一列进行排序
  14. setactive隐藏之后无法显示_U盘里面有文件但是看不见无法显示文件的解决方法...
  15. C#图片处理(裁剪,缩放,清晰度,水印)
  16. Python中IO编程-StringIO和BytesIO
  17. 基于MATLAB 的X-CT图像重建计算机仿真实验研究实验
  18. 节奏大师服务器不稳定,《节奏大师》停服是怎么回事 暂停运营维护优化
  19. 联盛德 HLK-W806 (十): 在 CDK IDE开发环境中使用WM-SDK-W806
  20. 微擎打开导航提示该网页无法正常运作

热门文章

  1. office套件_OfficeSuite v4.9免费专业Office办公套件
  2. softmax 导数推导
  3. Indesign快捷键大全
  4. Prometheus GPU 监控
  5. 第五章 主生产计划MPS 第1~3节 计划方案、MPS计划参数
  6. 用计算机写数字很,机密、秘密级计算机信息系统采用的口令应由大小写英文字母、数字、特殊字符中两者..._考试资料网...
  7. C++ 牛客网做题笔记【500题总结】
  8. 如何清除远程桌面访问痕迹,删除远程桌面缓存记
  9. printf(“%.1f\n“,8/5)的输出结果为什么是0.000000
  10. 蓝牙指环扫描枪【心科码】