计算机图形学课件--地质大学 第二章 二维基本图形的生成
- 格式:doc
- 大小:566.00 KB
- 文档页数:37
第二章二维基本图形的生成重 点:掌握二维图元直线、圆、区域填充、字符的生成算法。
难 点:理解二维图元生成的算法思想并且用C语言进行算法的实现。
课时安排:授课8学时(直线、圆:3学时;区域填充:4学时;字符:1学时);上机8学时(直线、圆:4学时;区域填充:4学时)。
图元生成算法的要求:准确、亮度均匀、速度快。
前面已经知道,矢量显示(随机扫描显示器)和光栅显示是两种完全不同的图形显示技术。
目前,光栅显示技术占主要地位。
在这一章里,主要介绍在光栅输出设备上,根据物体的坐标描述构造二维几何图形的方法。
我们知道,一幅图是由点、直线、曲线、多边形填充区域以及字符串等组成。
下面将讨论这些基本图元的生成技术和算法。
2.1 直线的扫描转换一、数学直线在数学上,理想的直线是一条由无穷多个无限小的连续的点组成。
二、光栅平面显示的直线但在光栅显示平面上,我们只能用二维光栅格网上尽可能靠近这条直线的象素点的集合来表示它。
每个象素具有一定的尺寸,是显示平面上可被访问的最小单位,它的坐标x和y只能是整数,也就是说相邻象素的坐标值是阶跃的而不是连续的。
三、直线的扫描转换直线的扫描转换,就是要找出显示平面上最佳逼近理想直线的那些象素的坐标值,并将这些象素置成所要求的颜色。
由于一幅图中可能包含成千上万条直线,所以要求绘制算法应该:1、最接近数学上的直线;2、沿着线段分布的象素应均匀;不均匀的例子如下图所示,对同样长的线段,如果进行图中的扫描转换,就会因为斜率的不同,产生的象素个数不相等,这样将导致象素亮度分布不均匀。
3、画线速度尽可能的快。
本节我们介绍两个常用的直线生成算法:数值微分法(DDA)和Bresenham算法。
2.1.1 生成直线的DDA算法数值微分法即DDA法(Digital Differential Analyzer),是一种基于直线的微分方程来生成直线的方法。
一、直线DDA算法描述:设(x1,y1)和(x2,y2)分别为所求直线的起点和终点坐标,由直线的微分方程得可通过计算由x方向的增量△x引起y的改变来生成直线:x i+1=x i+△x (2-2)y i+1=y i+△y=y i+△x·m (2-3) 也可通过计算由y方向的增量△y引起x的改变来生成直线:y i+1=y i+△y (2-4)x i+1=x i+△x=x i+△y/m (2-5) 式(2-2)至(2-5)是递推的。
二、直线DDA算法思想:选定x2-x1和y2-y1中较大者作为步进方向(假设x2-x1较大),取该方向上的增量为一个象素单位(△x=1),然后利用式(2-1)计算另一个方向的增量(△y=△x·m=m)。
通过递推公式(2-2)至(2-5),把每次计算出的(x i+1,y i+1)经取整后送到显示器输出,则得到扫描转换后的直线。
之所以取x2-x1和y2-y1中较大者作为步进方向,是考虑沿着线段分布的象素应均匀,这在下图中可看出。
另外,算法实现中还应注意直线的生成方向,以决定Δx及Δy是取正值还是负值。
三、直线DDA算法实现:1、已知直线的两端点坐标:(x1,y1),(x2,y2)2、已知画线的颜色:color3、计算两个方向的变化量:dx=x2-x1dy=y2-y14、求出两个方向最大变化量的绝对值:steps=max(|dx|,|dy|)5、计算两个方向的增量(考虑了生成方向):xin=dx/stepsyin=dy/steps6、设置初始象素坐标:x=x1,y=y17、用循环实现直线的绘制:for(i=1;i<=steps;i++){ putpixel(x,y,color);/*在(x,y)处,以color色画点*/x=x+xin;y=y+yin;}四、直线DDA算法演示:五、直线DDA算法特点:该算法简单,实现容易,但由于在循环中涉及实型数的运算,因此生成直线的速度较慢。
六、直线DDA算法程序:下面给出考虑不同斜率、不同方向直线的DDA画线算法程序:2.1.2 生成直线的B resenham算法从上面介绍的DDA算法可以看到,由于在循环中涉及实型数据的加减运算,因此直线的生成速度较慢。
在生成直线的算法中,B resenham算法是最有效的算法之一。
B resenham算法是一种基于误差判别式来生成直线的方法。
一、直线Bresenham算法描述:它也是采用递推步进的办法,令每次最大变化方向的坐标步进一个象素,同时另一个方向的坐标依据误差判别式的符号来决定是否也要步进一个象素。
我们首先讨论m=△y/△x,当0≤m≤1且x1<x2时的B resenham算法。
从DDA直线算法可知这些条件成立时,公式(2-2)、(2-3)可写成:x i+1=x i+1 (2-6)y i+1=y i+m(2-7)有两种B resenham算法思想,它们各自从不同角度介绍了B resenham算法思想,得出的误差判别式都是一样的。
二、直线B resenham算法思想之一:由于显示直线的象素点只能取整数值坐标,可以假设直线上第i个象素点坐标为(x i,y i),它是直线上点(x i,y i)的最佳近似,并且x i=x i(假设m<1),如下图所示。
那么,直线上下一个象素点的可能位置是(x i+1,y i)或(x i+1,y i+1)。
由图中可以知道,在x=x i+1处,直线上点的y值是y=m(x i+1)+b,该点离象素点(x i+1,y i)和象素点(x i+1,y i+1)的距离分别是d1和d2:d1=y-y i=m(x i+1)+b-y i(2-8)d2=(y i+1)-y=(y i+1)-m(x i+1)-b (2-9) 这两个距离差是d1-d2=2 y -2y i -1=2m(x i+1)-2y i+2b-1 (2-10)我们来分析公式(2-10):(1)当此值为正时,d1>d2,说明直线上理论点离(x i+1,y i+1)象素较近,下一个象素点应取(x i+1,y i+1)。
(2)当此值为负时,d1<d2,说明直线上理论点离(x i+1,y i)象素较近,则下一个象素点应取(x i+1,y i)。
(3)当此值为零时,说明直线上理论点离上、下两个象素点的距离相等,取哪个点都行,假设算法规定这种情况下取(x i+1,y i+1)作为下一个象素点。
因此只要利用(d1-d2)的符号就可以决定下一个象素点的选择。
为此,我们进一步定义一个新的判别式:p i=△x×(d1-d2)=2△y·x i-2△x·y i+c (2-11)式(2-11)中的△x=(x2-x1)>0,因此p i与(d1-d2)有相同的符号;这里△y=y2-y1,m=△y/△x;c=2△y+△x(2b-1)。
下面对式(2-11)作进一步处理,以便得出误差判别递推公式并消除常数c。
将式(2-11)中的下标i改写成i+1,得到:p i+1=2△y·x i+1-2△x·y i+1+c (2-12)将式(2-12)减去(2-11),并利用x i+1=x i+1,可得:p i+1= p i+2△y-2△x·(y i+1-y i) (2-13) 再假设直线的初始端点恰好是其象素点的坐标,即满足:y1=m x1+b (2-14) 由式(2-11)和式(2-14)得到p1的初始值:p1=2△y-△x (2-15) 这样,我们可利用误差判别变量,得到如下算法表示:初始p1=2△y-△x (2-16)当p i≥0时:y i+1=y i+1,x i+1=x i+1,p i+1=p i+2(△y-△x)否则:y i+1=y i,x i+1=x i+1,p i+1=p i+2△y从式(2-16)可以看出,第i+1步的判别变量p i+1仅与第i步的判别变量p i、直线的两个端点坐标分量差△x和△y有关,运算中只含有整数相加和乘2运算,而乘2可利用算术左移一位来完成,因此这个算法速度快并易于硬件实现。
三、直线B resenham算法思想之二:由于象素坐标的整数性,数学点(x i,y i)与所取象素点(x i,y ir)间会引起误差(εi),当x i列上已用象素坐标(x i,y ir)表示直线上的点(x i,y i),下一直线点B(x i+1,y i+1),是取象素点C(x i+1,y ir ),还是D(x i+1,y(i+1)r)呢?设A为CD边的中点,正确的选择:若B点在A点上方,选择D点;否则,选C点。
用误差式描述为:ε(x i+1)=BC-AC=(y i+1-y ir)-0.5 (2-8') 求递推公式:ε(x i+2)=(y i+2-y(i+1)r)-0.5 = y i+1+m-y(i+1)r-0.5 (2-9') 当ε(x i+1)≥0时,选D点,y(i+1)r = y ir+1ε(x i+2)= y i+1+m-y ir-1-0.5=ε(x i+1)+m-1 (2-10') 当ε(x i+1)﹤0时,选C点,y(i+1)r = y irε(x i+2)= y i+1+m-y ir-0.5=ε(x i+1)+m(2-11')初始时:)ε(x s+1)=BC-AC=m-0.5 (2-12'为了运算中不含实型数,同时不影响不等式的判断,将方程两边同乘一正整数。
令方程两边同乘2·Δx,即d=2·Δx·ε,则:初始时:d = 2·Δy-Δx (2-13')递推式:当d≥0时:{ d=d+2·(Δy-Δx);y++;x++;(2-14')}否则:{ d=d+2·Δy;x++;}四、直线B resenham算法实现:条件:0≤m≤1且x1<x21、输入线段的两个端点坐标和画线颜色:x1,y1,x2,y2,color;2、设置象素坐标初值:x=x1,y=y1;3、设置初始误差判别值:p=2·Δy-Δx;4、分别计算:Δx=x2-x1、Δy=y2-y1;5、循环实现直线的生成:for(x=x1;x<=x2;x++){ putpixel(x,y,color) ;if(p>=0){ y=y+1;p=p+2·(Δy-Δx);}else{ p=p+2·Δy;}}五、直线B resenham算法完善:现在我们修正(2-16)公式,以适应对任何方向及任何斜率线段的绘制。
如下图所示,线段的方向可分为八种,从原点出发射向八个区。
由线段按图中所示的区域位置可决定x i+1和y i+1的变换规律。
容易证明:当线段处于①、④、⑧、⑤区时,以|△x|和|△y|代替前面公式中的△x和△y,当线段处于②、③、⑥、⑦区时,将公式中的|△x|和|△y|对换,则上述两公式仍有效。