算法 & 数据结构——多边形填充
. 在很多图形相关的编辑器里都会有选区功能,有的只能按某种固定形状选择,比如:矩形,圆形……,有的可以按任意形状选择,有的甚至可以分析图片自动选区(例如:Photoshop魔法棒工具),今天来说说任意形状选区怎么实现。
. 通过鼠标描点,再用线段连接,组合成一个几何选区,这看似没有难度,它实际上……的确没有难度。如果要填充选区内部,这就有一丢丢难度(至少很久前我被这个问题困住很久)。
大概思路
. 想要填充一个多边形,必然要对其覆盖范围的每个像素填色,这一过程叫光栅化.然而,直接对一个多边形光栅化是很困难的,但我们可以把多边形切割成多个容易光栅化的形状,覆盖范围保持不变,之后我们对切割后的多个形状逐个光栅化,从而达到目的,因为多边形是任意的,所以可能形成多个闭合,又可能存在凹多边形,因此在光栅化之前,还需要将这些问题逐一解决.
三角形拆分
![]()
. 三角形是很容易光栅化的形状,只需要对三角形上下切割,使其变成平底或平顶三角形,之后再从上到下或者从下到上,依次求出水平线上两边的顶点位置,就可以逐行填色,达到光栅化的目的.正因如此,GPU也是逐三角形光栅化的,
闭合路径
要填充一个不规则的选区,要把它拆分成多个三角形,而怎么拆分成三角形就是问题所在。
在拆分三角形之前,需要计算出选区内包含的所有闭合路径,因为一个选区可能会有多个闭合路径,就像上图显示,选区包含了两个闭合路径.
从多边形的第三个顶点开始,每个顶点与下一个顶点形成一条线段,再依次与之前的顶点线段求交点,一旦出现交点,则必然产生一个闭合路径,以交点为界,剥离这个闭合路径即可
三角形切割
已经得到了所有的闭合路径,接下来就可以切割三角形了.这非常容易,只要从第一个顶点到每一个顶点链接就行了.
凹多边形切割
从图中可以看出,闭合路径只有一个,但这个路径是凹多边形,按上述的方法切割三角形,生成的多边形肯定会超出范围(自行脑补),但是几何学告诉我们,任何凹多边形都可以切成多个凸多边形.
只需要在多边形的凹点处,延伸出一条线段,连接到最近的边,这条线段作为交界,划分出两个多边形,再分别将这两个多边形重复此步骤,直到没有凹点,则这个多边形是凸多边形.
有了切割凹多边形的算法还不够,因为还不知道什么是凹多边形,什么是凸多边形,因此还得有一个算法来判断凹凸,这个算法相对来说就简单多了.
遍历多边形顶点,只要2点生成的线段方向与多边形整体方向不一致,这个多边形就是凹多边形.
之后还剩下一个算法,就是如何知道一个多边形的整体方向.
求出多边形最靠左的顶点,将该顶点到下一个顶点的向量与该顶点到上一个顶点的向量求方向即可.
整个算法到这就结束了,下图是凹多边形切割后的形状,很容易发现,多了几根线段,这些线段正是切分成凸多边形的线段,而闭合路径也由1个变成了3个,再用上述的方法计算三角形就容易多了.
效果展示
- 【数据结构与算法】字符串匹配之BF&KMP算法
- 数据结构与算法(C语言)<绪论>
- [翻译]C#数据结构与算法 – 前言&第一章
- [数据结构与算法]第一周(二):线性表---位查询&&放苹果
- [翻译]C#数据结构与算法 – 前言&第一章
- 数据结构与算法(三)栈&&队列
- 【数据结构与算法】Huffman树&&Huffman编码(附完整源码)
- 数据结构与算法——计算程序段的执行时间&&多项式求值
- 【转】 [翻译]C#数据结构与算法 – 前言&第一章 (原文:http://www.cnblogs.com/lsxqw2004/archive/2009/07/01/1366118.html)
- 【数据结构与算法】Huffman树&&Huffman编码(附完整源码)
- C语言进阶-第22~23讲:问题求解的一般过程&数据结构及算法概述
- [数据结构与算法]第一周(一):线性表---多项式加法&&字符串插入
- 数据结构第5章例题 若矩阵Am×n中存在某个元素aij满足:aij是第i行中的最小值且是第j列中的最大值,则称该元素为矩阵A的一个鞍点。试编写一个算法,找出A中的所有鞍点。
- 数据结构与算法01--堆栈 & 队列
- 算法 & 数据结构——收纳箱算法???
- <四>java数据结构与算法 插入排序
- 【数据结构与算法】Huffman树&&Huffman编码(附完整源码)
- 数据结构与算法问题 二叉搜索树
- 数据结构中随机数的算法
- 数据结构与算法_杂记_1