Drawing an Antiailiased Ellipse or Circle using Delphi5 Graphics

The software I am developing draws images based upon dimensional values drawn from a datbase. I am currently using the Wu-Line algorighm to antialaise straight lines with great results. However the curved lines of the image still display the jagged line which greatly detracts from the image quality. I have read that Wu also developed an antialiased curved line drawing algorithm but have been unable to locate any code showing the algorithm.

Does anyone have a reference to the algorithm or a similr algorithm that will draw antialiased ellipses, circles or arcs in 24 bit colors?

Mamouri,
Thank you for your response. Although, the code and sample present a very clear and concise insight into the method of antiailiasing a circle and I may need to devise a method of using it, I really need to find Wu's circle antiailiasing algorighm to work in conjunction with my present line antiailiasing code.

I am going to be away from my computer for the next 3 days. If the Wu algorithm has not turned up by then, I'll re-evaluate my requirements.

Actually DrawWuCirlce uses DrawWuLine method for drawing a circle. The source of DrawWuLine is attached. As you told in the Question you have the source code for drawing a line using Wu Algorithm. So I think it's easy to use the algorithm for drawing a circle using Wu Line Drawing function.

void DrawWuCirlce (CDC * pDC, int x, int y, int r){ short x1, y1, x2, y2; float dt = 5; for ( float theta= 0; theta< 360; theta += dt ) { x1 = (short)( r*cos(theta*3.141593/180.0)+x); y1 = (short)(-r*sin(theta*3.141593/180.0)+y); x2 = (short)( r*cos((theta+dt)*3.141593/180.0)+x); y2 = (short)(-r*sin((theta+dt)*3.141593/180.0)+y); DrawWuLine ( pDC, x1, y1, x2, y2, RGB(192,0,0)); }}

It's very appreciated if you could share Wu Lang Antialias Line Drawing function with community :)

0

Tom1myersAuthor Commented:

Please forgive my tardy responses to the solutions. A medical emergency has kept me from my computer.
I beleive that both responses will be quite useful.
Thank you for your patience and efforts.
I will post the procedure that was derived from the Wu Line code that I use to draw antialiased lines.
Tom Myers

0

Tom1myersAuthor Commented:

Attached is the code I use to draw antiailiased, straight lines.
After I have used the common Delphi code to sketch and color the image, I call the Wu procedure to draw over the boundry lines to match the existing colors on each side of the line.
I works great for me. Now I just need to incorporate the Wu antialiased circle code to complete the process.
Tom Myers

Uses Math, Graphics;procedure WuLine(ABitmap : TBitmap ; Point1, Point2 : TPoint ; AColor : TColor);procedure AlphaBlendPixel(ABitmap : TBitmap ; X, Y : integer ; R, G, B : byte ; ARatio : Real);Var X1,X2,Y1,Y2 : Integer; LineColor : TColor; Point1, Point2 : TPoint; DrawPlace : TBitmap;begin DrawPlace := TBitmap.Create; DrawPlace := Image1.Picture.Bitmap; Drawplace.PixelFormat := pf24Bit; Drawplace.Height := Image1.Height; DrawPlace.Width := Image1.Width; X1 := 10, X2 := 100, Y1 := 10, Y2 := 50; LineColor := clBlack WuLine(Drawplace, Point(X1,Y1), Point(X2,Y1),SketchColor.Color);procedure TFormDraw.WuLine(ABitmap : TBitmap ; Point1, Point2 : TPoint ; AColor : TColor);var deltax, deltay, loop, start, finish : integer; dx, dy, dydx : single; // fractional parts LR, LG, LB : byte; x1, x2, y1, y2 : integer;begin x1 := Point1.X; y1 := Point1.Y; x2 := Point2.X; y2 := Point2.Y; deltax := abs(x2 - x1); // Calculate deltax and deltay for initialisation deltay := abs(y2 - y1); if (deltax = 0) or (deltay = 0) then begin // straight lines ABitmap.Canvas.Pen.Color := AColor; ABitmap.Canvas.MoveTo(x1, y1); ABitmap.Canvas.LineTo(x2, y2); exit; end; LR := (AColor and $000000FF); LG := (AColor and $0000FF00) shr 8; LB := (AColor and $00FF0000) shr 16; if deltax > deltay then begin // horizontal or vertical if y2 > y1 then // determine rise and run dydx := -(deltay / deltax) else dydx := deltay / deltax; if x2 < x1 then begin start := x2; // right to left finish := x1; dy := y2; end else begin start := x1; // left to right finish := x2; dy := y1; dydx := -dydx; // inverse slope end; for loop := start to finish do begin AlphaBlendPixel(ABitmap, loop, trunc(dy), LR, LG, LB, 1 - frac(dy)); AlphaBlendPixel(ABitmap, loop, trunc(dy) + 1, LR, LG, LB, frac(dy)); dy := dy + dydx; // next point end; end else begin if x2 > x1 then // determine rise and run dydx := -(deltax / deltay) else dydx := deltax / deltay; if y2 < y1 then begin start := y2; // right to left finish := y1; dx := x2; end else begin start := y1; // left to right finish := y2; dx := x1; dydx := -dydx; // inverse slope end; for loop := start to finish do begin AlphaBlendPixel(ABitmap, trunc(dx), loop, LR, LG, LB, 1 - frac(dx)); AlphaBlendPixel(ABitmap, trunc(dx) + 1, loop, LR, LG, LB, frac(dx)); dx := dx + dydx; // next point end; end;end;// blend a pixel with the current colourprocedure TFormDraw.AlphaBlendPixel(ABitmap : TBitmap ; X, Y : integer ; R, G, B : byte ; ARatio : Real);Var LBack, LNew : TRGBTriple; LMinusRatio : Real; LScan : PRGBTripleArray;begin if (X < 0) or (X > ABitmap.Width - 1) or (Y < 0) or (Y > ABitmap.Height - 1) then Exit; // clipping LScan := ABitmap.Scanline[Y]; LMinusRatio := 1 - ARatio; LBack := LScan[X]; LNew.rgbtBlue := round(B*ARatio + LBack.rgbtBlue*LMinusRatio); LNew.rgbtGreen := round(G*ARatio + LBack.rgbtGreen*LMinusRatio); LNew.rgbtRed := round(R*ARatio + LBack.rgbtRed*LMinusRatio); LScan[X] := LNew;end;

Maybe you’ve fully adopted the cloud since the beginning. Or maybe you started with on-prem resources but are pursuing a “cloud and mobile first” strategy. Getting to that end state has its challenges. Discover how to build out a 100% cloud and mobile IT strategy in this webinar.

It's free and works like a charm. But I'm not sure about the algorithm.