光栅图形学概述
图形显示过程:一个三角形,原始数据是三个点的坐标,帧缓存中转化为点阵数据---此时已经有了图形的样子。问题:如何由几何参数得到图形的点阵形式?
图元的生成:指完成图元的参数表示形式到点阵表示形式的转换
点阵表示又分为两种
单缓存与双缓存机制
单缓存:生成点阵---存入缓存区---打印---再生成点阵
双缓存: 缓存2---打印
生成点阵---存入缓存1
①:交换缓存内容,缓存2用过的内容会被缓存1未打印的内容覆盖,交换后缓存1中已经打印的内容被新生成的点阵覆盖
图元的生成
扫描转换直线段
求与直线段充分接近的像素集,并以此像素集替代原连续直线段
法一:直线方程法 y=kx+b
yi,r即四舍五入
法二:数值微分DDA算法
round(yi+1)
(避免了乘法)
法三:中点算法
目标:消除浮点运算
设:
已计算出像素(xi , yi,r )如何判断距直线最近的下一个像素点(xi+1, yi+1)?
构造判别式:d = F(M) = F(xi+1, yi,r+0.5) 由 d 的正和负可判定下一个像素
d≥0,中点M在线段上方,取E;d <0,中点M在线段下方,取NE
(M是中点)
如何判定再下一个像素(xi+2,yi+2)?
增量d的初始值
因为只需要判断d的正负不需要大小。所以用2d代替d消除浮点数0.5
结论:
注意:结论只适用于k在0~1的情况,其他情况有其他的结论
扫描转换圆弧
特殊圆:圆心在原点的圆弧 其他情况:平移到原点扫描转换,然后再移回去
法一:方程法
缺点:开平方,三角函数运算,计算量大
法二:中点算法 (与线段的中点算法思路相同)
圆弧的正负划分性:
八分圆:八分之一个圆弧就可以还原出一个完整的圆 选图示圆弧
构造判别式:
D的初始值
结论:
消除乘法运算(Hi的递推公式里有乘法运算)
变量关系:
法三:逼近法 (分为内接逼近和外切逼近)
问题:多少条边合适/给定最大逼近误差,如何确定多边形的最少边数n或a?
小结:中点算法是一种高效的扫描转换算法。特点是只用到整数的加法运算。
条件是先画图元需要具有正负划分性
填充图元生成
步骤:确定那些像素在图元内部;用指定颜色绘制像素
两种方法:扫描线算法(参数->点阵);种子填充法(点阵->点阵)
扫描线算法: 逐点判断法;扫描判断法
一般单独处理矩形,原因: 比一般的多边形相比简单;应用多
图形共享边界的处理:左闭右开,下闭上开
矩形的参数:左下角坐标、右上角坐标
多边形表示:顶点表示;点阵表示
扫描转换多边形:将多边形顶点表示形式转换成点阵表示形式
多边形分类:凸、凹
评判表针:内角是否均小于180
多边形边的延长线是否划分顶点在两侧,都在延长线同侧为凸多边形
每条边建立向量,测试相邻边的叉积是否同号(向量积正负:右手定则)
图示为凹多边形
法一:逐点判断法
判断绘图窗口内的像素是否位于多边形内,若是,则绘制该像素
判断方法:射线法
从待判别点 v 发出射线,求与多边形交点个数 k,k 的奇偶性决定了点与多边形的内外关系:偶数:外,奇数:内
特殊情况的判别:
特点:简单,孤立考虑每一个点,速度慢。 改进:扫描线算法
法二:扫描线算法:利用相邻像素之间的连贯性,提高算法效率
一条扫描线与多边形的边有多个交点,每2个点形成一区间,区间内的像素位于多边形内
扫描线:平行于坐标轴的直线,一般取平行于X轴
扫描区间:扫描线与边的交点间的线段
步骤: 方法优化:连贯性P56
交点:假定扫描线按y 值小到大顺序进行
交点计算:
交点取整规则(需注意遵循共享边界原则):
交点坐标不能采用“四舍五入”原则,否则会导致部分像素位于多边形之外
规则三:对于扫描线和多边形的交点正好是多边形顶点的情况。该顶点应该视为几个交点?
检查该顶点对应的两条边的另外两个端点,这两个端点的Y值大于交点Y
值的个数是0,1,2,来决定该顶点视为0,1,2个交点
水平边不参与计算交点:
ABDEH是非水平边的靠下的端点,算是交点;CIGF则不算交点
算法实现
边表ET:
Deltax:用于递推计算交点x’=x+1/m
ymax:当扫描线 y = e + 1 == ymax,说明下一条扫描线与此边不相交
活性边表AEL: 活性边:与当前扫描线相交的边
作用:存储与当前扫描线的交点,同时快速计算下一条扫描线与多边形相交的点,且可判断边是否与下一条扫描线相交
种子填充算法 (区域填充算法要求区域是连通的)
将指定颜色从种子(人为选定)开始扩展到整个区域
表示方法:
内点表示:枚举区域内部像素,内部所有像素为同一颜色,与边界颜色不同
外界表示:枚举边界像素,外部所有像素为同一颜色,与内部颜色不同
连通性: 八连通包含四连通/八连通的能力要强于四连通
缺点:有的像素会重复判断,降低效率;递归会用到栈,空间占用大,效率低
改进:减少递归提高效率。 方法之一是使用扫描线填充法
两种方法比较