1、独殊一格,我们组:,独殊一格小组成员: 冯敏仪 负责系统的界面及线 条宽度代码,颜色相关代码 陈妍晖 负责直线算法 甘玉珍 负责圆形算法 徐俊敏 负责椭圆算法 萧碧薇 负责填充图形,本程序设计是用VB6.0和TC2.0制作而成,可以实现画直线,圆,椭圆这三种图形和填充一个长方形。VB6.0的使用方法:直线:先设定直线的起点及终点坐标,还可以设置直线的宽度及颜色。设置好后,按画直线按钮,即可。,圆:先设置圆的圆心,及半径,圆的线条的宽度及颜色。然后按画圆按钮,即可。画出圆形后,若选择填充,即可填充该图形。,椭圆:先设置后椭圆的实轴和虚轴,椭圆的线条宽度及颜色。然后按画椭圆按钮,即可。画出椭圆后,
2、若选择填充,即可填充该图形。注:在宽度和颜色都不设置的情况下,系统自动默认为1和黑色,TC2.0的使用方法: 画出一个长方形,实现对长方形的填充,直接运行即可。,负责系统的界面及线条宽度和颜色等相关代码,我负责的那部分很简单!界面的设计,只是用了一个form,再加几个VB里面很常用的按钮,例如:textbox;picturebox;label;commanButton. 线条的宽度就用了Picture1.DrawWidth就是决定Picture控件上划线的宽度颜色就用了一个VB里面很现成的ShowColor函数,冯敏仪:,在界面上用到的几个控件如下: textbox;label;commanB
3、utton.,这是我们的图形生成区,用了一个picturebox做成,刻度是用了两组label数组做成我们的横坐标跟纵坐标!,图形生成:在picturebox里面用了 Form_Paint()函数实现画图,程序如下:Private Sub Form_Paint()For i = 0 To 17 Label5(i).Left = Picture1.Left + (i + 1) * 567NextFor i = 0 To 11 Label6(i).Top = Picture1.Top + (i + 1) * 567NextEnd Sub,Showcolor函数:,在选择颜色的按钮写下下面函数Pri
4、vate Sub Command2_Click()CommonDialog1.ShowColorEnd Sub,负责直线算法,陈妍晖:,算法原理如下:过各个像素的中心构造一组虚拟网格线,首先按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后,采用增量计算,使得对于每一列,只要检查一个误差项的符号,就可以确定该列像素中与此交点最近的像素。,Bresenham算法,过各行各列象素中心构造一组虚拟网格线。按直线从起点到终点的顺序计算直线与各垂直网格线的交点,然后根据误差项的符号确定该列象素中与此交点最近的象素。,设直线l方程为yi+1=yi+k(xi+1-xi),其中,k = dy/dx。假
5、设当前像素的x坐标已经确定为xi,其y坐标为yi,由于坐标(xi,yi)(i=0,1,)只能取整数,那么下一个像素的x坐标xi+1=xi+1,而yi1的坐标有两种可能:1) 保持不变,即y i1yi;或者2) y坐标递增1,即y i1yi1。令di+1=di+k(xi+1-xi),y坐标是否增加1取决于误差项d i的值。因为直线的起始点在像素中心,所以初始误差d00。x每增加1,y的值相应递增直线的斜率值k,即di+1=di+k。一旦di+11,就把它减去1,这样保证di+1在01之间。. 当d i+10.5时,直线l与xxi1的垂线的交点最接近于当前像素(xi,yi)的右上方像素(xi1,y
6、i1); 当d i+10.5时,其交点更接近于(xi,yi)右边的像素(xi1, yi)。为方便计算,令e0=0.5,e i+1di+10.5,增量为k。. ei+10时,取当前像素(xi,yi)的右上方像素(xi1, yi1) 而当e i+11的直线,只要在上述算法中交换x和y之间的规则即可。,我们的程序:Private Sub Command1_Click()Picture1.DrawWidth = Val(Text5.Text)dx = Val(Text3.Text) * 567 - Val(Text1.Text) * 567 dx=xe-xs;dy = Val(Text4.Text)
7、* 567 - Val(Text2.Text) * 567 dy=ye-ys;x = 0y = 0d = 2 * x * dy - 2 * y * dx + 2 * dy - dxFor i = 0 To dx - 1 Picture1.PSet (x + Val(Text1.Text) * 567, y + Val(Text2.Text) * 567), CommonDialog1.Color If d = 0 Then y = y + 1 x = x + 1 d = d + 2 * dy - 2 * dx Else x = x + 1 d = d + 2 * dy End IfNextEn
8、d Sub,Bresenham算法的特点,Bresenham算法的优点如下: 不必计算直线的斜率,因此不做除法。 不用浮点数,只用整数。 只做整数加减运算和乘2运算,而乘2运算可以用移位操作实现。,Bresenham算法也是每个象素,需一个整数算法,其优点是可以用于其他二次曲线。,Bresenham算法的运算速度很快,并适于用硬件实现。,甘玉珍:,负责圆形算法,圆的生成算法设计与实现:1.了解显示原理和屏幕坐标的位置;2.掌握VB环境下的图形编程步骤;3. 认真阅读教材内容, 熟悉圆表示的原理和算法;4. 掌握圆的生成算法;5. 编程实现圆;6.设计和编制实验程序;7.运行的时候可以选择颜色跟
9、线条的宽度;输入测试数据,修改并调试程序,直至正确为止;8.记录最终测试数据和测试结果。圆心(5,5),半径R=4,圆的特征:,圆被定义为到给定中心位置(X,Y)的距离为R的点集。根据圆的对称性可知,只要扫描转换1/8圆弧,就可以用八对称性求出整个圆弧的像素集,然后画出圆。,中点画圆算法:在VB中的程序,Private Sub Command4_Click()Picture1.DrawWidth = Val(Text9.Text),x = 0y = Val(Text8.Text) * 567p = 1 - yPicture1.PSet (Val(Text6.Text) * 567, Val(T
10、ext7.Text) * 567), CommonDialog1.ColorWhile x y x = x + 1 If p 0 Then p = p + 2 * x + 1 Else y = y - 1 p = p + 2 * (x - y) + 1 End If,Picture1.PSet (Val(Text6.Text) * 567 + x, Val(Text7.Text) * 567 + y), CommonDialog1.ColorPicture1.PSet (Val(Text6.Text) * 567 - x, Val(Text7.Text) * 567 - y), CommonD
11、ialog1.ColorPicture1.PSet (Val(Text6.Text) * 567 - x, Val(Text7.Text) * 567 + y), CommonDialog1.ColorPicture1.PSet (Val(Text6.Text) * 567 + x, Val(Text7.Text) * 567 - y), CommonDialog1.ColorPicture1.PSet (Val(Text6.Text) * 567 + y, Val(Text7.Text) * 567 + x),CommonDialog1.ColorPicture1.PSet (Val(Tex
12、t6.Text) * 567 + y, Val(Text7.Text) * 567 - x), CommonDialog1.ColorPicture1.PSet (Val(Text6.Text) * 567 - y, Val(Text7.Text) * 567 + x), CommonDialog1.ColorPicture1.PSet (Val(Text6.Text) * 567 - y, Val(Text7.Text) * 567 - x), CommonDialog1.ColorWendEnd Sub,优点:,算法中的浮点数改写成整数,将乘法运算改成加法运算,即仅用整数实现中点画圆法,进
13、一步提高算法的效率。,中点画圆法的收获与体会:,通过这个课程设计对VB语言进一步应用与理解了。,对图形理论的更深入的理解。毕竟,从理论到实践还有那么一段距离,可是当你跨过去之后,也是对理论学习的一种补充与提高。更重要的是,就像老师说的:编程到了一定程度上时又要求理论知识的良好掌握。是的,两者相辅相成,缺一不可。通过本设计(中点画圆法),使自己了解计算机图形学的有关原理、算法及系统,掌握基本图形显示程序设计方法,为以后的进一步学习打下基础。,椭圆的生成采用的是椭圆的对称性,只考虑第一象限椭圆弧生成,分上下两部分,以切线斜率为-1的点作为分界点。运用了椭圆的中点画法,确定一个象素后,接着在两个侯选
14、象素的中点计算一个判别式的值,由判别式的符号确定更近的点。,徐俊敏 负责椭圆算法,填充代码部分:For i = 1 To ay = ix = 0p = 1 - yPicture1.PSet (Val(Text6.Text) * 567, Val(Text7.Text) * 567), CommonDialog1.ColorWhile x y x = x + 1 If p span.y = span-y;p-span.xLeft = span-xLeft;p-span.xRight = span-xRight; p-next=s-top;s-top=p; /*-出栈操作-*/ void PopS
15、tack(linkstack *s,Span *span) int x; stacknode *p=s-top; span-y = p-span.y;span-xLeft = p-span.xLeft;span-xRight = p-span.xRight; s-top=p-next; free(p); ,/*-将栈清空-*/ void SetStackEmpty(linkstack *s) stacknode *p=s-top; while( s-top != NULL) free(p); s-top=p-next; /*-判断栈是否为空-*/ int IsStackEmpty(linkst
16、ack *s) if(s-top = NULL) return 1; else return 0;,/*-核心程序开始-*/void ScanLineFill4(int x,int y,int oldColor,int newColor) int xLeft,xRight; int i; enum BOOL isLeftEndSet, spanNeedFill; Span span; linkstack *s=(linkstack*)malloc(sizeof(linkstack); s-top = NULL; /*填充并确定种子点(x,y)所在的区段*/ i = x; while(getpi
17、xel(i,y) = oldColor)/*向右填充*/ putpixel(i,y,newColor); i+; span.xRight = i - 1; /*确定区段右边界*/ i = x - 1; while(getpixel(i,y) = oldColor)/*向左填充*/ putpixel(i,y,newColor); i-; span.xLeft = i + 1; /*确定区段左边界*/,/*初始化*/ SetStackEmpty(s); span.y = y; PushStack(s,while( i xRight) spanNeedFill = FALSE; while(getp
18、ixel(i,y) = oldColor) /*向右填充*/ if( ! spanNeedFill) spanNeedFill = TRUE; if( ! isLeftEndSet) isLeftEndSet = TRUE; xLeft = i; putpixel(i,y,newColor); i+; if( spanNeedFill ) span.y = y; span.xLeft = xLeft; span.xRight = i - 1; PushStack(s, /*end of while( i xRight) */,while( i xRight) spanNeedFill = FA
19、LSE; while(getpixel(i,y) = oldColor) /*向右填充*/ if( ! spanNeedFill) spanNeedFill = TRUE; if( ! isLeftEndSet) isLeftEndSet = TRUE; xLeft = i; putpixel(i,y,newColor); i+; if( spanNeedFill ) span.y = y; span.xLeft = xLeft; span.xRight = i - 1; PushStack(s, /*end of while( i xRight) */,while(getpixel(i,y)
20、 = oldColor) /*向右填充*/ if( ! spanNeedFill) spanNeedFill = TRUE; if( ! isLeftEndSet) isLeftEndSet = TRUE; xLeft = i; putpixel(i,y,newColor); i+; if( spanNeedFill ) span.y = y; span.xLeft = xLeft; span.xRight = i - 1; PushStack(s, ,/* while(getpixel(i,y) != oldColor) */ i+; /*end of while( i xRight) */ delay(2000); /*延时*/ /*end of while( ! isStackEmpty() ) */ /*end of ScanLineFill4() */,/*-main()-*/int main() int poly10=100,100,150,100,150,200,100,200,100,100; initgr(); /*setbkcolor(3);*/ setcolor(5); cleardevice(); drawpoly(5,poly); ScanLineFill4(150,150,0,14); getch(); closegr(); return 0;,