Solved

Drawing an Antiailiased Ellipse or Circle using Delphi5  Graphics

Posted on 2008-06-20
6
2,709 Views
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.

Respectfully,
Tom Myers
0
Comment
Question by:Tom1myers
  • 3
  • 3
6 Comments
 
LVL 3

Accepted Solution

by:
Mamouri earned 500 total points
ID: 21832061
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
 

Author Comment

by:Tom1myers
ID: 21837158
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
 
LVL 3

Assisted Solution

by:Mamouri
Mamouri earned 500 total points
ID: 21837386
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
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 3

Expert Comment

by:Mamouri
ID: 21837389
Hi

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

Author Closing Comment

by:Tom1myers
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
0
 

Author Comment

by:Tom1myers
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);
 

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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

As game developers, we quickly learn that Artificial Intelligence (AI) doesn’t need to be so tough.  To reference Space Ghost: “Moltar, I have a giant brain that is able to reduce any complex machine into a simple yes or no answer. (http://www.youtu…
Recently, in one of the tech-blogs I usually read, I saw a post about the best-selling video games through history. The first place in the list is for the classic, extremely addictive Tetris. Well, a long time ago, in a galaxy far far away, I was…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …
Delivering innovative fully-managed cloud services for mission-critical applications requires expertise in multiple areas plus vision and commitment. Meet a few of the people behind the quality services of Concerto.

932 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now