Teen Programmers Unite  
 

 

Return to forum top

RE: Drawing circle in C++

Posted by Kruptos [send private reply] at February 23, 2003, 07:28:32 PM

Seems I can't reply to that message but off he top of my head here's something (it probably doesn't work):

/////////////////////////////////////////////////
int radius, rSquared;
COORD origin;

float Tx, Ty;
rSquared = radius^2;
for (Tx = (-1 * rSquared); Tx <= rSquared; Tx++) {
Ty = (int)sqrt(rSquared - (Tx^2)) + .5;
Tx += Origin.x;
Ty += Origin.y;
plot(Tx, Ty);
}

Posted by DragonWolf [send private reply] at February 24, 2003, 04:24:04 AM

*makes a cross symbol at the sqrt() and hisses*

That would draw a half circle. (though can easily be made to draw a full one by adding plot(Tx,-Ty) to the end)

Also, you will still get the ellipse effect.

Posted by CViper [send private reply] at February 24, 2003, 07:16:45 AM

you can avoid the ellipse-effect by multiplying the y-coords with the aspect ratio (width/height).

Posted by split [send private reply] at February 25, 2003, 02:05:25 PM

Is origin the center? I can't get this to work.

void circle(int radius1, int cx, int cy)
{

int radius=radius1, rSquared;
COORD Origin;
Origin.X=cx;
Origin.Y=cy;

int Tx, Ty;
rSquared = radius*radius;
for (Tx = (-1 * rSquared); Tx <= rSquared; Tx++) {
Ty = (int)sqrt(rSquared - (Tx*Tx)) + .5;
Tx += Origin.X;
Ty += Origin.Y;
plot(Tx, Ty);
}
}

Posted by CViper [send private reply] at February 25, 2003, 03:15:24 PM

hmm, I think the algorithm is flawed... you're setting Tx to -(radius^2) (squared not xor). In each loop you then increment it by one AND by Origin.X.

And, let's assume radius = 1, and Origin = { 0, 0 }. Then rSquared = 1, and initially Tx = -1. Ty would then be sqrtf( 1 - 1 ) + 0.5 = 0.5. The point { -1, 0.5 } does however not lie on a circle with radius 1.

[EDIT]Bad example, lot's of rounding also going on in there. Still, it shouldn't work[/EDIT]

Posted by split [send private reply] at February 25, 2003, 08:03:20 PM

So you're saying the initial algorithm is flawed and I'm not just having trouble figuring out how to get it working or is what I have done the problem?

Posted by split [send private reply] at February 25, 2003, 09:24:40 PM

Your example wasn't _totally_ clear (to me).

Posted by CViper [send private reply] at February 26, 2003, 03:22:07 AM

Hmm.. I'll try again (was kinda late yesterday, so bear with me :)

let's say you call the function with the parameters
radius = 2, cx = 0, cy = 0; that should draw a circle with radius 2 placed in at 0, 0.

rSquared = 4, (2 * 2).
now when you enter the loop, Tx will get set to -rSquared, thus Tx = -4
now, Ty = (int)sqrt( 4 - (-4 * -4)) + 0.5 = (int)sqrt( 4 - 16 ) + 0.5.

already there you'll run into some trouble, unless your math library supports complex numbers (sqrt( -12 ) = 3.46i)

So, it's the algorithm that is flawed, not your code :)

Posted by Mike_L [send private reply] at February 26, 2003, 09:10:10 PM

What kind of circle do you want? Does it have to be perfectly smooth?

There are several ways to do this. One way is to plot points going around the circle. Here is some pseudocode:

#define PI 3.14
#define INCREMENT (PI / 20)
void DrawCircle( int Cx, int Cy, int r ) {
float angle;
int x, y;
for( angle = 0; angle < PI; angle += INCREMENT ){
x = Cx + (int)(cos( angle ) * r)
y = Cy + (int)(sin( angle ) * r)
PlotPoint( x, y )
}
}

That will draw a dotted outline of a circle. You could use a line drawing function to connect the dots. You could also replace the sin() and cos() calls with table lookups which would be many times faster. Also it is very slow to call a function for each line segment. If possible, your graphics functions should write directly to the frame buffer.

Posted by Mike_L [send private reply] at February 26, 2003, 09:24:23 PM

If you want to draw graphics and don't neccessarily want to learn how graphics are drawn, then you should use a high-level API that uses hardware to draw graphics primitives. Some examples include: Evas, Win32 GDI, Direct3D, OpenGL

With every new PC having a graphics coprocessor, it's silly not to make use of it.

Posted by split [send private reply] at February 27, 2003, 03:17:15 PM

I'm actually more interested in learning how they are drawn than actually drawing them. I don't have enough math yet to figure out all of these things but that will probably change shortly. Thanks for the suggestion though. I have played around with OpenGL a little but that isn't where my interest lies.

Your function worked perfectly for what I was trying to do (except i had to change angle=0 to angle=0-r, but you probably knew that). I also discovered that some interesting things that can happen when you manipulate the value of the increment variable. Thanks a lot. Have a nice Kwanzaa.

Posted by deltacoder [send private reply] at March 01, 2003, 08:24:09 PM

basic math:

consider a circle with radius 1, with the center of the circle at (0,0)...

for any point on the circle (x,y), where the point is P degrees from straight right (1,0):

sin(P) = y
cos(P) = x
tan(P) = y/x

for instance, the point (0,1) is 90 degrees from straight right ( (0,1) is straight up), therefore, sin(90) = 1, cos(90) = 0, and tan(0) is undefined (because you'd be dividing by zero)

You must be logged in to post messages and see which you have already read.

Log on
Username:
Password:
Save for later automatic logon

Register as a new user
 
Copyright TPU 2002. See the Credits and About TPU for more information.