adroit
Joined: 21 Feb 2010
Posts: 252
|
I was read an ebook about techniques in C language and I found this interesting topic: the Hilbert curve.
I can't understand 'C' so I just copied the directions and made this code to follow them. N.B: The directions code wasn't originally implemented in this program. It was done for something else.
Here here's the code:
; Hilbert Curve Render
;
; This program doesn't perform any mathematical algorithm to
; generate the Hilbert curve. Instead, it draws each line segment
; according to the directions. If the directions are:
; Up, Right, Down, Left. It will draw one line upwards. Then,
; from the last position (the end of the first lines segment), it
; draws one line rightwards, then one line downwards and then one
; leftwards. These directions will form a rectangle (square).
;
org 100h
use16
;===========================================
; CODE
;===========================================
init:
mov ax,0013h
int 10h
start:
mov [x_pos],SCREEN_WIDTH/2
mov [y_pos],SCREEN_HEIGHT/2
sub [x_pos],36
add [y_pos],36
mov si,dir
call DrawHilbertCurve
xor ax,ax
int 16h
end_program:
mov ax,0003h
int 10h
mov ax,4C00h
int 21h
;===========================================
; FUNCTIONS
;===========================================
PutPixel:
mov ah,0Ch
mov al,[colour]
mov bh,0
mov cx,[x_pos]
mov dx,[y_pos]
int 10h
ret
;-------------------------------------------
DrawLineUp:
mov [counter],LINE_LENGTH
@@:
call PutPixel
sub [x_pos],SCREEN_WIDTH
dec [counter]
jnz @b ; jump if _counter <> = 0
ret ; else, exit function
;-------------------------------------------
DrawLineDown:
mov [counter],LINE_LENGTH
@@:
call PutPixel
add [x_pos],SCREEN_WIDTH
dec [counter]
jnz @b ; jump if _counter <> = 0
ret ; else, exit function
;-------------------------------------------
DrawLineLeft:
mov [counter],LINE_LENGTH
@@:
call PutPixel
dec [x_pos]
dec [counter]
jnz @b ; jump if _counter <> = 0
ret ; else, exit function
ret
;-------------------------------------------
DrawLineRight:
mov [counter],LINE_LENGTH
@@:
call PutPixel
inc [x_pos]
dec [counter]
jnz @b ; jump if _counter <> = 0
ret ; else, exit function
;-------------------------------------------
DrawHilbertCurve:
.loop:
mov al,[si]
inc si
or al,al
jz .return
@@:
mov bx,6 ; _drawgrid_addr index counter (size: word)
mov ah,4
.check_for_direction:
or ah,ah
jz .loop
cmp al,ah
je @f
dec ah
sub bx,2
jmp .check_for_direction
@@:
call [draw_line_addr+bx] ; call a draw line function
mov [colour],0xF ; restore colour
jmp .loop
.return:
inc si
ret
;===========================================
; CONSTANT AND DATA
;===========================================
SCREEN_HEIGHT = 200
SCREEN_WIDTH = 320
LINE_LENGTH = 10
; directional characters for grid drawing sequence
U = 1 ; up
D = 2 ; down
L = 3 ; left
R = 4 ; right
ENDSQ = 0 ; end direction sequence
; x & y coordinates
x_pos dw 0
y_pos dw 0
; counter variable
counter db 0
; colour variable
colour db 0
; draw line function addresses
draw_line_addr dw DrawLineUp,DrawLineDown,DrawLineLeft,DrawLineRight
; hilbert curve directions
dir db U,R,U,L,U,U,R,D,R,U,R,D,D,L,D,R,R,U,R,D,R,R,U,L,U,R,U,L,L,D,L,U,U,U,R
db D,R,R,U,L,U,R,U,L,L,D,L,U,L,L,D,R,D,D,L,U,L,D,L,U,U,R,U,L,ENDSQ
Try changing the LINE_LENGTH constant to something smaller to get a smaller curve.
This is only my first attempt at the curve, so next, I plan to study the equation behind the curve an implement it in Assembly language. (I suppose it is going to be hard).
_________________ meshnix
Last edited by adroit on 02 Jul 2012, 16:32; edited 3 times in total
|