[Back to EGAVGA SWAG index]  [Back to Main SWAG index]  [Original]

{ SC> I had some free time the other day so I decided to play around
 SC> With some Graphics.  I am using TRIG Functions to draw a
 SC> circle.  But it's not too fast.  I understand that using
 SC> Shift operators to multiply and divide will be faster.  But
 SC> am not sure how to do numbers which are not powers of 2.
 SC> Here is the code; how else can we make it faster?

Using shifts to multiply things is one way to speed it up but that's difficult
For generic multiplies and only applies to Integer multiplies.  There's an even
faster way to draw a circle if you are interested. <YES he says>  OK, first it
is called the "Bresenham Circle Algorithm" and Uses symmetry about the eight
octants to plot the circle and Uses only Integer arithmetic throughout.  Here
is the code.
}
Uses
  Graph, KASUtils;

Var
  Gd, Gm : Integer;

Procedure DrawCircle(X, Y, Radius:Word; Color:Byte);
Var
   Xs, Ys    : Integer;
   Da, Db, S : Integer;
begin
     if (Radius = 0) then
          Exit;

     if (Radius = 1) then
     begin
          PutPixel(X, Y, Color);
          Exit;
     end;

     Xs := 0;
     Ys := Radius;

     Repeat
           Da := Sqr(Xs+1) + Sqr(Ys) - Sqr(Radius);
           Db := Sqr(Xs+1) + Sqr(Ys - 1) - Sqr(Radius);
           S  := Da + Db;

           Xs := Xs+1;
           if (S > 0) then
                Ys := Ys - 1;

           PutPixel(X+Xs-1, Y-Ys+1, Color);
           PutPixel(X-Xs+1, Y-Ys+1, Color);
           PutPixel(X+Ys-1, Y-Xs+1, Color);
           PutPixel(X-Ys+1, Y-Xs+1, Color);
           PutPixel(X+Xs-1, Y+Ys-1, Color);
           PutPixel(X-Xs+1, Y+Ys-1, Color);
           PutPixel(X+Ys-1, Y+Xs-1, Color);
           PutPixel(X-Ys+1, Y+Xs-1, Color);
     Until (Xs >= Ys);
end;

{It Uses Sqr at the moment, but you could code it to use X * X instead of Sqr(X)
if you like since it will probably speed it up.  I haven't had time to optimise
it yet since it will ultimately be in Assembler.

Hope this comes in handy For what you're doing. :-) Oh BTW it assumes you have
a PlotDot routine which takes the obvious parameters.
}

begin
  EGAVGA_Exe;
  gd := detect;
  InitGraph(gd,gm,'');
  clearviewport;

  drawcircle(100,100,150,yellow);
  readln;
end.

[Back to EGAVGA SWAG index]  [Back to Main SWAG index]  [Original]