Jump to content
  • Advertisement
Sign in to follow this  
Weng

OpenGL How to draw an approximate circle?

This topic is 4519 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I am doing an exercise from the book "Beginning OpenGL Game Programming" by Dave Astle and Kevin Hawkins. The question asked to write a function to draw a 2D circle approximation. The origin starts at 0,0,0. The function has to accept the radius and the number of edges. Below is how I wrote the function. But when I ran it, there's only a straight white line appearing across the window, instead of an approximate circle. void DrawCircleApproximation(float radius, int numberOfSides, bool edgeOnly) { int i; double angle; if(edgeOnly) glBegin(GL_LINE_STRIP); else glBegin(GL_POLYGON); for(i = 0;i < numberOfSides;i++) { angle = (i * 2 * 3.142) / numberOfSides; glVertex3f(cosf(angle)*radius,0.0, sinf(angle)*radius); } if(edgeOnly) glVertex3f(radius,0.0,0.0); glEnd(); } What is wrong with the code above? I checked the code with the answer given in the book and they are similar.

Share this post


Link to post
Share on other sites
Advertisement
Your circle is being drawn on the XZ plane. OpenGL looks down the negative Z axis, so you're looking at the side of your circle. Try changing

glVertex3f(cosf(angle)*radius,0.0, sinf(angle)*radius);

to

glVertex3f(cosf(angle)*radius, sinf(angle)*radius, 0.0);

Of course you'll have to glTranslatef with a negative z or do something comparable to move your circle past your near clip plane.

Share this post


Link to post
Share on other sites
I don't really like the looks of this line

angle = (i * 2 * 3.142) / numberOfSides;

too many ints, and angle is a double. I bet if you stepped through that for loop and checked angle you might get some strange values. The book does something more like this.

angle = (float)i * 2.0 * 3.142 / numberOfSides;

I've run into problems myself with creating angles based on for loop ints and have had my angles all being rounded off to the same int for the whole loop.

Share this post


Link to post
Share on other sites
Quote:
Original post by Disgruntled Gamer
I don't really like the looks of this line

angle = (i * 2 * 3.142) / numberOfSides;

too many ints, and angle is a double. I bet if you stepped through that for loop and checked angle you might get some strange values. The book does something more like this.

angle = (float)i * 2.0 * 3.142 / numberOfSides;

I've run into problems myself with creating angles based on for loop ints and have had my angles all being rounded off to the same int for the whole loop.


Mmm. I'm not saying you shouldn't code with precision but this is, in my opinion, too picky. It's basically just a rewrite of something that works perfectly well. Why would you go and do that for? (Besides, I tust that the compiler will clean it up for you..)

Share this post


Link to post
Share on other sites
Quote:
Original post by Disgruntled Gamer
I don't really like the looks of this line

angle = (i * 2 * 3.142) / numberOfSides;

too many ints, and angle is a double. I bet if you stepped through that for loop and checked angle you might get some strange values. The book does something more like this.

angle = (float)i * 2.0 * 3.142 / numberOfSides;

I've run into problems myself with creating angles based on for loop ints and have had my angles all being rounded off to the same int for the whole loop.

Actually, the x86 architecture has a dedicated opcode that performs multiplication of int and double, resulting in a double value (same for division IIRC). This might be even more efficient than a cast. If you really worry about such things, you could use some very basic maths to improve the above calculation a lot by removing redundancy:

int i;
/* glVertex3f uses float arguments! */
float deltaAngle = 2.0f * PI / (numberOfSides + 0.0f); /* added float conversion */
float angle = 0.0f;

/* accumulate angle instead of discarding the previously calculated result on each iteration */
for( i = 0; i < numberOfSides; ++i, angle += deltaAngle )
{
/* essentially the same as using cosf,sinf :) - NB: both sinf and cosf return float as well */
glVertex3f( sinf(angle + PI*0.5f) * radius, 0.0f, sinf(angle) * radius );
}
/* close the line-strip - cos(0) => 1, sin(0) => 0 */
glVertex3f( radius, 0.0f, 0.0f );




Cheers,
Pat.

Share this post


Link to post
Share on other sites
Quote:
Original post by Disgruntled Gamer
I don't really like the looks of this line

angle = (i * 2 * 3.142) / numberOfSides;

too many ints, and angle is a double. I bet if you stepped through that for loop and checked angle you might get some strange values. The book does something more like this.

angle = (float)i * 2.0 * 3.142 / numberOfSides;

I've run into problems myself with creating angles based on for loop ints and have had my angles all being rounded off to the same int for the whole loop.

Actually I think he wants
angle = (i * 2 * 3.142) / (double) numberOfSides;
to prevent integer division.

Share this post


Link to post
Share on other sites
Quote:
Original post by deavik
Quote:
Original post by Disgruntled Gamer
I don't really like the looks of this line

angle = (i * 2 * 3.142) / numberOfSides;

too many ints, and angle is a double. I bet if you stepped through that for loop and checked angle you might get some strange values. The book does something more like this.

angle = (float)i * 2.0 * 3.142 / numberOfSides;

I've run into problems myself with creating angles based on for loop ints and have had my angles all being rounded off to the same int for the whole loop.

Actually I think he wants
angle = (i * 2 * 3.142) / (double) numberOfSides;
to prevent integer division.

As there's no problem with integer division in his original code, the extra cast is, although not wrong, unecessary.

Share this post


Link to post
Share on other sites
Quote:
Original post by Disgruntled Gamer
I don't really like the looks of this line

angle = (i * 2 * 3.142) / numberOfSides;

too many ints, and angle is a double. I bet if you stepped through that for loop and checked angle you might get some strange values. The book does something more like this.

angle = (float)i * 2.0 * 3.142 / numberOfSides;

I've run into problems myself with creating angles based on for loop ints and have had my angles all being rounded off to the same int for the whole loop.


There's nothing wrong with it.

a = i * 2; // int = int * int (fine so long as you don't get overflow)
b = a * 3.142; // double = int * double (fine, compiler promotes int to double for calculation)
c = b / numberOfSides; // double = double / int (again, compiler promotes int to double)

Share this post


Link to post
Share on other sites
Ok ok, I'm sorry, my float cast does nothing. It was done more out of stupidity than pickyness though. Here's a problem I had with ints and floats and why I tend to be a little too specific when I write out equations.


int n_stacks = 30;
float scale_factor;

for (int i=0;i<n_stacks;i++)
{
v = (PI / 2.0) - (PI * (i / n_stacks)); // bugged
// casting either int to a float fixes the problem.
scale_factor = i / (float)n_stacks;
v = (PI / 2.0) - (PI * scale_factor); // works
}


But in Wengs case his order of operations didn't cause the problem. Sorry if I caused any confusion, thanks for the feedback.

Share this post


Link to post
Share on other sites
Thanks guys for the replies, I have tried them out but the problem remains.

I tried using glVertex3f(cosf(angle)*radius,sinf(angle)*radius,0.0); but nothing appears on the openGL window

I also tried casting the integer variables to floats and the same thing happened.

I've also tried using glVertex2f instead of 3f but the problem remained the same.

Below is how I called the DrawCircleApproximationFunction.

int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); DrawCircleApproximation(5,5,false); //calling the function
return TRUE;
}

The first argument of the function is the radius. The second argument is the number of sides while the third argument determines whether to use GL_POLYGONS or GL_LINESTRIPS.

Is there anything wrong with the function calling?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!