计算机图形学课程论文.docx
《计算机图形学课程论文.docx》由会员分享,可在线阅读,更多相关《计算机图形学课程论文.docx(21页珍藏版)》请在冰豆网上搜索。
计算机图形学课程论文
《计算机图形学》课程论文
课程名称计算机图形学授课教师XXX
专业软件工程年级2013
姓名XXX
学号2013XXXXXXX
学期2015—2016学年第二学期
成绩授课教师签名
计算机图形学期末综合理论
摘要:
计算机图形学直线变换算法二维图形算法图形填充算法
引言:
计算机图形学是一种使用数学算法将二维或三维图形转化为计算机显示器的栅格形式的科学。
简单地说,计算机图形学的主要研究内容就是研究如何在计算机中表示图形、以及利用计算机进行图形的计算、处理和显示的相关原理与算法。
虽然通常认为CG是指三维图形的处理,事实上也包括了二维图形及图像的处理。
狭义地理解,计算机图形学是数字图象处理或计算机视觉的逆过程:
计算机图形学是用计算机来画图像的学科,数字图象处理是把外界获得的图象用计算机进行处理的学科,计算机视觉是根据获取的图像来理解和识别其中的物体的三维信息及其他信息。
实际上,计算机图形学、数字图象处理和计算机视觉在很多地方的区别不是非常清晰,很多概念是相通的,而且随着研究的深入,这些学科方向不断的交叉融入,形成一个更大的学科方向,可称之为“可视计算”。
计算机图形学主要包含四大部分的内容:
建模(Modeling)、渲染(Rendering)、动画(Animation)和人机交互(Human–computerInteraction,HCI)。
1、概论
1.1什么是计算机图形学
计算机图形学是利用计算机研究图形的表示、生成、处理、显示的学科。
计算机图形学计算机科学中,最为活跃、得到广泛应用的分支之一。
1.2计算机图形学的研究内容
如何在计算机中表示图形、以及利用计算机进行图形的计算、处理和显示的相关原理与算法,构成了计算机图形学的主要研究内容。
图形硬件、图形标准、图形交互技术、光栅图形生成算法、曲线曲面造型、实体造型、真实感图形计算与显示算法,以及科学计算可视化、计算机动画、自然景物仿真、虚拟现实等。
1.3基本概念
1.3.1怎样用计算机生成、处理和显示图形的学科
(1)图形的输入
如何开发利用图形输入设备及软件将图形输入到计算机中去,以便作各种处理。
(2)图形的处理
包括对图形进行变换(几何变换,投影变换)和运算(集合运算),裁减,着色,形变等……
(3)图形的输出
如何将图形特定的表示形式转换成图形输出系统便于接受的表示形式,并将图形在显示屏或打印机等输出设备上输出,或以文件的形式保存在磁盘上。
1.3.2相关的概念
(1)图形:
计算机图形学的研究对象,能在人的视觉系统中产生视觉印象的客观对象,包括自然景物、拍摄到的图片、用数学方法描述的图形等等
-构成图形的要素
(2)几何要素:
刻画对象的轮廓、形状等
(3)非几何要素:
刻画对象的颜色、材质等
1.4计算机中表示图形的方法
1.4.1点阵表示
⏹枚举出图形中所有的点(强调图形由点构成)
⏹简称为图像(数字图像)
1.4.2参数表示
⏹由图形的形状参数(方程或分析表达式的系数,线段的端点坐标等)以及属性参数(颜色、线型等)来表示图形
⏹简称为图形
2.直线生成算法
2.1直线数值微分算法
2.1.1数值微分算法基本原理
⏹设直线的起点坐标为(x0,y0),终点坐标为(x1,y1),二者均为整数坐标值,令dx=x1-x0,dy=y1-y0,则直线斜率k为:
⏹目标是能快速地求出能很好地表示直线的像素,涉及到大量的重复性的运算,因此,尽量用加法代替乘法运算,因为计算机中:
加法运算比乘法运算效率高
2.1.2数值微分算法描述与步骤
当|k|≤1时,从x的左端点x0开始,向x右端点步进。
步长=1个像素(即Dx=1),计算相应的y坐标y=kx+B;取像素点(x,round(y))作为当前点的坐标。
注意到:
yi+1=kxi+1+B
=k(xi+Dx)+B
=kxi+B+kDx
=yi+kDx
=yi+k
即:
当x每递增1,y递增k(即直线斜率);
上述分析的算法仅适用于|k|≤1的情形。
在这种情况下,x每增加1,y最多增加1
当|k|>1时,必须把x,y地位互换
2.1.3数值微分算法设计与代码实现
线段DDA算法伪代码描述下面用伪代码给出DDA算法。
ProcedureDDA-line(x1,y1,x2,y2)
BEGIN
/求线段在两坐标轴方向改变量的较大者/
IFabs(x2-x1)>=abs(y2-y1)THEN
length=abs(x2-x1)
ELSE
length=abs(y2-y1)
ENDIF
/定义dx或dy中的较大值为1/
dx=(x2-x1)/lengthdy=(y2-y1)/lengthx=x1+0.5*Sign(dx)y=y1+0.5*Sign(dy)
i=1
WHILE(iPLOT(Integer(x),Integer(y))x=x+dxy=y+dyi=i+lENDWHILEEND 2.1.4小结这种方法计算方法的缺点是计算量大。考虑到在计算机上实时编辑修改图形时,连续不断的需要在显示器上显示出大量的直线段,画线的速度就会非常地慢。因此需要对上述结果详细分析已给出较快的算法。 2.2直线中点画线算法2.2.1数值微分算法基本原理⏹原理●假设直线的斜率0●当前像素点为P(xp,yp),下一个像素为P1或P2●设M=(xp+1,yp+0.5),为p1与p2之中点,Q为理想直线与x=xp+1垂线的交点。将Q与M的y坐标进行比较:●M在Q的下方,则P2为下一点;●M在Q的上方,则P1为下一点。图2.1a图2.1b2.2.2数值微分算法描述与步骤⏹构造直线方程F(x,y)=ax+by+c=0⏹调整方程参数,使得:●点(x,y)位于直线上方:F(x,y)>0;●点(x,y)位于直线下方:F(x,y)<0;⏹把中点M的坐标带入方程,构造判别式:d=F(M)=F(xp+1,yp+0.5)=a(xp+1)+b(yp+0.5)+c⏹因此:●当d>0时,点M位于Q点上方,取P1为下一点;●当d<0时,点M位于Q点下方,取P2为下一点;●d=0时,Q和M重叠,任取P1、P2。如果取P1,则可合并为d≥0时取P1。图2.2a图2.2b⏹判别式d的增量算法:●设确定Pi(xi,yi)位置时判别式的值为di,则:●如果di≥0,则xi=xi-1+1,yi=yi-1di=F(xi-1+1,yi-1+0.5)=F(xi,yi+0.5)=axi+b(yi+0.5)+cdi+1=F(xi+1,yi+0.5)=a(xi+1)+b(yi+0.5)+c=axi+b(yi+0.5)+c+a=di+adi≥0→di+1=di+a ◆如果di<0,则xi=xi-1+1,yi=yi-1+1di=F(xi-1+1,yi-1+0.5)=F(xi,yi-0.5)=axi+b(yi-0.5)+cdi+1=F(xi+1,yi+0.5)=a(xi+1)+b(yi+0.5)+c=axi+b(yi-0.5)+c+a+b=di+(a+b)di<0→di+1=di+a+b判别式d的初值:直线的起始端点坐标为(x0,y0),则:d1=F(x0+1,y0+0.5)=ax0+by0+c+a+0.5b=F(x0,y0)+a+0.5b(F(x0,y0)=0)=a+0.5b(存在0.5b,为浮点运算)整数算法:算法中仅用到判别式d的符号,所以可用2d代替d进行递增运算: 2.2.3中点划线算法设计与代码实现voidMidpointLine(intx0,inty0,intx1,inty1,intcolor){inta,b,d1,d2,d,x,y;a=y0-y1,b=x1-x0,d=2*a+b;d1=2*a,d2=2*(a+b);x=x0,y=y0;drawpixel(x,y,color);while(x{if(d<0){x++,y++,d+=d2;}else{x++,d+=d1;}drawpixel(x,y,color);}}2.2.4小结如上面代码所示,DDA算法中的y和k都必须用浮点数表示,并且每一步运算都要对y进行舍入取整,这不利于硬件实现。中点画线法只包含整数变量,并且不含乘除法,因而解决了上述问题 2.3直线Breseham画线算法2.3.1直线Breseham画线基本原理Bresenham直线算法最初是为数字绘图仪而设计的。它的目标是选择表示直线的最佳像素点位置.为此,算法根据直线的斜率确定在x或y方向上每次递增一个单位,而另一方向上根据理论直线段与最近像素点的距离每次的增量为0或1。我们首先讨论直线斜率m∈[0,1]且x2>x1时的整数Bresenham算法,然后再推广到画任意线段的算法。2.3.2直线Breseham画线算法描述与步骤当直线斜率m∈[0,1],且x2>x1时,根据式(2.2.9)有:又由于显示直线的像素点只能取整数值坐标,可以假设直线上第i个像素点坐标为(xi,yi),它是直线上点(xi,yi)的最近似并且xi=xi。于是,要表达的直线上下一个(xi+1,yi+1)=(xi+1,yi+m)的最近似的像素点的可能位置是(xi+1,yi)或(xi+1,yi+1)。在x=xi+1处,直线上点的坐标y=m(xi+1)+b.该点与点(xi+1,yi)和(xi+1,yi+1)的距离分别是d1和d2:d1=y−yi=m(xi+1)+b−yi d2=(yi+1)−y=(yi+1)−m(xi+1)−b这两个距离的差为:d1−d2=2m(xi+1)−2yi+2b−1这个差有如下几何意义: (1)当此值为正时,真正的直线上点离像素点(xi+1,yi+1)较近,说明下一个直线上的像素点应取(xi+1,yi+1)。(2)当此值为负时,真正的直线上离像素点(xi+1,yi)较近,说明下一个直线像素点应取(xi+1,yi)。(3)当此值为零时,真正的直线上离上、下两个像素点的距离相等,我们规定取(xi+1,yi)作为下一个直线像素点。 因此,只要利用(d1−d2)的符号就可以决定下一个像素点的选择。如果我们定义一个新的判别式: pi=∆x∗(d1−d2)=2∆y·xi−2∆x·yi+c(2.2.18)因此式中的∆x=(x2−x1)>0,pi与(d1−d2)有相同符号;∆y=y2−y1;常数c=2∆y+∆x(2b−1)。pi的一个优点是省去了(d1−d2)中为了计算m所需要的除法运算。我们知道除法运算用硬件实现是比较复杂的。现在我们要进一步化简上述误差判别式以得到递推公式,消除常数c.以i+1代换此式中的i,得到:pi+1=2∆y·xi+1−2∆x·yi+1+c与前式相减,并利用xi+1=xi+1,可得,pi+1=pi+2∆y−2∆x·(yi+1−yi)再假设直线的初始端点恰好是其像素点的坐标,即满足:于是可得pi的初值y1=mx1+bp1=2∆y−∆x这样,利用误差判别变量,并注意到每一步x的增量为xi+1−xi=1就可得到如下算法表示:(1).(2).如果pi≥0,p1=2∆y−∆xxi+1=xi+1(2.2.23)yi+1=yi+1 pi+1=pi+2(∆y−∆x)(2.2.24)2.2.直线点阵转换算法(3).如果pi<0,yi+1=yi pi+1=pi+2∆y从式(2.2.20)可以看出,第i+1步的判别变量pi+1仅与第i步的判别变量pi、直线的两个端点坐标分增量∆x和∆y有关,计算也很简单,只用整数相加和乘2运算,没有四舍五入处理,而乘2可利用左移一位来实现,因此这个算法速度快并易于硬件实现。该算法的主要步骤如下: (1)输入线段的两个端点分别存于(xs,ys)和(xe,ye)中,(2)将第一点作为起始点,即有(x1,y1)=(xs,ys),(3)分别计算∆x、∆y及p1,若p1<0,下一点为(x1+1,y1),否则,取(x1+1,y1+1), (4)以单位步长增加x坐标,按式((2.2.24))或((2.2.25))计算pi。若pi<0,下一点的y坐标不变,否则y坐标加1。 (5)重复步骤(4)直到x逐步增加到xe为此。 在前面的处理中,我们假设m∈[0,1]。这一假设的几何意义是要绘的直线段与x−轴的夹角不超过与y−轴的夹角。或者更直观地,直线段的方向更靠近x−轴方向,如果有m>1,则说明直线段的方向更靠近y−轴方向。如果我们互换两个坐标轴,则直线段就满足前面的假设条件.因此,只要将算法中的x和y对换,则上述两个公式依然有效。如果m<0,则相应的只是x或y的方向的改变后,上述两个公式依然有效。这时实际上只是改变∆x或∆y的符号即可.2.3.3直线Breseham画线算法设计与代码实现ProcedureBresenham-line(xs,ys,xe,ye)BEGINdx=ABS(xe-xs);dy=ABS(ye-ys);x=xs;y=yss1=SIGN(xe-xs),s2=SIGN(ye-ys)Ifdy>dxTHENtemp=dx;dx=dy:dy=tempinterchange=1ELSEinterchange=OENDIFp=2*dy-dxFORi=1TOdxPLOT(x,y)IFp>=OTHENIFinterchange=1x=x+s1ELSEy=y+s2ENDIFp=p-2*dxENDIFIFinterchange=1THENy=y+s2ELSEx=x+s1ENDIFp=p+2*dyNEXTiEND2.3.4小结以下是近似图形和真实直线之间的差距,可以看得出来,其实实际上图形差距已经很小了。3.二维图形变换3.1二维图形平移变换3.1.1二维图形平移变换基本原理平移是指点从一个位置到另一个位置的直线移动,即把点P(x,y)平移到P′(x′,y′),在x−方向移动了距离Tx,在y−方向移动了距离Ty。于是可得平移公式平移变换用向量解释更清晰:平面上每一点都对应着一个从坐标原点到这一点的向量,平移变换实际上就是把整幅图形沿某个方向移动一段距离,这就是每个点加上一个向量.用坐标表示出的这个向量就是Tm=(Tx,Ty),称为平移矢量或位移矢量。用向量表示的平移变换公式就是3.1.2二维图形平移变换算法描述与步骤显然,多边形的平移变换是由构成多边形的每一条线的始、末点的坐标都加上相应的平移量而得到的。如图6.1所示,多边形从一个位置平移至另一个位置时,其平移量为(Tx,Ty)。由此可见。多边形的平移是通过改变定义其边的坐标值实现的,不需要对多边形边上的每一点都作变换。而圆和椭圆的平移则需要通过移动其园心坐标和依据其半径来实现。平移坐标系的平移变换最后要说明的是如果认为坐标系在x−方向移动了距离Tx,在y−方向移动了距离Ty,得到新的坐标系O′X′Y′,则在新的坐标系下,相当于点在x−方向反向移动了距离Tx,在y−方向反向移动了距离Ty。于是可得平移公式而不是(6.2.1).用向量表示的平移变换公式就是3.1.3二维图形平移变换算设计与代码实现voidmyDraw1(void){glClear(GL_COLOR_BUFFER_BIT);//清空glLoadIdentity();//将当前矩阵设为单位矩阵glColor3f(1.0,0.0,0.0);drawSquare();//在原点处绘制边长为2红色正方形glTranslatef(2.0,3.0,0.0);//向右移动2单位,向上移动3单位glColor3f(0.0,1.0,0.0);drawSquare();//绘制边长为2绿色正方形glTranslatef(0.0,-3.0,0.0);//再向下移动3单位glColor3f(0.0,0.0,1.0);drawSquare();//绘制边长为2蓝色正方形glFlush();}3.2二维图形缩放变换3.2.1二维图形缩放变换基本原理一个图形的尺寸,变换前、后成比例变化,即称之为比例变换。通过x−和y−坐标轴方向的比例变换因子Sx和Sy使点P(x,y)变换为P′(x′,y′),则3.2.2二维图形缩放变换算法描述与步骤如果选择一个能控制图形比例变换的点,使该点在变换后仍保持不变,则称其为基点。可以选择图形的顶点、中心点或其他任何位置的点为基点。上述比例变换只适合基点在坐标原点的比例变换.对于一个指定基点(xF,yF)(见图6.3)的比例变换,首先把坐标系原点平移到基点,在新坐标系下作基点在原点的比例变换,然后再把坐标系的原点平移回原来的原点。这时的比例变换公式为:3.2.3二维图形缩放变换算法设计与代码实现voidmyDraw12(void){glClear(GL_COLOR_BUFFER_BIT);//清空glLoadIdentity();//将当前矩阵设为单位矩阵glColor3f(1.0,0.0,0.0);drawSquare();//在原点处绘制边长为2红色正方形glScalef(1.0,1.5,1.0);//X和Z方向保持不变,Y方向放大为原来的1.5倍glColor3f(0.0,1.0,0.0);drawSquare();//绘制边长为2绿色正方形glTranslatef(0.0,-3.0,0.0);//再向下移动3单位glColor3f(0.0,0.0,1.0);drawSquare();//绘制边长为2蓝色正方形glFlush();}3.3二维图形对称变换3.3.1二维图形对称变换基本原理对称变换又可称为反射变换,镜像变换,从几何直观上表现为不同的类型:有关于x−轴,y−轴的对称变换,以及关于直线y=x,y=−x的直线对称变换,当然也有关于任意一条直线的对称变换。3.3.2二维图形对称变换算法描述与步骤(1)关于x−轴的对称变换 设对点P(x,y)作关于x−轴的对称变换后,得到点P′(x′,y′),则变换的特点是x坐标不变,y坐标由正变负,由负变正,即改变了符号.于是变换公式为:(2)关于y−轴的对称变换设对点P(x,y)作关于y−轴对称变换后,得到点P′(x′,y′),则变换的特点是y坐标不变,x坐标由正变负,由负变正,即改变了符号.于是变换公式为(4)关于任意直线,任意点的对称变换上述对称变换是对特定的直线和点的对称变换.对于任意点(这一点称对称中心)的对称变换,类似于前面的一般的比例变换和旋转变换,先要把坐标系原点平移到对称中心,再进行坐标系原点的对称变换,然后把坐标系平移回原来的坐标系原点。关于以任意指定直线作对称轴的对称变换,可先把坐标系原点平移到对称轴线上,再旋转坐标系,使x−轴(或上述其它三种轴对称变换的轴线)重合于这里的轴线;这时作相应的轴对称变换;然后,反向旋转坐标系到原来的坐标系方向,并把坐标系原点平移回原来的坐标系原点即可把关于坐标系原点及两条坐标轴的对称变换和比例变换结合起来考虑,我们可以看出比例变换的比例系数也可以是负数,这时的变换结果实际上相当于同时进行了比例变换和对称变换.如果两个比例系数都是负数,则对称变换是关于原点的对称变换;如果只有一个比例系数是负数,则对称变换是关于负数比例因子对应的坐标轴的对称变换。3.3.3二维图形对称变换算法设计与代码实现voidmyDraw3(void){glClear(GL_COLOR_BUFFER_BIT);//清空glLoadIdentity();//将当前矩阵设为单位矩阵glColor3f(1.0,0.0,0.0);drawSquare();//在原点处绘制边长为2红色正方形glScalef(1.0,1.5,1.0);//X和Z方向保持不变,Y方向放大为原来的1.5倍glColor3f(0.0,1.0,0.0);drawSquare();//绘制边长为2绿色正方形glSymmetry(0.0,-3.0,0.0);//对称变换glColor3f(0.0,0.0,1.0);drawSquare();//绘制边长为2蓝色正方形glFlush();} 3.4二维图形旋转变换3.4.1二维图形旋转变换基本原理图形上的点以坐标原点为中心旋转一定角度产生的变换称为旋转变换。设点P(x,y)旋转至P′(x′,y′),旋转角为θ(为确定起见设逆时针方向为旋转的正方向)。3.4.2二维图形旋转变换算法描述与步骤角φ是P(x,y)点在xy−平面内与x−轴的夹角,用来定义对点P(x,y)作旋转变换时的起始位置,即有3.4.3二维图形变换算法设计与代码实现voidmyDraw4(void){glClear(GL_COLOR_BUFFER_BIT);//清空glLoadIdentity();//将当前矩阵设为单位矩阵glColor3f(1.0,0.0,0.0);drawSquare();//在原点处绘制边长为2红色正方形glScalef(1.0,1.5,1.0);//X和Z方向保持不变,Y方向放大为原来的1.5倍glColor
PLOT(Integer(x),Integer(y))
x=x+dx
y=y+dy
i=i+l
ENDWHILEEND
2.1.4小结
这种方法计算方法的缺点是计算量大。
考虑到在计算机上实时编辑修改图形时,连续不断的需要在显示器上显示出大量的直线段,画线的速度就会非常地慢。
因此需要对上述结果详细分析已给出较快的算法。
2.2直线中点画线算法
2.2.1数值微分算法基本原理
⏹原理
●假设直线的斜率0●当前像素点为P(xp,yp),下一个像素为P1或P2●设M=(xp+1,yp+0.5),为p1与p2之中点,Q为理想直线与x=xp+1垂线的交点。将Q与M的y坐标进行比较:●M在Q的下方,则P2为下一点;●M在Q的上方,则P1为下一点。图2.1a图2.1b2.2.2数值微分算法描述与步骤⏹构造直线方程F(x,y)=ax+by+c=0⏹调整方程参数,使得:●点(x,y)位于直线上方:F(x,y)>0;●点(x,y)位于直线下方:F(x,y)<0;⏹把中点M的坐标带入方程,构造判别式:d=F(M)=F(xp+1,yp+0.5)=a(xp+1)+b(yp+0.5)+c⏹因此:●当d>0时,点M位于Q点上方,取P1为下一点;●当d<0时,点M位于Q点下方,取P2为下一点;●d=0时,Q和M重叠,任取P1、P2。如果取P1,则可合并为d≥0时取P1。图2.2a图2.2b⏹判别式d的增量算法:●设确定Pi(xi,yi)位置时判别式的值为di,则:●如果di≥0,则xi=xi-1+1,yi=yi-1di=F(xi-1+1,yi-1+0.5)=F(xi,yi+0.5)=axi+b(yi+0.5)+cdi+1=F(xi+1,yi+0.5)=a(xi+1)+b(yi+0.5)+c=axi+b(yi+0.5)+c+a=di+adi≥0→di+1=di+a ◆如果di<0,则xi=xi-1+1,yi=yi-1+1di=F(xi-1+1,yi-1+0.5)=F(xi,yi-0.5)=axi+b(yi-0.5)+cdi+1=F(xi+1,yi+0.5)=a(xi+1)+b(yi+0.5)+c=axi+b(yi-0.5)+c+a+b=di+(a+b)di<0→di+1=di+a+b判别式d的初值:直线的起始端点坐标为(x0,y0),则:d1=F(x0+1,y0+0.5)=ax0+by0+c+a+0.5b=F(x0,y0)+a+0.5b(F(x0,y0)=0)=a+0.5b(存在0.5b,为浮点运算)整数算法:算法中仅用到判别式d的符号,所以可用2d代替d进行递增运算: 2.2.3中点划线算法设计与代码实现voidMidpointLine(intx0,inty0,intx1,inty1,intcolor){inta,b,d1,d2,d,x,y;a=y0-y1,b=x1-x0,d=2*a+b;d1=2*a,d2=2*(a+b);x=x0,y=y0;drawpixel(x,y,color);while(x{if(d<0){x++,y++,d+=d2;}else{x++,d+=d1;}drawpixel(x,y,color);}}2.2.4小结如上面代码所示,DDA算法中的y和k都必须用浮点数表示,并且每一步运算都要对y进行舍入取整,这不利于硬件实现。中点画线法只包含整数变量,并且不含乘除法,因而解决了上述问题 2.3直线Breseham画线算法2.3.1直线Breseham画线基本原理Bresenham直线算法最初是为数字绘图仪而设计的。它的目标是选择表示直线的最佳像素点位置.为此,算法根据直线的斜率确定在x或y方向上每次递增一个单位,而另一方向上根据理论直线段与最近像素点的距离每次的增量为0或1。我们首先讨论直线斜率m∈[0,1]且x2>x1时的整数Bresenham算法,然后再推广到画任意线段的算法。2.3.2直线Breseham画线算法描述与步骤当直线斜率m∈[0,1],且x2>x1时,根据式(2.2.9)有:又由于显示直线的像素点只能取整数值坐标,可以假设直线上第i个像素点坐标为(xi,yi),它是直线上点(xi,yi)的最近似并且xi=xi。于是,要表达的直线上下一个(xi+1,yi+1)=(xi+1,yi+m)的最近似的像素点的可能位置是(xi+1,yi)或(xi+1,yi+1)。在x=xi+1处,直线上点的坐标y=m(xi+1)+b.该点与点(xi+1,yi)和(xi+1,yi+1)的距离分别是d1和d2:d1=y−yi=m(xi+1)+b−yi d2=(yi+1)−y=(yi+1)−m(xi+1)−b这两个距离的差为:d1−d2=2m(xi+1)−2yi+2b−1这个差有如下几何意义: (1)当此值为正时,真正的直线上点离像素点(xi+1,yi+1)较近,说明下一个直线上的像素点应取(xi+1,yi+1)。(2)当此值为负时,真正的直线上离像素点(xi+1,yi)较近,说明下一个直线像素点应取(xi+1,yi)。(3)当此值为零时,真正的直线上离上、下两个像素点的距离相等,我们规定取(xi+1,yi)作为下一个直线像素点。 因此,只要利用(d1−d2)的符号就可以决定下一个像素点的选择。如果我们定义一个新的判别式: pi=∆x∗(d1−d2)=2∆y·xi−2∆x·yi+c(2.2.18)因此式中的∆x=(x2−x1)>0,pi与(d1−d2)有相同符号;∆y=y2−y1;常数c=2∆y+∆x(2b−1)。pi的一个优点是省去了(d1−d2)中为了计算m所需要的除法运算。我们知道除法运算用硬件实现是比较复杂的。现在我们要进一步化简上述误差判别式以得到递推公式,消除常数c.以i+1代换此式中的i,得到:pi+1=2∆y·xi+1−2∆x·yi+1+c与前式相减,并利用xi+1=xi+1,可得,pi+1=pi+2∆y−2∆x·(yi+1−yi)再假设直线的初始端点恰好是其像素点的坐标,即满足:于是可得pi的初值y1=mx1+bp1=2∆y−∆x这样,利用误差判别变量,并注意到每一步x的增量为xi+1−xi=1就可得到如下算法表示:(1).(2).如果pi≥0,p1=2∆y−∆xxi+1=xi+1(2.2.23)yi+1=yi+1 pi+1=pi+2(∆y−∆x)(2.2.24)2.2.直线点阵转换算法(3).如果pi<0,yi+1=yi pi+1=pi+2∆y从式(2.2.20)可以看出,第i+1步的判别变量pi+1仅与第i步的判别变量pi、直线的两个端点坐标分增量∆x和∆y有关,计算也很简单,只用整数相加和乘2运算,没有四舍五入处理,而乘2可利用左移一位来实现,因此这个算法速度快并易于硬件实现。该算法的主要步骤如下: (1)输入线段的两个端点分别存于(xs,ys)和(xe,ye)中,(2)将第一点作为起始点,即有(x1,y1)=(xs,ys),(3)分别计算∆x、∆y及p1,若p1<0,下一点为(x1+1,y1),否则,取(x1+1,y1+1), (4)以单位步长增加x坐标,按式((2.2.24))或((2.2.25))计算pi。若pi<0,下一点的y坐标不变,否则y坐标加1。 (5)重复步骤(4)直到x逐步增加到xe为此。 在前面的处理中,我们假设m∈[0,1]。这一假设的几何意义是要绘的直线段与x−轴的夹角不超过与y−轴的夹角。或者更直观地,直线段的方向更靠近x−轴方向,如果有m>1,则说明直线段的方向更靠近y−轴方向。如果我们互换两个坐标轴,则直线段就满足前面的假设条件.因此,只要将算法中的x和y对换,则上述两个公式依然有效。如果m<0,则相应的只是x或y的方向的改变后,上述两个公式依然有效。这时实际上只是改变∆x或∆y的符号即可.2.3.3直线Breseham画线算法设计与代码实现ProcedureBresenham-line(xs,ys,xe,ye)BEGINdx=ABS(xe-xs);dy=ABS(ye-ys);x=xs;y=yss1=SIGN(xe-xs),s2=SIGN(ye-ys)Ifdy>dxTHENtemp=dx;dx=dy:dy=tempinterchange=1ELSEinterchange=OENDIFp=2*dy-dxFORi=1TOdxPLOT(x,y)IFp>=OTHENIFinterchange=1x=x+s1ELSEy=y+s2ENDIFp=p-2*dxENDIFIFinterchange=1THENy=y+s2ELSEx=x+s1ENDIFp=p+2*dyNEXTiEND2.3.4小结以下是近似图形和真实直线之间的差距,可以看得出来,其实实际上图形差距已经很小了。3.二维图形变换3.1二维图形平移变换3.1.1二维图形平移变换基本原理平移是指点从一个位置到另一个位置的直线移动,即把点P(x,y)平移到P′(x′,y′),在x−方向移动了距离Tx,在y−方向移动了距离Ty。于是可得平移公式平移变换用向量解释更清晰:平面上每一点都对应着一个从坐标原点到这一点的向量,平移变换实际上就是把整幅图形沿某个方向移动一段距离,这就是每个点加上一个向量.用坐标表示出的这个向量就是Tm=(Tx,Ty),称为平移矢量或位移矢量。用向量表示的平移变换公式就是3.1.2二维图形平移变换算法描述与步骤显然,多边形的平移变换是由构成多边形的每一条线的始、末点的坐标都加上相应的平移量而得到的。如图6.1所示,多边形从一个位置平移至另一个位置时,其平移量为(Tx,Ty)。由此可见。多边形的平移是通过改变定义其边的坐标值实现的,不需要对多边形边上的每一点都作变换。而圆和椭圆的平移则需要通过移动其园心坐标和依据其半径来实现。平移坐标系的平移变换最后要说明的是如果认为坐标系在x−方向移动了距离Tx,在y−方向移动了距离Ty,得到新的坐标系O′X′Y′,则在新的坐标系下,相当于点在x−方向反向移动了距离Tx,在y−方向反向移动了距离Ty。于是可得平移公式而不是(6.2.1).用向量表示的平移变换公式就是3.1.3二维图形平移变换算设计与代码实现voidmyDraw1(void){glClear(GL_COLOR_BUFFER_BIT);//清空glLoadIdentity();//将当前矩阵设为单位矩阵glColor3f(1.0,0.0,0.0);drawSquare();//在原点处绘制边长为2红色正方形glTranslatef(2.0,3.0,0.0);//向右移动2单位,向上移动3单位glColor3f(0.0,1.0,0.0);drawSquare();//绘制边长为2绿色正方形glTranslatef(0.0,-3.0,0.0);//再向下移动3单位glColor3f(0.0,0.0,1.0);drawSquare();//绘制边长为2蓝色正方形glFlush();}3.2二维图形缩放变换3.2.1二维图形缩放变换基本原理一个图形的尺寸,变换前、后成比例变化,即称之为比例变换。通过x−和y−坐标轴方向的比例变换因子Sx和Sy使点P(x,y)变换为P′(x′,y′),则3.2.2二维图形缩放变换算法描述与步骤如果选择一个能控制图形比例变换的点,使该点在变换后仍保持不变,则称其为基点。可以选择图形的顶点、中心点或其他任何位置的点为基点。上述比例变换只适合基点在坐标原点的比例变换.对于一个指定基点(xF,yF)(见图6.3)的比例变换,首先把坐标系原点平移到基点,在新坐标系下作基点在原点的比例变换,然后再把坐标系的原点平移回原来的原点。这时的比例变换公式为:3.2.3二维图形缩放变换算法设计与代码实现voidmyDraw12(void){glClear(GL_COLOR_BUFFER_BIT);//清空glLoadIdentity();//将当前矩阵设为单位矩阵glColor3f(1.0,0.0,0.0);drawSquare();//在原点处绘制边长为2红色正方形glScalef(1.0,1.5,1.0);//X和Z方向保持不变,Y方向放大为原来的1.5倍glColor3f(0.0,1.0,0.0);drawSquare();//绘制边长为2绿色正方形glTranslatef(0.0,-3.0,0.0);//再向下移动3单位glColor3f(0.0,0.0,1.0);drawSquare();//绘制边长为2蓝色正方形glFlush();}3.3二维图形对称变换3.3.1二维图形对称变换基本原理对称变换又可称为反射变换,镜像变换,从几何直观上表现为不同的类型:有关于x−轴,y−轴的对称变换,以及关于直线y=x,y=−x的直线对称变换,当然也有关于任意一条直线的对称变换。3.3.2二维图形对称变换算法描述与步骤(1)关于x−轴的对称变换 设对点P(x,y)作关于x−轴的对称变换后,得到点P′(x′,y′),则变换的特点是x坐标不变,y坐标由正变负,由负变正,即改变了符号.于是变换公式为:(2)关于y−轴的对称变换设对点P(x,y)作关于y−轴对称变换后,得到点P′(x′,y′),则变换的特点是y坐标不变,x坐标由正变负,由负变正,即改变了符号.于是变换公式为(4)关于任意直线,任意点的对称变换上述对称变换是对特定的直线和点的对称变换.对于任意点(这一点称对称中心)的对称变换,类似于前面的一般的比例变换和旋转变换,先要把坐标系原点平移到对称中心,再进行坐标系原点的对称变换,然后把坐标系平移回原来的坐标系原点。关于以任意指定直线作对称轴的对称变换,可先把坐标系原点平移到对称轴线上,再旋转坐标系,使x−轴(或上述其它三种轴对称变换的轴线)重合于这里的轴线;这时作相应的轴对称变换;然后,反向旋转坐标系到原来的坐标系方向,并把坐标系原点平移回原来的坐标系原点即可把关于坐标系原点及两条坐标轴的对称变换和比例变换结合起来考虑,我们可以看出比例变换的比例系数也可以是负数,这时的变换结果实际上相当于同时进行了比例变换和对称变换.如果两个比例系数都是负数,则对称变换是关于原点的对称变换;如果只有一个比例系数是负数,则对称变换是关于负数比例因子对应的坐标轴的对称变换。3.3.3二维图形对称变换算法设计与代码实现voidmyDraw3(void){glClear(GL_COLOR_BUFFER_BIT);//清空glLoadIdentity();//将当前矩阵设为单位矩阵glColor3f(1.0,0.0,0.0);drawSquare();//在原点处绘制边长为2红色正方形glScalef(1.0,1.5,1.0);//X和Z方向保持不变,Y方向放大为原来的1.5倍glColor3f(0.0,1.0,0.0);drawSquare();//绘制边长为2绿色正方形glSymmetry(0.0,-3.0,0.0);//对称变换glColor3f(0.0,0.0,1.0);drawSquare();//绘制边长为2蓝色正方形glFlush();} 3.4二维图形旋转变换3.4.1二维图形旋转变换基本原理图形上的点以坐标原点为中心旋转一定角度产生的变换称为旋转变换。设点P(x,y)旋转至P′(x′,y′),旋转角为θ(为确定起见设逆时针方向为旋转的正方向)。3.4.2二维图形旋转变换算法描述与步骤角φ是P(x,y)点在xy−平面内与x−轴的夹角,用来定义对点P(x,y)作旋转变换时的起始位置,即有3.4.3二维图形变换算法设计与代码实现voidmyDraw4(void){glClear(GL_COLOR_BUFFER_BIT);//清空glLoadIdentity();//将当前矩阵设为单位矩阵glColor3f(1.0,0.0,0.0);drawSquare();//在原点处绘制边长为2红色正方形glScalef(1.0,1.5,1.0);//X和Z方向保持不变,Y方向放大为原来的1.5倍glColor
●当前像素点为P(xp,yp),下一个像素为P1或P2
●设M=(xp+1,yp+0.5),为p1与p2之中点,Q为理想直线与x=xp+1垂线的交点。
将Q与M的y坐标进行比较:
●M在Q的下方,则P2为下一点;
●M在Q的上方,则P1为下一点。
图2.1a图2.1b
2.2.2数值微分算法描述与步骤
⏹构造直线方程
F(x,y)=ax+by+c=0
⏹调整方程参数,使得:
●点(x,y)位于直线上方:
F(x,y)>0;
●点(x,y)位于直线下方:
F(x,y)<0;
⏹把中点M的坐标带入方程,构造判别式:
d=F(M)
=F(xp+1,yp+0.5)
=a(xp+1)+b(yp+0.5)+c
⏹因此:
●当d>0时,点M位于Q点上方,取P1为下一点;
●当d<0时,点M位于Q点下方,取P2为下一点;
●d=0时,Q和M重叠,任取P1、P2。
如果取P1,则可合并为d≥0时取P1。
图2.2a
图2.2b
⏹判别式d的增量算法:
●设确定Pi(xi,yi)位置时判别式的值为di,则:
●如果di≥0,则xi=xi-1+1,yi=yi-1
di=F(xi-1+1,yi-1+0.5)=F(xi,yi+0.5)
=axi+b(yi+0.5)+c
di+1=F(xi+1,yi+0.5)
=a(xi+1)+b(yi+0.5)+c
=axi+b(yi+0.5)+c+a
=di+a
di≥0→di+1=di+a
◆如果di<0,则xi=xi-1+1,yi=yi-1+1
di=F(xi-1+1,yi-1+0.5)=F(xi,yi-0.5)
=axi+b(yi-0.5)+c
=axi+b(yi-0.5)+c+a+b
=di+(a+b)
di<0→di+1=di+a+b
判别式d的初值:
直线的起始端点坐标为(x0,y0),则:
d1=F(x0+1,y0+0.5)
=ax0+by0+c+a+0.5b
=F(x0,y0)+a+0.5b(F(x0,y0)=0)
=a+0.5b(存在0.5b,为浮点运算)
整数算法:
算法中仅用到判别式d的符号,所以可用2d代替d进行递增运算:
2.2.3中点划线算法设计与代码实现
voidMidpointLine(intx0,inty0,intx1,inty1,intcolor)
{
inta,b,d1,d2,d,x,y;
a=y0-y1,b=x1-x0,d=2*a+b;
d1=2*a,d2=2*(a+b);
x=x0,y=y0;
drawpixel(x,y,color);
while(x{if(d<0){x++,y++,d+=d2;}else{x++,d+=d1;}drawpixel(x,y,color);}}2.2.4小结如上面代码所示,DDA算法中的y和k都必须用浮点数表示,并且每一步运算都要对y进行舍入取整,这不利于硬件实现。中点画线法只包含整数变量,并且不含乘除法,因而解决了上述问题 2.3直线Breseham画线算法2.3.1直线Breseham画线基本原理Bresenham直线算法最初是为数字绘图仪而设计的。它的目标是选择表示直线的最佳像素点位置.为此,算法根据直线的斜率确定在x或y方向上每次递增一个单位,而另一方向上根据理论直线段与最近像素点的距离每次的增量为0或1。我们首先讨论直线斜率m∈[0,1]且x2>x1时的整数Bresenham算法,然后再推广到画任意线段的算法。2.3.2直线Breseham画线算法描述与步骤当直线斜率m∈[0,1],且x2>x1时,根据式(2.2.9)有:又由于显示直线的像素点只能取整数值坐标,可以假设直线上第i个像素点坐标为(xi,yi),它是直线上点(xi,yi)的最近似并且xi=xi。于是,要表达的直线上下一个(xi+1,yi+1)=(xi+1,yi+m)的最近似的像素点的可能位置是(xi+1,yi)或(xi+1,yi+1)。在x=xi+1处,直线上点的坐标y=m(xi+1)+b.该点与点(xi+1,yi)和(xi+1,yi+1)的距离分别是d1和d2:d1=y−yi=m(xi+1)+b−yi d2=(yi+1)−y=(yi+1)−m(xi+1)−b这两个距离的差为:d1−d2=2m(xi+1)−2yi+2b−1这个差有如下几何意义: (1)当此值为正时,真正的直线上点离像素点(xi+1,yi+1)较近,说明下一个直线上的像素点应取(xi+1,yi+1)。(2)当此值为负时,真正的直线上离像素点(xi+1,yi)较近,说明下一个直线像素点应取(xi+1,yi)。(3)当此值为零时,真正的直线上离上、下两个像素点的距离相等,我们规定取(xi+1,yi)作为下一个直线像素点。 因此,只要利用(d1−d2)的符号就可以决定下一个像素点的选择。如果我们定义一个新的判别式: pi=∆x∗(d1−d2)=2∆y·xi−2∆x·yi+c(2.2.18)因此式中的∆x=(x2−x1)>0,pi与(d1−d2)有相同符号;∆y=y2−y1;常数c=2∆y+∆x(2b−1)。pi的一个优点是省去了(d1−d2)中为了计算m所需要的除法运算。我们知道除法运算用硬件实现是比较复杂的。现在我们要进一步化简上述误差判别式以得到递推公式,消除常数c.以i+1代换此式中的i,得到:pi+1=2∆y·xi+1−2∆x·yi+1+c与前式相减,并利用xi+1=xi+1,可得,pi+1=pi+2∆y−2∆x·(yi+1−yi)再假设直线的初始端点恰好是其像素点的坐标,即满足:于是可得pi的初值y1=mx1+bp1=2∆y−∆x这样,利用误差判别变量,并注意到每一步x的增量为xi+1−xi=1就可得到如下算法表示:(1).(2).如果pi≥0,p1=2∆y−∆xxi+1=xi+1(2.2.23)yi+1=yi+1 pi+1=pi+2(∆y−∆x)(2.2.24)2.2.直线点阵转换算法(3).如果pi<0,yi+1=yi pi+1=pi+2∆y从式(2.2.20)可以看出,第i+1步的判别变量pi+1仅与第i步的判别变量pi、直线的两个端点坐标分增量∆x和∆y有关,计算也很简单,只用整数相加和乘2运算,没有四舍五入处理,而乘2可利用左移一位来实现,因此这个算法速度快并易于硬件实现。该算法的主要步骤如下: (1)输入线段的两个端点分别存于(xs,ys)和(xe,ye)中,(2)将第一点作为起始点,即有(x1,y1)=(xs,ys),(3)分别计算∆x、∆y及p1,若p1<0,下一点为(x1+1,y1),否则,取(x1+1,y1+1), (4)以单位步长增加x坐标,按式((2.2.24))或((2.2.25))计算pi。若pi<0,下一点的y坐标不变,否则y坐标加1。 (5)重复步骤(4)直到x逐步增加到xe为此。 在前面的处理中,我们假设m∈[0,1]。这一假设的几何意义是要绘的直线段与x−轴的夹角不超过与y−轴的夹角。或者更直观地,直线段的方向更靠近x−轴方向,如果有m>1,则说明直线段的方向更靠近y−轴方向。如果我们互换两个坐标轴,则直线段就满足前面的假设条件.因此,只要将算法中的x和y对换,则上述两个公式依然有效。如果m<0,则相应的只是x或y的方向的改变后,上述两个公式依然有效。这时实际上只是改变∆x或∆y的符号即可.2.3.3直线Breseham画线算法设计与代码实现ProcedureBresenham-line(xs,ys,xe,ye)BEGINdx=ABS(xe-xs);dy=ABS(ye-ys);x=xs;y=yss1=SIGN(xe-xs),s2=SIGN(ye-ys)Ifdy>dxTHENtemp=dx;dx=dy:dy=tempinterchange=1ELSEinterchange=OENDIFp=2*dy-dxFORi=1TOdxPLOT(x,y)IFp>=OTHENIFinterchange=1x=x+s1ELSEy=y+s2ENDIFp=p-2*dxENDIFIFinterchange=1THENy=y+s2ELSEx=x+s1ENDIFp=p+2*dyNEXTiEND2.3.4小结以下是近似图形和真实直线之间的差距,可以看得出来,其实实际上图形差距已经很小了。3.二维图形变换3.1二维图形平移变换3.1.1二维图形平移变换基本原理平移是指点从一个位置到另一个位置的直线移动,即把点P(x,y)平移到P′(x′,y′),在x−方向移动了距离Tx,在y−方向移动了距离Ty。于是可得平移公式平移变换用向量解释更清晰:平面上每一点都对应着一个从坐标原点到这一点的向量,平移变换实际上就是把整幅图形沿某个方向移动一段距离,这就是每个点加上一个向量.用坐标表示出的这个向量就是Tm=(Tx,Ty),称为平移矢量或位移矢量。用向量表示的平移变换公式就是3.1.2二维图形平移变换算法描述与步骤显然,多边形的平移变换是由构成多边形的每一条线的始、末点的坐标都加上相应的平移量而得到的。如图6.1所示,多边形从一个位置平移至另一个位置时,其平移量为(Tx,Ty)。由此可见。多边形的平移是通过改变定义其边的坐标值实现的,不需要对多边形边上的每一点都作变换。而圆和椭圆的平移则需要通过移动其园心坐标和依据其半径来实现。平移坐标系的平移变换最后要说明的是如果认为坐标系在x−方向移动了距离Tx,在y−方向移动了距离Ty,得到新的坐标系O′X′Y′,则在新的坐标系下,相当于点在x−方向反向移动了距离Tx,在y−方向反向移动了距离Ty。于是可得平移公式而不是(6.2.1).用向量表示的平移变换公式就是3.1.3二维图形平移变换算设计与代码实现voidmyDraw1(void){glClear(GL_COLOR_BUFFER_BIT);//清空glLoadIdentity();//将当前矩阵设为单位矩阵glColor3f(1.0,0.0,0.0);drawSquare();//在原点处绘制边长为2红色正方形glTranslatef(2.0,3.0,0.0);//向右移动2单位,向上移动3单位glColor3f(0.0,1.0,0.0);drawSquare();//绘制边长为2绿色正方形glTranslatef(0.0,-3.0,0.0);//再向下移动3单位glColor3f(0.0,0.0,1.0);drawSquare();//绘制边长为2蓝色正方形glFlush();}3.2二维图形缩放变换3.2.1二维图形缩放变换基本原理一个图形的尺寸,变换前、后成比例变化,即称之为比例变换。通过x−和y−坐标轴方向的比例变换因子Sx和Sy使点P(x,y)变换为P′(x′,y′),则3.2.2二维图形缩放变换算法描述与步骤如果选择一个能控制图形比例变换的点,使该点在变换后仍保持不变,则称其为基点。可以选择图形的顶点、中心点或其他任何位置的点为基点。上述比例变换只适合基点在坐标原点的比例变换.对于一个指定基点(xF,yF)(见图6.3)的比例变换,首先把坐标系原点平移到基点,在新坐标系下作基点在原点的比例变换,然后再把坐标系的原点平移回原来的原点。这时的比例变换公式为:3.2.3二维图形缩放变换算法设计与代码实现voidmyDraw12(void){glClear(GL_COLOR_BUFFER_BIT);//清空glLoadIdentity();//将当前矩阵设为单位矩阵glColor3f(1.0,0.0,0.0);drawSquare();//在原点处绘制边长为2红色正方形glScalef(1.0,1.5,1.0);//X和Z方向保持不变,Y方向放大为原来的1.5倍glColor3f(0.0,1.0,0.0);drawSquare();//绘制边长为2绿色正方形glTranslatef(0.0,-3.0,0.0);//再向下移动3单位glColor3f(0.0,0.0,1.0);drawSquare();//绘制边长为2蓝色正方形glFlush();}3.3二维图形对称变换3.3.1二维图形对称变换基本原理对称变换又可称为反射变换,镜像变换,从几何直观上表现为不同的类型:有关于x−轴,y−轴的对称变换,以及关于直线y=x,y=−x的直线对称变换,当然也有关于任意一条直线的对称变换。3.3.2二维图形对称变换算法描述与步骤(1)关于x−轴的对称变换 设对点P(x,y)作关于x−轴的对称变换后,得到点P′(x′,y′),则变换的特点是x坐标不变,y坐标由正变负,由负变正,即改变了符号.于是变换公式为:(2)关于y−轴的对称变换设对点P(x,y)作关于y−轴对称变换后,得到点P′(x′,y′),则变换的特点是y坐标不变,x坐标由正变负,由负变正,即改变了符号.于是变换公式为(4)关于任意直线,任意点的对称变换上述对称变换是对特定的直线和点的对称变换.对于任意点(这一点称对称中心)的对称变换,类似于前面的一般的比例变换和旋转变换,先要把坐标系原点平移到对称中心,再进行坐标系原点的对称变换,然后把坐标系平移回原来的坐标系原点。关于以任意指定直线作对称轴的对称变换,可先把坐标系原点平移到对称轴线上,再旋转坐标系,使x−轴(或上述其它三种轴对称变换的轴线)重合于这里的轴线;这时作相应的轴对称变换;然后,反向旋转坐标系到原来的坐标系方向,并把坐标系原点平移回原来的坐标系原点即可把关于坐标系原点及两条坐标轴的对称变换和比例变换结合起来考虑,我们可以看出比例变换的比例系数也可以是负数,这时的变换结果实际上相当于同时进行了比例变换和对称变换.如果两个比例系数都是负数,则对称变换是关于原点的对称变换;如果只有一个比例系数是负数,则对称变换是关于负数比例因子对应的坐标轴的对称变换。3.3.3二维图形对称变换算法设计与代码实现voidmyDraw3(void){glClear(GL_COLOR_BUFFER_BIT);//清空glLoadIdentity();//将当前矩阵设为单位矩阵glColor3f(1.0,0.0,0.0);drawSquare();//在原点处绘制边长为2红色正方形glScalef(1.0,1.5,1.0);//X和Z方向保持不变,Y方向放大为原来的1.5倍glColor3f(0.0,1.0,0.0);drawSquare();//绘制边长为2绿色正方形glSymmetry(0.0,-3.0,0.0);//对称变换glColor3f(0.0,0.0,1.0);drawSquare();//绘制边长为2蓝色正方形glFlush();} 3.4二维图形旋转变换3.4.1二维图形旋转变换基本原理图形上的点以坐标原点为中心旋转一定角度产生的变换称为旋转变换。设点P(x,y)旋转至P′(x′,y′),旋转角为θ(为确定起见设逆时针方向为旋转的正方向)。3.4.2二维图形旋转变换算法描述与步骤角φ是P(x,y)点在xy−平面内与x−轴的夹角,用来定义对点P(x,y)作旋转变换时的起始位置,即有3.4.3二维图形变换算法设计与代码实现voidmyDraw4(void){glClear(GL_COLOR_BUFFER_BIT);//清空glLoadIdentity();//将当前矩阵设为单位矩阵glColor3f(1.0,0.0,0.0);drawSquare();//在原点处绘制边长为2红色正方形glScalef(1.0,1.5,1.0);//X和Z方向保持不变,Y方向放大为原来的1.5倍glColor
if(d<0)
{x++,y++,d+=d2;}
else
{x++,d+=d1;}
}
2.2.4小结
如上面代码所示,DDA算法中的y和k都必须用浮点数表示,并且每一步运算都要对y进行舍入取整,这不利于硬件实现。
中点画线法只包含整数变量,并且不含乘除法,因而解决了上述问题
2.3直线Breseham画线算法
2.3.1直线Breseham画线基本原理
Bresenham直线算法最初是为数字绘图仪而设计的。
它的目标是选择表示直线的最佳像素点位置.为此,算法根据直线的斜率确定在x或y方向上每次递增一个单位,而另一方向上根据理论直线段与最近像素点的距离每次的增量为0或1。
我们首先讨论直线斜率m∈[0,1]且x2>x1时的整数Bresenham算法,然后再推广到画任意线段的算法。
2.3.2直线Breseham画线算法描述与步骤
当直线斜率m∈[0,1],且x2>x1时,根据式(2.2.9)有:
又由于显示直线的像素点只能取整数值坐标,可以假设直线上第i个像素点坐标为(xi,yi),它是直线上点(xi,yi)的最近似并且xi=xi。
于是,要表达的直线上下一个(xi+1,yi+1)=(xi+1,yi+m)的最近似的像素点的可能位置是(xi+1,yi)或(xi+1,yi+1)。
在x=xi+1处,直线上点的坐标y=m(xi+1)+b.该点与点(xi+1,yi)和(xi+1,yi+1)的距离分别是d1和d2:
d1=y−yi=m(xi+1)+b−yi
d2=(yi+1)−y=(yi+1)−m(xi+1)−b
这两个距离的差为:
d1−d2=2m(xi+1)−2yi+2b−1
这个差有如下几何意义:
(1)当此值为正时,真正的直线上点离像素点(xi+1,yi+1)较近,说明下一个直线上的像素点应取(xi+1,yi+1)。
(2)当此值为负时,真正的直线上离像素点(xi+1,yi)较近,说明下一个直线
像素点应取(xi+1,yi)。
(3)当此值为零时,真正的直线上离上、下两个像素点的距离相等,我们规
定取(xi+1,yi)作为下一个直线像素点。
因此,只要利用(d1−d2)的符号就可以决定下一个像素点的选择。
如果我们
定义一个新的判别式:
pi=∆x∗(d1−d2)=2∆y·xi−2∆x·yi+c(2.2.18)
因此式中的∆x=(x2−x1)>0,pi与(d1−d2)有相同符号;∆y=y2−y1;常数c=2∆y+∆x(2b−1)。
pi的一个优点是省去了(d1−d2)中为了计算m所需要的除法运算。
我们知道除法运算用硬件实现是比较复杂的。
现在我们要进一步化简上述误差判别式以得到递推公式,消除常数c.以i+1代换此式中的i,得到:
pi+1=2∆y·xi+1−2∆x·yi+1+c与前式相减,并利用xi+1=xi+1,可得,
pi+1=pi+2∆y−2∆x·(yi+1−yi)再假设直线的初始端点恰好是其像素点的坐标,即满足:
于是可得pi的初值
y1=mx1+bp1=2∆y−∆x
这样,利用误差判别变量,并注意到每一步x的增量为xi+1−xi=1就可得到如下算法表示:
(1).
(2).如果pi≥0,
p1=2∆y−∆xxi+1=xi+1(2.2.23)
yi+1=yi+1 pi+1=pi+2(∆y−∆x)(2.2.24)
2.2.直线点阵转换算法(3).如果pi<0,
yi+1=yi pi+1=pi+2∆y
从式(2.2.20)可以看出,第i+1步的判别变量pi+1仅与第i步的判别变量pi、直线的两个端点坐标分增量∆x和∆y有关,计算也很简单,只用整数相加和乘2运算,没有四舍五入处理,而乘2可利用左移一位来实现,因此这个算法速度快并易于硬件实现。
该算法的主要步骤如下:
(1)输入线段的两个端点分别存于(xs,ys)和(xe,ye)中,
(2)将第一点作为起始点,即有(x1,y1)=(xs,ys),(3)分别计算∆x、∆y及p1,若p1<0,下一点为(x1+1,y1),否则,取(x1+
1,y1+1), (4)以单位步长增加x坐标,按式((2.2.24))或((2.2.25))计算pi。
若pi<0,下
一点的y坐标不变,否则y坐标加1。
(5)重复步骤(4)直到x逐步增加到xe为此。
在前面的处理中,我们假设m∈[0,1]。
这一假设的几何意义是要绘的直
线段与x−轴的夹角不超过与y−轴的夹角。
或者更直观地,直线段的方向更靠近x−轴方向,如果有m>1,则说明直线段的方向更靠近y−轴方向。
如果我们互换两个坐标轴,则直线段就满足前面的假设条件.因此,只要将算法中的x和y对换,则上述两个公式依然有效。
如果m<0,则相应的只是x或y的方向的改变后,上述两个公式依然有效。
这时实际上只是改变∆x或∆y的符号即可.
2.3.3直线Breseham画线算法设计与代码实现
ProcedureBresenham-line(xs,ys,xe,ye)
dx=ABS(xe-xs);dy=ABS(ye-ys);x=xs;y=ys
s1=SIGN(xe-xs),s2=SIGN(ye-ys)
Ifdy>dxTHEN
temp=dx;dx=dy:
dy=temp
interchange=1
interchange=O
p=2*dy-dx
FORi=1TOdx
PLOT(x,y)
IFp>=OTHEN
IFinterchange=1
x=x+s1
ELSEy=y+s2
p=p-2*dx
IFinterchange=1THEN
y=y+s2ELSE
p=p+2*dy
NEXTi
END
2.3.4小结
以下是近似图形和真实直线之间的差距,可以看得出来,其实实际上图形差距已经很小了。
3.二维图形变换
3.1二维图形平移变换
3.1.1二维图形平移变换基本原理
平移是指点从一个位置到另一个位置的直线移动,即把点P(x,y)平移到P′(x′,y′),在x−方向移动了距离Tx,在y−方向移动了距离Ty。
于是可得平
移公式
平移变换用向量解释更清晰:
平面上每一点都对应着一个从坐标原点到这一
点的向量,平移变换实际上就是把整幅图形沿某个方向移动一段距离,这就是每个点加上一个向量.用坐标表示出的这个向量就是Tm=(Tx,Ty),称为平移矢量或位移矢量。
用向量表示的平移变换公式就是
3.1.2二维图形平移变换算法描述与步骤
显然,多边形的平移变换是由构成多边形的每一条线的始、末点的坐标都加上相应的平移量而得到的。
如图6.1所示,多边形从一个位置平移至另一个位置时,其平移量为(Tx,Ty)。
由此可见。
多边形的平移是通过改变定义其边的坐标值实现的,不需要对多边形边上的每一点都作变换。
而圆和椭圆的平移则需要通过移动其园心坐标和依据其半径来实现。
平移坐标系的平移变换最后要说明的是如果认为坐标系在x−方向移动了距离Tx,在y−方向移动了
距离Ty,得到新的坐标系O′X′Y′,则在新的坐标系下,相当于点在x−方向反向移动了距离Tx,在y−方向反向移动了距离Ty。
于是可得平移公式
而不是(6.2.1).用向量表示的平移变换公式就是
3.1.3二维图形平移变换算设计与代码实现
voidmyDraw1(void)
glClear(GL_COLOR_BUFFER_BIT);//清空
glLoadIdentity();//将当前矩阵设为单位矩阵
glColor3f(1.0,0.0,0.0);
drawSquare();//在原点处绘制边长为2红色正方形
glTranslatef(2.0,3.0,0.0);//向右移动2单位,向上移动3单位
glColor3f(0.0,1.0,0.0);
drawSquare();//绘制边长为2绿色正方形
glTranslatef(0.0,-3.0,0.0);//再向下移动3单位
glColor3f(0.0,0.0,1.0);
drawSquare();//绘制边长为2蓝色正方形
glFlush();
3.2二维图形缩放变换
3.2.1二维图形缩放变换基本原理
一个图形的尺寸,变换前、后成比例变化,即称之为比例变换。
通过x−和y−坐标轴方向的比例变换因子Sx和Sy使点P(x,y)变换为P′(x′,y′),则
3.2.2二维图形缩放变换算法描述与步骤
如果选择一个能控制图形比例变换的点,使该点在变换后仍保持不变,则称其为基点。
可以选择图形的顶点、中心点或其他任何位置的点为基点。
上述比例变换只适合基点在坐标原点的比例变换.
对于一个指定基点(xF,yF)(见图6.3)的比例变换,首先把坐标系原点平移到基点,在新坐标系下作基点在原点的比例变换,然后再把坐标系的原点平移回原来的原点。
这时的比例变换公式为:
3.2.3二维图形缩放变换算法设计与代码实现
voidmyDraw12(void)
glScalef(1.0,1.5,1.0);//X和Z方向保持不变,Y方向放大为原来的1.5倍glColor3f(0.0,1.0,0.0);
3.3二维图形对称变换
3.3.1二维图形对称变换基本原理
对称变换又可称为反射变换,镜像变换,从几何直观上表现为不同的类型:
有关于x−轴,y−轴的对称变换,以及关于直线y=x,y=−x的直线对称变换,当然也有关于任意一条直线的对称变换。
3.3.2二维图形对称变换算法描述与步骤
(1)关于x−轴的对称变换 设对点P(x,y)作关于x−轴的对称变换后,得到点P′(x′,y′),则变换的特点是x坐标不变,y坐标由正变负,由负变正,即改变了符号.于是变换公式为:
(2)关于y−轴的对称变换
设对点P(x,y)作关于y−轴对称变换后,得到点P′(x′,y′),则变换的特点是y坐标不变,x坐标由正变负,由负变正,即改变了符号.于是变换公式为
(4)关于任意直线,任意点的对称变换上述对称变换是对特定的直线和点的对称变换.对于任意点(这一点称对称中心)的对称变换,类似于前面的一般的比例变换和旋转变换,先要把坐标系原点平移到对称中心,再进行坐标系原点的对称变换,然后把坐标系平移回原来的坐标系原点。
关于以任意指定直线作对称轴的对称变换,可先把坐标系原点平移到对称轴线上,再旋转坐标系,使x−轴(或上述其它三种轴对称变换的轴线)重合于这里的轴线;这时作相应的轴对称变换;然后,反向旋转坐标系到原来的坐标系方向,并把坐标系原点平移回原来的坐标系原点即可把关于坐标系原点及两条坐标轴的对称变换和比例变换结合起来考虑,我们可以看出比例变换的比例系数也可以是负数,这时的变换结果实际上相当于同时进行了比例变换和对称变换.如果两个比例系数都是负数,则对称变换是关于原点的对称变换;如果只有一个比例系数是负数,则对称变换是关于负数比例因子对应的坐标轴的对称变换。
3.3.3二维图形对称变换算法设计与代码实现
voidmyDraw3(void)
glSymmetry(0.0,-3.0,0.0);//对称变换
3.4二维图形旋转变换
3.4.1二维图形旋转变换基本原理
图形上的点以坐标原点为中心旋转一定角度产生的变换称为旋转变换。
设点P(x,y)旋转至P′(x′,y′),旋转角为θ(为确定起见设逆时针方向为旋转的正方向)。
3.4.2二维图形旋转变换算法描述与步骤
角φ是P(x,y)点在xy−平面内与x−轴的夹角,用来定义对点P(x,y)作旋转变换时的起始位置,即有
3.4.3二维图形变换算法设计与代码实现
voidmyDraw4(void)
glScalef(1.0,1.5,1.0);//X和Z方向保持不变,Y方向放大为原来的1.5倍glColor
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1