Drawing an Antiailiased Ellipse or Circle using Delphi5  Graphics

Posted on 2008-06-20
Last Modified: 2013-12-21
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.

Tom Myers
Question by:Tom1myers
  • 3
  • 3

Accepted Solution

Mamouri earned 500 total points
ID: 21832061
Take a look to this delphi code and sample:
It's free and works like a charm. But I'm not sure about the algorithm.

Author Comment

ID: 21837158
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,
Tom Myers

Assisted Solution

Mamouri earned 500 total points
ID: 21837386

Here is a very good implementation of Wu Lang Algorithm for drawing circles in C++:

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

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.


Expert Comment

ID: 21837389

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

Author Closing Comment

ID: 31469192
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

Author Comment

ID: 21891280
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);
  X1,X2,Y1,Y2    : Integer;
  LineColor      : TColor;
  Point1, Point2 : TPoint;
  DrawPlace      : TBitmap;
  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);
  deltax, deltay, loop, start, finish : integer;
  dx, dy, dydx : single; // fractional parts
  LR, LG, LB : byte;
  x1, x2, y1, y2 : integer;
  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);
  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)
      dydx := deltay / deltax;
    if x2 < x1 then
      start := x2; // right to left
      finish := x1;
      dy := y2;
    end else
      start := x1; // left to right
      finish := x2;
      dy := y1;
      dydx := -dydx; // inverse slope
    for loop := start to finish do
      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 else
    if x2 > x1 then // determine rise and run
      dydx := -(deltax / deltay)
      dydx := deltax / deltay;
    if y2 < y1 then
      start := y2; // right to left
      finish := y1;
      dx := x2;
    end else
      start := y1; // left to right
      finish := y2;
      dx := x1;
      dydx := -dydx; // inverse slope
    for loop := start to finish do
      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
// blend a pixel with the current colour
procedure TFormDraw.AlphaBlendPixel(ABitmap : TBitmap ; X, Y : integer ; R, G, B : byte ; ARatio : Real);
  LBack, LNew : TRGBTriple;
  LMinusRatio : Real;
  LScan : PRGBTripleArray;
  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;

Open in new window


Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Delphi application Soap connection 5 120
Delphi XE10 Round Image 2 158
count7 challenge 12 126
How to save the image in the .cds File ClientDataSet? 1 22
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.

837 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question