byrdJR 127 Report post Posted August 18, 2004 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] 0 Share this post Link to post Share on other sites
Zahlman 1682 Report post Posted August 18, 2004 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.) 0 Share this post Link to post Share on other sites
byrdJR 127 Report post Posted August 18, 2004 Thank you for your help, but I don't exactly understand what you mean by normalized. Could you elaborate please?Thanx again! 0 Share this post Link to post Share on other sites
BiGF00T 435 Report post Posted August 19, 2004 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 0 Share this post Link to post Share on other sites
Chris Hare 462 Report post Posted August 19, 2004 Quote:Original post by BiGF00Ti 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 thisYep, each component is divided by the square root of the squared components summed. The resultant vector has a magnitude of 1. 0 Share this post Link to post Share on other sites
byrdJR 127 Report post Posted August 19, 2004 O.K I think I understand.Thanx! I'm about to see if I can get it to work! 0 Share this post Link to post Share on other sites
Daos 103 Report post Posted August 19, 2004 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! 0 Share this post Link to post Share on other sites
Daos 103 Report post Posted August 19, 2004 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)*ki,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) 0 Share this post Link to post Share on other sites
gohacker82 122 Report post Posted August 19, 2004 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.... 0 Share this post Link to post Share on other sites
BiGF00T 435 Report post Posted August 19, 2004 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 :Pyou 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. 0 Share this post Link to post Share on other sites
Daos 103 Report post Posted August 19, 2004 Made sphere in OpenGL I made the sphere earlier SORRY! I made a little mistakez=radius*cos(beta) is correct.Better explanation for normalizing a vectorVectors 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 numberRemember how easy it is to work with cartezian axesYou 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 0 Share this post Link to post Share on other sites
byrdJR 127 Report post Posted August 21, 2004 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(); 0 Share this post Link to post Share on other sites
Daos 103 Report post Posted August 21, 2004 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));} 0 Share this post Link to post Share on other sites
byrdJR 127 Report post Posted August 24, 2004 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 0 Share this post Link to post Share on other sites