图形学复习
CH7 光栅化
前几章介绍了几何处理和裁剪变换,接下来的步骤就是光栅化
光栅化是将形式表示的几何图元转换为阵列表示的数据片元的过程,片元中每一个像素对应帧缓冲区中的每一个像素
7.1 线段生成算法
(1)DDA画线算法
设直线表达式为y=mx+b,输入直线两端点坐标(x0,y0)和(xend,yend),可以计算出m=yend?y0xend?x0和b=y0?m?x0
DAA是基于微分运算的线段生成算法,其主要计算式便是δy=mδx:
若|m|≤1则x方向的变化大于y方向的变化,以x方向为主方向,取δx=1根据m计算δy=mδx
若|m|>1则y方向的变化大于x方向的变化,以y方向为主方向,取δy=1根据m计算δx=1mδy
为了有效的避免了斜率为正无穷时xend?x0=0的除零计算,我们将不直接计算m而是直接比较Δy=|yend?y0|和Δx=|xend?x0|的大小确定步长,计算出步长后每一步从的(x,y)更新到(x+xstep,y+ystep)并计算取整即可(注意,像素永远是整数点)
下面是DDA算法C语言版本代码:
void lineDDA(int x0, int y0, int xend, int yend){
int steps, k;
float xstep, ystep;
float x = x0, y = y0;
int dx = xend - x0;
int dy = yend - y0;
if (fabs(dx) >= fabs(dy))
steps = dx;
else
steps = dy;
xstep = (float)dx / (float)steps;
ystep = (float)dy / (float)steps;
setPixel(round(x), round(y));
for (k = 0; k < steps; k++) {
x += xstep;
y += ystep;
setPixel(round(x), round(y));
}
}
DDA算法避免的迭代时的乘积运算因此比直接用直线表达式求点坐标效率更高,但是,每一步骤中的浮点操作和取整运算开销仍然较大(体系结构告诉我们整数运算和浮点运算效率可以相差几十倍)
(2)Bresenham画线算法
Bresenham画线算法是一种精确而有效的线段生成算法,它运用DDA的思想并通过邻近点的比较避免了浮点操作和取整运算,下面讨论斜率小于1的线段的Bresenham画线算法(斜率大于1只需要类似DDA中的比较、交换即可)
再进一步方便讨论,限定0≤m≤1,我们需要确定的是当前画了点(xk,yk)之后下一步要画的点(xk+1,yk+1)的位置,由于x是主方向所以取xk+1=xk+1毋庸置疑,而x是主方向说明了ystep≤xstep=1,则yk≤yk+1≤yk+1,由于只能去整数点那么yk+1就只能是yk、yk+1二者其中之一,很显然我们只用选一个离yk