第二章光栅图形学 光栅图形显示器可以看作一个象素的矩阵。在光栅显示器上显示任何一种图形,实际上都是一些具有 种或多种颜色的象素集合。确定最佳逼近图形的象素集合,并用指定属性写象素的过程称为图形的扫描 转换或光栅化。对于一维图形,在不考虑线宽时,用一个象素宽的直、曲线来显示图形。二维图形的光栅 化必须确定区域对应的象素集,并用指定的属性或图案显示之,即区域填充。 任何图形进行光栅化时,必须显示在屏幕的一个窗口里,超出窗口的图形不予显示。确定一个图形的 哪些部分在窗口内,必须显示:哪些部分落在窗口之外,不该显示的过程称为裁剪。裁剪通常在扫描转换 之前进行,从而可以不必对那些不可见的图形进行扫描转换。 对图形进行光栅化时,由于显示器的空间分辨率有限,对于非水平、垂直、±45°直线,因象素逼近误 差,使所画图形产生畸变(台阶、锯齿)的现象称之为走样:用于减少或消除走样的技术称为反走样 ( ant ia l i as ing)。提高显示器的空间分辨率可以减轻走样问题,但这是以提高设备成本为代价的。实际上 当显示器的象素可以用多亮度显示时,可以通过调整图形上各象素的亮度来减轻走样问题 由于存在不透光的物体,因此阻挡了来自某些物体部分的光线到达观察者,这些物体部分成为隐藏部 分。隐藏部分是不可见的,如果不把隐藏的线或面删除,还可能发生对图的错误理解。为了使计算机图形 够真实的反映这一现象,必须把隐藏的部分从图中消除,习惯上称作消除隐藏线和隐藏面,或简称为消 2.1直线段的扫描转换算法 在数学上,理想的直线是没有宽度的,由无数个点构成的集合。当我们对直线进行光栅化时,只能在显 示器所给定的有限个象素组成的矩阵中,确定最佳逼近于该直线的一组象素,并且按扫描线顺序,对这些 象素进行写操作,这就是通常所说的用显示器绘制直线或直线的扫描转换。由于一个图中可以包含成千上 万条直线,所以要求绘制算法应尽可能的快。本节我们介绍一个象素宽直线的三个常用算法:数值微分法 (DDA)、中点画线法和 Bresenham算法 211数值微分(DDA法 已知过端点P(Aony,P(x,y)的直线段L(P),;直线斜率为x0画线过程从x的 左端点x开始,向ⅹ右端点步进,步长=1(个象素),计算相应的y坐标y=kx+B:取象素点(x, round(y) 作为当前点的坐标 计算v yi* kxM+B =k1X:+B+k△X =y+k△x 即:当Ⅹ每递增1,y递增k(即直线斜率): DDA画线算法程序 void DDALine(int Xo, int yo, int Xi, int y, int color) int X: float dx, dy, y, k; dx Xr-Xo, dy=yr-yo k=dyldx, y=yo Line:P0(0,0)--P1(5,2) for(X=XG;X≤X,X++) o drawpixel(x, int(y+0. 5), color) 举例:用DDA方法扫描转换连接两点P0(0,0)和P1(52) x int(y+0.5)y+0.5 000 100.4+0.5 210.8+0.5 012345 311.2+0.5 421.6+0.5 图2.1.1直线段的扫描转换 注意上述分析的算法仅适用于k≤1的情形。在这种情况下,x每 必须把ⅹ,y地位互换,y每增加1,x相应增加1/k。在这个算法中,y与k必须用浮点数表示,而且每一 步都要对y进行四舍五入后取整。这使得它不利于硬件实现 计算机图形学第二章第18页共27页计算机图形学 第二章 第 18 页 共 27 页 第二章 光栅图形学 光栅图形显示器可以看作一个象素的矩阵。在光栅显示器上显示任何一种图形,实际上都是一些具有 一种或多种颜色的象素集合。确定最佳逼近图形的象素集合,并用指定属性写象素的过程称为图形的扫描 转换或光栅化。对于一维图形,在不考虑线宽时,用一个象素宽的直、曲线来显示图形。二维图形的光栅 化必须确定区域对应的象素集,并用指定的属性或图案显示之,即区域填充。 任何图形进行光栅化时,必须显示在屏幕的一个窗口里,超出窗口的图形不予显示。确定一个图形的 哪些部分在窗口内,必须显示;哪些部分落在窗口之外,不该显示的过程称为裁剪。裁剪通常在扫描转换 之前进行,从而可以不必对那些不可见的图形进行扫描转换。 对图形进行光栅化时,由于显示器的空间分辨率有限,对于非水平、垂直、±45 直线,因象素逼近误 差,使所画图形产生畸变(台阶、锯齿)的现象称之为走样;用于减少或消除走样的技术称为反走样 (antialiasing)。提高显示器的空间分辨率可以减轻走样问题,但这是以提高设备成本为代价的。实际上, 当显示器的象素可以用多亮度显示时,可以通过调整图形上各象素的亮度来减轻走样问题。 由于存在不透光的物体,因此阻挡了来自某些物体部分的光线到达观察者,这些物体部分成为隐藏部 分。隐藏部分是不可见的,如果不把隐藏的线或面删除,还可能发生对图的错误理解。为了使计算机图形 能够真实的反映这一现象,必须把隐藏的部分从图中消除,习惯上称作消除隐藏线和隐藏面,或简称为消 隐。 2.1 直线段的扫描转换算法 在数学上,理想的直线是没有宽度的,由无数个点构成的集合。当我们对直线进行光栅化时,只能在显 示器所给定的有限个象素组成的矩阵中,确定最佳逼近于该直线的一组象素,并且按扫描线顺序,对这些 象素进行写操作,这就是通常所说的用显示器绘制直线或直线的扫描转换。由于一个图中可以包含成千上 万条直线,所以要求绘制算法应尽可能的快。本节我们介绍一个象素宽直线的三个常用算法:数值微分法 (DDA)、中点画线法和 Bresenham 算法。 2.1.1 数值微分(DDA)法 已知过端点 P0 (x0, y0), P1(x1, y1)的直线段 L(P0, P1),;直线斜率为 画线过程从 x 的 左端点 x0开始,向 x 右端点步进,步长=1(个象素),计算相应的 y 坐标 y=kx+B;取象素点(x, round(y)) 作为当前点的坐标。 计算 yi+1 = kxi+1+B = k1 xi+B+k x = yi+k x 当 x =1; yi+1 = yi+k 即:当 x 每递增 1,y 递增 k(即直线斜率); 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; 举例:用 DDA 方法扫描转换连接两点 P0(0,0)和 P1(5,2)的直线段。 x int(y+0.5) y+0.5 0 0 0 1 0 0.4+0.5 2 1 0.8+0.5 3 1 1.2+0.5 4 2 1.6+0.5 注意上述分析的算法仅适用于 k ≤1 的情形。在这种情况下,x 每增加 1,y 最多增加 1。当 k 1 时, 必须把 x,y 地位互换,y 每增加 1,x 相应增加 1/k。在这个算法中,y 与 k 必须用浮点数表示,而且每一 步都要对 y 进行四舍五入后取整。这使得它不利于硬件实现。 图 2.1.1 直线段的扫描转换