Solved

Drawing an Antiailiased Ellipse or Circle using Delphi5  Graphics

Posted on 2008-06-20
6
2,699 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
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
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

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
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…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

747 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

12 Experts available now in Live!

Get 1:1 Help Now