Weiler-Athenton算法
与Sutherland-Hodgeman算法的比较:
Sutherland-Hodgeman算法解决了裁剪窗口为凸多边形窗口的问题,但一些应用需要涉及任意多边形窗口(含凹多边形窗口)的裁剪,就可能会出错。而Weiler-Atherton多边形裁剪算法正是满足这种要求的算法。
如下图,对凹多边形 P1P2P3P4 进行裁剪,Sutherland-Hodgeman算法会得到如下中间图形,但正确的裁剪结果应该为最右边的图。
算法描述:
在算法中,裁剪窗口、被裁剪多边形可以是任意多边形:凸的、凹的(内角大于180o)、甚至是带有内环的(子区),见下图。
裁剪窗口和被裁剪多边形处于完全对等的地位,这里我们称:
1、被裁剪多边形为主多边形,记为A;
2、裁剪窗口为裁剪多边形,记为B。
主多边形A和裁剪多边形B的边界将整个二维平面分成了四个区域:
1、A∩B(交:属于A且属于B);
2、A-B(差:属于A不属于B);
3、B-A(差:属于B不属于A);
4、A∪B(并:属于A或属于B,取反;即:不属于A且不属于B)。
内裁剪:即通常意义上的裁剪,取图元位于窗口之内的部分,结果为A∩B。
外裁剪:取图元位于窗口之外的部分,结果为A-B。
观察下图,不难发现裁剪结果区域的边界由被裁剪多边形 A 的部分边界和裁剪窗口 B 的部分边界两部分构成,并且在交点处边界发生交替,即由被裁剪多边形 A 的边界转至裁剪窗口 B 的边界,或者反之。
由于多边形构成一个封闭的区域,所以,如果被裁剪多边形和裁剪窗口有交点,则交点成对出现。这些交点分成两类:
一类称 “进” 点,即被裁剪多边形由此点进入裁剪窗口,如图中 J1,J3,J5,J7,J9 ,J11这几个点;
一类称 “出” 点,即被裁剪多边形由此点离开裁剪窗口,如图中 J0,J2,J4,J6,J8 ,J10这几个点 。
算法步骤:
(以下,主多边形即被裁剪多边形,裁剪多边形即裁剪窗口。)
(1) 建立主多边形和裁剪多边形的顶点表,如下图所示。
(2) 求主多边形和裁剪多边形的交点,并将这些交点按顺序插入两个多边形的顶点表中。在两多边形顶点表中的相同交点间建立双向指针。
(3) 裁剪,如果存在没有被跟踪过的交点,执行以下步骤:
- 建立裁剪结果多边形的顶点表。
- 选取任意 没有被跟踪过的交点 为始点,将其输出到结果多边形顶点表中。
- 如果该交点为 进点 ,跟踪主多边形边界;否则跟踪裁剪多边形边界。
- 跟踪多边形边界,每遇到多边形顶点,将其输出到结果多边形顶点表中,直到遇到新的交点。
- 将该交点输出到结果多边形顶点表中,并通过连接该交点的双向指针改变跟踪方向(如果上一步跟踪的是主多边形边界,现在改为跟踪裁剪多边形边界;反之,如果上一步跟踪的是裁剪多边形边界,现在改为跟踪主多边形边界)。
- 重复第 4 、5 步直到回到起点。
如图,我这里选择没有被跟踪过的交点 J7 为始点,将 J7 输出到多边形顶点表中。-------> 交点 J7 为 进点,则跟踪主多边形(即顺着左边顶点表往下走) -------> 这时遇到新的交点 J0 -------> 将交点 J0 输出到多边形顶点表中,改变跟踪方向(即顺着箭头来到了右边的顶点表) -------> 现在开始重复第 4、5步,直到回到起点 J7 。
如上图,此番操作完成后,这时多边形顶点表中的内容为: J7 , J0 , q0 , J3 , J4 , J5 , J6 , J7 .
此时,任然有没被跟踪过的交点,再次选取任意没被跟踪过的交点,进行如上操作,直到所有的交点都被跟踪完毕,则裁剪结束。
交点的奇异情况:
算法特点:
1、裁剪窗口可以是矩形、任意凸多边形、任意凹多边形。
2、可实现被裁剪多边形相对裁剪窗口的内裁或外裁,即保留窗口内的图形或保留窗口外的图形,因此在三维消隐中可以用来处理物体表面间的相互遮挡关系。
3、裁剪思想新颖,方法简洁,裁剪一次完成,与裁剪窗口的边数无关。
核心代码:
PS: 这里是完整代码,欢迎移步: 进行下载
Weiler-Athenton算法相关推荐
- java实现线段裁剪算法,多边形裁剪算法java
Weiler-Atherton 任意多边形裁剪 Sutherland-Hodgeman 算法解决了裁剪窗口为凸多边形窗口的问题,但一些应用需要涉及 任意多边形窗口(含凹多边形窗口)的裁剪.Weiler ...
- golang通过RSA算法生成token,go从配置文件中注入密钥文件,go从文件中读取密钥文件,go RSA算法下token生成与解析;go java token共用
RSA算法 token生成与解析 本文演示两种方式,一种是把密钥文件放在配置文件中,一种是把密钥文件本身放入项目或者容器中. 下面两种的区别在于私钥公钥的初始化, init方法,需要哪种取哪种. 通过 ...
- 通用解题法——回溯算法(理解+练习)
积累算法经验,积累解题方法--回溯算法,你必须要掌握的解题方法! 什么是回溯算法呢? 回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就&quo ...
- 伍六七带你学算法 进阶篇-生命游戏
有趣的算法题–生命游戏 难度-中等 根据 百度百科 ,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机. 想要体验生命游戏的小伙伴可以到这里-->生命游戏 进入 ...
- 伍六七带你学算法 进阶篇-排序算法
给定一个整数数组 nums,将该数组升序排列. 示例 1: 输入:[5,2,3,1] 输出:[1,2,3,5] 示例 2: 输入:[5,1,1,2,0,0] 输出:[0,0,1,1,2,5] 各排序算 ...
- 伍六七带你学算法 入门篇-卡牌分组
力扣-914. 卡牌分组 难度-简单 这是一道非常有趣的题,提交通过率令人深思 ,思考它是不是一道简单的题- 开始正题: 给定一副牌,每张牌上都写着一个整数. 此时,你需要选定一个数字 X,使我们可以 ...
- 伍六七带你学算法 入门篇-最小的k个数
java面试题-最小的k个数 难度-简单 输入整数数组 arr ,找出其中最小的 k 个数.例如,输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 示例 1: 输入:a ...
- 十大算法,描述+代码+演示+分析+改进(赶紧收藏!)
十大算法 1.冒泡排序 (1)算法描述 冒泡排序是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来.走访数列的工作是重复地进行直到没有再需要 ...
- 人工智能3d建模算法_打破国外垄断,全国产3D芯片为机器人“点睛”
◎ 科技日报记者 崔爽 传统机器人只有"手",只能在固定好的点位上完成既定操作,而新一轮人工智能技术大大推动了机器和人的协作,这也对机器人的灵活性有了更高要求. 要想像人一样测量. ...
- 算法设计思想(5)— 递归法
1. 递归概念 递归 Recursion是指在函数的定义中使用函数自身的方法,直观上来看,就是某个函数自己调用自己. 递归有两层含义: 递归问题必须可以分解为若干个规模较小.与原问题形式相同的子问 ...
最新文章
- 理解 Linux/Unix 登录脚本
- 菜鸟驿站:今年双11期间全国站点将普遍延长营业时间
- Java基础之StringBuffer和StringBuilder的区别
- Python XML解析(转载)
- RFM模型实现用户分层
- 机器学习 Cohen s Kappa,Quadratic Weighted Kappa 详解
- js和jsp的区别和联系
- KNN和K-Means
- win10系统遇到深色背景自动降低亮度解决方法、WIN10自动调节亮度、如何关闭WIN10自动调节亮度
- 关于算法的学习以及一些总结(一)
- 在iOS上建局域网网站
- AI人工智能可以做哪些课题的毕业设计毕设
- 削华为足,以适IBM之履的再造流程
- linux日志管理工具logrotate配置
- 你知道有哪些用于文件同步的方法?
- lintcode backpack
- (病毒安全)电脑装多款杀毒软件可以吗?
- 房企高周转之殇:恶果显现 减配、质量问题、虚假销售
- 原生Android平板,LG G Pad 8.3评测:原汁原味的安卓平板
- Low-cost Sensor-enabled Freehand 3D Ultrasound