扫描线填充算法(1)

参考网址:http://blog.csdn.net/orbit/article/details/7368996
http://wenku.baidu.com/view/4ee141347c1cfad6195fa7c9.html?from=search
http://download.csdn.net/detail/xiaowei_cqu/4408894
扫描转换和区域填充这个问题是:怎样在离散的像素集上表示一个连续的二维图形。
多边形的两种表示方法:
这里写图片描述
1、定点表示
如上图所示,可以实用点(P1,P3,P10,P8,P11,P12)这些点来表示。
2、点阵表示
也可以使用点(P1~P13)来表示图形。

两个表示方法的比较:
1、顶点表示方法,直观、几何意义强,占用内存空间少,但没有确切指明哪些像素在多边形内部,所以不能直接用于面着色。
2、可以直接用于着色,因为包含了所有的点信息。但是表示的数量太大。

多边形的扫描转换:
把多边形的顶点表示转换为点阵表示,这种转换称为多边形的扫描转换。

这里写图片描述
如果Yk+1=Yk+1;

数据结构:
一条边的记录包含了三个数据部分:
(1)该边y的最大值y;
(2)该边底端的x坐标xi;
(3)该边的斜率的倒数1/m;
(4)以及下一个边记录地址的指针;

举例:
这里写图片描述]

对于下面的多边形为其建立边表:
这里写图片描述
建立边表的方法:
(1)与x轴平行的边不计入;
(2)多边形的顶点分为两大类:一类是局部极值点,如上图的P1和P3。另外一类是非极值点,如上图的P2、P4、P5。当扫面线与第一类顶点相交时,应看作两个点;而当扫描线与第二类顶点相交时,应视为一个点;
对于极值点则要记录两条边;
(3)扫描线按照y轴从低到高顺次记录;
(4)一条边按照y轴的高低记录;
(5)多条边以x轴递增顺序记录;
上图说明:
(1)扫描线y=1,穿过了P3点,此点为极值点,则有两条边。P3P4和P3P2。注意不是P4P3和P2P3。也不是P3P2和P3P4。因为对于一条边来说,P4的y大于P3的y,所以是P3P4。同理,P3P2也是这么得到的。又因为P2点的x轴坐标大于P4点的坐标,所以P3P4在P3P2的前面。
(2)扫描线y=2,和多边形的两条边相交,P3P4和P3P2,但是这两条边已经被扫描线1占用了,也就不算做新的边,故扫描线2的边表为空。
(3)扫描线y=3,穿越了P4P5,P3P4,P3P2,这里只有P4P5是新的边,所以加入扫描线3的边表。
(4)扫描线y=4,与多边形相交的边有P4P5和P3P2,而这两条边都已经在边表中,所以扫描线4的边表为空。
(5)扫描线y=5,与多边形相交的边有P4P5、P3P2、P2P1,其中只有线段P2P1是新边,所以扫描线y=5的边表中有一个新边。
(6)扫描线y=6,与多边形相交的边有P4P5、P5P1、P2P1,其中只有线段P5P1是新边,所以扫描线y=6的边表中有一个新边。
(7)扫描线y=7,与多边形相交的边有P5P1、P2P1,这些边都不是新边,所以不需要加入边表中去。
边表的数据结构:
(Ymax,Xi,1/m,指针)
其中Ymax为边的两个端点的y值大的那一个y。而Xi为较低点的x,m为斜率,这里取个倒数。

算法过程:
(1)开始y=1,将边表中的y=1节点AET中,什么是AET呢?active edge table,俗称活化边表。这里要保证AET链表中记录按照x递增排列,如下图所示:
这里写图片描述
(2)因为上图中P3P4和P3P2两个xi是相同的都是6,中间没有任何点需要着色,所以无需处理。
(3)然后因为P3P4和P3P2的两个y值一个是3,一个是5,而此时处理的是y=1,所以不需要删除。为什么不删除呢?因为此时y=1还没有到达y=3和y=5。
(4)对保留下来的每个记录,用Xi+1/m代替Xi,比如:
这里写图片描述
(5)使yi+1,以便进入下一轮循环。当y=2时,ET表为空,所以不需要ET表加入AET表。此时上图中x=4和x=6.5,将他们之间的点填上像素。由于y=2,此时没有达到y=3和y=5,所以不必删除节点。
(6)再让Xi+1/m代替Xi,得到:
这里写图片描述
使yi=3,此时他的边表不为空,所以将其ET表加入,得到:
这里写图片描述
注意按照xi的升序排列。
将Xi=2,至Xi=7之间填上颜色。
(7)由于此时yi=3,而第一个节点的yi=3,所以去掉此节点。
这里写图片描述
(8)再用Xi+1/m代替Xi,得到:
这里写图片描述
使yi=4,重复继续。

你可能感兴趣的:(cg)