计算机图形学有很多可以研究的内容,而作为初学者,你必须要知道的经典算法和经典问题有哪些?
本文将介绍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.画家消隐算法:
原理简述:从远景开始逐步绘制到近景,这样后绘制的部分就会覆盖先绘制的部分,自然达到消隐目的
算法流程图: