# can anyone explain algorithm behind drawing a cylinder?

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

## Recommended Posts

can anyone explain algorithm behind drawing a cylinder, as used in light tutorial for direct3D. I am relatively new to this gaming world, any help would be highly appreciated. Thanks in advance

##### Share on other sites
Its not that difficult, basically i use two circle and connect them with faces
have a look at my code , sorry for source tags but i don't remeber how to put them

bool CreateCylinder( CMesh *Mesh,
int Size,
int Mode)
{

if ( Size < 0 ) Size = -Size;
if ( Size < 4 || Size==0 )
return false;

float minorStep ;
float a,du;
float px,py,pz;
float nx,ny,nz;
float d;
int i;

////////////////////////////////////////

Mesh->Reset();

Mesh->ReserveFileName("Cylinder.3df");

///////////////////////////////////////
// allocate vertex list

if ( Mesh->ReserveVertexBuffer( Size*Size )==false )
return false;

// allocating proper sized texcoords list
if ( Mesh->ReserveTexCoordBuffer( Size*Size )==false )
return false;

//////////////////////////////////////////
// allocating surfaces

if ( Mesh->ReserveSurfaceBuffer( Size*2 )==false )
return false;

/////////////////////////////////////////

du=(1.0f/(float)Size);

minorStep = 2.0F * __PI *du;

a=0.0f;

for (i=0; i<Size; i++)
{

px = sin(a);
py= -1.0f;
pz = cos(a);

nx= px;
ny= py;
nz= pz;

d=sqrt( nx*nx+ny*ny+nz*nz);

nx/=d;
ny/=d;
nz/=d;

Mesh->AddVertex( px , py , pz ,nx,ny,nz );

/////////////////////////////

px = sin(a);
py= 1.0f;
pz = cos(a);

nx= px;
ny= py;
nz= pz;

d=sqrt( nx*nx+ny*ny+nz*nz);

nx/=d;
ny/=d;
nz/=d;

Mesh->AddVertex( px , py , pz ,nx,ny,nz );

a+=minorStep;
}

///////////////////////////////////
// last 2 triangles closing the mesh

px = sin(a);
py= -1.0f;
pz = cos(a);

nx= px;
ny= py;
nz= pz;

d=sqrt( nx*nx+ny*ny+nz*nz);

nx/=d;
ny/=d;
nz/=d;

Mesh->AddVertex( px , py , pz ,nx,ny,nz );

/////////////////////////////

px = sin(a);
py= 1.0f;
pz = cos(a);

nx= px;
ny= py;
nz= pz;

d=sqrt( nx*nx+ny*ny+nz*nz);

nx/=d;
ny/=d;
nz/=d;

Mesh->AddVertex( px , py , pz ,nx,ny,nz );

for ( i=0; i<2*Size; i+=2 )
{
}

//////////////////////////////////////////////////////////
// capping size*2+2

switch ( Mode )
{

case _VT_CAPBOTH_ :

a=0.0f;

i=0;

for ( i=0; i< Size; i++ )
{
px = sin(a);
py= -1.0f;
pz = cos(a);

Mesh->AddVertex( px , py , pz ,0,-1,0 );

a+=minorStep;
}

px = sin(a);
py= -1.0f;
pz = cos(a);

Mesh->AddVertex( px , py , pz ,0,-1,0 );

for ( i=Size*2+2; i<Size*2+2+Size; i++ )

/////////////////////////////////////////////

a=0.0f;

for ( i=0; i< Size; i++ )
{
px = sin(a);
py= 1.0f;
pz = cos(a);

Mesh->AddVertex( px , py , pz ,0,1,0 );

a+=minorStep;
}

px = sin(a);
py= 1.0f;
pz = cos(a);

Mesh->AddVertex( px , py , pz ,0,1,0 );

for ( i=Size*3+4; i<Size*4+4; i++ )

break;

case _VT_CAPTOP_ :

a=0.0f;

for ( i=0; i< Size; i++ )
{
px = sin(a);
py= 1.0f;
pz = cos(a);

Mesh->AddVertex( px , py , pz ,0,-1,0 );

a+=minorStep;
}

px = sin(a);
py = 1.0f;
pz = cos(a);

Mesh->AddVertex( px , py , pz ,0,-1,0 );

for ( i=Size*2+2; i<Size*2+2+Size; i++ )

break;

case _VT_CAPBOTTOM_ :

a=0.0f;

for ( i=0; i< Size; i++ )
{
px = sin(a);
py= -1.0f;
pz = cos(a);

Mesh->AddVertex( px , py , pz ,0,1,0 );

a+=minorStep;
}

px = sin(a);
py= -1.0f;
pz = cos(a);

Mesh->AddVertex( px , py , pz ,0,1,0 );

for ( i=Size*2+2; i<Size*2+2+Size; i++ )

break;

}

//////////////////////////////////////////////

Mesh->Finalize();

///////////////////////////////////
// sets normal flag as computed

Mesh->SetBitFlag( _VT_NORMALS_COMPUTED_,true );

return true;
}

##### Share on other sites
Thanks, but i was asking for the explanation of this code:

// Fill the vertex buffer. We are algorithmically generating a cylinder
// here, including the normals, which are used for lighting.
CUSTOMVERTEX* pVertices;
if( FAILED( g_pVB->Lock( 0, 0, ( void** )&pVertices, 0 ) ) )
return E_FAIL;
for( DWORD i = 0; i < 50; i++ )
{
FLOAT theta = ( 2 * D3DX_PI * i ) / ( 50 - 1 );
pVertices[2 * i + 0].position = D3DXVECTOR3( sinf( theta ), -1.0f, cosf( theta ) );
pVertices[2 * i + 0].normal = D3DXVECTOR3( sinf( theta ), 0.0f, cosf( theta ) );
pVertices[2 * i + 1].position = D3DXVECTOR3( sinf( theta ), 1.0f, cosf( theta ) );
pVertices[2 * i + 1].normal = D3DXVECTOR3( sinf( theta ), 0.0f, cosf( theta ) );
}
g_pVB->Unlock();

This code is used to generate a cylinder, and is used in the lighting tutorial of the microsoft direct3D samples, i am asking for the logic behind it.

##### Share on other sites
The sin and cos, which are used to generate x and z coordinates of the vertices, will produce the circle given theta which goes from 0 to pi*2 (full circle in radians). For each iteration of i (in this case, 50 iterations), a single edge for a face of the cylinder is created. The edge's y coordinate goes from -1 to +1; this defines the cylinder's length.

Since the normal of a vertex on a cylinder slice is essentially the same as its normalized position, the x and z coordinates of the normal are the same except the y component which is zero - because the normals point directly outward from the cylinder surface.

The code in your last post does not cap the cylinder at either end.

Locking is a way to gain access to the internal data of buffers. You get a pointer to which you copy your stuff; then, you unlock the buffer so as to let the device use the data.

I think that the sample also uses an index buffer that basically tells the device which vertices to use for given triangles. I assume that Mesh::AddSurface mentioned in your first post adds 3 indices to the index buffer in order to specify the triangles.

##### Share on other sites
Thanks a lot for describing it, but still i cannot entirely build the idea in my mind about drawing the cylinder. It would be nice, if you can suggest me any article on the internet, of describing the concept with some visual representations.
I am clear about the locking and releasing of vertex buffers, i am just concerned about the formulas used to build the coordinates of individual vertices.

##### Share on other sites
That code doesn not draw a cylinder, it creates one.

Sine/cosine are commonly used to describe the radius of a circle.

Assume we have our angles in radians (which range from -pi to pi, or sometims 0 to 2pi, but see wikipedia), then with the following you will get a point on the unit circle's radius:
angle = something between -PI and +PIu = cos (angle)v = sin (angle)

You can create more circles by multiplying u and v with a radius:
angle = something between -PI and +PIradius = arbitraryu = radius * cos (angle)v = radius * sin (angle)

Now, you can pack this one into a loop to produce a number of points on a circle's radius:

radius = arbitraryfor (angle=-PI; angle<PI; angle+=(2*PI)/numSegments)    u = radius * cos (angle)    v = radius * sin (angle)

You can use u,v as coordinates to initialise vertices to be passed to some graphics API. Now think about it: How can you define a cylinder with the circe code?

##### Share on other sites
You just need to understand the relation of sine and cosine (sinf and cosf in the code) to the unit circle, and you will "get" the idea :)

##### Share on other sites
Quote:
 Original post by v71_3Its not that difficult, basically i use two circle and connect them with faceshave a look at my code , sorry for source tags but i don't remeber how to put them*süpersnip*

Source-tags. Furthermore: What is all that supposed to do? Looks a bit waste, but maybe the source-tags reveal the secret [oh].