PDA

View Full Version : Circles to Cylinders



Jiggered
08-02-2012, 05:37 AM
I'm in the middle of a C++ project where I'm using cylinders to make a clock, I successfully made a circle using gl_line_strip but I need cylinders, I figure I could just add another dimension to add a height to it but I'm now thinking that isn't the way.

Circle:



void drawCircle(float Radius, int numPoints)
{
float PI = 3.14159;

glBegin( GL_LINE_STRIP );

for( int i=0; i<numPoints; i++ )
{
float Angle = i * (2.0*PI/numPoints);
float X = cos( Angle )*Radius;
float Y = sin( Angle )*Radius;
float Z = (0.0f, 0.0f, 30.1f);
glVertex3f( X, Y, Z);
}

glEnd();
}


Is there a way I can modify this to make it a cylinder, or would I need to go in a completely different direction?

Kophay
08-02-2012, 06:49 AM
I 'd be interested to know myself if there is a more efficient way but the least you can do is this:

I assume that x,y,z in your code are homogeneous coords. Then add a 4th one, w, let that be your "extra" one and let z be the 3rd coordinate in space.

then
x = r*cos(angle)
y = r*sin(angle)
z = cylinderheight/2
w=(0.0f,0.0f,0.0f,1.0f)

running a loop similar to what you already have
gives you a circle in 3d space that is situated at z=cylinderheight/2, you can instead use
x = r*cos(angle)
y = cylinderheight/2
z = r*sin(angle)
w=(0.0f,0.0f,0.0f,1.0f)

if you wanted your cylinder to sit "upright" instead.

Then run a similar loop again replacing cylinderheight/2 with -cylinderheight/2. That will give you a second circle, so now you have the "top" and "bottom" of the cylinder. So now you can use a line_strip for each of the circles and then connect corresponding points between the circles with line. That gives a convincing representation of a cylinder, but like I said, I 'm not sure if there's a more efficient way. Intuition dictates that it should be possible to do it with just one loop - the one you currently have - , just by "projecting" the circle, just haven't worked out details yet. And there may yet be some more efficient technique I don't know of.

(and of course that's just an example, you can adjust the coords to have the cylinder top and bottom wherever you wish)

Carmine
08-02-2012, 11:04 AM
.... but I need cylinders ... gluCylinder

Jiggered
08-03-2012, 10:04 AM
I 'd be interested to know myself if there is a more efficient way but the least you can do is this:

I assume that x,y,z in your code are homogeneous coords. Then add a 4th one, w, let that be your "extra" one and let z be the 3rd coordinate in space.

then
x = r*cos(angle)
y = r*sin(angle)
z = cylinderheight/2
w=(0.0f,0.0f,0.0f,1.0f)

running a loop similar to what you already have
gives you a circle in 3d space that is situated at z=cylinderheight/2, you can instead use
x = r*cos(angle)
y = cylinderheight/2
z = r*sin(angle)
w=(0.0f,0.0f,0.0f,1.0f)

if you wanted your cylinder to sit "upright" instead.

Then run a similar loop again replacing cylinderheight/2 with -cylinderheight/2. That will give you a second circle, so now you have the "top" and "bottom" of the cylinder. So now you can use a line_strip for each of the circles and then connect corresponding points between the circles with line. That gives a convincing representation of a cylinder, but like I said, I 'm not sure if there's a more efficient way. Intuition dictates that it should be possible to do it with just one loop - the one you currently have - , just by "projecting" the circle, just haven't worked out details yet. And there may yet be some more efficient technique I don't know of.

(and of course that's just an example, you can adjust the coords to have the cylinder top and bottom wherever you wish)



Works, thank you. But I'm having trouble drawing the second circle. So I edited my for loop to have the first circle in it, but I can't seem to get the second to draw.

Kophay
08-03-2012, 01:04 PM
Ok here's some code I wrote quick to get a cylinder:


GLfloat Vertices[3004];
long cylicount=0;
//top circle
for (float j=0; j<2*M_PI; j+=M_PI/180){
Vertices[cylicount]=cyliradius*cos(j);
Vertices[cylicount+1]=cyliheight;
Vertices[cylicount+2]=cyliradius*sin(j);
Vertices[cylicount+3]=1.0f;
cylicount+=4;
}

//bottom circle

for (float j=0; j<2*M_PI; j+=M_PI/180){
Vertices[cylicount]=cyliradius*cos(j);
Vertices[cylicount+1]=-cyliheight;
Vertices[cylicount+2]=cyliradius*sin(j);
Vertices[cylicount+3]=1.0f;
cylicount+=4;
}

//the points to draw lines between
for (float j=0; j<2*M_PI; j+=M_PI/4){
Vertices[cylicount]=cyliradius*cos(j);
Vertices[cylicount+1]=cyliheight;
Vertices[cylicount+2]=cyliradius*sin(j);
Vertices[cylicount+3]=1.0f;
cylicount+=4;
Vertices[cylicount]=cyliradius*cos(j);
Vertices[cylicount+1]=-cyliheight;
Vertices[cylicount+2]=cyliradius*sin(j);
Vertices[cylicount+3]=1.0f;
cylicount+=4;
}

Then drew them with

glDrawArrays(GL_POINTS, 0, 720);
glDrawArrays(GL_LINES,720,18);

Since the the 3rd loop just recreates points of the circles it should be possible to use the so called indexed drawing to reuse them. Varying the j step you can get as many or as few points on the circles as you like and use other primitive types to draw between them. And use your shaders to prettify them.

Here's a couple of pics of what the above looks like

837
838

Carmine
08-03-2012, 05:22 PM
glucylinder

Jiggered
08-04-2012, 08:17 AM
So using glDrawArrays is the only way to call the shape multiple times?

Kophay
08-04-2012, 09:53 AM
No. There's at least glDrawElements - and these two are what I 've used myself so far trying to steer clear of pre3.3 stuff.

Jiggered
08-09-2012, 02:47 AM
So after some tweaking I managed to draw the cylinder without glDrawElements, still using my for loops. So my for loops are all in a function, then called and I specify the radius, height and number of sides.

Is there a way I can call this function multiple times to draw the cylinder, but multiple places?
I tried a for loop which calls then glTranslates, but it didn't seem to work.

BionicBytes
08-09-2012, 07:06 AM
then post your draw loop and let's see. More than likely you are not preserving the current state of the modelview matrix between draw calls.
When you post, statements like
but it didn't seem to work. are not helpful and won't get you any answers. Please state what did not work and what you observered.