一、基本概念
光栅化(Rasterization)也叫扫描转换。
一幅2D图像通常含有很多几何原图,而2D显示仪器是由离散的像素组成。
像素的数目一般少于几何原图的数目。
将2D图像的几何原图转换为像素表示的过程叫光栅化。
复杂度:O(Pp),其中P是原始图像的量;p是离散像素的数量。
像素的表示有两种:坐标(x,y)表示的一个像素格的位置
①半数字中心:像素格的左下角
②数字中心:像素格的中心
像素的邻域:
①4邻域
②8邻域
光栅化的难点:
①确定像素和几何原图的对应关系
②效率
二、数学曲线
1.隐式形式(函数)
f(x,y)<0,点(x,y)在曲线内
=0,点(x,y)在曲线上
>0,点(x,y)在曲线外
①线:l(x,y)≡ax+by+c
②圆:c(x,y)≡(x-xc)2+(y-yc)2-r2
2.参数形式
f(x,y)=f(x(t),y(t))
①线:l(t)=(x(t),y(t));其中x(t)=x1+t(x2-x1),y(t)=y1+t(y2-y1)
②圆:c(t)=(x(t),y(t));其中x(t)=xc+rcos(2πt),y(t)=yc+rsin(2πt)
三、有限微分(finite differences)
用函数表示几何原图时需要对每一个像素栅格进行估值——浪费性能
利用有限微分降低开销
k重向前微分(Kth fd):δkfi=δk-1fi+1-δk-1fi
例子:
对直线l(x,y)先通过δxl(x,y)+l(x,y)得到l(x+1,y);再用类似方法得到l(x,y+1)
因为要确定几何原图在哪个像素里,所以效率不高
四、线段栅格化算法
选择选段数学上的最近的像素
常数线宽,独立的斜率,没有缺口,高效
line1 ( int xs, int ys, int xe, int ye, colour c ) { float s; int x y; s = (ye - ys) / (xe - xs); (x, y) = (xs, ys); while (x <= xe) { setpixel (x, y, c); x=x+1 ; y = ys + round(s * (x - xs)); } }
这是第一象限斜率小于1的线段的栅格化算法
因为round操作过多,影响效率,可以引入一个变量e表面小数部分,如果大于1/2则y+1,e--
由于浮点数的精度问题,会有误差积累
五、Bresenham直线算法
同四的条件相同
由于是找最近的像素,假设目前已选的点是(xi,yi),接下来确定下一个点是S(xi+1,yi)还是T(xi+1,yi+1)
假设两点距离真实线在y方向的距离分别是s和t,则可以通过s-t来判断改选S还是T
s-t=(y-yi)-[(yi+1)-y]=2y-2yi-1=2m(xi+1)+2b-2yi-1 //y用xi+1来表达,不是x
用dy/dx代替m,有dx(s-t)=2dy(xi+1)+2bdx-2dxyi-dx=2dyxi-2dxyi+C //dy=ye-ys,dx同理
假设ei=dx(s-t)与s-t同号 //dx>0
ei+1-ei=2dy(xi+1-xi)-2dx(yi+1-yi)
所以选中的是T的时候:ei+1=ei+2(dy-dx) //yi+1-yi=1
选中的是S的时候:ei+1=ei+2dy //yi+1-yi=0
line3 (int xs, int ys, int xe, int ye, colour c) { int x, y, e, dx, dy; e = -(dx >> 1); dx =(xe -xs); dy =(ye -ys); (x y) = (xs ys); while(x <= xe) { setpixel(x, y, c); x = x + 1; e = e + dy; if(e >= 0) { y = y + 1; e = e - dx; } } }
六、圆的栅格化算法
分为8个象限,计算一个,然后用对称的办法递推至其他的
set8pixels ( int x, int y, colour c ) { setpixel(x, y, c); setpixel(y, x, c); setpixel(y, -x, c); setpixel(x, -y, c); setpixel(-x, -y, c); setpixel(-y, -x, c); setpixel(-y, x, c); setpixel(-x, y, c); }
Bresenham 算法
选取45度到90度这一象限,所以已选择点P(xi,yi)要确定下一个点选T(xi+1,yi)还是S(xi+1,yi-1)
设D(T)=(xi+1)2+yi2-r2>0,D(S)=(xi+1)2+(yi-1)2-r2<0
令di=D(T)+D(S)
di<0时,则|D(T)|<|D(S)|
di≥0时,则|D(T)|≥|D(S)|
di+1-di=2(xi+1+1)2+yi+12+(yi+1-1)2-2(xi+1)2-yi2-(yi-1)2
di+1=di+4xi+2(yi+12-yi2)-2(yi+1-yi)+6 //因为xi+1=xi+1
选中T时:di+1=di+4xi+6 //因为yi+1=yi
选中S时:di+1=di+4(xi-yi)+10 //因为yi+1=yi-1
circle ( int r, colour c ) { int x, y, d; x = 0; y = r; d = 3 - 2 * r; while(x <= y) { set8pixels(x, y, c); if(d < 0) d = d + 4 * x + 6; else { d = d + 4 * ( x - y ) + 10; y--; } x++; } }
原文:http://www.cnblogs.com/l00196472/p/3616426.html