Sign in to follow this  
byrdJR

I need help!

Recommended Posts

I'm trying to build a sphere using the cylinder approximation algorithm that is in the lighting tutorial of the DX SDK. here's my code:
	FLOAT Y = 1.0f;
	FLOAT Y2 = 0.0f;
	Y2 = (FLOAT)(Y - 0.04);
	DWORD n = 0;
    for( DWORD i=1; i<26; i++ )
    {
		if( i>=13 )
		{ 
			cylinderSize = i - n;
			n = n + 2;
		}
		else 
		{
			
			cylinderSize = i;
			
		}

		if(i>=2)
		{
			Y = Y2;
			Y2 = (FLOAT)(Y - 0.04);
		}

		for( DWORD  j=0; j<50; j++)
		{
			FLOAT theta = (2*D3DX_PI*j)/(50-1);
			
				pVertices[2*j+((i-1)*48)].position = D3DXVECTOR3( cylinderSize*(sinf(theta)/13), Y, cylinderSize*(cosf(theta)/13) );
				
				pVertices[2*j+((i-1)*49)].position = D3DXVECTOR3( cylinderSize*(sinf(theta)/13), Y2, cylinderSize*(cosf(theta)/13) );
				
			
		}
This algorithm is basically trying to draw 25 cylinders stacked on top of each other. The variable cylinderSize is used to determine the size of the cylinder based on which cylinder is currently being drawn. The variable Y is used to determine the height of each cylinder, which I set to 0.04 for each cylinder. Also there are 50 even and 50 odd vertices being drawn for each cylinder. My problem is that i'm not getting a sphere. It is more like the shape of a Hershey's kiss. So I'm not exactly sure what the problem is but I think it could be how the triangles are being drawn between each vertice. I dunno. All I know is that I need someone to point me in the right direction. Thanx! [Edited by - byrdJR on August 18, 2004 11:44:23 PM]

Share this post


Link to post
Share on other sites
Your "cylinder size" is the radius of each cylinder at each step, and you're having it increase and then decrease linearly. That's not the shape a sphere has. You'll need to take the square root of the *normalized* cylinder radius, and rescale. (divide by max so you have something in the range 0..1; take square root; multiply again by the max so it's big enough.)

Share this post


Link to post
Share on other sites
Thank you for your help, but I don't exactly understand what you mean by normalized. Could you elaborate please?

Thanx again!

Share this post


Link to post
Share on other sites
i think normalize means that it has the length 1 after normalization... if i remember correctly then you have to divide the vector by the magnitude.
read this

Share this post


Link to post
Share on other sites
Quote:
Original post by BiGF00T
i think normalize means that it has the length 1 after normalization... if i remember correctly then you have to divide the vector by the magnitude.
read this


Yep, each component is divided by the square root of the squared components summed. The resultant vector has a magnitude of 1.

Share this post


Link to post
Share on other sites
I know nobody likes math but i'll try a better explanation for building a sphere.
The parametric equation of a sphere is:
x=R*cos(alpha)*sin(beta)
y=R*sin(alpha)*sin(beta)
z=R*sin(beta), where R is the radius and alpha and beta are angles in radians.
-alpha is from 0 to 2*PI (PI=3.1415f)
-beta is from 0 to PI

***at first you must choose a resolution(the number of steps needed to complete a meridian and a latitude orbit)--this is called biliniar interpolation*****

eg. resoulution=64--at each and every step you add PI/64 to beta and 2*PI/64 to alpha
----------------OpenGL code---------------------------------

du=2*PI/(double)resolution;
dv=PI/(double)resolution;
glBegin(GL_QUADS);
for(i=0;i<resolution;i++)
{
u=i*du;
for(j=0;j<resolution;j++)
v=j*dv;
p1=Get3DPoint(u,v);
p2=Get3DPoint(u+du,v);
p3=Get3DPoint(u+du,v+dv);
p4=Get3DPoint(u,v+dv);


glVertex3f(p1.x,p1.y,p1.z);
glVertex3f(p2.x,p2.y,p2.z);
glVertex3f(p3.x,p3.y,p3.z);
glVertex3f(p4.x,p4.y,p4.z)
/*Get3DPoint-computes the coordinates by substitution in the parametric equation*/


}


glEnd();


Happy coding!












Share this post


Link to post
Share on other sites

To normalize a vector...


v=a.x*i+a.y*j+a.z*k;(our vector)
vlength=sqrt(a.x*a.x+a.y*a.y+a.z*a.z);

vnormalized=(a.x/vlength)*i+(a.y/vlength)*j+(a.z/vlength)*k



i,j,k are unity vectors (length=1) i=(1,0,0)(on x axis),j=(0,1,0)(on y axis),k=(0,0,1)(on z axis)

Share this post


Link to post
Share on other sites
the normal vector shows the direction of your plane facing.

why the normal should be devide with magnitude ?

coz we just want to have the derection of the plane facing.

no needs big number in normal vector..

if the normal vector normalized,and then we look for the vextor length. i,m sure the length number will be 1.

...
sorry for my bad english
....

Share this post


Link to post
Share on other sites
you mean the normal vector... that is the upright vector on something. but we were talking about the normalized vector. they are different. good that we had vector math last semester :P
you take every element of your vector and devide it by the magnitude (length of the vector). then you get a vector to the same direction but with the length 1. very useful.

Share this post


Link to post
Share on other sites

Made sphere in OpenGL



I made the sphere earlier

SORRY!

I made a little mistake
z=radius*cos(beta) is correct.

Better explanation for normalizing a vector


Vectors give direction ,this means that v1(1,2,3) is the same thing as v2(k*1,k*2,k*3) where k is any real number

Remember how easy it is to work with cartezian axes
You would probably choose v1(1,0,0)than v2(1.45f,0,0);
In this case it doesn't metter how much you "stretch" a point

Share this post


Link to post
Share on other sites
ok I used the parametric equations for a sphere, but nothing is being drawn. Only the back buffer is being shown. here's my code:
// Fill the vertex buffer. We are algorithmically generating a shpere
// 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 j=0; j<100; j++)
{
FLOAT theta = (2*D3DX_PI*j)/(100-1);
FLOAT phi = (D3DX_PI*j)/(100-1);

pVertices[2*j+0].position = D3DXVECTOR3( 2*(FLOAT(sinf(phi)*cos(theta))), 2*(FLOAT(sin(phi)*sin(theta))), 2*(FLOAT(cosf(phi))) );

pVertices[2*j+1].position = D3DXVECTOR3( 2*(FLOAT(sinf(phi)*cos(theta))), 2*(FLOAT(sin(phi)*sin(theta))), 2*(FLOAT(cosf(phi))) );




}



g_pVB->Unlock();

Share this post


Link to post
Share on other sites


void CSphere::Draw()
{


glPushMatrix();

double du=2*PI/(double)resolution;
double dv=PI/(double)resolution;

double u=0.0f,v=0.0f;
CPoint3D p1,p2,p3,p4;


glColor3f(1.0f,1.0f,1.0f);

glBindTexture(GL_TEXTURE_2D,texture.texture[1]);





glBegin(GL_QUADS);

for(int i=0;i<resolution;i++)
{
u=i*du;

for(int j=0;j<resolution;j++)
{
v=j*dv;
p1=GetPoint3D(u,v);
p2=GetPoint3D(u,v+dv);
p3=GetPoint3D(u+du,v+dv);
p4=GetPoint3D(u+du,v);

glTexCoord2d(u/10*PI,v/PI);
glVertex3d(p1.x,p1.y,p1.z);
glTexCoord2d(u/10*PI,(v+dv)/PI);
glVertex3d(p2.x,p2.y,p2.z);
glTexCoord2d((u+du)/10*PI,(v+dv)/PI);
glVertex3d(p3.x,p3.y,p3.z);
glTexCoord2d((u+du)/10*PI, v/PI);
glVertex3d(p4.x,p4.y,p4.z);
}

}

glEnd();


glPopMatrix();


}
//**********************************************
CPoint3D CSphere::GetPoint3D(double u, double v)
{


return CPoint3D(r*cos(u)*sin(v), r*sin(u)*sin(v), r*cos(v));

}



Share this post


Link to post
Share on other sites
Daos can you please explain why you increment v by dv for P2 and P3 and also increment u by du for P3 and P4?

thanx

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this