光栅化

一、基本概念

光栅化(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):δkfik-1fi+1k-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++;
    }
}
posted on 2014-03-21 19:53  金融挨踢狗  阅读(1234)  评论(0)    收藏  举报