Board index » delphi » Drawing a circle, pixel by pixel

Drawing a circle, pixel by pixel

Search Google for Bresenham's circle algorithm.
It's very fast and doesn't have that problem.
--
Finn Tolderlund

"Jon Lennart Berg" <jon...@c2i.net> wrote in message
news:3dae89b1\$1@newsgroups.borland.com...

Quote
> For some time now i have been using the following routine to calculate a
> circle pixel by pixel. It works great except that when the circle has a
> radius span of more than 360, the pixels start to move away from each

other.

Re:Drawing a circle, pixel by pixel

By the way:
The problem with your old procedure is that you always draw 360 pixels (for
x:=0 to 359 do) nomatter how big or small the circle is.
This means that for small circles you draw too many pixels and for large
circles you draw too few pixels.
--
Finn Tolderlund

"Jon Lennart Berg" <jon...@c2i.net> wrote in message
news:3daec4cf\$1@newsgroups.borland.com...

Quote
> Thanks!
> Works like a charm... :)
> Lennart Berg

Re:Drawing a circle, pixel by pixel

Since the formula for a circle's circumference is 2*Radius*Pi you have draw
This means that your old procedure should be changed to something like this:
Canvas: TCanvas; Color: TColor);
var
{x,}xpos,ypos: Integer;
Pix, Pixels: Integer;
x: Real;
begin
Pixels := Round(2* Radius * Pi);
//for x:=0 to 359 do
for pix := 0 to Pixels-1 do
begin
x := 360 * pix / Pixels; {calculate a value of 0-359}
Canvas.Pixels[xpos,ypos] := Color;
end;
end;
--
Finn Tolderlund

"Jon Lennart Berg" <jon...@c2i.net> skrev i en meddelelse
news:3db00f6f@newsgroups.borland.com...

Quote
> I figured that, but i was unsure about what values i should place there.
> I guess (X * Y * X) would give correct results??

> Lennart Berg

> "Finn Tolderlund" <f...@nospam.com> skrev i melding
> news:3dafb1bb\$1@newsgroups.borland.com...
> > By the way:
> > The problem with your old procedure is that you always draw 360 pixels
> (for
> > x:=0 to 359 do) nomatter how big or small the circle is.
> > This means that for small circles you draw too many pixels and for large
> > circles you draw too few pixels.
> > --
> > Finn Tolderlund

Re:Drawing a circle, pixel by pixel

Quote
Finn Tolderlund wrote:

> Since the formula for a circle's circumference is 2*Radius*Pi you have draw
> This means that your old procedure should be changed to something like this:
> procedure Circle(xStart, yStart, Radius: Integer;
>   Canvas: TCanvas; Color: TColor);
> var
>   {x,}xpos,ypos: Integer;
>   Pix, Pixels: Integer;
>   x: Real;
> begin
>   Pixels := Round(2* Radius * Pi);
>   //for x:=0 to 359 do
>   for pix := 0 to Pixels-1 do
>   begin
>     x := 360 * pix / Pixels; {calculate a value of 0-359}
>     Canvas.Pixels[xpos,ypos] := Color;
>   end;
> end;
> --
> Finn Tolderlund

You might also check if this renders faster:

Canvas: TCanvas; Color: TColor);
var
xpos,ypos: Integer;
Pix, Pixels: Integer;
x: Real;
begin
//for x:=0 to 359 do
x:=pi*2/pixels;
with canvas do
for pix := 0 to Pixels do
begin
x := 360 * pix / Pixels; {calculate a value of 0-359}
if  pix=0 then moveto(x,y) else lineto(x,y);
end;
end;

This way you can use the canvas pen width in your drawing
procedure as well.
Since this connects all the points you can reduce the number of
steps if you like and still get a closed circle.

Remco

Re:Drawing a circle, pixel by pixel

Okay, a bit late, but:

procedure MidPointCircle(iBitmap: TBitmap; iX, iY, iRadius: integer; iValue:
TColor);

procedure CirclePoints(iOriginX,iOriginY,iX, iY: integer; iValue: TColor);
begin
iBitmap.Canvas.Pixel [iOriginX + iX, iOriginY + iY]  :=  iValue;
iBitmap.Canvas.Pixel [iOriginX + iY, iOriginY + iX]  :=  iValue;
iBitmap.Canvas.Pixel [iOriginX + iY, iOriginY - iX]  :=  iValue;
iBitmap.Canvas.Pixel [iOriginX + iX, iOriginY - iY]  :=  iValue;
iBitmap.Canvas.Pixel [iOriginX - iX, iOriginY - iY]  :=  iValue;
iBitmap.Canvas.Pixel [iOriginX - iY, iOriginY - iX]  :=  iValue;
iBitmap.Canvas.Pixel [iOriginX - iY, iOriginY + iX]  :=   iValue;
iBitmap.Canvas.Pixel [iOriginX - iX, iOriginY + iY]  :=   iValue;
end;

var  { Introduction to computer graphics (Foley, van Dam, Feiner, Hughes,
Philips),
isbn 0-201-60921-5. }
x,y,d: integer;
deltaE,deltaSE: integer;
begin
(* This function uses second-order partial differences to compute
increments *)
(* in the decision variable. Assumes center of circle is at origin. *)
x := 0;
deltaE := 3;

CirclePoints (iX,iY, x,y, iValue);

while (y > x) do
begin
if (d < 0) then
begin
inc (d, deltaE);
inc (deltaE, 2);
inc (deltaSE, 2);
inc (x);
end else begin
inc (d, deltaSE);
inc (deltaE, 2);
inc (deltaSE, 4);
inc (x);
dec (y);
end;
CirclePoints (iX,iY, x,y, iValue);
end;
end;

"Remco de Korte" <re...@onwijs.com> wrote in message
news:3DB13B82.DF9D713A@onwijs.com...

Quote
> Finn Tolderlund wrote:

> > Since the formula for a circle's circumference is 2*Radius*Pi you have
draw
> > This means that your old procedure should be changed to something like
this:
> > procedure Circle(xStart, yStart, Radius: Integer;
> >   Canvas: TCanvas; Color: TColor);
> > var
> >   {x,}xpos,ypos: Integer;
> >   Pix, Pixels: Integer;
> >   x: Real;
> > begin
> >   Pixels := Round(2* Radius * Pi);
> >   //for x:=0 to 359 do
> >   for pix := 0 to Pixels-1 do
> >   begin
> >     x := 360 * pix / Pixels; {calculate a value of 0-359}
> >     Canvas.Pixels[xpos,ypos] := Color;
> >   end;
> > end;
> > --
> > Finn Tolderlund

> You might also check if this renders faster:

>    Canvas: TCanvas; Color: TColor);
>  var
>    xpos,ypos: Integer;
>    Pix, Pixels: Integer;
>    x: Real;
>  begin
>    Pixels := Round(2*Radius * Pi);
>    //for x:=0 to 359 do
>    x:=pi*2/pixels;
>    with canvas do
>    for pix := 0 to Pixels do
>    begin
>      x := 360 * pix / Pixels; {calculate a value of 0-359}