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

汇编语言实现图形绘制

一、准备工作

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 座标 颜色
4 0~319 0~199 0、1
5 0~319 0~199 0~3
6 0~639 0~199 0、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 黑色 black 1000 灰色 gray
0001 蓝色 blue 1001 淡蓝色 light blue
0010 绿色 green 1010 淡绿色 light green
0011 青色 cyan 1000 淡青色 light cyan
0100 红色 red 1100 淡红色 light red
0101 紫红色 magenta 1101 淡紫红色 light magenta
0110 棕色 brown 1110 黄色 yellow
0111 银色 light gray 1111 白色 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

运行结果:

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

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

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

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

猜你喜欢

转载自blog.csdn.net/qq_40298054/article/details/84496944
今日推荐