扫描线填充算法讲解

合集下载

案例10 扫描线种子填充算法

案例10  扫描线种子填充算法

程序代码
PointTemp.x=xleft;PointTemp.y=PointTemp.y-2; //处理下一条扫描线 while(PointTemp.x<xright) { bSpanFill=FALSE; while(pDC->GetPixel(Round(PointTemp.x),Round(PointTemp.y))!=BoundaryClr && pDC->GetPixel(Round(PointTemp.x),Round(PointTemp.y))!=SeedClr) { bSpanFill=TRUE; PointTemp.x++; } if(bSpanFill) { if(PointTemp.x==xright && pDC->GetPixel(Round(PointTemp.x), Round(PointTemp.y))!=BoundaryClr && pDC->GetPixel(Round(PointTemp.x),Round(PointTemp.y))!=SeedClr) PopPoint=PointTemp; else PopPoint.x=PointTemp.x-1;PopPoint.y=PointTemp.y; Push(PopPoint); bSpanFill=FALSE; } while((pDC->GetPixel(Round(PointTemp.x),Round(PointTemp.y))==BoundaryClr && PointTemp.x<xright) || (pDC->GetPixel(Round(PointTemp.x),Round(PointTemp.y)) ==SeedClr && PointTemp.x<xright)) PointTemp.x++; } }

扫描线多边形填充算法

扫描线多边形填充算法

扫描线多边形填充算法扫描线多边形填充算法(Scanline Polygon Fill Algorithm)是一种计算机图形学中广泛使用的算法,用于将一个封闭的多边形形状涂色填充。

它通过扫描线的方式,从上到下将多边形内的像素按照预设的填充颜色来进行填充。

本文将详细介绍扫描线多边形填充算法的原理、流程和实现细节。

1.算法原理:扫描线多边形填充算法基于扫描线的思想,在水平方向上扫描每一行像素,并检测多边形边界与扫描线的交点。

通过将扫描线从上到下扫过整个多边形,对于每一行像素,找出与多边形边界交点的水平线段,然后根据填充颜色将像素点进行填充。

2.算法流程:-找出多边形的最小和最大Y坐标,确定扫描线的范围。

-从最小Y坐标开始,到最大Y坐标结束,逐行进行扫描。

-对于每一行,找出与多边形边界交点的水平线段。

-根据填充颜色,为每个水平线段上的像素点进行填充。

3.算法实现:-首先,需要根据给定的多边形描述边界的顶点坐标,计算出每条边的斜率、最小和最大Y值以及每条边的X坐标交点。

-然后,对于每一扫描线,找出与多边形边界交点的水平线段,即找出交点的X坐标范围。

-最后,根据填充颜色,将该范围内的像素点进行填充。

4.算法优化:- 针对复杂多边形,可以使用活性边表(AET,Active Edge Table)来管理边界信息,加快查找交点的速度。

-可以使用桶排序来排序边界事件点,提高扫描速度。

-根据多边形边的特征,对算法进行优化,减少不必要的计算和内存消耗。

5.算法应用:-扫描线多边形填充算法广泛应用于计算机图形学中的图形渲染、图像处理等领域。

-在游戏开发、CAD绘图、虚拟现实等应用中,扫描线多边形填充算法被用于快速绘制和渲染复杂多边形。

总结:扫描线多边形填充算法是一种经典的计算机图形学算法,通过扫描线的方式对多边形进行填充。

它可以高效地处理各种形状的多边形,包括凸多边形和凹多边形。

算法虽然简单,但在实际应用中具有广泛的用途。

贵州大学--实验三-多边形填充算法

贵州大学--实验三-多边形填充算法

贵州大学实验报告学院:计算机科学与信息专业:软件工程班级:102班边界上的象素填充所遵循的规则为:“左闭右开”,“下闭上开”(将左边界和下边界的点算为内部,而将右边界和上边界算为外部)顶点:“上开下闭”。

几种特殊情况:1.扫描线交于一顶点,共享的两条边分另处于扫描线的两边,这时交点只取一个。

2.共享交点的两条边处于扫描线的上方,这时交点取二个。

3.共享交点的两条边处于扫描线的下方,这时交点取0个。

4.水平边在算法中不起任何作用,可不考虑。

活性边表(提高效率):为了减少求交的计算量,要利用一条边与相继的两条扫描线的交点的连贯性。

在处理一条扫描线时只对活性边(与它相交的多边形的边)进行求交运算。

把交点按x增加方向存在一个链表(活性边表)中。

活性边:与当前扫描线相交的边。

活性边表(AEL):按交点x的增量顺序存放在一个链表中,该链表称作活性边表(AEL)。

二、种子填充算法种子填充首先假定区域由封闭轮廓线围成,且轮廓线内某点是已知的,然后开始搜索与种子点相邻且位于轮廓线内的点。

如果这相邻点不在轮廓线内,则已达到轮廓线的边界;如果相邻点在轮廓线之内,则这相邻点成为新的种子点,继续搜索下去。

只适用于光栅扫描设备。

区域分类(区域采用边界定义,即区域边界上与边界外的象素取相同值,区域内部的点取不同值)1、四向连通区域:各象素在水平垂直四个方向是边通的。

即从区域内任一点出发,可水平/垂直移动到达区域内任一点。

实验结果运用扫描线算法进行多边形的填充时,截图显示如下:运用扫描线种子算法进行多边形的填充时,截图显示如下:(注:可编辑下载,若有不当之处,请指正,谢谢!)[文档可能无法思考全面,请浏览后下载,另外祝您生活愉快,工作顺利,万事如意!]。

扫描线填充算法讲解

扫描线填充算法讲解

扫描线算法(Scan-Line F illing)扫描线算法适合对矢量图形进行区域填充,只需要直到多边形区域的几何位置,不需要指定种子点,适合计算机自动进行图形处理的场合使用,比如电脑游戏和三维CAD软件的渲染等等。

对矢量多边形区域填充,算法核心还是求交。

《计算几何与图形学有关的几种常用算法》一文给出了判断点与多边形关系的算法――扫描交点的奇偶数判断算法,利用此算法可以判断一个点是否在多边形内,也就是是否需要填充,但是实际工程中使用的填充算法都是只使用求交的思想,并不直接使用这种求交算法。

究其原因,除了算法效率问题之外,还存在一个光栅图形设备和矢量之间的转换问题。

比如某个点位于非常靠近边界的临界位置,用矢量算法判断这个点应该是在多边形内,但是光栅化后,这个点在光栅图形设备上看就有可能是在多边形外边(矢量点没有大小概念,光栅图形设备的点有大小概念),因此,适用于矢量图形的填充算法必须适应光栅图形设备。

2.1扫描线算法的基本思想扫描线填充算法的基本思想是:用水平扫描线从上到下(或从下到上)扫描由多条首尾相连的线段构成的多边形,每根扫描线与多边形的某些边产生一系列交点。

将这些交点按照x坐标排序,将排序后的点两两成对,作为线段的两个端点,以所填的颜色画水平直线。

多边形被扫描完毕后,颜色填充也就完成了。

扫描线填充算法也可以归纳为以下4个步骤:(1)求交,计算扫描线与多边形的交点(2)交点排序,对第2步得到的交点按照x值从小到大进行排序;(3)颜色填充,对排序后的交点两两组成一个水平线段,以画线段的方式进行颜色填充;(4)是否完成多边形扫描?如果是就结束算法,如果不是就改变扫描线,然后转第1步继续处理;整个算法的关键是第1步,需要用尽量少的计算量求出交点,还要考虑交点是线段端点的特殊情况,最后,交点的步进计算最好是整数,便于光栅设备输出显示。

对于每一条扫描线,如果每次都按照正常的线段求交算法进行计算,则计算量大,而且效率底下,如图(6)所示:图(6)多边形与扫描线示意图观察多边形与扫描线的交点情况,可以得到以下两个特点:(1)每次只有相关的几条边可能与扫描线有交点,不必对所有的边进行求交计算;(2)相邻的扫描线与同一直线段的交点存在步进关系,这个关系与直线段所在直线的斜率有关;第一个特点是显而易见的,为了减少计算量,扫描线算法需要维护一张由“活动边”组成的表,称为“活动边表(AET)”。

多边形扫描线填充算法技巧

多边形扫描线填充算法技巧

多边形扫描线填充算法技巧扫描线填充算法是计算机图形学中常用的一种填充算法,用于对多边形进行填充。

其基本原理是通过扫描线与多边形边界的交点来确定需要填充的像素点。

本文将介绍多边形扫描线填充算法的基本思想以及一些常用的优化技巧。

一、基本思想多边形扫描线填充算法的基本思想是将多边形分解成一系列水平线段,然后对每条水平线段进行扫描,找出与多边形边界相交的点,并进行填充。

具体步骤如下:1. 确定多边形的边界:对于给定的多边形,首先需要确定其边界。

可以使用边界表(edge table)来存储多边形的边界信息,包括每条边的起点和终点坐标以及斜率等。

2. 初始化扫描线:从多边形边界中找出最小的y坐标和最大的y坐标,作为扫描线的起点和终点。

3. 扫描线算法:对于每条扫描线,通过遍历边界表,找出与扫描线相交的边界线段。

根据相交点的x坐标,确定需要填充的像素点范围。

4. 填充像素点:根据上一步确定的像素点范围,将扫描线上的像素点进行填充。

二、技巧和优化1. 边界表的构建:为了提高算法的效率,可以对边界表进行排序,按照扫描线的y坐标来排序。

这样可以减少对边界表的遍历次数,提高算法的执行速度。

2. 边界交点的计算:在扫描线算法中,需要计算扫描线与多边形边界的交点。

可以使用活性边表(active edge table)来存储当前与扫描线相交的边界线段,并根据交点的x坐标进行排序。

这样可以减少计算交点的次数,提高算法的效率。

3. 填充像素点的优化:在填充像素点时,可以使用扫描线种子填充算法来进行优化。

该算法通过选择合适的填充起点,在填充过程中自动推进扫描线,减少不必要的计算和填充操作,提高填充的速度。

4. 填充规则的处理:在实际应用中,可能会遇到一些特殊情况,如多边形内部有孔洞或交叉等。

针对这些情况,可以通过修改填充规则来处理。

常用的填充规则有奇偶填充规则和非零填充规则,可以根据实际情况选择合适的填充规则。

5. 像素点颜色的处理:在多边形填充过程中,可以通过设置填充的颜色或纹理来实现不同的效果。

带孔多边形填充算法

带孔多边形填充算法

带孔多边形填充算法一. 基本原理用自上而下的每一条水平的扫描线扫描多边形,每一条扫描线被多边形分成几段,每一段要么在多边形内,要么在多边形外。

在内的填充,在外的舍弃。

见图1图1二. 基本算法1. 水平扫描线与线段求交点假定当前扫描线y 与多边形的某一条边的交点x 坐标为x,那么下一条扫描线y-1与该边的交点不必从头算起,只要加上一个增量即可。

设增量为dx,显然dx= -(x1-x0)/(y1-y0) 结果是:若y=y i ,x=x i ,则当y=y i -1时,x=x i -(x1-x0)/(y1-y0)图22. 活性边与活性边表为了提高效率,在处理一条扫描线时,仅对与它相交的多边形的边进行求交运算。

我们把与当前扫描线相交的边称为活性边,并把它们按与扫描线交点x 坐标递增的顺序存放在一个链表中,称此链表为活性边表。

由于边的连贯性(即当某条边与当前扫描线相交时,它很可能也与下一条扫描线相交),以及扫描线的连贯性(当前扫描线与各边的交点顺序与下一条扫描线与各边的交点顺序很可能相同或非常类似),在当前扫描线处理完毕之后,我们不必为下一条扫描线从头开始构造活性边表,而只要对当前扫描线的活性边表稍作修改,即可更新得到下一条扫描线的活性边表。

例如,(见图3)扫描线6的活性边表如下:P 6P 1 →P 6P 5→ P 5P 4 →P 4P 3扫描线4的活性边表如下:P 6P 1→P 4P 3扫描线3的活性边表如下:P 6P 1→P 3P 2 (满足上闭下开的原则)。

扫描线2的活性边表如下:P 1P 2→P 2P 3 (满足上闭下开的原则)。

y-1 (x0,y0) (x1,y1) y dx 1图3 3.Y 桶表为了方便活性边表的建立与更新,我们为每一条扫描线建立一个新边表,存放在该扫描线第一次出现的边。

也就是说,若某边的较高端点为Y max ,则该边就放在扫描线Y max 的新边表中。

这样,当我们按扫描线从大到小顺序处理扫描线时,该边在该扫描线第一次出现。

计算机图形学扫描线种子填充算法

计算机图形学扫描线种子填充算法

2.1 深度递归的种子填充算法
2.2 扫描线种子填充算法
2.1 深度递归的种子填充算法
种子填色又称边界填色(Boundary Filling)。 它的功能是,给出多边形光栅化后的边界位置及边 界色代码oundary_color,以及多边形内的一点(x, y)位置,要求将颜色fill_color填满多边形。
动画演示
扫描线种子填充算法特点
1. 该算法考虑了扫描线上象素的相关性,种子象 素不再代表一个孤立的象素,而是代表一个尚 未填充的区段。 2. 进栈时,只将每个区段选一个象素进栈(每个 区段最右边或最左边的象素),这样解决了堆 栈溢出的问题。 3. 种子出栈时,则填充整个区段。 4. 这样有机的结合:一边对尚未填充象素的登记 (象素进栈),一边进行填充(象素出栈), 既可以节省堆栈空间,又可以实施快速填充。

3. 已知有一个5边形如下。建立新边表 NET,并写出每一条扫描线经过时活性边 表AET中的数据状态。
X ΔX Ymax
第1项存当前扫描线与边的交点坐标x值; 第2项存从当前扫描线到下一条扫描线间x的增量Dx; 第3项存该边所交的最高扫描线号ymax; 第4项存指向下一条边的指针。
假定当前扫描线与多边形某一条边的交点的x 坐标为x,则下一条扫描线与该边的交点不要重计 算,只要加一个增量△x。(连贯性) 设该边的直线方程为:ax+by+c=0; 若y=yi,x=x i;则当y = y i+1时, x i+1=xi-b/a 其中ΔX= -b/a为常数, 另外使用增量法计算时,我们需要知道一条边 何时不再与下一条扫描线相交,以便及时把它从 活性边表中删除出去。
建立或调整AET(ActiveEdgeList);

扫描线种子填充算法

扫描线种子填充算法

扫描线种子填充算法扫描线种子填充算法的基本过程如下:当给定种子点(x, y)时,首先分别向左和向右两个方向填充种子点所在扫描线上的位于给定区域的一个区段,同时记下这个区段的范围[xLeft, xRight],然后确定与这一区段相连通的上、下两条扫描线上位于给定区域内的区段,并依次保存下来。

反复这个过程,直到填充结束。

扫描线种子填充算法可由下列四个步骤实现:(1) 初始化一个空的栈用于存放种子点,将种子点(x, y)入栈;(2) 判断栈是否为空,如果栈为空则结束算法,否则取出栈顶元素作为当前扫描线的种子点(x, y),y是当前的扫描线;(3) 从种子点(x, y)出发,沿当前扫描线向左、右两个方向填充,直到边界。

分别标记区段的左、右端点坐标为xLeft和xRight;(4) 分别检查与当前扫描线相邻的y - 1和y + 1两条扫描线在区间[xLeft, xRight]中的像素,从xLeft开始向xRight方向搜索,若存在非边界且未填充的像素点,则找出这些相邻的像素点中最右边的一个,并将其作为种子点压入栈中,然后返回第(2)步;这个算法中最关键的是第(4)步,就是从当前扫描线的上一条扫描线和下一条扫描线中寻找新的种子点。

如果新扫描线上实际点的区间比当前扫描线的[xLeft, xRight]区间大,而且是连续的情况下,算法的第(3)步就处理了这种情况。

如图所示:新扫描线区间增大且连续的情况假设当前处理的扫描线是黄色点所在的第7行,则经过第3步处理后可以得到一个区间[6,10]。

然后第4步操作,从相邻的第6行和第8行两条扫描线的第6列开始向右搜索,确定红色的两个点分别是第6行和第8行的种子点,于是按照顺序将(6, 10)和(8, 10)两个种子点入栈。

接下来的循环会处理(8, 10)这个种子点,根据算法第3步说明,会从(8, 10)开始向左和向右填充,由于中间没有边界点,因此填充会直到遇到边界为止,所以尽管第8行实际区域比第7行的区间[6,10]大,但是仍然得到了正确的填充。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

扫描线算法(Scan-Line F illing)扫描线算法适合对矢量图形进行区域填充,只需要直到多边形区域的几何位置,不需要指定种子点,适合计算机自动进行图形处理的场合使用,比如电脑游戏和三维CAD软件的渲染等等。

对矢量多边形区域填充,算法核心还是求交。

《计算几何与图形学有关的几种常用算法》一文给出了判断点与多边形关系的算法――扫描交点的奇偶数判断算法,利用此算法可以判断一个点是否在多边形内,也就是是否需要填充,但是实际工程中使用的填充算法都是只使用求交的思想,并不直接使用这种求交算法。

究其原因,除了算法效率问题之外,还存在一个光栅图形设备和矢量之间的转换问题。

比如某个点位于非常靠近边界的临界位置,用矢量算法判断这个点应该是在多边形内,但是光栅化后,这个点在光栅图形设备上看就有可能是在多边形外边(矢量点没有大小概念,光栅图形设备的点有大小概念),因此,适用于矢量图形的填充算法必须适应光栅图形设备。

扫描线算法的基本思想扫描线填充算法的基本思想是:用水平扫描线从上到下(或从下到上)扫描由多条首尾相连的线段构成的多边形,每根扫描线与多边形的某些边产生一系列交点。

将这些交点按照x坐标排序,将排序后的点两两成对,作为线段的两个端点,以所填的颜色画水平直线。

多边形被扫描完毕后,颜色填充也就完成了。

扫描线填充算法也可以归纳为以下4个步骤:(1)求交,计算扫描线与多边形的交点(2)交点排序,对第2步得到的交点按照x值从小到大进行排序;(3)颜色填充,对排序后的交点两两组成一个水平线段,以画线段的方式进行颜色填充;(4)是否完成多边形扫描?如果是就结束算法,如果不是就改变扫描线,然后转第1步继续处理;整个算法的关键是第1步,需要用尽量少的计算量求出交点,还要考虑交点是线段端点的特殊情况,最后,交点的步进计算最好是整数,便于光栅设备输出显示。

对于每一条扫描线,如果每次都按照正常的线段求交算法进行计算,则计算量大,而且效率底下,如图(6)所示:图(6)多边形与扫描线示意图观察多边形与扫描线的交点情况,可以得到以下两个特点:(1)每次只有相关的几条边可能与扫描线有交点,不必对所有的边进行求交计算;(2)相邻的扫描线与同一直线段的交点存在步进关系,这个关系与直线段所在直线的斜率有关;第一个特点是显而易见的,为了减少计算量,扫描线算法需要维护一张由“活动边”组成的表,称为“活动边表(AET)”。

例如扫描线4的“活动边表”由P1P2和P3P4两条边组成,而扫描线7的“活动边表”由P1P2、P6P1、P5P6和P4P5四条边组成。

第二个特点可以进一步证明,假设当前扫描线与多边形的某一条边的交点已经通过直线段求交算法计算出来,得到交点的坐标为(x, y),则下一条扫描线与这条边的交点不需要再求交计算,通过步进关系可以直接得到新交点坐标为(x + △x, y + 1)。

前面提到过,步进关系△x是个常量,与直线的斜率有关,下面就来推导这个△x。

假设多边形某条边所在的直线方程是:ax + by + c = 0,扫描线yi和下一条扫描线y i+1与该边的两个交点分别是(xi,yi)和(xi+1,yi+1),则可得到以下两个等式:axi + byi+ c = 0 (等式 1)axi+1 + byi+1+ c = 0 (等式 2)由等式1可以得到等式3:x i = -(byi+ c) / a (等式 3)同样,由等式2可以得到等式4:x i+1 = -(byi+1+ c) / a (等式 4)由等式 4 –等式3可得到x i+1– xi= -b (yi+1- yi) / a由于扫描线存在yi+1 = yi+ 1的关系,将代入上式即可得到:x i+1– xi= -b / a即△x = -b / a,是个常量(直线斜率的倒数)。

“活动边表”是扫描线填充算法的核心,整个算法都是围绕者这张表进行处理的。

要完整的定义“活动边表”,需要先定义边的数据结构。

每条边都和扫描线有个交点,扫描线填充算法只关注交点的x坐标。

每当处理下一条扫描线时,根据△x直接计算出新扫描线与边的交点x坐标,可以避免复杂的求交计算。

一条边不会一直待在“活动边表”中,当扫描线与之没有交点时,要将其从“活动边表”中删除,判断是否有交点的依据就是看扫描线y是否大于这条边两个端点的y坐标值,为此,需要记录边的y坐标的最大值。

根据以上分析,边的数据结构可以定义如下:65typedef struct tagEDGE66{67double xi;68double dx;69int ymax;74}EDGE;根据EDGE的定义,扫描线4和扫描线7的“活动边表”就分别如图(7)和图(8)所示:图(7)扫描线4的活动边表图(8)扫描线7的活动边表前面提到过,扫描线算法的核心就是围绕“活动边表(AET)”展开的,为了方便活性边表的建立与更新,我们为每一条扫描线建立一个“新边表(NET)”,存放该扫描线第一次出现的边。

当算法处理到某条扫描线时,就将这条扫描线的“新边表”中的所有边逐一插入到“活动边表”中。

“新边表”通常在算法开始时建立,建立“新边表”的规则就是:如果某条边的较低端点(y坐标较小的那个点)的y坐标与扫描线y相等,则该边就是扫描线y的新边,应该加入扫描线y的“新边表”。

上例中各扫描线的“新边表”如下图所示:图(9)各扫描线的新边表讨论完“活动边表(AET)”和“新边表(NET)”,就可以开始算法的具体实现了,但是在进一步详细介绍实现算法之前,还有以下几个关键的细节问题需要明确:(1)多边形顶点处理在对多边形的边进行求交的过程中,在两条边相连的顶点处会出现一些特殊情况,因当出现这种情况的时候,会对填充产生影响,因为填充的过程是成对选择交点的过程,错误的计算交点个数,会造成填充异常。

假设多边形按照顶点P1、P2和P3的顺序产生两条相邻的边,P2就是所说的顶点。

多边形的顶点一般有四种情况,如图(10)所展示的那样,分别被称为左顶点、右顶点、上顶点和下顶点:图(10)多边形顶点的四种类型左顶点――P1、P2和P3的y坐标满足条件:y1 < y2 < y3;右顶点――P1、P2和P3的y坐标满足条件:y1 > y2 > y3;上顶点――P1、P2和P3的y坐标满足条件:y2 > y1 && y2 > y3;下顶点――P1、P2和P3的y坐标满足条件:y2 < y1 && y2 < y3;对于左顶点和右顶点的情况,如果不做特殊处理会导致奇偶奇数错误,常采用的修正方法是修改以顶点为终点的那条边的区间,将顶点排除在区间之外,也就是删除这条边的终点,这样在计算交点时,就可以少计算一个交点,平衡和交点奇偶个数。

结合前文定义的“边”数据结构:EDGE,只要将该边的ymax修改为ymax – 1就可以了。

对于上顶点和下顶点,一种处理方法是将交点计算做0个,也就是修正两条边的区间,将交点从两条边中排除;另一种处理方法是不做特殊处理,就计算2个交点,这样也能保证交点奇偶个数平衡。

(2)水平边的处理水平边与扫描线重合,会产生很多交点,通常的做法是将水平边直接画出(填充),然后在后面的处理中就忽略水平边,不对其进行求交计算。

(3)如何避免填充越过边界线边界像素的取舍问题也需要特别注意。

多边形的边界与扫描线会产生两个交点,填充时如果对两个交点以及之间的区域都填充,容易造成填充范围扩大,影响最终光栅图形化显示的填充效果。

为此,人们提出了“左闭右开”的原则,简单解释就是,如果扫描线交点是1和9,则实际填充的区间是[1,9),即不包括x坐标是9的那个点。

扫描线算法实现扫描线算法的整个过程都是围绕“活动边表(AET)”展开的,为了正确初始化“活动边表”,需要初始化每条扫描线的“新边表(NET)”,首先定义“新边表”的数据结构。

定义“新边表”为一个数组,数组的每个元素存放对应扫描线的所有“新边”。

因此定义“新边表”如下:510 std::vector< std::list<EDGE>> slNet(ymax - ymin +1);ymax和ymin是多边形所有顶点中y坐标的最大值和最小值,用于界定扫描线的范围。

slNet 中的第一个元素对应的是ymin所在的扫描线,以此类推,最后一个元素是ymax所在的扫描线。

在开始对每条扫描线处理之前,需要先计算出多边形的ymax和ymin并初始化“新边表”:503void ScanLinePolygonFill(const Polygon& py,int color)504{505 assert());506507int ymin =0;508int ymax =0;509 GetPolygonMinMax(py, ymin, ymax);510 std::vector< std::list<EDGE>> slNet(ymax - ymin +1);511 InitScanLineNewEdgeTable(slNet, py, ymin, ymax);512ush_front(e);344}345else346{347=;348if>=349=-1;350else351=;352 slNet[- ymin].push_front(e);353}354}355}356}多边形的定义Polygon和本系列第一篇《计算几何与图形学有关的几种常用算法》一文中的定义一致,此处就不再重复说明。

算法通过遍历所有的顶点获得边的信息,然后根据与此边有关的前后两个顶点的情况确定此边的ymax是否需要-1修正。

ps和pe 分别是当前处理边的起点和终点,pss是起点的前一个相邻点,pee是终点的后一个判断结果对此边的ymax进行-1修正,算法实现非常简单,注意与扫描线平行的边是不处理的,因为水平边直接在HorizonEdgeFill()函数中填充了。

ProcessScanLineFill()函数开始对每条扫描线进行处理,对每条扫描线的处理有四个操作,如下代码所示,四个操作分别被封装到四个函数中:467void ProcessScanLineFill(std::vector< std::list<EDGE>>& slNet,468int ymin,int ymax,int color)469{470 std::list<EDGE> aet;471472for(int y = ymin; y <= ymax; y++)473{474 InsertNetListToAet(slNet[y - ymin], aet);475 FillAetScanLine(aet, y, color);476//删除非活动边477 RemoveNonActiveEdgeFromAet(aet, y);478//更新活动边表中每项的xi值,并根据xi重新排序479 UpdateAndResortAet(aet);480}481}InsertNetListToAet()函数负责将扫描线对应的所有新边插入到aet中,插入操作到保证aet还是有序表,应用了插入排序的思想,实现简单,此处不多解释。

相关文档
最新文档