PDA

View Full Version : Whats the best way to draw a shaded circle?



Dozo23
09-27-2014, 08:22 PM
I want to draw a circle that starts out dark at the top and slower gets lighter towards the bottom. I am using gl_lines to draw out the circle and change each lines color.


glBegin(GL_LINES);
glColor3f(0.0,0.0,0.0);
glVertex2f(0.0, 0.0);
glVertex2f(0.05, 0.0);

glColor3f(0.1,0.1,0.1);
glVertex2f(-0.02, -0.01);
glVertex2f(0.07, -0.01);

glColor3f(0.2,0.2,0.2);
glVertex2f(-0.04, -0.02);
glVertex2f(0.09, -0.02);

glColor3f(0.3,0.3,0.3);
glVertex2f(-0.05, -0.03);
glVertex2f(0.1, -0.03);

glColor3f(0.4,0.4,0.4);
glVertex2f(-0.06, -0.04);
glVertex2f(0.11, -0.04);
glVertex2f(-0.06, -0.05);
glVertex2f(0.11, -0.05);

Thats some of what I got. But that's just not practical. Is there a better way to get this done? Should I use a for loop or while loop?

Agent D
09-28-2014, 04:20 AM
Are we discussing a problem with the shading of the circle, or programming language features and coding style?

Assuming it's the later: Both the points on the circle and your shading effect can be calculated. It's definitely better generating the points in a loop.
On the one hand you can controll a lot of parameters (e.g. how many line segments should the circle have, etc...) without code changes and on the
other hand, a loop is definitely going to be smaller than a wall of glVertex* calls.


Should I use a for loop or while loop?
They are equivalent. It doesn't matter.

Dozo23
09-28-2014, 10:05 AM
I am trying to code the circle in a more effective way. i am new to opengl so i dont know if GL_LINES is the best method to get this done.

I also want to try to make the circle as smoothed as possible. Right now i get a circle but the edges are not smooth.

Agent D
09-28-2014, 10:35 PM
Perhaps, GL_LINE_LOOP might be an easier choice for programmatical generation of a circle. When using GL_LINE_LOOP, every point you specify by calling glVertex*
is connected to the last point specified and when you call glEnd( ), the last point is automatically connected to the first point you specified.

You could for instance write a simple for loop that loops over degress from 0 to <360 and compute a position on the circle. Here's some pseudo-C for that simplistic approach:


int i, step=10;

glBegin( GL_LINE_LOOP );
for( i=0; i<360; i+=step )
glVertex2f( cos( ((float)i)*DEGTORAD ), sin( ((float)i)*DEGTORAD ) );
glEnd( );


The smaller "step", the more line segments and thus the smoother the circle.

Dozo23
09-29-2014, 09:38 AM
Thanks a lot.

How do I now make it so that the circle is dark at the top and slower gets lighter downward, eventually becoming white at the bottom?

I was making each line individually and choosing the color for it.

Agent D
09-29-2014, 10:41 AM
If the color is bright at the bottom and dark at the top, it must obviously be a function of y.

Why not try something linear:


int i, step=10;
float x, y, c;

glBegin( GL_LINE_LOOP );
for( i=0; i<360; i+=step )
{
x = cos( ((float)i)*DEGTORAD );
y = sin( ((float)i)*DEGTORAD );
c = y * (-0.5f) + 0.5f;
glColor3f( c, c, c );
glVertex2f( x, y );
}
glEnd( );

Dozo23
09-29-2014, 07:48 PM
I worked on it and this is what i have now.


float x, y, z;
glBegin(GL_POLYGON);
for (float i = 0.0; i < 360; i+=1) {
x = cos(((float) i) * (3.1415/180));
y = sin(((float) i) * (3.1415/180));
z = y * (-0.5f) + (0.5f);
glColor3f(z, z, z);
glVertex2f(x, y);
}

It does exactly what i want it to do but location and size of the circle is not where i want them to be.

My window is currently 500 by 500 and the circle takes up the entire window.

What i want to know is how would i change the radius and how do i change the location of the circle? I would like to place more circles in the same window.

Agent D
09-30-2014, 03:44 AM
How familiar are you with the following things:

OpenGL(R)
The C programming language
Trigonometry
Linear algebra


There are many ways to resize/move the circle in the image. If it fills the entire window, you obviously have your transformation and projection matrices set to identity. You could multiply your x and y values with the desired radius and add an offset, or you could use glTranslatef/glRotatef to do the same thing (basics of legacy OpenGL(R)). When you resize your window to a non rectangular shape, you will probably notice that the circle is no longer a circle, since your projection matrix is identity.

Basic knowledge of linear algebra and the legacy OpenGL(R) API you are using can be very helpfull here. In this case, a little knowledge of trignometry got you the solution of how to programmatically generate circle points.

You initially asked if you should use a for-loop or a while-loop and replaced the loop counter with a float, that you compare against an integer and add an integer to and then cast in to a float. How familiar are you with the C programming language you are using? (Or programming languages in general, since pretty much every imparative programming language has for and while loops). When you want to do OpenGL(R) based 3D graphics, fundamental understanding of the programming language you use is essential.

Dozo23
09-30-2014, 07:23 AM
I am not familiar with OpenGL. I am new to it and I think that is what I was confused with. I have programed in C++ but not in a while. I have a good understanding of for loops and while loops. I just didn't think of using cos and sin to create a circle. That made it much more simple. I was trying to pick coordinates and drawing individual lines, which was making it confusing and more difficult. I was trying to figure out a simpler way and using sin and cos was it.