drawing cones

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

Recommended Posts

I want to write a class for drawing cones based on the parametric equations: x=(r0-v*r0/h0)*cos(v); y=(r0-v*r0/h0)*sin(v); z=u; h is height, r radius, and u ,v are the parameters. But my code totally doesn't work. Can you correct it, or tell me what i'm doing wrong? Or if you have similar code for a cone or even for a cylinder, i would appriciate it . Thanks, Peter: class Cone{ public: float r0; float h0; Cone(){} Cone(float r, float h){ r0=r; h0=h; float xx[100][100],yy[100][100],zz[100][100]; for (int i=0;i<21;i++) for (int j=0;j<2*PI*10+2;j++){ float u=(float)i/10;float v= (float)j/10; xx[j]=(r0-v*r0/h0)*cos(v); yy[j]=(r0-v*r0/h0)*sin(v); zz[j]=u;// } for (int i=0;i<21;i++) for (int j=0;j<2*PI*10+2;j++){ glBegin (GL_TRIANGLE_STRIP); Vector s1,s2,s3,nn,s4;s1= Vector(xx[j],yy[j],zz[j]); s2=Vector(xx[j+1],yy[j+1],zz[j+1]); s3=Vector(xx[i+1][j+1],yy[i+1][j+1],zz[i+1][j+1]); nn=(s1-s2)%(s1-s3)*-1; //glNormal3f(xx[j],yy[j],zz[j]); glNormal3f(nn.vx,nn.vy,nn.vz); //glNormal3f(xx[j],yy[j],zz[j]); glVertex3f(xx[j],yy[j],zz[j]); //glNormal3f(xx[j+1],yy[j+1],zz[j+1]); glVertex3f(xx[j+1],yy[j+1],zz[j+1]); //glNormal3f(xx[i+1][j+1],yy[i+1][j+1],zz[i+1][j+1]); glVertex3f(xx[i+1][j+1],yy[i+1][j+1],zz[i+1][j+1]); //glNormal3f(xx[i+1][j],yy[i+1][j],zz[i+1][j]); //glVertex3f(xx[i+1][j],yy[i+1][j],zz[i+1][j]); glEnd();glFlush(); } } };

Share on other sites
look around for teh old andy pike tutorials, he covers how to do this, i found a zip file containing his tutorials a couple weeks ago, although i forget where.

something a little unrelated, you should really name your variables radius and height rather than r and h, liek what do u and v stand for? usually they'd be texture coords

here is an excerpt from the andy pike article, see if this explains what you need (hopefully this isn't against gamedev policy, i'd just give you a link, but the tutorials aren't hosted directly anymore)

How to make a cone
Our cone will be made up from one triangle fan for the bottom and a triangle list for the sides. As for the cylinder above, we need to specify the number of segments, the height and the radius for our cone. Fig 9.2 below shows how the cone will be made up; there are 8 segments in this cone. The red arrows show the normals for one segment of this cone. To create the cone, we will use an index buffer and a vertex buffer. We will store the triangles for the sides in the index buffer and use the vertex buffer to store the vertices for the side triangles and the base triangle fan. This is so that we get the correct shading around the cone and a sharp edge between the sides and base.

Fig 9.2

To create the cone we need to specify the number of segments. There are 8 segments in the diagram above. The more segments there are, the smoother and rounder the cone will appear. We also need to know the height and radius of the cone. Once we know the height, radius and number of segments, we can defined the position of our vertices together with their Normal value and texture coordinates. The following code snippet shows how this is done.

bool CCone::UpdateVertices(){    CONE_CUSTOMVERTEX* pVertex;    WORD* pIndices;    WORD wVertexIndex = 0;    int nCurrentSegment;    //Lock the vertex buffer    if(FAILED(m_pVertexBuffer->Lock(0, 0, (BYTE**)&pVertex, 0)))    {        LogError("<li>CCone: Unable to lock vertex buffer.");        return false;    }    //Lock the index buffer     if(FAILED(m_pIndexBuffer->Lock(0, m_dwNumOfIndices, (BYTE**)&pIndices, 0)))    {        LogError("<li>CCone: Unable to lock index buffer.");        return false;    }    float rDeltaSegAngle = (2.0f * D3DX_PI / m_nSegments);    float rSegmentLength = 1.0f / (float)m_nSegments;    float ny0 = (90.0f - (float)D3DXToDegree(atan(m_rHeight / m_rRadius))) / 90.0f;    //For each segment, add a triangle to the sides triangle list    for(nCurrentSegment = 0; nCurrentSegment < m_nSegments; nCurrentSegment++)    {        float x0 = m_rRadius * sinf(nCurrentSegment * rDeltaSegAngle);        float z0 = m_rRadius * cosf(nCurrentSegment * rDeltaSegAngle);        pVertex->x = 0.0f;        pVertex->y = 0.0f + (m_rHeight / 2.0f);        pVertex->z = 0.0f;        pVertex->nx = x0;        pVertex->ny = ny0;        pVertex->nz = z0;        pVertex->tu = 1.0f - (rSegmentLength * (float)nCurrentSegment);        pVertex->tv = 0.0f;        pVertex++;        pVertex->x = x0;        pVertex->y = 0.0f - (m_rHeight / 2.0f);        pVertex->z = z0;        pVertex->nx = x0;        pVertex->ny = ny0;        pVertex->nz = z0;        pVertex->tu = 1.0f - (rSegmentLength * (float)nCurrentSegment);        pVertex->tv = 1.0f;        pVertex++;        //Set three indices (1 triangle) per segment        *pIndices = wVertexIndex;         pIndices++;        wVertexIndex++;                *pIndices = wVertexIndex;         pIndices++;        wVertexIndex += 2;        if(nCurrentSegment == m_nSegments - 1)        {            *pIndices = 1;             pIndices++;            wVertexIndex--;        }        else        {            *pIndices = wVertexIndex;             pIndices++;            wVertexIndex--;         }    }    //Create the bottom triangle fan: Center vertex    pVertex->x = 0.0f;    pVertex->y = 0.0f - (m_rHeight / 2.0f);    pVertex->z = 0.0f;    pVertex->nx = 0.0f;    pVertex->ny = -1.0f;    pVertex->nz = 0.0f;    pVertex->tu = 0.5f;    pVertex->tv = 0.5f;    pVertex++;    //Create the bottom triangle fan: Edge vertices    for(nCurrentSegment = m_nSegments; nCurrentSegment >= 0; nCurrentSegment--)    {        float x0 = m_rRadius * sinf(nCurrentSegment * rDeltaSegAngle);        float z0 = m_rRadius * cosf(nCurrentSegment * rDeltaSegAngle);            pVertex->x = x0;        pVertex->y = 0.0f - (m_rHeight / 2.0f);        pVertex->z = z0;        pVertex->nx = 0.0f;        pVertex->ny = -1.0f;        pVertex->nz = 0.0f;        float tu0 = (0.5f * sinf(nCurrentSegment * rDeltaSegAngle)) + 0.5f;        float tv0 = (0.5f * cosf(nCurrentSegment * rDeltaSegAngle)) + 0.5f;        pVertex->tu = tu0;        pVertex->tv = tv0;        pVertex++;    }    if(FAILED(m_pVertexBuffer->Unlock()))    {        LogError("<li>CCone: Unable to unlock vertex buffer.");        return false;    }    if(FAILED(m_pIndexBuffer->Unlock()))    {        LogError("<li>CCone: Unable to unlock index buffer.");        return false;    }    return true; }

So what is going on here? Well, as with the cylinder, we lock the vertex and index buffers ready for writing. Then we use the same calculations as before to calculate the segment angle and segment length. We also calculate the y part of the normals for the side's vertices. This is done by using simple trigonometry with the height and radius to form a right-angled triangle, so that we can find the correct Normal angle. Then, as with the cylinder, we loop around once for each segment adding a new triangle to the index buffer and vertices to the vertex buffer as required.

Once we've done that, we use the same method as the cylinder to define the triangle fan for the base of the cone. We then unlock the index and vertex buffers, and are ready for rendering.

Share on other sites
Quote:
 Original post by godsenddeathlook around for teh old andy pike tutorials, he covers how to do this, i found a zip file containing his tutorials a couple weeks ago, although i forget where.

Here perhaps?

Share on other sites
yes, smart ass, that appears to be where i got it :) thanks i'm gonna book mark it

Share on other sites
Thanks guys, problem solved!