Solved

Draw ellipse

Posted on 2002-06-11
22
616 Views
Last Modified: 2012-05-04
I wish to follow an eliptic route .
For example I wish to go from a point (100,100) and to draw an ellipse ( with next dimensions for example : 100 and 75 ), point by point, to my canvas.

Attention, POINT BY POINT .
0
Comment
Question by:ginsonic
  • 9
  • 4
  • 3
  • +5
22 Comments
 
LVL 27

Expert Comment

by:kretzschmar
Comment Utility
would be a nice qow, nick :-))
0
 
LVL 9

Author Comment

by:ginsonic
Comment Utility
I thinking to this :)
0
 
LVL 8

Accepted Solution

by:
Cesario earned 100 total points
Comment Utility
try this code ;-)

procedure TForm1.Button1Click(Sender: TObject);
var
  mx,my,x,y,cnt :Integer;
begin
  With Canvas Do
  Begin
    moveTo ( 400,200);
    mx :=  100;
    my :=  75;
    For cnt := 0 to 360 do
    begin
      x := 400 + trunc(mx * sin ( cnt*pi/180 ));
      y := 200 + Trunc(my * cos ( cnt*pi/180 ));
      Pixels[x,y] := clBlack;
    End;
  End;
end;
0
 
LVL 8

Expert Comment

by:Cesario
Comment Utility
to ginsonic:
sorry, for delay but I was last 2 weeks offline.
You can contact me  C_Lababidi@hotmail.com

Best Regards

Cesario
0
 
LVL 3

Expert Comment

by:tongalite
Comment Utility
Hi Ginsonic
Do you mean with a time delay in the drawing from point to point?
T.
0
 
LVL 11

Expert Comment

by:robert_marquardt
Comment Utility
Yes i know not POINT by POINT, but Win32 AngleArc function is not well known and needs mentioning.
0
 
LVL 11

Expert Comment

by:robert_marquardt
Comment Utility
I recall that it is possible to tweak Bresenham algoritm to draw ellipses.
0
 
LVL 7

Expert Comment

by:Cynna
Comment Utility
ginsonic,

Cesario provided you with correct answer. You could tweek it a little by replacing Trunc with Round (more accurate curve) and using precalculated trigonometric table (much more speed).

0
 
LVL 11

Expert Comment

by:robert_marquardt
Comment Utility
After a fast Google search i found this algorithm in a newsgroup message which i translated to Pascal. It is completely untested. The text is from the message.

: I am looking an algorithm for drawing an ellipse .
: The input shall be the midpoint and the two axes .

Here is one implementation in C of the algorithm...

Remark : Only one quarter of the ellipse is computated, the rest
         is set by symmetry.

         a  and  b  are the half-axes (I hope this is the right
         word for it) of the ellipse in  x- and y-direction.
         If you like a circle set  a=b=radius  .

--------------------------------- cut ---------------------------------
procedure symmetry(x, y: Integer);
begin
  PUT_PIXEL( x, y);  // This would obviously be inlined!
  PUT_PIXEL(-x, y);  // and offset by a constant amount
  PUT_PIXEL(-x,-y);
  PUT_PIXEL( x,-y);
end;

procedure bresenham_ellipse(a, b: Integer);
var
  x, y, a2, b2, S, T: Integer;
begin
  a2 := a*a;
  b2 := b*b;
  x  := 0;
  y  := b;
  S  := a2*(1-2*b) + 2*b2;
  T  := b2 - 2*a2*(2*b-1);
  symmetry(x, y);
  repeat
    if S < 0 then
    begin
      S := S + 2*b2*(2*x+3);
      T =  T + 4*b2*(x+1);
      Inc(x);
    end
    else
    if T < 0 then
    begin
      S := S + 2*b2*(2*x+3) - 4*a2*(y-1);
      T := T + 4*b2*(x+1) - 2*a2*(2*y-3);
      Inc(x);
      Dec(y);
    end
    else
    begin
      S := S - 4*a2*(y-1);
      T := T - 2*a2*(2*y-3);
      Dec(y);
    end;
    symmetry(x, y);
  until y <= 0;
end;
0
 
LVL 9

Author Comment

by:ginsonic
Comment Utility
I realise that Cesario solution solve my question , so I will give the points to him.

But I wait anothers working solutions for anothers points . Alike kretzschmar's Q.O.W.

If you have solution or can improve proposed one the put a comment and take new points :)
0
 
LVL 9

Author Comment

by:ginsonic
Comment Utility
I realise that Cesario solution solve my question , so I will give the points to him.

But I wait anothers working solutions for anothers points . Alike kretzschmar's Q.O.W.

If you have solution or can improve proposed one the put a comment and take new points :)
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 9

Author Comment

by:ginsonic
Comment Utility
I realise that Cesario solution solve my question , so I will give the points to him.

But I wait anothers working solutions for anothers points . Alike kretzschmar's Q.O.W.

If you have solution or can improve proposed one the put a comment and take new points :)
0
 
LVL 9

Author Comment

by:ginsonic
Comment Utility
ups
0
 
LVL 7

Expert Comment

by:Cynna
Comment Utility
ginsonic,

This are optimized versions (DrawEllipse() and even faster, DrawEllipse2()):

const RESOLUTION = 100; // larger=better but slower

// Requires global vars (trig. tables)
var
  Form1: TForm1;
  SinTable, CosTable: Array [0..360*RESOLUTION] of Double;

......

procedure BuildTrigTable;
// Precalculation of sin and cos. Resolution is 1/RESOLUTION degree.
var i: Integer;
    radian: Double;
begin
  for i:= 0 to 360*RESOLUTION do begin
      radian:=i*PI/(180*RESOLUTION);
      SinTable[i]:=Sin(radian);
      CosTable[i]:=Cos(radian);
  end;
end;

procedure DrawEllipse(Where: TCanvas; Center, R: TPoint);
// Draws ellipse, centered around Center, with halfaxes: a=R.X , b=R.Y
var i,x,y, xold, yold: Integer;
begin
  for i:= 0 to 360*RESOLUTION do begin
      x:=Center.X+Round(R.X*CosTable[i]);
      y:=Center.Y+Round(R.Y*SinTable[i]);
      if (xold<>x) or (yold<>y) then Where.Pixels[x,y]:=Where.Pen.Color;
      xold:=x; yold:=y;
  end;
end;

procedure DrawEllipse2(Where: TCanvas; Center, R: TPoint);
// Draws ellipse, centered around Center, with halfaxes: a=R.X , b=R.Y
var i,x,y, xold, yold: Integer;
begin
  for i:= 0 to 360*RESOLUTION do begin
      x:=Center.X+Round(R.X*CosTable[i]);
      y:=Center.Y+Round(R.Y*SinTable[i]);
      if i=0 then begin
        Where.Pixels[x,y]:=Where.Pen.Color;
        Where.MoveTo(x,y);
      end
      else if (xold<>x) or (yold<>y) then Where.LineTo(x,y);
      xold:=x; yold:=y;
  end;
end;



COMMENTS
-------------

1. DrawEllipse() uses precalculated trig. table instead of slow trig. functions. On the down-side, you must call BuildTrigTable before using DrawEllipse().

2. BuildTrigTable is called only once. After that, tables are built, and we can use them instead of real sin,cos.
It is usually called at the execution start (for example, initialization section, OnCreate event of the main form etc.)

3. RESOLUTION defines granulation of real functions. This shouldn't be below 10 for DrawEllipse().

4. DrawEllipse2() is good for very low RESOLUTION (even for RESOLUTION=1 !!). But, it uses LineTo to aproximate ellipse segments.
If you want real speed, and are willing to live without Pixels (that is, use LineTo), it's better to use DrawEllipse2() with RESOLUTION of 1..10, which is *very* fast.

EXAMPLE OF USE (place TButton on the form)
----------------------------------------------------

procedure TForm1.Button1Click(Sender: TObject);
var i: Integer;
begin
  BuildTrigTable; // Call it *ONLY* once (OnForm1Create is good place)
  Randomize;
  for i:=1 to 100 do
     DrawEllipse(Form1.Canvas,
                 Point(100+Random(100),100+Random(100)),
                 Point(50+Random(100) , 10+Random(100)));
end;
0
 
LVL 9

Author Comment

by:ginsonic
Comment Utility
Add a sleep(1) and see what slow is it.
0
 
LVL 7

Expert Comment

by:Cynna
Comment Utility
ginsonic,

Why should you put sleep(1) (inside DrawEllipse() loop I assume) ?
0
 
LVL 1

Expert Comment

by:Fraction
Comment Utility
Add a sleep(10) and it's really slow ;-)
0
 
LVL 9

Author Comment

by:ginsonic
Comment Utility
Just to create a nice slide draw ellipse. Try with Cesario sample and see what I wish to say.
0
 
LVL 7

Expert Comment

by:Cynna
Comment Utility
ginsonic,

If you want to create animation effect, you can regulate delay in my code by changing RESOLUTION const. Decrease it and you'll get faster animation if that's what you want. Set it to 1 and see what happens.

But, I don't quite understand what you want:

> If you have solution or can improve proposed one the put a comment and take new points :)

Could you tell us what you mean by improved solution? What should be improved in accepted answer?
0
 
LVL 9

Author Comment

by:ginsonic
Comment Utility
I talk about a slow animation when draw step by step . Draw a point , sleep a while , draw next ....

About improvement ... any proposed solution not just the accepted one . Just to be a better way alike accepted .
0
 
LVL 4

Expert Comment

by:delphi3
Comment Utility
a comment only:

unit EllipseUnit1;
{This is an illustration of an ellipse that starts at
 point (100,100) and fits in a rectangle of 100,75. Continues
 until back again to point (100,100)}

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Math;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}


procedure TForm1.Button1Click(Sender: TObject);
var
  mx, my, x, y, cnt: Integer;
  y1: Real;
begin
  Canvas.Pen.Color := clGreen;
  //first a bit of a container
  //100 Width, 75 Height; 1/2 width = 50; 1/2 height = 38
  Canvas.MoveTo(100, 100); // Start point for request
  Canvas.LineTo(150, 100);
  Canvas.LineTo(150, 175);
  Canvas.LineTo(50, 175);
  Canvas.LineTo(50, 100);
  Canvas.LineTo(100, 100);
  Canvas.Pen.Color := clBlue;
  Canvas.LineTo(100, 175); // Axis line
  Canvas.Pen.Color := clBlack;
  Canvas.MoveTo(50, 138); // Axis line
  //Center is located at (100,138)
  Canvas.LineTo(100, 138);
  Canvas.Pen.Color := clWhite;
  Canvas.LineTo(150, 138);// Axis line

  { A bit of Standard Algebra:

   Draw an Ellipse
   Center of the ellipse is located at h,k and the
   major axis is 'a' the minor axis is 'b'

   the equation is:

  (((x-h)^2)/a^2) + (((y-k)^2)/b^2) = 1

    Eventual substitutions:
   a = 50; b = 38 ; h = 100; k = 100;

    Algebraic equivalents
   (((y-k)^2)/b^2) = 1 - (((x-h)^2)/a^2)

   (y-k)^2)  = (1- (((x-h)^2)/a^2))* b^2

    and solving for y

    y-k = + square root ((1- (((x-h)^2)/a^2))* b^2)
    y-k = - square root ((1- (((x-h)^2)/a^2))* b^2)
    y = k + square root ((1- (((x-h)^2)/a^2))* b^2)
    y = k - square root ((1- (((x-h)^2)/a^2))* b^2)

   substitution of values

   y = 100 + square root ((1- (((x-100)^2)/50^2))* 38^2)
   y = 100 - square root ((1- (((x-100)^2)/50^2))* 38^2)
   square root = power raised to the 0.5
  y = 100 - power(((1- ((power(x-100),2)/(power,50,2))* (power,38,2),0.5)
  }

  Canvas.TextOut(100,80, 'Starts Here at (100,100)');
  Canvas.Pen.Color := clRed;
  Canvas.MoveTo(100, 138);
  for x := 100 to 150 do
  begin
  Sleep(5);
    y := Round(137.5 - (power((1 - (power(x - 100, 2)) / (power(50, 2))) * power(38, 2), 0.5)));
    Canvas.LineTo(X, Y);
  end;
  Canvas.Pen.Color := clYellow;
   for x := 150 downto 50 do
  begin
   Sleep(5);
    y := Round(137.5 + (power((1 - (power(x - 100, 2)) / (power(50, 2))) * power(38, 2), 0.5)));
    Canvas.LineTo(X, Y);
  end;
   Canvas.Pen.Color := clBlack;
   for x := 51 to 100 do
  begin
   Sleep(5);
    y := Round(137.5 - (power((1 - (power(x - 100, 2)) / (power(50, 2))) * power(38, 2), 0.5)));
    Canvas.LineTo(X, Y);
  end;
   Canvas.TextOut(100,80, 'Ends Here at (100,100)    ');
end;


procedure TForm1.Button2Click(Sender: TObject);
begin
  Application.Terminate;
end;

end.
// Form as text
object Form1: TForm1
  Left = 456
  Top = 182
  Width = 258
  Height = 368
  Caption = 'Ellipse'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -13
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 120
  TextHeight = 16
  object Button1: TButton
    Left = 64
    Top = 232
    Width = 115
    Height = 25
    Caption = 'Show Ellipse'
    TabOrder = 0
    OnClick = Button1Click
  end
  object Button2: TButton
    Left = 64
    Top = 272
    Width = 115
    Height = 25
    Caption = 'Close'
    TabOrder = 1
    OnClick = Button2Click
  end
end

Goal :

From: ginsonic
Status: Waiting for Answer Points: 100
  Email A Friend
  I wish to follow an eliptic route.
  for example I wish to go from a point(100, 100) and to draw an ellipse(with next dimensions for example
  : 100 and 75), point by point, to my canvas.

0
 
LVL 9

Author Comment

by:ginsonic
Comment Utility
I will stop the topic now. Don't have enough time , sorry .
But not before accept the delphi3 comments , too.
Take a look for your points in questions list .

Thanks to all for support,
Nick
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Suggested Solutions

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
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…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
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: …

743 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

18 Experts available now in Live!

Get 1:1 Help Now