Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 10 of 10

Thread: Circles to Cylinders

  1. #1
    Junior Member Newbie
    Join Date
    Aug 2012
    Posts
    6

    Circles to Cylinders

    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:

    Code :
    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?

  2. #2
    Junior Member Newbie
    Join Date
    Jul 2012
    Posts
    6
    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)
    Last edited by Kophay; 08-02-2012 at 07:01 AM.

  3. #3
    Intern Contributor
    Join Date
    Apr 2012
    Posts
    98
    Quote Originally Posted by Jiggered View Post
    .... but I need cylinders ...
    gluCylinder

  4. #4
    Junior Member Newbie
    Join Date
    Aug 2012
    Posts
    6
    Quote Originally Posted by Kophay View Post
    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.

  5. #5
    Junior Member Newbie
    Join Date
    Jul 2012
    Posts
    6
    Ok here's some code I wrote quick to get a cylinder:

    Code :
    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

    Click image for larger version. 

Name:	cyli1.jpg 
Views:	41 
Size:	32.5 KB 
ID:	837
    Click image for larger version. 

Name:	cyli2.jpg 
Views:	33 
Size:	36.5 KB 
ID:	838
    Last edited by Kophay; 08-03-2012 at 01:54 PM.

  6. #6
    Intern Contributor
    Join Date
    Apr 2012
    Posts
    98
    glucylinder

  7. #7
    Junior Member Newbie
    Join Date
    Aug 2012
    Posts
    6
    So using glDrawArrays is the only way to call the shape multiple times?

  8. #8
    Junior Member Newbie
    Join Date
    Jul 2012
    Posts
    6
    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.

  9. #9
    Junior Member Newbie
    Join Date
    Aug 2012
    Posts
    6
    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.

  10. #10
    Senior Member OpenGL Pro BionicBytes's Avatar
    Join Date
    Mar 2009
    Location
    UK, London
    Posts
    1,171
    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.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •