1. 程式人生 > >組合語言實現圖形繪製——矩形、三角形等

組合語言實現圖形繪製——矩形、三角形等

組合語言實現圖形繪製

一、準備工作

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

執行結果:

由於解析度較低,所以斜線比較粗糙

根據上述程式即可完成三角形、矩形等圖形的繪製:

將上述程式封裝為子程式,三角形即可呼叫兩次斜線子程式,一次橫線子程式完成繪製;矩形可呼叫兩次橫線、兩次豎線子程式完成繪製。

在繪製等邊三角形時,由於等邊三角形具有其特殊性,所以在程式碼方面可存在一定優化,如果感興趣可看下篇文章。