13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)

♥,.*,.♥,.*,.♥,.*,.♥,.*♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥♥,.*,.♥,.*,.♥,.*,.♥,.*♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥

目录

1.光栅化

2.区域填充(种子填充算法)

3.多边形的扫描转换(扫描线算法)

4.多边形的扫描转换与区域填充比较

♥,.*,.♥,.*,.♥,.*,.♥,.*♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥♥,.*,.♥,.*,.♥,.*,.♥,.*♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥

1.光栅化

光栅化是在设备变换的时候进行的操作。即从图像坐标系得到规格化设备坐标系。

光栅图形的本质是点阵表示

多边形有两种表示方式:

  • 顶点表示:利用有序顶点来表示多边形
  • 点阵表示:用多边形内部的像素集合来表示多边形

多边形的扫描转换就是将多边形的顶点表示转换为多边形的点阵表示。

13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)

2.区域填充

将已经表示成点阵的像素集合,进行区域内部的填充。

区域有两种表示:

(1)内部表示

区域内的所有像素着同一种颜色,边界像素不能着上述颜色。

(2)边界表示

边界上的所有像素着同一种颜色,区域内部像素不能着上述颜色。

区域填充的类型有四连通邻域和八连通邻域。

13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)

区域填充可以使用区域种子填充算法

内部表示的区域种子填充算法为(四连通区域):

Flood_Fill_4(x, y, G0, G1)

{

if(GetPixel(x,y) ==G0 ) // GetPixel(x,y) 返回(x,y)的颜色

  {

        SetPixel(x, y, G1);  //将(x,y)的添上颜色G1

        Flood_Fill_4(x-1, y, G0, G1);

        Flood_Fill_4(x, y+1, G0, G1); 

        Flood_Fill_4(x+1, y, G0, G1);

        Flood_Fill_4(x, y-1, G0, G1);

  }

}

边界表示的区域种子填充算法为:

Fill_Boundary_4_Connnected(x, y, BoundaryColor, InteriorColor)

// (x,y) 种子像素的坐标;

// BoundaryColor 边界像素颜色; InteriorColor 需要填充的内部像素颜色

{

        if(GetPixel(x,y) != BoundaryColor && GetPixel(x,y)!= InteriorColor )

        // GetPixel(x,y): 返回像素(x,y)颜

         {

               SetPixel(x, y, InteriorColor); // 将像素(x, y)置成填充颜色  

               Fill_Boundary_4Connnected(x, y+1, BoundaryColor, InteriorColor);

               Fill_Boundary_4Connnected(x, y-1, BoundaryColor, InteriorColor);

               Fill_Boundary_4Connnected(x-1, y, BoundaryColor, InteriorColor);

               Fill_Boundary_4Connnected(x+1, y, BoundaryColor, InteriorColor);

          }

}

3.多边形的扫描转换

多边形的扫描转换就是将多边形的顶点表示转换为多边形的点阵表示。

多边的扫描转换有逐点判断算法扫描线算法

3.1 逐点判断算法

逐个像素判断是否位于多边形内部。

判断的方法为射线法

射线法:从当前的像素发射一条不经过顶点的射线,如果与多边形的交点为奇数个点,则说明该点在多边形内部,如果与多边形的交点为偶数个点,则说明该点在多边形的外部。

射线法的虽然实现比较简单,但是速度慢。

3.2 扫描线算法

扫描线算法充分利用了相邻像素的连贯性。

连贯性有:区域连贯性、扫描线连贯性、边的连贯性

(1)区域连贯性:多边形区域内部相邻的像素具有相同的性质。

13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)

如图可以看出两条扫描线之间的长方形区域被分割成若干的梯形。梯形的腰为边界。

并且如果梯形位于多边形内,则梯形内所有的点都位于多边形内(因此可以提高效率)。

(2)扫描线连贯性:区域连贯性在一条扫描线上的反映。

13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)

从图可以看出扫描线与多边形的交点个数为偶数(1,2,3,4,5,6)。

红色区间为(1,2),(3,4),(5,6)位于多边形内部。绿色部分位于多边形外部。

因此如果交点区间属于多边形内,则区间内的所有点均位于多边形内。

(3)边连贯性:直线的线性性质在光栅上的表现。

13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)

扫描线与边的交点:

1(x1,y1)    2(x2,y2)    11(x11,y11)    22(x22,y22)

相邻的扫描线(y1=y11+1)与边的交点存在关系:

13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)

则可以得到:

13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)

则利用这个增量算法可以快速的算出其他交点。

通过(1)(2)(3)可以得出,

扫描线连贯性+边连贯性=区域连贯性

还有一个关键点,就是奇异点

13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)

如上图,1,2位奇异点。奇异点为扫描线与多边形交于多边形的交点。

奇异点的分类:

(1)极值点

在极值点处,按照两个交点计算。

13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)

如图,13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)为极值点。满足:13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)

即相邻的三个顶点位于扫描线的同一侧。

(2)非极值点

在非极值点处,按照一个交点计算。

13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)

如图,13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)为非极值点。满足:13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)

即相邻的三个顶点位于扫描线的两侧。

对于非极值点,在预处理的时候截断一个单位,这样扫描线与多边形只有一个交点。

13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)

多边形的扫描转换算法

其思想为:

从下到上进行扫描。

计算扫描线13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)与多边形的交点。然后根据多边形的边的连贯性,从下到上的顺序求得各条扫描线的交点序列。根据区域和扫描线的连贯性,判断位于多边形内部的区段。最后对多边形内部的直线段进行着色。

多边形扫描转换算法的数据结构有两个:

(1)分类的边表ET(Sorted Edge Table):记录多边形信息

(2)活化边链表AEL(Active Edge List):记录当前扫描线信息

边的数据结构:

13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法):边的上端点的y坐标

x:边的下端点的x坐标。在活化边链表中,表示扫描线与边的交点的x坐标。‘’

dx:边的斜率的导数

next:指向下一条边的指针

分类的边表ET(Sorted Edge Table)

分类的边表是按边的下端点的纵坐标y对非水平边进行分类的指针数组。

如果下端点的纵坐标y值等于i的边,归入第i类。

同一类中,各边按照x值递增的顺序排成行(水平边不加入分类边表中)。

边表的数据结构即上述介绍的边的数据结构。

举例:

13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)

首先进行预处理,由于P0和P4点是非极值点,因此对其进行截断操作(截断操作可以见极值点和非极值点的介绍)

扫描线由下至上扫描,

y=1,扫描线与多边形的边没有交点,数据结构为null。

y=2,扫描线与多边形的边e7和e5交于P6和P5点,此时数据结构为:

13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)(同一类型按照x的递增顺序进行排列)

[4,7,-2]为边e7的数据,4为边的上端点的y坐标系,7为边的下端点的x坐标。-2为边斜率的导数,最后存储了一个指针指向边e5。

y=3,扫描线与多边形的边(新的边)没有交点,与已经扫描过的边(旧边)的交点已经被归为了旧边中。

y=4,扫描线与多边形的边(新的边)没有交点(P0点进行了截断操作,少了一个像素点)。

y=5,扫描线与e1边相交(P0点进行了截断操作),此时e1边与y=5相交于点(17/6,5),此时数据结构为:

13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)

y=6,扫描线与e4边相交(P4点进行了截断操作),此时e4边与y=6相交于点(29/2,6),此时数据结构为:

13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)

y=7,扫描线与e2和e3边相交,此时数据结构为:

13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)

综上,边的数据结构为:

13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)

活化边链表AEL(Active Edge List)

活化边链表由与当前扫描线相交的边组成。其记录了多边形的边沿扫描线的交点序列。

基本单元是与扫描线相交的边。

活化边链表与分类边表的不同:分类边表记录的是初始状态,而活化边表随着扫描线的移动会动态更新。

举例:

13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)

y=3和y=8时,如果是分类边表表示法,则链表为空。

如果是活化边链表表示法,则为:

13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)

即活化边链表,会随着扫描线的移动动态更新数据,但是边的数据结构是不变的。

多边形扫描转换算法的步骤为:

(1)首先对y初始化。取扫描线纵坐标y的初始值为ET中非空元素的最小序号。在本例中是y=2。

(2)对ALE进行初始化。将边的活化链表AEL设置为空。

(3)从下到上的顺序对纵坐标值为y的扫描线进行如下操作:

a.如果分类边表ET中的第y类元素非空,则将属于该类的所有边从ET中取出并插入到边的活化链表AEL中,同时将ET中相应的边删除。在AEL中按照x值递增的方向进行排序。

b.对于当前扫描线,边的活化链表非空,则将AEL中的边交点两两依次配对。每一对边与当前扫描线的交点区间位于多边形的内部,依次对区间上的像素按照多边形的属性进行着色。

c.将活化链表AEL中满足y=ymax的边删除。

d.更新活化链表AEL。两x累加,x=x+dx,将y值累加,y=y+1。

当分类边表和活化边链表都为空的时候,算法结束。

多边形扫描算法的优点与不足

优点:

  • 充分利用多边形的区域、扫描线和边的连贯性,提高了计算的效率

不足:

  • 算法的数据结构和程序结构复杂
  • 对表的维护和排序开销大

4.多边的扫描转换与区域填充比较

(1)基本思想

多边形扫描转换是将多边新顶点表示转换为点阵表示,扫描过程利用了多边形的各种连贯性。

区域填充算法不改变区域的表示方法,利用的是区域的连贯性。

(2)对边界的要求不同

多边形扫描只要求每一条扫描线与多边形有偶数个交点。

区域填充中,四连通区域必须是封闭的八连通边界,八连通区域必须是封闭的四连通边界。

(3)出发点不同

区域填充需要区域内的一个种子点,多边形扫描则没有要求。

 

Click 下一篇文章:14.曲面消隐——图像空间算法(Z-buffer)+对象空间算法(画家算法+二叉空间剖分树)

 

♥,.*,.♥,.*,.♥,.*,.♥,.*♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥♥,.*,.♥,.*,.♥,.*,.♥,.*♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥

广告时间:

本宝宝开通了一个公众号,记录日常的深度学习和强化学习笔记。

希望大家可以共同进步,嘻嘻嘻!

求关注,爱你呦!

13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)