13图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)
♥,.*,.♥,.*,.♥,.*,.♥,.*♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥♥,.*,.♥,.*,.♥,.*,.♥,.*♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥
目录
1.光栅化
2.区域填充(种子填充算法)
3.多边形的扫描转换(扫描线算法)
4.多边形的扫描转换与区域填充比较
♥,.*,.♥,.*,.♥,.*,.♥,.*♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥♥,.*,.♥,.*,.♥,.*,.♥,.*♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥,.*,.♥
1.光栅化
光栅化是在设备变换的时候进行的操作。即从图像坐标系得到规格化设备坐标系。
光栅图形的本质是点阵表示。
多边形有两种表示方式:
- 顶点表示:利用有序顶点来表示多边形
- 点阵表示:用多边形内部的像素集合来表示多边形
多边形的扫描转换就是将多边形的顶点表示转换为多边形的点阵表示。
2.区域填充
将已经表示成点阵的像素集合,进行区域内部的填充。
区域有两种表示:
(1)内部表示
区域内的所有像素着同一种颜色,边界像素不能着上述颜色。
(2)边界表示
边界上的所有像素着同一种颜色,区域内部像素不能着上述颜色。
区域填充的类型有四连通邻域和八连通邻域。
区域填充可以使用区域种子填充算法。
内部表示的区域种子填充算法为(四连通区域):
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)区域连贯性:多边形区域内部相邻的像素具有相同的性质。
如图可以看出两条扫描线之间的长方形区域被分割成若干的梯形。梯形的腰为边界。
并且如果梯形位于多边形内,则梯形内所有的点都位于多边形内(因此可以提高效率)。
(2)扫描线连贯性:区域连贯性在一条扫描线上的反映。
从图可以看出扫描线与多边形的交点个数为偶数(1,2,3,4,5,6)。
红色区间为(1,2),(3,4),(5,6)位于多边形内部。绿色部分位于多边形外部。
因此如果交点区间属于多边形内,则区间内的所有点均位于多边形内。
(3)边连贯性:直线的线性性质在光栅上的表现。
扫描线与边的交点:
1(x1,y1) 2(x2,y2) 11(x11,y11) 22(x22,y22)
相邻的扫描线(y1=y11+1)与边的交点存在关系:
则可以得到:
则利用这个增量算法可以快速的算出其他交点。
通过(1)(2)(3)可以得出,
扫描线连贯性+边连贯性=区域连贯性
还有一个关键点,就是奇异点。
如上图,1,2位奇异点。奇异点为扫描线与多边形交于多边形的交点。
奇异点的分类:
(1)极值点
在极值点处,按照两个交点计算。
如图,为极值点。满足:
即相邻的三个顶点位于扫描线的同一侧。
(2)非极值点
在非极值点处,按照一个交点计算。
如图,为非极值点。满足:
即相邻的三个顶点位于扫描线的两侧。
对于非极值点,在预处理的时候截断一个单位,这样扫描线与多边形只有一个交点。
多边形的扫描转换算法
其思想为:
从下到上进行扫描。
计算扫描线与多边形的交点。然后根据多边形的边的连贯性,从下到上的顺序求得各条扫描线的交点序列。根据区域和扫描线的连贯性,判断位于多边形内部的区段。最后对多边形内部的直线段进行着色。
多边形扫描转换算法的数据结构有两个:
(1)分类的边表ET(Sorted Edge Table):记录多边形信息
(2)活化边链表AEL(Active Edge List):记录当前扫描线信息
边的数据结构:
:边的上端点的y坐标
x:边的下端点的x坐标。在活化边链表中,表示扫描线与边的交点的x坐标。‘’
dx:边的斜率的导数
next:指向下一条边的指针
分类的边表ET(Sorted Edge Table)
分类的边表是按边的下端点的纵坐标y对非水平边进行分类的指针数组。
如果下端点的纵坐标y值等于i的边,归入第i类。
同一类中,各边按照x值递增的顺序排成行(水平边不加入分类边表中)。
边表的数据结构即上述介绍的边的数据结构。
举例:
首先进行预处理,由于P0和P4点是非极值点,因此对其进行截断操作(截断操作可以见极值点和非极值点的介绍)。
扫描线由下至上扫描,
y=1,扫描线与多边形的边没有交点,数据结构为null。
y=2,扫描线与多边形的边e7和e5交于P6和P5点,此时数据结构为:
(同一类型按照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),此时数据结构为:
y=6,扫描线与e4边相交(P4点进行了截断操作),此时e4边与y=6相交于点(29/2,6),此时数据结构为:
y=7,扫描线与e2和e3边相交,此时数据结构为:
综上,边的数据结构为:
活化边链表AEL(Active Edge List)
活化边链表由与当前扫描线相交的边组成。其记录了多边形的边沿扫描线的交点序列。
基本单元是与扫描线相交的边。
活化边链表与分类边表的不同:分类边表记录的是初始状态,而活化边表随着扫描线的移动会动态更新。
举例:
y=3和y=8时,如果是分类边表表示法,则链表为空。
如果是活化边链表表示法,则为:
即活化边链表,会随着扫描线的移动动态更新数据,但是边的数据结构是不变的。
多边形扫描转换算法的步骤为:
(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图形光栅化——区域填充(种子填充)+多边形扫描转换(扫描线算法)相关推荐
- 图形学学习笔记2——点阵图形光栅化
点阵图形光栅化 将参数描述的图形转化为点阵的算法,评价指标有:精度.时间复杂度.空间复杂度.对实时性要求高的实时渲染场景比如游戏动画,应该需要更快的转化为点阵.类似制作动画片的离线渲染就对精度要求更高 ...
- c++实现种子填充算法与扫描线算法
前言 默认您已经配置好相关环境. 如若没有,可以自行搜索"EasyX"下载安装. 本教程主要从代码方面讲解算法的实现. 至于理论部分还请大家自行搜索其他文章.(该类文章非常多) 种 ...
- 计算机图形学三:光栅化-Rasterization
文章目录 什么是光栅化? 像素和屏幕 直线光栅化(Linear Rasterization) DDA数值微分算法 中点Bresenham算法 三角形光栅化(Triangle Rasterization ...
- 多边形区域填充算法--扫描线种子填充算法
分享一下我老师大神的人工智能教程.零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow http://bl ...
- 基本图形的光栅化算法
如何在指定的输出设备上根据坐标描述构造基本二维几何图形(点.直线.圆.椭圆.多边形域.字符串及其相关属性等). 图形生成的概念 图形的生成:是在指定的输出设备上,根据坐标描述构造二维几何图形. 图形的 ...
- 洪水填充算法_区域填充算法和多边形填充的扫描线算法
本文主要介绍几种区域填充算法,重点解释多边形的扫描线填充算法,最后实现了多边形填充算法,包括在附录文件中.在参考[5]中,作者详细介绍了一系列区域填充算法,可以查看相应网页.代码的下载地址为:http ...
- 计算机图形学 -- 光栅图形学扫描线填充多边形[转]
http://blog.sina.com.cn/s/blog_55a8a96d0100084k.html 研究如何用一种颜色或图案来填充一个二维区域.一般来说,区域的封闭轮廓是简单的多边形.若轮廓线由 ...
- 复杂多边形光栅化算法
虽然已经一年多没有维护gbox这个图形库项目了,最近确实时间不够用... 今年的重点是把xmake彻底正好,至少在架构和大功能(包依赖管理)上,要完全落实下来,后期就是零散的维护和插件功能扩展了.. ...
- opengl 区域填充之种子填充线扫描法
青岚影视 www.qldyy.net 在事先画好的一个区域内,使用区域填充之种子填充线扫描法将其填充完毕.同时带有鼠标和键盘事件,并添加了菜单.对于存在的改变窗口大小程序会出现问题还没有很好的解决,只 ...
最新文章
- hdu 2795 段树--点更新
- mysql等价语句是_Mysql基本语句(个人笔记)
- Nginx深入了解-基础(一)
- .NET Core实战项目之CMS 第二章 入门篇-快速入门ASP.NET Core看这篇就够了
- CentOS7 搭建Pulsar 消息队列环境,CentOS(Linux)部署Pulsar,亲测成功,以及Python操作Pulsar实例驱动
- rocketMQ基本架构简介
- 面向对面 静态参数 与 组合
- MySql事务隔离级别概述
- win10 安装flutter记录
- Swift自定义Class实现Hashable
- 【译】使用Java编写Oracle Tuxedo应用
- win10连wifi显示无Internet最全解决方案
- 作为老师的一些思考(二)
- 怎样测试手机性能软件,如何检测手机性能的软件
- xyoj 6042:让人头疼的“双十一”
- 【解决笔记本电脑声音音量低的方法】
- USACO-Arithmetic Progressions
- address localhost:8080 is already in use(端口被占用)Windows系统问题解决
- 在网址上输入www.xxx.com到返回界面给用户发生了什么?
- java 百万数据查询_java一次性查询几十万,几百万数据解决办法
热门文章
- 基于Java毕业设计超市货品进销存系统前台源码+系统+mysql+lw文档+部署软件
- 字符串内排序-C语言
- delphi android jni,Delphi使用android的NDK是通过JNI接口,封装好了,不用自己写本地代码,直接调用...
- Wex5 组件的bind-visible属性控制显隐
- Nginx的进程管理与重载原理
- 作为后端开发人员应该懂的TCP、HTTP、Socket、Socket连接池,一文详解丨Linux后端开发
- java list底层实现_java中linkedlist的底层实现
- android js接口调用方法,详解Android JS相互调用
- shell脚本判断文件是否存在
- java文件放在哪里_Java文件路径