




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第二章 直线扫描转换算法n1.光栅图形学n2.逐点画线算法n3.DDA画线算法n4.BRESENHAM画线算法n5.关于线宽线型n6.Visual C+中基本绘图函数 2.1 光栅图形学n计算机图形学已成为计算机技术中发展最快的领域,计算机图形软件也相应得到快速发展。计算机绘图显示有屏幕显示、打印机打印图样和绘图机输出图样等方式,其中用屏幕显示图样是计算机绘图的重要内容。n计算机上常见的显示器为光栅图形显示器,光栅图形显示器可以看作像素的矩阵。像素是组成图形的基本元素,一般称为“点”。通过点亮一些像素,灭掉另一些像素,即在屏幕上产生图形。在光栅显示器上显示任何一种图形必须在显示器的相 应像素点
2、上画上所需颜色,即具有一种或多种颜色的像素集合构成图形。确定最佳接近图形的像素集合,并用指定属性写像素的过程称为图形的扫描转换或光栅化。对于一维图形,在不考虑线宽时,用一个像素宽的直、曲线来显示图形。二维图形的光栅化必须确定区域对应的像素集,并用指定的属性或图案进行显示,即区域 填充。n什么是光栅图形学? 光栅显示器 图形光栅化、 光栅化图形的处理n光栅显示器上显示的图形,称之为光栅图形。光栅显示器可以看作是一个象素矩阵,在光栅显示器上显示的任何一个图形,实际上都是一些具有一种或多种颜色和灰度象素的集合。由于对一个具体的光栅显示器来说,象素个数是有限的,象素的颜色和灰度等级也是有限的,象素是有
3、大小的,所以光栅图形只是近似的实际图形。如何使光栅图形最完美地逼近实际图形,便是光栅图形学要研究的内容。以后,我们提到“显示器”时,如未特别声明,均指光栅显示器。 光栅图形学算法特点n1.要充分考虑屏幕像素,光栅的特性,如何逼近真实图形,如何减小这个误差,如何提高图形处理速度是图形学算法的追求。n2.编写计算机图形学算法,最好还要具备计算方法的基础知识,了解计算机是如何求解方程,了解求解过程与实际人思维的不同,也就是把人思维的计算方法翻译到机器,这就是计算方法研究的内容。光栅图形学的研究内容直线段的扫描转换算法圆弧的扫描转换算法多边形的扫描转换与区域填充字符裁剪反走样消隐n直线段是最基本的图形
4、,因此直线段生成的质量好坏与速度快慢将直接影响整个图形生成的质量和速度。所以直线段生成算法在图形软件设计中起着关键的作用。n如果已知屏幕中直线段的二个端点,可以有多种不同的数学方法来决定应改变在二端点之间的哪些像素的亮度值才能显示出二点间的直线,生成直线段的算法之间区别主要是判别和生成x,y增量过程和方法不同,所能适应的设备环境也不同。下面介绍三种基本的画线算法。光栅图形中点的表示(x,y)坐标地址线性表地址线性表1D表示显示屏幕显示屏幕2D表示像素由其左下角坐标表示像素由其左下角坐标表示光栅图形中点的表示xyxmaxxminymaxymin地址地址 = (xmax-xmin) * (y-ym
5、in) + (x-xmin) + 基地址基地址每行像素点数每行像素点数行数行数行中位置行中位置n在光栅显示器的荧光屏上生成一个对象,实质上是往帧缓存寄存器的相应单元中填入数据。画一条从(x1, y1)到(x2, y2)的直线,实质上是一个发现最佳逼近直线的象素序列,并填入色彩数据的过程。这个过程也称为直线光栅化。 直线扫描转换的本质n直线的扫描转换确定最佳逼近于该直线的一组象素按扫描线顺序,对这些象素进行写操作,对一维图形,不考虑线宽,则用一个像素宽的直线来显示图形。任何图形的光栅化,必须显示在一个窗口内,否则不予显示。即确定一个图形的哪些部分在窗口内,哪些在窗口外,即裁剪。n图形显示前需要:
6、扫描转换+裁剪n裁剪-扫描转换:最常用,节约计算时间。n扫描转换-裁剪:算法简单;2.2 逐点画线算法n在数学上,理想的直线是没有宽度在数学上,理想的直线是没有宽度的,由无数个点构成的集合。当我的,由无数个点构成的集合。当我们对直线进行光栅化时,只能在显们对直线进行光栅化时,只能在显示器所给定的有限个像素中,确定示器所给定的有限个像素中,确定最佳逼近于该直线的一组像素。用最佳逼近于该直线的一组像素。用写点方式对像素进行写操作,这就写点方式对像素进行写操作,这就是通常所说的用显示器绘制直线,是通常所说的用显示器绘制直线,或直线的扫描转换或直线的扫描转换 逐点画线算法(1/19)n逐点比较法算法的
7、基本思想是:在绘制直线的过程中,每绘制一个点就与原直线进行比较,根据比较的结果决定下一步的走向,这样一步一步逼近直线,逐点比较法的执行过程如下:偏差判别开始X方向移动终点判别是结束偏差计算否Y方向移动逐点画线算法(2/19)n逐点比较法是针对笔式绘图机提出的。根据绘图机的结构原理及数字控制原理, 绘图机的笔架可能的移动方向(称为走步方向)有八个:+X、 -X、+Y、-Y、+X+Y、-X+Y、-X-Y、+X-Y。 其中+X、-X、+Y、-Y四个走步方向是一般绘图机都提供的,称为基本走步方向。可见,绘图机的基本绘图元素是与走步方向相对应的小直线段。绘图机所画的一般直线和曲线,实际上是由许多小直线段
8、所组成的折线来逼近的。逐点画线算法(3/19) 根据所画图线的已知条件(如直线两个端点坐标等)计算画图所需要的一系列中间点(即折线的端点)的坐标,称为插补运算。插补运算可用软件或硬件实现,不少绘图机采用插补器(或称线发生器、弧发生器)来完成插补运算,目的在于提高图线生成速度。逐点比较法可用于插补运算。 逐点画线算法(4/19)逐点画线算法(5/19)n若画第一象限的直线OA,如上页图所示,起点为O(0,0), 终点为A(xa, ya),设绘图笔当前的位置为K(xk,yk),这里坐标均为局部坐标。点K相对于直线OA的位置有三种情况:点K在OA上方,点K在OA上以及点K在OA下方。为判断点K与OA
9、的相对位置,引入偏差函数F(k)。 nF(k)=x(a)y(k)-x(k)y(a)当K在OA上时,F(k)=0; K在OA上方时,F(k)0; K在OA下方时,F(k)0。 逐点画线算法(6/19)n对第一象限内直线的生成规定如下:n 当F(k)0时,绘图笔从当前位置沿+X方向走一步,记作+x; 当F(k)0时,绘图笔从当前位置沿+Y方向走一步,记作+y;在绘图笔到达新的位置时,应计算出新位置的偏差,为判断绘图笔下一步走向作准备。n 绘图笔走+x时,新点坐标为nX(k+1)=x(k)+1, y(k+1)=y(k)n这时新点偏差为nF(k+1)=x(a)y(k+1)-x(k+1)y(a)=x(a
10、)y(k)-x(k)y(a)-y(a)=F(k)-y(a)逐点画线算法(7/19)n绘图笔走+y时,新点坐标为nX(k+1)=xk, y(k+1)=y(k)+1n这时新点偏差为nF(k+1)=x(a)y(k+1)-x(k+1)y(a)=x(a)y(k)+x(a)-x(k)y(a)=F(k)+x(a) 根据新偏差F(k+1)的正、负号再确定绘图笔的下一步走向,这样逐步进行,直到绘图笔到达直线的终点为止。终点判断可由X及Y向总走步数J(J=|x(a)|+|y(a)|)来控制,每走一步J减去1,当J=0 时即到达终点。 逐点画线算法(8/19)n对其他象限内直线段生成计算走步方向的规定如下图所示。偏
11、差的递推计算均按以下两式进行:n 当沿X方向走步时, F(k+1)=F(k)-|y(a)|;n 当沿Y方向走步时,F(k+1)=F(k)+|x(a)|。 XYFk0Fk0Fk0Fk0Fk0Fk0Fk0Fk0O逐点画线算法(9/19)01234512LINE(0,0)TO(5,2) 画点 (0,0)F(0)=0 (1,0)F(1)0 (2,1)F(3)0 (3,1)F(4)0 (4,2)F(6)0 (5,2)逐点画线算法(10/19)n优点: 整个算法实现可以使用整数,没有使用浮点数运算,没有乘除运算,所以适合硬件实现,大多数绘图仪使用这个算法。n缺点: 逐点画线法一次只能位移一步,所以画出来的
12、直线粗细不均匀。逐点画线算法(11/19)n逐点画线算法VC源代码(不包含交互内容,直接内置画线段的起始点,并且没有实现F(k)计算的递推工作)nvoid CMyView:OnPointline() n n CDC *pDC=GetDC();nCOLORREF color=RGB(255,0,0);/ 前面四句就是设备环境,当然表现形式可以不一样逐点画线算法(12/19)n int a1=30;n int b1=30;n int b2=800;n int a2=600; /我们实现最简单的画线算法,二点已经确定/后面我们再讲如何交互n int x1,y1,x2,y2; /起始点坐标n int
13、itype; /画线不同循环类型n int i;n int xx,yy;逐点画线算法(13/19)nif (a1a2&b1a2&b1b2)n n n x1=a2;n y1=b2;n x2=a1;n y2=b1;n itype=1;n 逐点画线算法(14/19)nif (a1b2)n n x1=a1;n y1=b1;n x2=a2;n y2=b2;n itype=2;n n if (a1a2&b1b2)n n x1=a2;n y1=b2;n x2=a1;n y2=b1;n itype=2;n 逐点画线算法(15/19)n/前面的代码具有我自己的风格,因为VC的工作区坐标的
14、特性,我们分析以后,画线存在二个类型,即把理论中的分四个象限画线情况归结为二类,画线起点和始点我们灵活变化一下,简化编程。nint k=abs(x2-x1)+abs(y2-y1); / 书上的终点判别不是这么求的 xx=x1; n yy=y1; n switch (itype)n 逐点画线算法(16/19)ncase 1 :n n xx=x1; n yy=y1; n for (i=0;iSetPixel(xx,yy,color); n if (x2-x1)*(yy-y1)-(xx-x1)*(y2-y1)=0)n xx=xx+1; n elsen yy=yy+1; n n return;逐点画线
15、算法(17/19)ncase 2 :n nxx=x1; n yy=y1; nfor (i=0;iSetPixel(xx,yy,color);n if (x2-x1)*(y1-yy)-(xx-x1)*(y1-y2)=0)n xx=xx+1; n elsen yy=yy-1; n nnreturn; n nn注意:从一个理论上的算法提炼到具体一个编译器可以运行编译的程序,可能会有多种不同的编写程序方法,但执行效果是一样的,都能体现算法的精髓。 上面的逐点画线算法没有实现计算误差中 F(K)的递推工作,效率可能会低点,同学们可以考虑把这个可执行无误算法改进一下。 优秀的程序不仅要求无误执行,还要有良
16、好的性能,茁壮性(出错处理好)等要求。逐点画线算法(18/19)n 上面这个程序还有些bug,那就是不能绘制水平或竖直的直线,还有未能实现F(k)的递推工作,这些留给同学们去做,可以在程序中加入一些代码来解决这个问题。同学们还可以根据自己对算法的理解重新编写代码,不用和我编写的思路一样。比如实现四象限方向画图,判断F(k)的正负,如果为正,分四种象限情况走步,如果为负,分四种象限情况走步。逐点画线算法(19/19)逐点法编程另一个思路n坐标变换的思想 坐标变换的思想对后面的曲线曲面编程很有帮助 根据一开始上课推导的最简单的逐点法绘制直线,从第一象限原点出发到第一象限的一个点得到的算法,利用坐标
17、变换来把其他的相当于其他象限的直线绘制映射到第一象限的最简直线绘制中来。void CMyView:OnLine1() CDC *pDC=GetDC();COLORREF color=RGB(255,0,0);int x1=0,y1=0;int x2=500,y2=200;int i;int f=0; int x=x1,y=y1;最简第一象限逐点法绘制源码 pDC-SetPixel(x1,y1,color); int k=abs(x2-x1)+abs(y2-y1); for (i=0;i0) y=y+1; f=f-x2; pDC-SetPixel(x,y,color);else x=x+1; f
18、=f+y2; pDC-SetPixel(x,y,color); 最简第一象限逐点法绘制源码 CDC *pDC=GetDC(); COLORREF color=RGB(255,0,0); int a1=3; int b1=3; int b2=800; int a2=600; int x1,y1,x2,y2; /起始点坐标 int itype; /画线不同循环类型 int i; int f1=0; int f2=0; int k=abs(a2-a1)+abs(b2-b1);坐标变换映射逐点法绘制源码 if (a1a2&b1a2&b1b2) x1=a1; y1=b1; x2=abs(
19、a1-a2); y2=abs(b1-b2); itype=1; 坐标变换映射逐点法绘制源码 if (a1b2) x1=a1; y1=b1; x2=abs(a1-a2); y2=abs(b1-b2); itype=2; if (a1a2&b1SetPixel(x1,y1,color);坐标变换映射逐点法绘制源码 switch (itype) case 1 : for (i=0;i0) y=y+1; f1=f1-x2; pDC-SetPixel(x1-x,y1-y,color); else x=x+1; f1=f1+y2; pDC-SetPixel(x1-x,y1-y,color); br
20、eak;坐标变换映射逐点法绘制源码 case 2 : for (i=0;i0) yy=yy+1; f2=f2-x2; pDC-SetPixel(x1+xx,y1-yy,color); else xx=xx+1; f2=f2+y2; pDC-SetPixel(x1+xx,y1-yy,color); return; (本程序也没考虑水平竖直线)坐标变换映射逐点法绘制源码n数值微分法(Digital Differential Analyzer)是一种基于直线微分方程来生成直线的方法。n回顾一下数值微分的几何意义,一阶数值微分反应的是变化率,表达瞬时变化趋势和快慢的量。2.3 DDA画线算法 DDA画
21、线算法(1/14)n已知线段端点:P0(x0,y0), P1(x1,y1)n直线方程 y=kx+b (xi, yi), i=0,.n.n浮点数取整 : yi=round(yi)=(int)(yi+0.5)用到浮点数的乘法、加法和取整运算 DDA画线算法(2/14)n增量算法yi+1=kxi+1+b=k(xi+1)+b=yi+k(xi,yi)(xi+1,yi+k)n缺点:有浮点数取整运算不利于硬件实现效率低仅适用于k 1的情形:x每增加1,y最多增加1。当 k 1时,必须把x,y互换。 DDA画线算法(3/14)n思考:如何改进算法更适合于编程实现呢?n基本思想用数值方法解微分方程 dy/dt
22、= xdy/dt = y xn+1 = xn + x yn+1 = yn + y 如何选取如何选取? DDA画线算法(4/14)n对称的DDA取=2-n使 2n-1max(|x |,|y|)2nn简单的DDA取= 1/max(|x |,|y|)使 |x |, |y|中必有一个是单位步长x为最大时, x =1, x =ky为最大时, y =1, y =1/k 简单DDA法是按x, y绝对值较大的方向走步的,在这个方向上,每步走一个像素,然后再确定另一个方向的走步。 简单DDA法生成直线的精度同对称DDA法,但它在求一个点时要做两次除法以决定坐标增量值。简单DDA法不适合硬件实现,只适合于软件处理
23、。 DDA画线算法(5/14)n【例】用对称DDA法在起点A(2,1)和终点B(12,7)之间生成一段直线。n 求解的第一步是计算初值x, y, n。这里x=10, y=6, n=4。n 第二步按递推公式循环计算点的坐标,并取整显示。表是本例的循环计算过程。 图是其屏幕显示结果。DDA画线算法(6/14)DDA画线算法(7/14)DDA画线算法(8/14)AB753124681012 对称DDA法生成的直线比较精确,像点位置偏离直线不超过半个像素。逻辑上也比较简单,用 2 的负指数幂作为,意味着把存放x和y的寄存器通过移位操作就可得到点与点之间的坐标增量x、y,而不用除法计算,计算直线上每一点
24、只用两次加法即可实现。对称DDA法适合用硬件来实现, 当然也可用软件来实现。 DDA画线算法(9/14)DDA画线算法(10/14)n/简单的DDA画线算法,绘制线段的起始点也是内置的,没有加入交互过程。这是DDA的基本算法,希望同学们好好体会算法,从理论上的算法到具体程序的过程。nvoid CMyView:OnDdaline() nnCDC *pDC=GetDC();nCOLORREF color=RGB(255,0,0);n/设备环境DDA画线算法(11/14)n int x1=30;n int y1=600;n int x2=180;n int y2=200;n int i;n floa
25、t xincrement,yincrement,xx,yy;n int k=abs(x2-x1);n if(abs(y2-y1)k) k=abs(y2-y1);n xincrement=(float)(x2-x1)/k;n yincrement=(float)(y2-y1)/k;DDA画线算法(12/14)n xx=(x1+0.5);n yy=(y1+0.5);n/为什么加0.5?因为我们对像素要取整,xx本为浮点数,但后面绘制图形时候要取整n for (i=0;iSetPixel(int)xx,(int)yy,color);nxx=xx+xincrement;nyy=yy+yincremen
26、t;nnDDA画线算法(13/14)n 上面是简单DDA算法的实现,如果要改成对称的DDA算法,只要更改k的取值就好,不过对于k值的选取需要计算一下。同学们为了体验算法,可以实现基本的DDA画线算法,就是前面介绍的增量算法k 1的情形:(xi,yi)(xi+1,yi+k)当 k 1时,必须把x,y互换。DDA画线算法(14/14)2.4 BRESENHAM画线算法nBresenhamBresenham算法是计算机图形学领域中使用算法是计算机图形学领域中使用最广泛的直线扫描转换算法。该算法最初最广泛的直线扫描转换算法。该算法最初是为数字绘图仪设计的。由于它也适用于是为数字绘图仪设计的。由于它也适
27、用于光栅图形显示器,所以后来被广泛用于直光栅图形显示器,所以后来被广泛用于直线的扫描转换与其他一些应用。为了讨论线的扫描转换与其他一些应用。为了讨论方便,学习的开始也假定直线的斜率在方便,学习的开始也假定直线的斜率在0 0、l l之间。其他情况可类似处理。之间。其他情况可类似处理。过各行、 各列像素中心构造一组虚拟网格线, 按直线从起点到终点的顺序计算直线与各垂直网格线的交点, 然后确定该列像素中与该交点最近的像素。 yyk+1yykxkxk+1xP2P1d2d10BRESENHAM画线算法(2/16)BRESENHAM画线算法(3/16)n最大位移方向每次走一步k1时,x为最大位移方向ny方
28、向走步与否取决于误差e值的大小n误差计算n初值:e0= y/ xn当e0.5时,最接近P2(xi+1,yi+1)y方向走一步n当e0.5时,最接近P1(xi+1,yi)y方向不走步eP1P2PeeP1P2PeBRESENHAM画线算法(4/16)n为方便与0比较,设e=e-0.5ne0=y/ x-0.5n当e0时,最接近P2(xi+1,yi+1)y方向走一步n当e0时,最接近P1(xi+1,yi)y方向不走步n有除法,不宜硬件实现eP1P2PeeP1P2PeBRESENHAM画线算法(5/16)n如何改进算法,去掉这个除法运算呢?n分析这个像素增量算法,我们发现每次我们判断走步的依据仅仅是e的
29、正负,与e的本身数值大小没关系。BRESENHAM画线算法(6/16)n设e=e2xne0=2y - x n当e0时,最接近P2(xi+1,yi+1)y方向走一步n当e0时,最接近P1(xi+1,yi)y方向不走步n分析这个新算法,其实并没有改变什么ne0=y/ x-0.5n当e0时,最接近P2(xi+1,yi+1)y方向走一步n当e0时,最接近P1(xi+1,yi)y方向不走步n有除法,不宜硬件实现BRESENHAM画线算法(7/16)n下一步误差的计算n当e0时,y方向走一步e=2y/ x - 1 =e + y/ x - 1 e=e + 2y - 2xn当e=0) s1=1; else s
30、1=-1;nif(y2-y1=0) s2=1; else s2=-1;n/考虑到八个方向问题BRESENHAM画线算法(13/16)nif(deltaydeltax)nn temp=deltax;n deltax=deltay;n deltay=temp;n interchange=1;nn else interchange=0;n/考虑到是否斜率大于1交换x,y问题n/这是一种编程实现上的技巧BRESENHAM画线算法(14/16)n int f=2*deltay-deltax; n for(i=0;iSetPixel(x,y,color);n if(f=0)nn x+=s1;n y+=s2
31、; n f=f+2deltay-2*deltax;n BRESENHAM画线算法(15/16)n elsenn if(interchange=1) y+=s2;n else x+=s1;n pDC-SetPixel(x,y,200);n f=f+2*deltay;nn nBRESENHAM画线算法(16/16)n程序说明:n(1)以上程序已经考虑到所有象限直线的生成。n(2)Bresenham算法的优点如下:n 不必计算直线的斜率,因此不做除法。n 不用浮点数,只用整数。n 只做整数加减运算和乘2运算,而乘2运算可以用移位操作实现。n Bresenham算法的运算速度很快。 2.5 关于线宽线
32、型 前面我们编程实现的画图算法都是一个像素宽度的连续的直线(逐点画线法画出来的线粗细步均匀),实际使用中我们经常还需要用到各种宽度不同的线,实线,还有虚线来表达不同的含义。常用商业软件都提供了类似的功能,比如word,autocad等等软件。 要产生具有宽度的线,可以顺着扫描所生成的单像素线条轨迹, 移动一把具有一定宽度的“刷子”来获得,“刷子”的形状可以是一条线段或一个正方形。也可以采用区域填充的办法间接地产生有宽度的线(如AutoCAD系统即是)。关于线宽线型(/)(1)垂直线刷子:假设直线斜率在1,1之间,把刷子放置成垂直方向,刷子中点对准直线一端点,然后让刷子中心往直线的另一端移动,即
33、可“刷出”具有一定宽度的线。关于线宽线型(/)n实现方法:在直线的扫描转换中,计算出与直线最近的像素点后,在绘制点的同时,分别向上和向下多绘制几个点,即可实现垂直刷的宽度线。关于线宽线型(/)(2)水平线刷子:直)水平线刷子:直线斜率不在线斜率不在1,1之间,可以把刷子之间,可以把刷子放置成水平方向,放置成水平方向,刷子中点对准直刷子中点对准直线线端点并往直线端点并往直线的另一端移动,可的另一端移动,可“刷出刷出”具有一定具有一定宽度的线。宽度的线。 关于线宽线型(/)n实现方法:在直线的扫描转换中,实现方法:在直线的扫描转换中,计算出与直线最近的像素点后,在计算出与直线最近的像素点后,在绘制
34、点的同时,分别向左和向右多绘制点的同时,分别向左和向右多绘制几个点,即可实现水平刷的宽绘制几个点,即可实现水平刷的宽度线。度线。 关于线宽线型(/)n(3)方形刷子:把边宽为指定线宽的正方)方形刷子:把边宽为指定线宽的正方形的中心沿直线作平行移动,即可获得具形的中心沿直线作平行移动,即可获得具有线宽的线条。有线宽的线条。 关于线宽线型(/)n实现正方形刷子最简单的办法是,实现正方形刷子最简单的办法是,把方形中心对准单像素宽的线条上把方形中心对准单像素宽的线条上各个像素,并把方形内的像素全部各个像素,并把方形内的像素全部置成线条颜色。这种简单方法将会置成线条颜色。这种简单方法将会重复地写像素。这
35、是因为对应于相重复地写像素。这是因为对应于相邻两像素的方形一般会重叠许多像邻两像素的方形一般会重叠许多像素。素。关于线宽线型(/)关于线宽线型(/)n线刷子的优缺点: 算法简单、效率高是线刷子的优点。但是,线的始末端总是水平或垂直的。因此,当线宽较大时,看起来很不自然。当比较接近水平的线与比较接近垂直的线汇合时,汇合处外角将有缺口,如图 所示。n生成具有宽度的线条还可以采用区域填充的算法。先算出线条各角点,再用直线段把相邻角点连接起来,最后调用多边形填充算法把所得的四边形进行填色,即得到具有宽度的线条。 用这种方法还可以生成两端粗细不一样的线条。关于线宽线型(/) 在绘图应用中常用到不同线型的
36、线条,以便区分各种不同的意义。如采用实线表示立体线框图中可见的轮廓线,用虚线表示不可见的轮廓线, 用点划线表示中心线等等。关于线宽线型(/) 线型可以用一个布尔值的序列来存放。例如,用一个 32 位整数可以存放 32 个布尔值。用这样的整数存放线型定义时,线型必须以 32 个像素为周期进行重复。可按下述语句写像素: if(位串i%32)drawpixel(x, y,color); 其中i为循环变量,在扫描转换算法的内循环中,每处理一个像素就递增 1,然后除以 32 取余。 关于线宽线型(/) 用这种简单办法实现的线型有个毛病。因为每位对应于算法的一个迭代步骤而不是线条上一个长度单位,因此线型中
37、的笔划长度与直线长度有关,斜线上的笔划长度比横向或竖向上的笔划更长。对于工程图,这种变化是不能接受的。这时,每个笔划应该作为与角度无关的线段进行计算并扫描转换。粗线的线型计算为实的或透明的正方形,其顶点位置根据线型要求进行准确计算。然后对正方形进行扫描转换,对于垂直或水平的粗线线型,可以用写方块的简单办法进行。 关于线宽线型(/)n在我们选用的教材上(P32),使用了一种最灵活的方式画虚线,通过定义实线和虚线的距离来选择绘图像素点。n这种方法有个缺点,那就是直线段的总长度可能不是实线部分加上虚线部分距离的整数倍,可能会造成绘制虚线二头端点为空的情况。n还有个缺点,那就是大量的除法计算效果不太好
38、。关于线宽线型(/)n实际利用Visual C+中编制图形程序,可以利用图形学算法自己动手编制基本图形程序,作为图形程序的基类,当然还可利用系统中已提供的图形基类。下面简单介绍Visual C+提供的常用绘制图形函数。2.6 Visual C+中基本绘图函数n1点n画点是最基本的绘图操作,在绘图中,画点是通过调用CDC:SetPixel()或CDC SetPixelV()函数来实现的,原型如:n(1)COLORREF SetPixel(int x, int y, COLORREF crColor);n(2)COLORREF SetPixel(POINT point, COLORREF crCo
39、lor);n(3)BOOL SetPixelV(int x, int y, COLORREF crColor);n(4)BOOL SetPixelV(POINT point, COLORREF crColor);Visual C+中基本绘图函数(1/18)n2画笔n一般格式:Cpen( ) Cpen(int nPenStyle, int nWidth, CORLORREF crColor);n各属性意义:nPenStyle设置画笔的式样,式样有:PS_SOLID(实线),PS_DASH(虚线)、PS_DASHDOT(点划线)、PS_DASHDOTDOT(双点划线)、PS_DOT(点线)、PS_
40、NULL(空笔不画线);nWidth设置线的宽度,默认值为1(1个像素宽);crColor表示颜色,可用DWOR表示,也可用RGB(r, g, b)表示。Visual C+中基本绘图函数(2/18)n3画刷n用于指定填充的特征,画刷创建的格式如下:n(1)CBrush CBrush(创建一个空的画刷对象),可用GreateSolidBrush(),Greateha- tchBrush(),GreatehatchBrushIndrect(),GreatePatternBrush(),GreateDIBPatternBrush()建立画刷。n(2)CBrush CBrush()建立单一颜色的画刷,
41、用次画刷画出的图形内部将会填充指定颜色。Visual C+中基本绘图函数(3/18)n(3)CBrush CBrush(int nIndex, COLORREF crColor);构建名为hatch的画刷,特点为画出的多边形内部将填充nrColor指定的线条格式,nrColor有HS_BDIAGONAL(45左下右上的斜线)、HS_CROSS(垂直线和水平线)、HS_DIAGCROSS(45左上右下、左上右下的相交斜线)、HS_HDLAGNAL(45左上右下的斜线)、HS_HORIZONAL(水平线)、HS_VERTICAL(垂直线)。Visual C+中基本绘图函数(4/18)n(4)CBr
42、ush CBrush(Cbitmap *pBitmap)中pBitmap指向Cbitmap对象的指针,这一位图对象包含用做画刷图案的位图,此位图必须为88大小,否则将对原位图进行裁剪。n创建画刷和画笔后,还要用CDC类选中画笔和画刷,用CPaintDC,CClientDC或CWindowDC来选中、绘图及撤销对象。Visual C+中基本绘图函数(5/18)nCClientDC对象代表客户程序区域的绘图画面只能在窗口的客户区域中画图。若需处理整个画面(包括客户程序区域和非客户程序区)设备上下文的调用和释放可用CWindowDC。Visual C+中基本绘图函数(6/18)n4绘制直线函数n(1
43、)MoveTo()函数用来设置当前的x,y的位置,创建的格式如下:nCPoint MoveTo(int x, int y);nCPoint MoveTo(POINT point);n其中x,y用于定义新位置的坐标,point指定新位置,可为其传递一个POINT对象。n功能:将线的起点从当前位置移到新位置(x,y),并且只移动点不画线。Visual C+中基本绘图函数(7/18)n(2)LineTo()用于绘制起点坐标到终点直线,创建的格式如下:nBOOL LineTo(int x, int y);nBOOL LineTo(POINT point);n其中x,y用于定义线的终点坐标,point指
44、定线段端点位置,可为其传递一个POINT结构或POINT对象。n功能:从当前的位置到新位置(x,y)画线(不包括此端点)。Visual C+中基本绘图函数(8/18)n5椭圆函数n创建的格式如下:nBOOL Ellipse(int x1, int y1 , int x2, int y2);nBOOL Ellipse(LPCRECT lpRect);n说明:x1, y1为限定椭圆范围的矩形左上角坐标,x2, y2为限定椭圆范围的矩形右下角坐标。nLpRect指定椭圆的限定矩形,可为其传递一个CRect对象。Visual C+中基本绘图函数(9/18)n6函数绘制一段椭圆弧Arc()n创建的格式如
45、下:nBOOL Arc(int x1, int y1 , int x2, int y2, int x3, int y3 , int x4, int y4);nBOOL Ellipse(LPCRECT lpRect);nx1, y1为限定椭圆弧范围的矩形左上角坐标;x2, y2为限定椭圆弧范围的矩形右下角坐标。x3, y3为起点坐标;x4, y4为终点坐标。 Visual C+中基本绘图函数(10/18)n7矩形函数n创建的格式如下:nBOOL Rectangle(int x1, int y1, int x2, int y2);nx1, y1为矩形左上角坐标,x2, y2为矩形右下角坐标。n功能:使用当前画笔画一矩形。Visual C+中基本绘图函数(11/18)n8连续画线函数n创建的格式如下:n(1)BOOL PolyLine(LPPOIN
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年陕能(庆阳)能源开发有限公司招聘15人笔试参考题库附带答案详解
- 朝阳师范高等专科学校《程序设计课程设计》2023-2024学年第二学期期末试卷
- 郑州科技学院《锻压工艺及设备》2023-2024学年第二学期期末试卷
- 蚌埠学院《药学综合技能》2023-2024学年第二学期期末试卷
- 安徽大学江淮学院《大数据新闻》2023-2024学年第二学期期末试卷
- 苏州卫生职业技术学院《测试技术与传感器》2023-2024学年第二学期期末试卷
- 海南外国语职业学院《医学影像成像理论》2023-2024学年第二学期期末试卷
- 辽宁省交通高等专科学校《播音主持创作基础(一)》2023-2024学年第二学期期末试卷
- 武汉信息传播职业技术学院《电网调度与运行及案例分析》2023-2024学年第二学期期末试卷
- 荆楚理工学院《铸造合金及其熔炼》2023-2024学年第二学期期末试卷
- 2024-2025学年八年级数学上册:构造三角形全等方法-作公共边、公共角、垂直
- 2024届新高考数学大题训练:数列(30题)(解析版)
- 福建省能源石化集团有限责任公司招聘笔试题库2024
- 2024年安徽省高考政治+历史+地理试卷(真题+答案)
- “两弹一星”精神弘扬与传承智慧树知到期末考试答案章节答案2024年青海师范大学
- 2024年江苏省盐城市中考数学试题(原卷版)
- 中医内科学:汗证
- 房产土地税培训课件
- 电子行业研发工程师劳动合同范本
- 法律法规合规性评价记录表
- 能源英语面面观 知到智慧树网课答案
评论
0/150
提交评论