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?

Any help will be sincerely appreciated.

Respectfully,
Tom Myers
Tom1myersAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

MamouriCommented:
Take a look to this delphi code and sample: http://www.simdesign.nl/tips/tip002.html
It's free and works like a charm. But I'm not sure about the algorithm.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Tom1myersAuthor Commented:
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.

Until then,
Respectfully,
Tom Myers
0
MamouriCommented:
Hi,

Here is a very good implementation of Wu Lang Algorithm for drawing circles in C++: http://www.codeproject.com/KB/GDI/antialias.aspx

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));
	}
}

Open in new window

0
Exploring SharePoint 2016

Explore SharePoint 2016, the web-based, collaborative platform that integrates with Microsoft Office to provide intranets, secure document management, and collaboration so you can develop your online and offline capabilities.

MamouriCommented:
Hi

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 colour
procedure 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;

Open in new window

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Game Programming

From novice to tech pro — start learning today.