光栅显示器上显示的图形,称之为光栅图形。光栅显示器可以看作是一个象素矩阵,在光栅显示器上显示的任何一个图形,实际上都是一些具有一种或多种颜色和灰度象素的集合。由于对一个具体的光栅显示器来说,象素个数是有限的,象素的颜色和灰度等级也是有限的,象素是有大小的,所以光栅图形只是近似的实际图形。
确定最佳逼近图形的象素集合,并用指定的颜色和灰度设置象素的过程称为图形的扫描转换或光栅化。对于一维图形,在不考虑线宽时,用一个象素宽的直线或曲线来显示图形。二维图形的光栅化必须确定区域对应的象素集,将各个象素设置成指定的颜色和灰度,也称之为区域填充。任何图形光栅化后,显示在屏幕上的一个窗口里,超出窗口的部分不予显示。确定一个图形的哪些部分在窗口内,必须显示;哪些部分落在窗口之外,不予显示,这需要对图形进行裁剪。裁剪通常在扫描转换之前进行,从而可以对图形不可见部分不必进行扫描转换。在光栅图形中,非水平和垂直的直线用象素集合表示时,会呈锯齿状,这种现象称之为走样(aliasing);用于减少或消除走样的技术称为反走样(antialiasing)。提高显示器的空间分辨率可以减轻走样问题,但这是以提高设备成本为代价的。实际上,当显示器象素可以用多亮度(或灰度)显示时,可以通过调整图形上各象素的亮度来减轻走样问题。
图形反映的是现实世界中的物体,大多数物体是不透明的,如果从某一个角度观察物体,则物体的某些部分便不可见,即被隐藏起来了。如果在该物体的图形中,不把隐藏的线或面删除,容易导致对图形的错误理解。为了使计算机图形能够真实地反映这一现象,必须把隐藏的部分从图形中消除,习惯上称作消除隐藏线和隐藏面,或简称为消隐。
直线段的扫描转换算法
数学上的直线是没有宽度、由无数个点构成的集合,显然,光栅显示器只能近地似显示直线。当我们对直线进行光栅化时,需要在显示器有限个象素中,确定最佳逼近该直线的一组象素,并且按扫描线顺序,对这些象素进行写操作,这个过程称为用显示器绘制直线或直线的扫描转换。
由于在一个图形中,可能包含成千上万条直线,所以要求绘制算法应尽可能地快。一个象素宽直线绘制的三个常用算法:数值微分法(DDA)、中点画线法和Bresenham算法。
数值微分(DDA)法:
设过端点P0(x0 ,y0)、P1(x1 ,y1)的直线段为L(P0 ,P1),则直线段L的斜率 L的起点P0的横坐标x0向L的终点P1的横坐标x1步进,取步长=1(个象素),用L的直线方程y=kx+b计算相应的y坐标,并取象素点(x,round(y))作为当前点的坐标。因为:
yi+1 = kxi+1+b
= k1xi+b+kDx
= yi+kDx
所以,当Dx =1; yi+1 = yi+k。也就是说,当x每递增1,y递增k(即直线斜率)。根据这个原理,我们可以写出DDA画线算法程序。
DDA画线算法程序
void DDALine(int x0,int y0,int x1,int y1,int color)
{ int x;
float dx, dy, y, k;
dx = x1-x0; dy=y1-y0;
k=dy/dx,;y=y0;
for (x=x0;x< x1;x++)
{ drawpixel (x, int(y+0.5), color);
y=y+k;
}
}
确定最佳逼近图形的象素集合,并用指定的颜色和灰度设置象素的过程称为图形的扫描转换或光栅化。对于一维图形,在不考虑线宽时,用一个象素宽的直线或曲线来显示图形。二维图形的光栅化必须确定区域对应的象素集,将各个象素设置成指定的颜色和灰度,也称之为区域填充。任何图形光栅化后,显示在屏幕上的一个窗口里,超出窗口的部分不予显示。确定一个图形的哪些部分在窗口内,必须显示;哪些部分落在窗口之外,不予显示,这需要对图形进行裁剪。裁剪通常在扫描转换之前进行,从而可以对图形不可见部分不必进行扫描转换。在光栅图形中,非水平和垂直的直线用象素集合表示时,会呈锯齿状,这种现象称之为走样(aliasing);用于减少或消除走样的技术称为反走样(antialiasing)。提高显示器的空间分辨率可以减轻走样问题,但这是以提高设备成本为代价的。实际上,当显示器象素可以用多亮度(或灰度)显示时,可以通过调整图形上各象素的亮度来减轻走样问题。
图形反映的是现实世界中的物体,大多数物体是不透明的,如果从某一个角度观察物体,则物体的某些部分便不可见,即被隐藏起来了。如果在该物体的图形中,不把隐藏的线或面删除,容易导致对图形的错误理解。为了使计算机图形能够真实地反映这一现象,必须把隐藏的部分从图形中消除,习惯上称作消除隐藏线和隐藏面,或简称为消隐。
直线段的扫描转换算法
数学上的直线是没有宽度、由无数个点构成的集合,显然,光栅显示器只能近地似显示直线。当我们对直线进行光栅化时,需要在显示器有限个象素中,确定最佳逼近该直线的一组象素,并且按扫描线顺序,对这些象素进行写操作,这个过程称为用显示器绘制直线或直线的扫描转换。
由于在一个图形中,可能包含成千上万条直线,所以要求绘制算法应尽可能地快。一个象素宽直线绘制的三个常用算法:数值微分法(DDA)、中点画线法和Bresenham算法。
数值微分(DDA)法:
设过端点P0(x0 ,y0)、P1(x1 ,y1)的直线段为L(P0 ,P1),则直线段L的斜率 L的起点P0的横坐标x0向L的终点P1的横坐标x1步进,取步长=1(个象素),用L的直线方程y=kx+b计算相应的y坐标,并取象素点(x,round(y))作为当前点的坐标。因为:
yi+1 = kxi+1+b
= k1xi+b+kDx
= yi+kDx
所以,当Dx =1; yi+1 = yi+k。也就是说,当x每递增1,y递增k(即直线斜率)。根据这个原理,我们可以写出DDA画线算法程序。
DDA画线算法程序
void DDALine(int x0,int y0,int x1,int y1,int color)
{ int x;
float dx, dy, y, k;
dx = x1-x0; dy=y1-y0;
k=dy/dx,;y=y0;
for (x=x0;x< x1;x++)
{ drawpixel (x, int(y+0.5), color);
y=y+k;
}
}