
How to draw a circle
I''m making a little paint program and ... well, the above pretty much spells it out
I already have a few options (like Bresenham''s) but most of these only draw circles with odd widths/heights. Can anyone spell out for the math moron an algorithm for drawing circles/ellipses of any size, ideally an algorithm that needs only the bounding box coordinates??
Chris Barry (crbarry at mts.net)
My Personal Programming Depot

Jesus saves ... the rest of you take 2d4 fire damage.
for (float angle = 0.0; angle<360; angle++)
{
x = x-radius * cos(angle);
y = y-radius * sin(angle);
PlotPixel(x,y);
}
The above code will give you a circle (if x-radius == y-radius), but it's slow, and not a perfect circle (you will get some holes for bigger circles). For a paint program, where you have to draw circles really quick, you may want to use available libraries, if any.
My compiler generates one error message: "does not compile."
[edited by - nicho_tedja on October 12, 2002 5:09:29 PM]
{
x = x-radius * cos(angle);
y = y-radius * sin(angle);
PlotPixel(x,y);
}
The above code will give you a circle (if x-radius == y-radius), but it's slow, and not a perfect circle (you will get some holes for bigger circles). For a paint program, where you have to draw circles really quick, you may want to use available libraries, if any.
My compiler generates one error message: "does not compile."
[edited by - nicho_tedja on October 12, 2002 5:09:29 PM]
My compiler generates one error message: "does not compile."
Sure thing 
cos() and sin() can do the job for you. The idea is that using vectors, you can draw the unit circle. Translate & manipulate it a bit => taadaa
In pseudo code it would be something like

cos() and sin() can do the job for you. The idea is that using vectors, you can draw the unit circle. Translate & manipulate it a bit => taadaa

void pixel( int x, int y );for(int i = 0; i < 360; i++) { pixel( static_cast(widthOfCircle*cos( i*3.14/180)), static_cast(heightOfCircle*sin(i*3.14/180)) );}
long Temp1 = 0.0, Temp2 = 0.0;
for(int Angle)= 0; Angle < 360; Angle++
Temp1 = sin(Angle * 3.14 / 180);
Temp2 = cos(Angle * 3.14 / 180);
for(int Angle)= 0; Angle < 360; Angle++
Temp1 = sin(Angle * 3.14 / 180);
Temp2 = cos(Angle * 3.14 / 180);
Here is some VB code I just knocked up, it doesn't use any trig functions at all, only a single division and some multiplications. Basically, it just simulates a particle in circluar motion, under the effect of a constant centre seeking force. It only draws circles at the origin, but I'm sure you are smart enough to figure out how to add an offset 
I was also thinking of something along the lines of:
But, it is imperfect (has holes at top until I can find a better way of incrementing x) and it would also be slower (has a Square root for every tick).
EDIT: If you have any problem with a particular line of VB code, just give me a bell. Pset is the pixel plotting command in case you couldn't work it out.
[edited by - ragonastick on October 13, 2002 3:37:18 AM]

Const PI As Single = 3.14159265358979Sub DrawCircle(r As Single, PicBox As PictureBox) Dim x As Single, y As Single Dim vx As Single, vy As Single Dim ax As Single, ay As Single Dim i As Single Dim Inc As Single 'Increment - smaller increment takes longer Inc = 1 / r 'Initial position (r, 0) x = r y = 0 'Initial velocity (0, r) vx = 0 vy = r 'Initial acceleration ax = -x * Inc ay = 0 For i = 0 To PI / 2 Step Inc 'Move particle x = x + vx * Inc y = y + vy * Inc 'Adjust velocity vx = vx + ax vy = vy + ay 'Adjust acceleration (accelerate towards centre) ax = -x * Inc ay = -y * Inc 'Draw points in each quadrant PicBox.PSet (x, y) PicBox.PSet (-x, y) PicBox.PSet (x, -y) PicBox.PSet (-x, -y) NextEnd Sub
I was also thinking of something along the lines of:
Sub DrawCircle(r As Single, PicBox As PictureBox) Dim x As Single, y As Single x = -r + 0.01 Do y = Sqr(r * r - x * x) PicBox.PSet (x, y) PicBox.PSet (-x, y) PicBox.PSet (x, -y) PicBox.PSet (-x, -y) x = x + Abs(y / x) Loop Until x >= 0End Sub
But, it is imperfect (has holes at top until I can find a better way of incrementing x) and it would also be slower (has a Square root for every tick).
EDIT: If you have any problem with a particular line of VB code, just give me a bell. Pset is the pixel plotting command in case you couldn't work it out.
[edited by - ragonastick on October 13, 2002 3:37:18 AM]
Trying is the first step towards failure.
Aw, I just reread your question, you want a circle/ellipse which will fit a bounding box. In that case, I would definately stick with the first method I posted, but we need to modify the initial velocity and position.
The new source:
a is the radius of the horizontal axis and b is the radius of the vertical radius.
The method I''m using to calculate the Increment is mainly based on intuition, so it may be incorrect for the ''optimum'' ellipse. It ''feels'' right though
When you go to fit one of these ellipses in a bounding box, first, find the midpoint of the bounding box:
MidX = (X1 + X2) * 0.5
MidY = (Y1 + Y2) * 0.5
Then:
a = Abs(X1 - MidX)
b = Abs(Y1 - MidY)
Use MidX and MidY to offset the ellipse.
Actually, I don''t think you even need the absolute value here unless you are drawing parts of a circle. Oh yeah - in the for loop, it is measuring in radians if you do want to draw arcs and stuff, just get rid of the 4 quadrant optimisation and only draw when i is in the correct range.
The new source:
Sub DrawEllipse(a As Single, b As Single, PicBox As PictureBox) Dim x As Single, y As Single Dim vx As Single, vy As Single Dim ax As Single, ay As Single Dim i As Single Dim Inc As Single ''Increment - smaller increment takes longer Inc = 1 / Sqr(a * a + b * b) ''Initial position (r, 0) x = a y = 0 ''Initial velocity (0, b) vx = 0 vy = b ''Initial acceleration ax = -x * Inc ay = 0 For i = 0 To PI / 2 Step Inc ''Move particle x = x + vx * Inc y = y + vy * Inc ''Adjust velocity vx = vx + ax vy = vy + ay ''Adjust acceleration (accelerate towards centre) ax = -x * Inc ay = -y * Inc ''Draw points in each quadrant PicBox.PSet (x, y) PicBox.PSet (-x, y) PicBox.PSet (x, -y) PicBox.PSet (-x, -y) NextEnd Sub
a is the radius of the horizontal axis and b is the radius of the vertical radius.
The method I''m using to calculate the Increment is mainly based on intuition, so it may be incorrect for the ''optimum'' ellipse. It ''feels'' right though

When you go to fit one of these ellipses in a bounding box, first, find the midpoint of the bounding box:
MidX = (X1 + X2) * 0.5
MidY = (Y1 + Y2) * 0.5
Then:
a = Abs(X1 - MidX)
b = Abs(Y1 - MidY)
Use MidX and MidY to offset the ellipse.
Actually, I don''t think you even need the absolute value here unless you are drawing parts of a circle. Oh yeah - in the for loop, it is measuring in radians if you do want to draw arcs and stuff, just get rid of the 4 quadrant optimisation and only draw when i is in the correct range.
Trying is the first step towards failure.
Whoa, lotsa help ^_^ Much appreciated; I''ll give this stuff a whirl.
Chris Barry (crbarry at mts.net)
My Personal Programming Depot
Chris Barry (crbarry at mts.net)
My Personal Programming Depot
Jesus saves ... the rest of you take 2d4 fire damage.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement