基本图形生成算法
图元扫描转换
直线段扫描转换
圆弧扫描转换
实区域填充
图形的剪裁
图形反走样
消隐
光栅化算法
线段光栅化算法
DDA算法
中点Bresenham画线算法
Bresenham改进算法
圆光栅化算法
中点算法
中点整数算法
中点整数优化算法
直线的扫描转换:
最佳逼近于该直线的一组象素;按扫描线顺序,对这些象素进行写操作
一、直线段的生成
1.DDA算法
原理:直线的一阶导数连续,且X Y的变化量成正比,通过每次加一定的增量绘点
由于精度有限,选择ε=1/max(|Δx|,|Δy|),则ε*Δx或ε*Δy称为最大步长;每次在最大位移上增加一个步长
当|k|≤1,max=|Δx|:x‘=x±1,y'=y±k
当|k|≥1,max=|Δy|:x‘=x±1/k,y'=y±1
注意:每次绘制的点,对求出的x’和y‘四舍五入,即加0.5再取整int
2.中点画线法Bresenham
直线将坐标平面分成三部分:在线上,F(x,y)=0;在上方,F(x,y)>0;;在下方,F(x,y)<0。
每次在最大位移方向走一步,另一方向是否走取决于误差项d
假设0≤k≤1:
求出正的dx和dy;d0=dx-2*dy;UL=2*dx-2*dy,DL=-2*dy;
绘制当前的点(x,y),x++;
判断d的正负:d>0则取正右侧的点,绘制后,d’=d+DL;否则取右上方的点,绘制后,d‘=d+UL
二、圆的生成
中点画圆法;画八分之一后对称
第一个点:(0,r);d0=1.25-r(实际上多采用1-r,结果相同)
判断d的正负:
d<0:d’=d+2x+3,下一个点取正右侧点;
d>0:d'=d+2(x-y)+5,下一个点取右下角的点。
三、椭圆的扫描转换
类似于圆的扫描转换。
分界线:切线斜率为-1的点
四、多边形填充算法
实区域填充算法分类:
扫描线填充算法---扫描线顺序
有序边表算法
边缘填充算法
种子填充算法---内部一个点出发
简单种子算法
扫描线种子算法
Ⅰ-扫描线填充算法:
1.顶点交点的计数问题
检查交于该顶点的两条边的另外两个端点的y值大于该顶点y值的个数
2.影响效率的原因
求交和排序——简化交点运算——每条扫描线的活动边表
1)有序边表法
活性边表:
与当前扫描线相交的边称为活性边;按与扫描线交点x坐标递增的顺序存入一个链表中,称为活动边表;记录了多边形边沿扫描线的交点序列。
对当前扫描线的活动边表作更新,即可得到下一条扫描线的活动边表
活性边表中的信息
x:当前扫描线与边的交点
△x=-b/a:从当前扫描线到下一条扫描线之间的x增量
ymax:边所交的最高扫描线
指向下一个的指针
活性边表的更新
新边插入、旧边删除
新边表:
存放该扫描线第一次出现的边;方便活性边表的更新
新边表的信息
x:扫描线与该边的初始交点
△x:x的增量
ymax:该边的最大y值
有序边表算法的数据结构:
由新边表ET和活性边表AEL两部分组成
表结构ET和AEL中的基本元素为多边形的边
x: 在ET中表示边的下端点的x坐标,在AEL中则表示边与扫描线的交点的坐标;
Δx:边的斜率的倒数;
ymax:边的上端点的y坐标;
next:指向下一条边的指针。
填表示例:
算法:
优缺点:
优点:每个像素值访问一次且与设备无关;
缺点:数据结构复杂 只适合软件实现
2)边缘填充算法 / 看图就明白了
按照边的顺序逆时针进行、填充每条边所对应正右侧的部分、填充奇数次保留,偶数次抵消;
优点:有帧缓存的显示器;任意顺序处理多边形的边;仅访问与该边有交点的扫描线上右方的像素,算法简单
缺点:每一像素可能被访问多次,输入/输出量大;图形输出不能与扫描同步进行,全部画完才能打印
补充:栅栏填充算法 / 原来的参照线为最右侧,改为“栅栏”
Ⅱ-种子填充算法-要求区域是连通的
简单种子算法
从一个点向外扩展;四连通or八连通
4连通:
(1)栈顶像素出栈
(2)将出栈象素置成填充色
(3)按右、上、左、下顺序检查与出栈象素相邻的四象素,若其中某象素不在边界上且未被置成填充色,则将其入栈
可以填充有孔区域
缺点:象素会入栈多次,降低效率占空间;算法简单但是费时间和内存
扫描线种子填充算法
减少递归;适用于边界表示的4连通区域
在任意不间断区间中只取一个种子像素——
(1)栈顶像素出栈
(2)沿扫描线对出栈像素的左右像素进行填充,直到遇到边界像素为止
(3)将上述区间内最左、最右像素记为xl和xr
(4)在区间[xl,xr]中检查与当前扫描线相邻的上下两条扫描线是否全为边界像素、或已填充的像素,若不是,则把每一区间的最右像素取为种子像素入栈
可以填充有孔区域
五、图形反走样技术
阶梯边界/细节失真/狭小意识/动画序列中时隐时现,产生闪烁
方法:
提高分辨率-代价高,减轻而不消除;分辨率*2,点距/2,帧缓存&时间*4
高分辨率-(显示模式)计算、低分辨率显示-减轻而不消除;(把每个像素分为四个子像素,扫描转换算法求得各子像素的灰度值,然后对四像素的灰度值简单平均,作为该像素的灰度值)
简单区域取样-改变直线段模型。将直线段→有一定宽度的狭长矩形 、当直线段与象素有交,求出相交区域的面积 、根据面积确定该象素的亮度值(仍有锯齿效应,灰度差)