Board index » delphi » Assembly routes for Circle drawing

Assembly routes for Circle drawing

Does anyone out there know how to draw a circle in Assembly?
I need a perfect route to draw a circle, i mean a perfect circle.  I
tried to use Algerbra to draw a circle but it missed lots of pixel
and it is too slow too.  Can some one show me a better way?
I am very appreciated.
My email address is nowsc...@cadvision.com

 

Re:Assembly routes for Circle drawing


Quote
Never Die! wrote:

> Does anyone out there know how to draw a circle in Assembly?
> I need a perfect route to draw a circle, i mean a perfect circle.  I
> tried to use Algerbra to draw a circle but it missed lots of pixel
> and it is too slow too.  Can some one show me a better way?
> I am very appreciated.

Look up the Bresenham (I think it was) algorithm for circle
drawing.

- Alf

Re:Assembly routes for Circle drawing


Quote
In article <4va4f5$3...@elmo.cadvision.com> nowsc...@cadvision.com (Never Die!) writes:
>Does anyone out there know how to draw a circle in Assembly?
>I need a perfect route to draw a circle, i mean a perfect circle.  I
>tried to use Algerbra to draw a circle but it missed lots of pixel
>and it is too slow too.  Can some one show me a better way?
>I am very appreciated.
>My email address is nowsc...@cadvision.com

Using algebra and/or trigonometry are generally the slowest (though most
accurate) ways of drawing a circle on a computer.  The Bresenham is one of
the best bets and is very fast because 1.) it is pure integer math, and 2.)
it takes advantage of the reflective properties of a circle -- only a 45
degree arc is calculated.

Unfortunately, the Bresenham algorithm is not quite accurate, especially
with small circles (which look like octagons).  But there's a modified
Bresenham algorithm that is a good deal more accurate.  Here's the code,
both in Turbo Pascal and assembler.  I believe I translated the circle()
procedure from a C listing I have, and I translated the assembler listing
from the Pascal source.

BTW, you'll need to provide your own plot() procedure, but that should be
easy enough to accomplish.

This is written for TP7, and is intended for mode 13h (320x200x256c).

procedure circle (xcent,ycent,rad:integer;colr:byte);

var
  x, y, d : integer;
  dE, dSE : integer;

begin
  x := 0;
  y := rad;

  d := 1 - rad;
  dE := 3;
  dSE := -(rad shl 1) + 5;
  plot(xcent-x, ycent-y, colr);
  plot(xcent-x, ycent+y, colr);
  plot(xcent+y, ycent-x, colr);
  plot(xcent-y, ycent+x, colr);

  while y>x do
    begin
      if d<0 then
        begin
          d := d + dE;
          dE := dE + 2;
          dSE := dSE + 2;
          x := x + 1;
        end
      else
        begin
          d := d + dSE;
          dE := dE + 2;
          dSE := dSE + 4;
          x := x + 1;
          y := y - 1;
        end;
    plot(xcent+x, ycent-y, colr);
    plot(xcent-x, ycent+y, colr);
    plot(xcent-x, ycent-y, colr);
    plot(xcent+x, ycent+y, colr);
    plot(xcent+y, ycent-x, colr);
    plot(xcent-y, ycent+x, colr);
    plot(xcent-y, ycent-x, colr);
    plot(xcent+y, ycent+x, colr);
  end;
end;

procedure circle_asm (xcent,ycent,rad:integer;colr:byte); assembler;

{bx = xp; cx = yp; dx = d}

var
  dE, dSE : integer;

asm
  mov   ax,rad
  shl   ax,1
  not   ax
  add   ax,5
  mov   [dSE],ax
  mov   ax,3
  mov   [dE],3
  mov   bx,0
  mov   cx,rad
  mov   dx,1
  sub   dx,cx
  mov   ax,[SegA000]
  mov   es,ax
@Plot1A:
  mov   ax,[ycent]
  sub   ax,cx
  shl   ax,6
  mov   di,ax
  shl   ax,2
  add   di,ax
  add   di,[xcent]
  sub   di,bx
  mov   al,colr
  stosb
@Plot2A:
  mov   ax,[ycent]
  add   ax,cx
  shl   ax,6
  mov   di,ax
  shl   ax,2
  add   di,ax
  add   di,[xcent]
  sub   di,bx
  mov   al,colr
  stosb
@Plot3A:
  mov   ax,[ycent]
  sub   ax,bx
  shl   ax,6
  mov   di,ax
  shl   ax,2
  add   di,ax
  add   di,[xcent]
  add   di,cx
  mov   al,colr
  stosb
@Plot4A:
  mov   ax,[ycent]
  add   ax,bx
  shl   ax,6
  mov   di,ax
  shl   ax,2
  add   di,ax
  add   di,[xcent]
  sub   di,cx
  mov   al,colr
  stosb
@CircLoop:
  cmp   bx,cx
  jg    @Done
@CheckDecide:
  test  dx,-1
  js    @NegDecision
@NonNegDecision:
  add   dx,[dSE]
  add   [dE],2
  add   [dSE],4
  inc   bx
  dec   cx
  jmp   @Plot1
@NegDecision:
  add   dx,[dE]
  add   [dE],2
  add   [dSE],2
  inc   bx
@Plot1:
  {plot (xcent-yp,ycent-xp,colr);}
  mov   ax,[ycent]
  sub   ax,bx
  shl   ax,6
  mov   di,ax
  shl   ax,2
  add   di,ax
  add   di,[xcent]
  sub   di,cx
  mov   al,colr
  stosb
@Plot2:
  {plot (xcent-yp,ycent+xp,colr);}
  mov   ax,[ycent]
  add   ax,bx
  shl   ax,6
  mov   di,ax
  shl   ax,2
  add   di,ax
  add   di,[xcent]
  sub   di,cx
  mov   al,colr
  stosb
@Plot3:
  {plot (xcent+yp,ycent-xp,colr);}
  mov   ax,[ycent]
  sub   ax,bx
  shl   ax,6
  mov   di,ax
  shl   ax,2
  add   di,ax
  add   di,[xcent]
  add   di,cx
  mov   al,colr
  stosb
@Plot4:
  {plot (xcent+yp,ycent+xp,colr);}
  mov   ax,[ycent]
  add   ax,bx
  shl   ax,6
  mov   di,ax
  shl   ax,2
  add   di,ax
  add   di,[xcent]
  add   di,cx
  mov   al,colr
  stosb
@Plot5:
  {plot (xcent-xp,ycent-yp,colr);}
  mov   ax,[ycent]
  sub   ax,cx
  shl   ax,6
  mov   di,ax
  shl   ax,2
  add   di,ax
  add   di,[xcent]
  sub   di,bx
  mov   al,colr
  stosb
@Plot6:
  {plot (xcent-xp,ycent+yp,colr);}
  mov   ax,[ycent]
  add   ax,cx
  shl   ax,6
  mov   di,ax
  shl   ax,2
  add   di,ax
  add   di,[xcent]
  sub   di,bx
  mov   al,colr
  stosb
@Plot7:
  {plot (xcent+xp,ycent-yp,colr);}
  mov   ax,[ycent]
  sub   ax,cx
  shl   ax,6
  mov   di,ax
  shl   ax,2
  add   di,ax
  add   di,[xcent]
  add   di,bx
  mov   al,colr
  stosb
@Plot8:
  {plot (xcent+xp,ycent+yp,colr);}
  mov   ax,[ycent]
  add   ax,cx
  shl   ax,6
  mov   di,ax
  shl   ax,2
  add   di,ax
  add   di,[xcent]
  add   di,bx
  mov   al,colr
  stosb
  jmp   @CircLoop
@Done:
end;

--
Scott Earnest          | We now return you to our regularly scheduled |
siny...@{*word*104}space.org | chaos and mayhem. . . .                      |

Other Threads