汇编语言实现图形绘制——矩形、三角形等

汇编语言实现图形绘制

一、准备工作

1.INT 10H的功能

INT 10H 是由 BIOS 对屏幕及显示器所提供的服务程序。使用 INT 10H 中断服务程序时,先指定 AH 寄存器编,该编号表示欲调用的功用,然后再定义其它寄存器内容,当一切设定好之后再调用 INT 10H。下面是我们在程序中用到的指令:

AH=00H

AH=00/INT 10H 是用来设定显示模式的服务程序,AL 寄存器表示欲设定的模式

;AL部分模式说明
mov al,12h          ;640*480 256的图形模式:            
mov al,13h          ;320*200 256色的图形模式:

;完整调用
mov al,13h          ;320*200 256色的图形模式:
mov ah,0            ;是用来设定显示模式的服务程序
int 10h

AH=0CH

AH=0Ch/INT 10H 是在绘图模式中显示一点 ( 也就是写入点像),而 AH=0DH/INT 10H 则是读取点像。

写入时,要写入位置 X 坐标存于 CX 寄存器,Y 坐标存于 DX 寄存器,颜色存于 AL 寄存器。对于汇编的显示窗口,左上角为原点,向右为X轴,越往右X数值越大;向下为Y轴,越往下Y数值越大。X、Y坐标的边界以及颜色的种类则和之前定义的显示模式相关。

显示模式X 座标Y 座标颜色
40~3190~1990、1
50~3190~1990~3
60~6390~1990、1

AH=0DH/INT 10H 则是读取某一位置之点像,您必须指定 CX、DX,而 INT 10H 会传回该位置点像之颜色。

;完整调用
mov cx,10             ;x坐标
mov dx,10             ;y坐标
mov al,1100b          ;淡红色
mov ah,0ch            ;写入点像
int 10h               ;调用中断
二进制数颜色例子二进制数颜色例子
0000黑色black1000灰色gray
0001蓝色blue1001淡蓝色light blue
0010绿色green1010淡绿色light green
0011青色cyan1000淡青色light cyan
0100红色red1100淡红色light red
0101紫红色magenta1101淡紫红色light magenta
0110棕色brown1110黄色yellow
0111银色light gray1111白色white

2.Bresenham直线算法

对于直线、竖线的绘制,方法比较简单

而对于斜线的绘制,则存在一些问题。因为我们的屏幕是由像素点构成,而像素点的坐标都是整数,但是在直线上每一点的坐标不一定是整数,所以我们将要对该点进行近似处理,选取屏幕上最接近该点的像素点进行绘制。

Bresenham直线算法就是用来描绘由两点所决定的直线的算法,它会算出一条线段在 n 维光栅上最接近的点。这个算法只会用到较为快速的整数加法、减法和位元移位,常用于绘制电脑画面中的直线。是计算机图形学中最先发展出来的算法。

我们以0<K<1的斜线为例:

若图,该算法的核心思想:

当前点为A(X,Y),由于K的限制性,下一个绘制的点为B(X+1,Y)或者C(X+1,Y+1)。而直线上的点为C点,该点介于B点和D点之间,所以我么就要判断C点是偏向于B点还是D点。其中一种方法是将(X+1,Y+1/2)带入直线方程F中:

若F(X+1,Y+1/2)> 0,则证明B、D之间的中点在直线上方,则选取B点为下一个绘制的像素点。

若F(X+1,Y+1/2)< 0,则证明B、D之间的中点在直线下方,则选取D点为下一个绘制的像素点。

在知道核心思想之后,为了提高运行效率,该算法通过一系列复杂的数学公式简化了运算方式(有兴趣的同学可以去了解一下),只会用到较为快速的整数加法、减法和位元移位就能完成上述操作,最终运算结果如下:

对于直线y=kx+b(已知两点(x1,y1)(x2,y2),设y2>y1,△y=y2-y1,△x=|x2-x1|)

推导过程:

P=△y-1/2 = f(x+1)-f(x)-1/2= kx+k-kx-1/2=k-1/2=△y/△x - 1/2   为了简化运算,两边同乘2△x,由于我们只需要看左边符号,所以忽略△x,最终结果如下:

P=2△y-△x

1、0<K<1(X+1,判断Y)

Pn=2△y-△x

若Pn < 0,下一个绘制点为(X+1,Y),Pn+1=Pn+2△y

若Pn >= 0,下一个绘制点为(X+1,Y+1),Pn+1=Pn+2(△y-△x)

2、K>1(Y+1,判断X)

Pn=2△y-△x

若Pn < 0,下一个绘制点为(X,Y+1),Pn+1=Pn+2△x

若Pn >= 0,下一个绘制点为(X+1,Y+1),Pn+1=Pn+2(△x-△y)

3、-1<K<0(X-1,判断Y)

Pn=2△y-△x

若Pn < 0,下一个绘制点为(X-1,Y),Pn+1=Pn+2△y

若Pn >= 0,下一个绘制点为(X-1,Y+1),Pn+1=Pn+2(△y-△x)

4、K<-1(Y+1(y2>y1),判断X)

Pn=2△y-△x

若Pn < 0,下一个绘制点为(X,Y+1),Pn+1=Pn+2△x

若Pn >= 0,下一个绘制点为(X-1,Y+1),Pn+1=Pn+2(△x-△y)

二、代码实现

1、直线

    ;横线            
    ;mov al,12h         ;640*480 256的图形模式:            
    mov al,13h          ;320*200 256色的图形模式:
    mov ah,0            ;是用来设定显示模式的服务程序
    mov cx,10           ;x坐标
    mov bx,100          ;终止x坐标
    mov dx,10           ;y坐标
    int 10h
    pheng:
        mov al,1100b     ;淡红色
        mov ah,0ch       ;写入点像
        inc cx
        cmp cx,bx
        int 10h
    jne pheng

运行结果:

2、竖线

    ;竖线
    ;mov al,13h         ;320*200 256色的图形模式:
    ;mov ah,0           ;是用来设定显示模式的服务程序
    mov cx,10           ;x坐标
    mov bx,100          ;终止x坐标
    mov dx,10           ;y坐标
    ;int 10h
    pshu:
        mov al,1100b    ;淡红色
        mov ah,0ch      ;写入点像
        inc dx
        cmp dx,bx
        int 10h
    jne pshu

运行结果:

3、斜线

    mov al,13h          ;320*200 256色的图形模式:
    mov ah,0             ;是用来设定显示模式的服务程序   
    int 10h
    
    
    mov x1,20
    mov x2,70
    mov y1,10
    mov y2,200  
    
    mov ax,x2
    mov bx,x1
    cmp ax,bx
    jae dpos1
    sub bx,ax
    mov s1,-1
    mov xd,bx
    jmp d1
dpos1:
    sub ax,bx
    mov s1,1
    mov xd,ax   
d1: 
    mov ax,y2
    mov bx,y1
    cmp ax,bx
    jae dpos2    	;y2>=y1
    sub bx,ax    	;y2<y1
    mov s2,-1 
    mov yd,bx
    jmp d2
dpos2:
    sub ax,bx
    mov s2,1
    mov yd,ax
    
d2:  
    add ax,ax
    mov bx,xd 
    sub ax,bx  
    mov p,ax   		;2dy-dx
             
    mov cx,x1         
    mov dx,y1
    
pxie: 

    mov al,1100b    ;淡红色
    mov ah,0ch      ;写入点像
    int 10h
    
    mov ax,p
    mov bx,0
    cmp ax,bx
    jge ppos        ;p>=0
    jl pneg         ;p<0
                         

ppos:   
    mov ax,xd
    mov bx,yd
    cmp ax,bx
    ja ddpos1       ;xd>yd
    jbe ddneg1      ;xd<=yd
    
    
ddpos1: 		;0<k<1  或者  -1<k<0  同时  p>=0
    mov ax,x1		;x=x+1
    mov bx,s1
    add ax,s1
    mov x1,ax
    
    mov ax,s2		;y=y+1
    mov bx,y1
    add bx,ax
    mov y1,bx
    
    mov ax,p		;Pn+1=Pn+2(dy-dx)
    mov bx,xd
    mov cx,yd
    add bx,bx
    add cx,cx
    sub cx,bx
    add ax,cx
    mov p,ax
    
    jmp plot

ddneg1:			;k>1  或者  k<-1   同时  p>=0
    mov ax,y1 		;y=y+1
    inc ax
    mov y1,ax
    
    mov ax,s1		;x=x+1  或者  x=x-1
    mov bx,x1
    add bx,ax
    mov x1,bx
    
    mov ax,p		;Pn+1=Pn+2(dx-dy)
    mov bx,xd
    mov cx,yd
    add bx,bx
    add cx,cx
    sub bx,cx
    add ax,bx
    mov p,ax
    
    jmp plot

pneg:
    mov ax,xd
    mov bx,yd
    cmp ax,bx
    ja ddpos2       ;xd>yd
    jbe ddneg2      ;xd<=yd   
    
    
ddpos2:			;0<k<1  或者  -1<k<0  同时  p<0
    mov ax,x1		;x=x+1
    mov bx,s1
    add ax,s1
    mov x1,ax
    
    mov ax,p		;Pn+1=Pn+2dy
    mov bx,yd
    add bx,bx
    add ax,bx
    mov p,ax
    
    jmp plot



ddneg2: 		;k>1  或者  k<-1   同时  p<0
    mov ax,y1 		;y=y+1
    inc ax
    mov y1,ax
    
    mov ax,p		;Pn+1=Pn+2dx
    mov bx,xd
    add bx,bx
    add ax,bx
    mov p,ax
    
    jmp plot
    

plot:
    mov cx,x1		;X坐标
    mov dx,y1		;Y坐标
    cmp cx,x2		;是否绘图完毕
    jne pxie

运行结果:

由于分辨率较低,所以斜线比较粗糙

根据上述程序即可完成三角形、矩形等图形的绘制:

将上述程序封装为子程序,三角形即可调用两次斜线子程序,一次横线子程序完成绘制;矩形可调用两次横线、两次竖线子程序完成绘制。

在绘制等边三角形时,由于等边三角形具有其特殊性,所以在代码方面可存在一定优化,如果感兴趣可看下篇文章。


版权声明:本文为qq_40298054原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。