计算机图形学经典算法及问题总结

计算机图形学有很多可以研究的内容,而作为初学者,你必须要知道的经典算法和经典问题有哪些?

本文将介绍DDA直线生成算法(C语言描述),Bresenham直线生成算法(C语言描述),Cohen-Sutherland裁剪算法Bezier曲线问题Zbuffer消隐算法(流程图),画家消隐算法(流程图)

1.DDA直线生成算法:

原理简述:通过Δx和Δy确定移动步数step = max { Δx, Δy },则每次x移动:Δx/step,y移动:Δy/step。(优点:光滑;缺点:用到int->float计算慢)

C语言描述:

void DDAline(int x1,int x2,int x3,int x4,RBG colour){
    int i,step;
    int x = x1;
    int y = y1;
    if( abs(x2-x1) > abs(y2-y1) )
        step = abs(x2-x1);
    else step = abs(y2-y1);
    for( i = 0 ; i < step ; i++){
        putpixel(x , y , colour);
        x = x + float( float(x2-x1)/step );
        y = y + float( float(y2-y1)/step );
    }

}

2.Bresenham直线生成算法:

原理简述:

k=<1,Δx>0时:x++,然后通过比较y在这个x取值时可能的值与真实直线的误差,当误差绝对值小于1/2(e<0),即可以确定该值是整型画线下误差最小的点。

k=<1,Δx<0时:x--,然后通过比较y在这个x取值时可能的值与真实直线的误差,当误差绝对值小于1/2(e<0),即可以确定该值是整型画线下误差最小的点。

k>1,Δy>0时:y++,然后通过比较x在这个y取值时可能的值与真实直线的误差,当误差绝对值小于1/2(e<0),即可以确定该值是整型画线下误差最小的点。

k>1,Δy<0时:y--,然后通过比较x在这个y取值时可能的值与真实直线的误差,当误差绝对值小于1/2(e<0),即可以确定该值是整型画线下误差最小的点。

其中误差:

当 |k|=<1,初值:e = 2 |Δy| -2 |Δx|,e<0:e = e+2 |Δy|;e>0:e = e-2 |Δx|。

当 |k| >1,初值:e = 2 |Δx| -2 |Δy|,e < 0:e = e + 2 |Δx|;e>0:e = e - 2 |Δy|。

C语言描述:

void Bline(int x1, int x2, int y1, int y2, int colour){
    int x = x1, y = y1;
    int i;
    int flagx = 1, flagy = 1;
    if(x2 - x1 < 0) flagx = -1;
    if(y2 - y1 <0 ) flagy = -1;
    m = abs(y2 - y1) / abs(x2 - x1);
    if (m <= 1) {
        e = 2*abs(y2 - y1) - 2*abs(x2 - x1); 
        for (i = 0; i < abs(x2 - x1); x += flagx){
            putpixel(x,y,colour);
            if(e <= 0)  
                e += 2*abs(x2 - x1);
            else{
                y += flagy;
                e -= 2*abs(y2 - y1); 
            }
        }
    }
    if(m > 1){
        e = 2*abs(x2 - x1) - 2*abs(y2 - y1);
        for(i = 0; i < abs(y2 -y1); y += flagy){
            putpixel(x,y,colour);
            if(e <= 0) e += 2*abs(y2 - y1);
            else{
                x += flagx;
                e -= 2*abs(x2 -x1);
            }
        }
    }

}

3.Bezier 曲线问题:

4.Cohen-Sutherland裁剪算法:(即编码裁剪方法)

step1:编码:

把窗口的四条边界线延伸,在平面上划分出九个区域,用四位二进制数C3C2C1C0对这九个区域的点进行编码:C0:线段端点是否在窗口左边界左侧;C1:线段端点是否在右边界右侧;C2:线段端点是否在下界之下;C3:线段端点是否在上边界之上。

int pCode(int x,int y){
    int code = 0;
    if(x < Wleft) code |= 8;
    if(x > Wright) code |= 4;
    if(y < Wbotton) code |= 2;
    if(y > Wtop) code |= 1;
    return code;
}

step2:判断线段是否可见:

完全可见的充要条件:!P1Code&&!P2Code

完全不可见的条件:按位与不为零 或 按位与为零但与窗口没有交点,不考虑交点的充分条件:按位与不为零

部分可见的条件:按位与为零且有交点,不考虑交点的充分条件:两个编码一个为零一个不为零

(中点分割算法用中点代替线段与窗口求交,省去了大量乘除运算)

5.Zbuffer消隐算法:

原理简述:Z轴缓冲也被称为深度缓冲,它保存在屏幕上每个像素的深度值。在把显示对象的每个面上每一点的颜色值填入帧缓冲器相应单元前,要把这点的z坐标值和z缓冲器中相应单元的值进行比较。只有前者大于后者时才改变帧缓冲器的那一单元的值,同时z缓冲器中相应单元的值也要改成这点的z坐标值。如果这点的z坐标值小于z缓冲器中的值,则说明对应象素已经显示了对象上一个点的属性,该点要比考虑的点更接近观察点(如果当前像素的深度和深度缓存中的值相等,那么也认为当前像素被挡住了)。Z-Buffer算法在像素级上以近物取代远物。面片在屏幕上的出现顺序是无关紧要的。

优点:远比总体排序灵活简单,有利于硬件实现;缺点:占用空间大,没有利用图形的相关性与连续性

算法流程图:

6.画家消隐算法:

原理简述:从远景开始逐步绘制到近景,这样后绘制的部分就会覆盖先绘制的部分,自然达到消隐目的

算法流程图:

 

你可能感兴趣的:(计算机图形学)