Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2867
  • Last Modified:

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
0
Tom1myers
Asked:
Tom1myers
  • 3
  • 3
2 Solutions
 
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
 
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Featured Post

[Webinar] Cloud and Mobile-First Strategy

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.

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now