nasm - What is the easiest way to draw a perfectly filled circle(disc) in assembly? -


i'd draw filled* circle(disc) in assembly in 320x200 mode 100 pixel radius. what's quickest/easiest way?

(*: mean disc filled when color e.g. constant white , has no black pixels in it.)

if quickest mean quickest write, here simple solution dos.

it doesn't use dos service exit one.
meant generate com file (raw output nasm fine, rename com extension).

bits 16  org 100h  push 0a000h           ;video memory graphics segment pop es  mov ax, 0013h         ;320x200@8bpp int 10h   push 09h              ;blue push 159              ;cx push 99               ;cy push 60               ;radius call drawfilledcircle  ;wait key xor ah, ah int 16h  ;restore text mode mov ax, 0003h int 10h  ;return mov ax, 4c00h int 21h   ;color ;cx ;cy ;r drawfilledcircle:  push bp  mov bp, sp   sub sp, 02h   mov cx, word [bp+04h]   ;r   mov ax, cx                mul ax                  ;ax = r^2  mov word [bp-02h], ax   ;[bp-02h] = r^2     mov ax, word [bp+06h]  sub ax, cx              ;i = cy-r  mov bx, word [bp+08h]  sub bx, cx              ;j = cx-r   shl cx, 1  mov dx, cx              ;dx = copy of 2r  .advance_v:  push cx  push bx   mov cx,  dx  .advance_h:   ;save values   push bx   push ax   push dx    ;compute (i-y) , (j-x)   sub ax, word [bp+06h]   sub bx, word [bp+08h]    mul ax                  ;compute (i-y)^2    push ax   mov ax, bx                mul ax   pop bx                  ;compute (j-x)^2 in ax, (i-y)^2 in bx    add ax, bx              ;(j-x)^2 + (i-y)^2   cmp ax, word [bp-02h]   ;;(j-x)^2 + (i-y)^2 <= r^2    ;restore values before jump   pop dx   pop ax   pop bx    ja .continue            ;skip pixel if (j-x)^2 + (i-y)^2 > r^2    ;write pixel   push word [bp+0ah]   push bx   push ax   call writepx   .continue:    ;advance j   inc bx  loop .advance_h   ;advance  inc ax    pop bx            ;restore j  pop cx            ;restore counter  loop .advance_v   add sp, 02h    pop bp  ret 08h    ;color ;x ;y writepx:  push bp  mov bp, sp   push ax  push bx   mov bx, word [bp+04h]  mov ax, bx  shl bx, 6  shl ax, 8  add bx, ax       ;320 = 256 + 64   add bx, word [bp+06h]  mov ax, word [bp+08h]   ;todo: clip   mov byte [es:bx], al   pop bx  pop ax   pop bp  ret 06h 

it common technique writing plane figures given parameters, it's called rasterization.

given center c(x, y) , radius r of circle, algorithm follow

1. = y-r y+r 1.1   j = x-r x+r 1.1.1     if (i-y)^2 + (j-x)^2 <= r^2 1.1.1.1      drawpixel(j, i) 1.1.1     end if 1.1   end 1. end 

this not optimized speed, @ all!
indeed create multiple routine sake of clarity. use stack lot.

note writepx not clip coordinates!


if want speed things need more specific on requirement.
example radius fixed? if yes can use block of memory encode quarter of circle, this

0 0 0 0 0 1 1 1 0 0 0 1 1 1 1 1 0 0 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1  

where each digits may bit or byte depending on speed vs memory constraints.
can copy block directly video memory or use template (kind of chroma key technique).
printing other 3 quarters of circle simple play counters.

if radius not fixed can boost code above by

  • inlining functions call
  • avoid use of stack as possible
  • don't compute distance @ every cycle compute previous value using basic calculus.
  • compute more 1 pixel @ time , combine writings.

Comments

Popular posts from this blog

Fail to load namespace Spring Security http://www.springframework.org/security/tags -

sql - MySQL query optimization using coalesce -

unity3d - Unity local avoidance in user created world -