一.基本原理

           扫描线多边形区域填充算法是按扫描线顺序(由下到上),计算扫描线与多边形的相交区间,再用要求的颜色显示这些区间的象素,即完成填充工作。

                                       

           区间的端点可以通过计算扫描线与多边形边界线的交点获得。

           对于一条扫描线,多边形的填充过程可以分为四个步骤:

(1)求交:计算扫描线与多边形各边的交点;

(2)排序:把所有交点按x值递增顺序排序;

(3)配对:第一个与第二个,第三个与第四个等等;每对交点代表扫描线与多边形的一个相交区间;

(4)填色:把相交区间内的象素置成多边形颜色;

如图所示,扫描线 6 与多边形的边界 线交于四点A、B、C、D。
这四点把扫描线分 为五个区间 [0, 2],[2, 3.5],[3.5, 7],[7, 11], [11, 2]。
其中, [2, 3.5], [7, 11] 两个区间落在 多边形内,该区间内的象素应取多边形色。
其它区间内的象素取背景色。
这里的四个交点在计算时未必是按从左到 右的顺序获得。
例如,当多边形采用顶点序列 P1P2P3P4P5P6 表示时,把扫描线 6 分别与边 P1P2,P2P3,P3P4,P4P5,P5P6,P6P1 相 交,
得到交点序列D、C、B、A,必须经过排 序,才能得到从左到右,按 x 递增顺序排列的
交点 x 坐标序列。

二.问题

(1)当扫描线与多边形顶点相交时,交点 的取舍问题(保证交点正确配对):

     检查相交顶点的两条边的另外两个顶点的y值。按这两个y值中大于交点y值的个数是0,1,2来决定是取零个、一个、还是两个。

当扫描线与多边形顶点相交 时,会出现异常情况。例如图所示,扫描线 2 与 P1 相交。
按前述方法求得交点 ( x 坐标)序列:2,2,8。这将导致 [2, 8] 区间内的 象素取背景色,
而这个区间的象素正是属于多 边形内部,需要填充的。
所以,我们拟考虑当 扫描线与多边形的顶点相交时,相同的交点只 取一个。
这样,扫描线 2 与多边形的交点序列就成为 2,8。正是我们所希望的结果。
然而,按新的规定,扫描线 7 与多边形的 交点序列为 2,9,11。
这将导致错把[2,9]区间作为多边形内部来填充。
为了正确地进行交点取舍,必须对上述两种 情况区别对待。
在第一种情况,扫描线交于一顶 点,而共享顶点的两条边分别落在扫描线的两边 。
这时,交点只算一个。在第二种情况,共享交 点的两条边在扫描线的同一边,这时交点作为零个或两个,
取决于该点是多边形的局部最高点还是局部最低点。
具体实现时,只需检查顶点的两条边的另 外两个端点的 y 值。按这两个 y 值中大于交点 y 值的个数是 0,1,2 来决定是取零个、一 个、还是二个。
例如,扫描线 1 交于顶点 P2,由于共享该顶点的两条边的另外二个顶点 均高于扫描线,故取交点 P2 两次。
这使得 P2 象素用多边形颜色设置。
再考虑扫描线 2。在 P1 处,由于 P6 高于扫描线,而 P2 低于扫描 线,所以该交点只算一个。
而在 P6 处,由于 P1和P5均在下方,所以扫描线 7 与之相交时,交点算零个,该点不予填充。
//
(如果某一条边,平行于某一条扫描线;那这一条边,不予记录)///

(2)多边形边界上象素的取舍问题(避免填充扩大化):

对扫描线与多边形的相交区间取左闭右开。

例如,对左下角为 (1,1),右上角为(3,3)的正方形填充 时,若对边界上所有象素均进行填充,
被填充的象素覆盖的面积为 3×3 单位,而方形实际面积只有 2×2 单 位。显然,
这个扩大化问题是由于对边界上的所有象素进行填充引起的。
为了克服这个问 题,规定落在右/上边界的象素不予填充,而落在左/下边界的象素予以填充。
在具体实现时,只要对扫描线与多边形的 相交区间取*左闭右开*。
容易看出,我们在前面 一个问题所采用的方法,即扫描线与多边形顶
点相交时,交点的取舍方法,保证了多边形的 “下闭上开”——丢弃上方水平边以及上方非
水平边上作为局部最高点的顶点。
重合点的处理:当扫描线和边界相交于边界顶点时,同时产生两个交点,通常采用 “起闭终开”或“起开终闭” 。
水平边处理:水平边不参加求交计算,跳过。

三. 解决步骤

 为了计算每条扫描线与多边形各边的交点, 最简单的方法是把多边形的所有边放在一个表中。

这样处理效率很低。这是因为一条扫描线 往往只与少数几条边相交,甚至与整个多边形 都不相交。若在处理每条扫描线时,不分青红 皂白地把所有边都拿来与扫描线求交,则其中 决大多数计算都是徒劳无用的。

为了提高效率,在处理一条扫描线时,仅 对与它相交的多边形的边进行求交运算。我们 把与当前扫描线相交的边称为活性边,并把它 们按与扫描线交点 x 坐标递增的顺序存放在一个链表中,称此链表为活性边表(AET)。

 假定当前扫描线与多边形某一条边的交点的x坐标为x,则下一条扫描线与该边的交点不要重计算,只要加一个增量△x。(连贯性)

        设该边的直线方程为:ax+by+c=0;

        若y=yi,x=xi;则当y = yi+1时,

         xi+1=xi-b/a

       其中ΔX= -b/a为常数,

       另外使用增量法计算时,我们需要知道一条边何时不再与下一条扫描线相交,以便及时把它从活性边表中删除出去。

x i+1 = ( - by i+1 –c)/a = x i –b/a 其中△x = -b/a 为常量。△x 可以存放在对应 边的活性边表结点中。另外,使用增量法计算 时,我们需要知道一条边何时与下一条扫描线 相交,以便及时把它从活性边表中删除出去, 避免下一步进行无谓的计算。综上所述,活性边表的结点中至少应为对应边保存如下内容:

第1项存当前扫描线与边的交点坐标x值;

第2项存从当前扫描线到下一条扫描线间x的增量D x;

第3项存该边所交的最高扫描线号ymax;

第4项存指向下一条边的指针(Λ代表一条边的退出,即结束或抛弃);

扫描线6的活性边表  :

扫描线7的活性边表:

 为了方便活性边表的建立与更新,我们为每一条扫描线建立一个新边表(NET),存放在该扫描线第一次出现的边。也就是说,若某边的较低端点为ymin,则该边就放在扫描线ymin的新边表中。

1.这个结构实际上是一个指针数组,数组的每个变量是个指针,
这个指针指向所有的以这个y值作为起点的边。
2.把多边形所有的边全部填成这样的结构,插到这个指针数组里面来。
3.从上面这个指针数组里面就知道多边形是从哪里开始的。
在这个指针数组里只有1、2、3、5处有边,因此当从下往上进行扫描转换的时候,
从y=1开始做,而在1这条线上有两条边进来了,然后就把这两条边放进活性边表来处理。
4.当处理y=2这条扫描线时(活性边里有2条边),先看活性边表里是否有边要退出和加入,
实际上p1p2边要退出了(y=ymax),p1p6边要加入了。
退出的边要从活性边表里去掉,不退出的边要进行处理,即把x值加上一个增量。
(这时p1p2变后边需要加一个Λ)
5.后面持续步骤3,4,只到y=5这扫描线结束。
6.即每做一次新的扫描线时,要对已有的边进行三个处理:
一是否被去除掉;如果不被去除;
第二就要对它的数据进行更新,所谓更新数据就是要更新它的x值,即x+△x;
最后,就是有没有新的边进来,新的边在NET里,可以插入排序插进来。

四.算法描述

这个算法过程从来没有求交,这套数据结构使得你不用求交点!避免了求交运算。

扫描线多边形填充算法的主要步骤:

  1. 建立NET(NewEdgeList)
  2. 从最低扫描线开始到最高扫描线循环
  3. 建立或调整AET(ActiveEdgeList)
  4. 按照AET中的接点顺序填充
void polyfill (多边形  polygon, 颜色 color)
{ for (各条扫描线i ){ 初始化新边表头指针NET [i];把ymin = i 的边放进边表NET [i];   }y = 最低扫描线号;初始化活性边表AET为空;for (各条扫描线i ){ 把新边表NET[i]中的边结点用插入排序法插入AET表,使之按x坐标递增顺序排列;遍历AET表,把y max= i 的结点从AET表中删除,并把y max > i结点的x值递增D x;若允许多边形的边自相交,则用冒泡排序法对AET表重新排序;遍历AET表,把配对交点区间(左闭右开)上的象素(x, y),用drawpixel (x, y, color) 改写象素颜色值;}
}

计算机图形学 ———— 扫描线多边形填充算法 (讲解)相关推荐

  1. 计算机图形学:多边形填充算法(算法原理及代码实现)

    一.实现方案 扫描线算法: 实现原理: 把图形的填充转换为扫描线从上往下扫描填充,这时我们只需要判断每一条扫描线与图形的交点,而我们可以根据扫描线的连贯性,对交点进行排序,第1个点与第2个点之间,第3 ...

  2. 【计算机图形学 】扫描线多边形填充算法 | OpenGL+鼠标交互

    文章目录 其他计算机图形学实验 前言 思路借鉴 步骤 1.点的结构体 2. AET 活性边表.NET新边表 的结构体 3. 扫描线算法实现 4. 改变鼠标响应函数 完整代码 总结 其他计算机图形学实验 ...

  3. 图形学初步----------多边形填充算法

    参考博文: https://blog.csdn.net/xiaowei_cqu/article/details/7693985 https://blog.csdn.net/xiaowei_cqu/ar ...

  4. 计算机图形学 OpenGl-种子填充算法画红黄绿交通灯

    一.实验原理 我就不多叙述了,课本上说的已经够多了,其次我自己也是借鉴别人的代码写出来的 二.上机环境 VS2010 三.代码运行效果 四.完整代码 #include <GL/glut.h> ...

  5. 计算机图形学绘制多边形代码_《GPU编程与CG语言之阳春白雪下里巴人》- 第二章(GPU 图形绘制管线)...

    第二章 GPU 图形绘制管线 万事开头难,每门科学都是如此. ------ 马克思 图形绘制管线描述 GPU 渲染流程,即"给定视点.三维物体.光源.照明模式,和纹理等元素,如何绘制一幅二维 ...

  6. 多边形区域填充算法--扫描线种子填充算法

    分享一下我老师大神的人工智能教程.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow http://bl ...

  7. 边界填充算法讲解_边界填充算法

    边界填充算法讲解 Boundary fill is the algorithm used frequently in computer graphics to fill a desired color ...

  8. 图形学初步--------种子填充算法

    上篇博文讲到了填充算法的扫描线填充,这篇博文讲解另一大算法思路----------种子填充. 一.概念 种子填充算法假设在多边形或区域内部至少有一个像素是已知的.然后设法找到区域内所有其他像素,并对它 ...

  9. java实现种子填充算法,Java编写图形学的种子填充算法

    用C写的图形学填充算法已经很多了,看到不少帖子都是在问关于如何用Java编写图形学的填充算法,说来也巧,我刚好要做一个这个方面的实验,用的是扫描线种子填充算法,由于时间仓促,代码质量可能不算很高,希望 ...

最新文章

  1. ATS名词术语(待续)
  2. 上标3下标6算法_图解堆排序算法
  3. java第10次作业 计科1501 张鹏
  4. 启明云端分享 | sigmastar SSD201开发板网口直连PC升级
  5. python request 留位置4
  6. vue练习之vue+cnode api
  7. 1092 最好吃的月饼 (20分)
  8. 【共生性】CVPR 2019:Multi-Label Image Recognition with Graph Convolutional Networks
  9. 如何向小白讲述软件架构发展历程?
  10. CSDN资源下载积分规则
  11. 网络安全实验室-解密关1
  12. 博士申请 | 澳门大学张一博教授课题组招收计算机视觉方向全奖博士生
  13. FRM考试时间明细,FRM考试全方面日程表
  14. 银行核心系统之存款业务(一)
  15. 20165107 网络对抗技术 Exp4 恶意代码分析
  16. 使 div 水平 垂直 居中
  17. 阿里百川 WKWebView 无法拦截URL
  18. tpc-c 测试方案
  19. 买游戏来运营_游戏化思维帮你玩转社群运营
  20. layui模块显示收缩_修改layui的后台模板的左侧导航栏可以伸缩的方法

热门文章

  1. 【随缘一练】一棵树,请你给每个顶点染成红色或蓝色
  2. 【论文泛读44】BoolQ:探索自然是/否问题的惊人难度
  3. 重庆大学计算机学院博士复试分数线,计算机学院2017年博士研究生招生复试录取工作实施细则...
  4. 一部好片-----好市多多
  5. 怎么将PDF文本转变成为PPT格式
  6. 求和函数符号计算机,电脑上怎么打求和,多次幂等数学符号
  7. 从开创到引领,今麦郎如何成为数字化快消龙头?
  8. homestead 下用thinkPHP
  9. 马蜂窝:2018中国省域自由行大数据系列报告之东北地区(附下载)
  10. 全面了解什么CMMI认证