摘要
本绘图程序人机交互性好,可以方便的调节矩形,三角,圆的大小和形状。在采用bresenham算法提高了运行速度同时,图形的显示方法是采用写像素的方法定位精确轨迹平滑。同时还增加了动态显示效果,可以直观的看到像素点的移动。程序在编译之后只有2KB大小占用内存小运算快速。
关键字:绘图 动态显示 任意大小
计算机图形显示软件设计
1. 方案选择
1.1字符构成图形
在图形由字符构成时,屏幕的显示模式为为文字型。编程简单但是图像质量和交互性很差
1.2在图片模式下直接导入相关图形的图片
程序较易实现,显示的效果非常好。但是图片在取模之后很大,在读取像素写像素时较慢。交互性也不好
1.3在图片模式下采用计算求点写像素的方法绘图
程序编程复杂,算法复杂。绘图效果较好,程序很灵活可以显示各种形状大小的三角,矩形和圆。交互性很好而且还可以改变颜,添加动态显示,实现图像移动等效果。
1.4在图片模式下采用鼠标绘图
程序的交互性很好,可以很方便的确定图形绘制的位置和大小。但是编程太复杂,查阅了有关资料。是使用dos中断来调用鼠标,之后对鼠标跟踪控制。
在综合比较之下,程序的性能是首要考虑的指标。方案三和方案四比起来较易编写一些。所以最终采用的是方案三。
2. 编程思想
在程序设计时采用先整体再分块,模块化编程的思想。首先整体设计出程序的框架,写
好主程序。再分模块写好各个子函数。调试好一个功能后再去编写下一个模块。
主函数的主体是一个分支选择程序。包含了三个绘图模块圆,三角,矩形的数据定义和分支入口程序段。而三个绘图子模块中又各自包含了若干子函数。同时为了使程序紧凑,还编写了一些各个子模块公共使用的子函数。
程序概要框架图如下
图1:程序概要框架图
3. 程序设计
3.1 主程序设计
主程序主体是一个分支选择程序,包含了提示菜单,输入部分和选择部分。采用MOV AH,9 INT 21H中断在屏幕上输出提示信息。MOV AH,1 INT 21H从键盘输入一个字符将它的存在AL中再与1,2,3,q相比较跳转到响应的子函数入口程序段中。
同时还设计了检验输入的程序段再输入不为1,2,3 q,时将自动跳转提示重新输入。
图2:主程序流程图
3.2矩形子程序设计
在矩形子程序中采用写像素点的方法,点动成线将四条线一条一条的画出来。首先提示输入信息输入矩形的长和宽。调用一个输入函数将输入数据以16进制的方式存入AX中,再转存到L_S ,W_S 中。
之后将屏幕的模式设为图像模式640*480*16,将长和宽一次存入CX中采用循环LOOP指令。保持X不变Y依次增加或者Y不变X依次增加将四条直线一一画出。同时为了使显示效果更好一些对线条进行了加粗,宽度为两个像素。
为了使程序结构清晰编写了WRITE_PIXEL宏指令,每调用一次就画出一个点。而且可以认为的设定点的位置颜等。
在函数中还加入了延时子程序,每画完一个点之后就调用一个延时子程序。这样就可以在屏幕上实现动态显示。
在这部分的程序设计中也是采用模块化的思想,先画出一条直线。改变参数就可以画出另外的三条直线。同时在屏幕模式设定时也编写宏指令SETMODE。
调用的宏指令如下
WRITE_PIXEL MACRO PAGE1,ROW,COLUMN,COLOR
MOV AH,0CH
MOV AL,COLOR
MOV BH,PAGE1
MOV DX,ROW
MOV CX,COLUMN
INT 10H
ENDM
SETMODE MACRO MODE1
MOV AH,0
MOV AL,MODE1
INT 10H
ENDM
子程序流程图如下
图3:矩形子程序流程图
3.3三角形子程序设计
在三角形绘制中程序也分为几个部分,首先是三个顶点的输入子程序。然后将三个顶点压栈,再调用Bresenham画线子程序。在Bresenham画线子程序中依次调用写像素子程序和延时子程序实现三条线段的动态显示。
三角部分整体程序框架图如
图4:三角子程序框架图
Bresenham画线算法是绘制三角形的核心程序,分析如下
Bresenham算法是计算机图形学中为了“显示器(屏幕或打印机)系由像素构成”的这个特性而设计出来的算法,使得在求直线各点的过程中全部以整数来运算,因而大幅度提升计算速度。
Bresenham算法是计算机图形学领域使用最广泛的直线扫描转换方法。其原理是过各行、各列像素中心构造一组虚拟网格线,按直线从起点到终点顺序计算直线各垂直网格线的交点,然后确定该列像素中与此交点最近的像素。
该算法的优点在于可以采用增量计算,使得对于每一列,只要检查一个误差项 的符号,就可以确定该列所求的像素。
例如对于直线方程Y=kX+b;
A:0<K<1时候的算法
1:输入线段的两个端点Point1和Point2,并且存储到Point1(x1,y1)和Point2(x2,y2)中;
2:将Point1载入桢缓存,绘画第一个起始点;
3:计算常量△x、△y、2△y和2(△y-△x),并且获得一个决策参数的第一个值:P = 2△y-△x;
4:从n=0开始,在沿线经过每个Xn处,进行下面的检测:
如果Pn<0,下一个点绘制的是(Xn+1,yn),并且Pn+1=Pn+2△y
如果P0>=0,下一个点绘制的是(Xn+1,Yn+1),并且Pn+1=Pn+2(△y-△x)
5:重复执行△x-1次步骤4;
B:斜率k= 1或斜率k=0时候的算法
对于斜率等于0或者斜率等于1时候,不需要通过算法直接的对于其中单一坐标变量进行处理。
C:斜率k<0的情况算法
将起始点和中止点坐标Point1和Point2交换,可以转化到斜率为0和1之内的算法去实现。
3.3圆形子程序设计
图5:圆形子程序框架图
在圆绘制模块中同样是采用Bresenham画线算法。先由键盘输入圆半径,再设置成图形模式。在调用圆Bresenham子程序将相关点堆栈,然后再调用圆画点子程序在屏幕上下左右四个点上向两边同时开始画点。每画一个点就调用一下延时子程序实现绘图的动态显示。
3.4公共使用子程序设计
为了使程序结构较清晰,将三个子模块和主函数共同使用的子函数统一编写。它们是数据输入子函数READ可以讲键盘输入的数据转化为16进制存在AX中。在各个子函数的数据输入模块都是调用的这个子函数。还有写像素子函数PIXEL。它的作用是把经过Bresenham算法堆栈的数据用写像素的方法写在屏幕上。延时子函数DELAY它的作用是延时使图像动态显示。清屏CLEAR它的作用是调背景清屏。便于在图形模式和文字模式之间进行转换。
在其中的延时子程序采用了双层循环的方法,因为各个子程序运行用时不同为了便于调试和取得更好的效果。不同的子模块对应不同的延时子程序。
4. 硬件原理
显示器有字符显示模式和图形显示两种工作方式
在图形方式下的屏幕由一个一个的像素做成。通过读写屏幕上的各个像素就
可以显示出各种各样的图形。
在汇编语言中提供了多种图形显示模式。设置模式的方法是:AL=模式号,AH=00H,然后通过BIOS功能调用INT10H来实现。
表1常见的图形显示模式
显示模式号 | 分辨率 | 彩数 | 适用显卡 |
0DH | 320*200 | 16 | EGA VGA |
OEH | 640*200 | 16 | EGA VGA |
0FH | 640*350 | 2 | EGA VGA |
10H | 640*350 | 16 | EGA VGA |
11H | 640*480 | 2 | MCGA VGA |
12H | 640*480 汇编语言如何编程 | 16 | VGA |
13H | 320*200 | 256 | MCGA VGA |
VGA显卡上256KB显存,被划分为4个64KB的位平面。比如屏幕上像素的位置是(X,Y),则改像素在显存位平面中字节地址的计算公式为:
字节地址=A0000H+Y*(640/8)+X MOD 8(屏幕中有640列,每字节8位)
5. 调试结果
图6:主菜单截屏
矩形绘制输入长168,宽100
图7:矩形截屏
三角形输入
图8:三角形截屏
图9:圆形截屏
结束语
这次的微机课设用的时间很久,从接到题目分析。到后来的程序编写调试费了很多的功夫。
收获很多,一方面是专业知识。计算机怎么来显示图形,显存是怎么工作的。怎样将内容直接写到内存中在屏幕上反映出来。对这些知识有了更深入的了解,同时对于分支选择程序。子程序的调用压栈出栈断点保护有了更深入的理解。在程序就要调试完成的时候突然发现了一个致命的错误。画完圆之后无法再画矩形。为了排查这个问题花了好长的时间一直没有解决。后来经过请教同学和仔细的思考后发现。在画圆程序中使用过CX,而在画矩形时矩形的大小是由CX来决定的。虽然前面加入了压栈出栈,但是CX值已经被改变了。再写入数据后只是把低位覆盖高位仍然是有数据的。就造成了程序的错误。类似这样的错误还有很多。调试程序的过程也是一个不断检测错误不断反思的过程。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论