I am trying to draw a cylinder in specific position, that is:
the center of one end is: x1,y1,z1
the center of the other end is: x2, y2, z2
the radius of one end is: radius1
the redius of the other end is:radius2
the current method I use is:
glTranslate to x1,y1,z1,
glRotate
the glCylinder.
But seem the code works fine in some situation, but not in all situations.
Please let me know if I am correct.
here is my code:
void CMy_gl_func::draw_cylinder(
float center_x1, float center_y1, float center_z1, float radius1,
float center_x2, float center_y2, float center_z2, float radius2,
int use_texture, int texture_index,
int color_r, int color_g, int color_b)
{
float length;
float delta_x, delta_y, delta_z;
GLUquadricObj *pObj = gluNewQuadric(); // Get a new Quadric off the stack
if(use_texture==1)
{
glEnable(GL_TEXTURE_2D);
glColor3d(255,255,255);
glBindTexture(GL_TEXTURE_2D,
g_tex_general[texture_index].ID);
gluQuadricTexture(pObj, true); // This turns on texture coordinates for our Quadric
}
else
glColor3ub(color_r, color_g, color_b);
//glColor3d(color_r, color_g, color_b);
//glColor3ub(255, 0, 0);
glPushMatrix(); // Push on a new matrix scope
glTranslatef(center_x1,
center_y1,
center_z1); // Translate this sphere to the left
delta_x = center_x2 - center_x1;
delta_y = center_y2 - center_y1;
delta_z = center_z2 - center_z1;
float degree_x=0;
float degree_y=0;
float degree_z=0;
float degree=0;
if(delta_x!=0 && delta_y!=0 && delta_z!=0)
{
if(delta_y>0)
{
//begin rotate around y
degree_y = (float)(180*atan(delta_x/delta_z)/PI);
if(delta_z<0)
degree_y += 180;
//end rotate around y
//begin rotate around x
degree_x = (float)(180*atan(delta_y/delta_z)/PI);
if(delta_y<0)
degree_x += 180;
degree_x = -degree_x;
//end rotate around x
//begin rotate around z
degree_z = (float)(180*atan(delta_y/delta_x)/PI);
if(delta_x<0)
degree_z += 180;
//end rotate around z
glRotatef(degree_x,1,0,0);
glRotatef(degree_y,0,1,0);
glRotatef(degree_z,0,0,1);
}
else //delta_y<0
{
//begin rotate around y
degree_y = (float)(180*atan(delta_x/delta_z)/PI);
if(delta_z<0)
degree_y += 180;
//end rotate around y
//begin rotate around x
degree_x = (float)(180*atan(delta_y/delta_z)/PI);
degree_x = -degree_x;
//end rotate around x
//begin rotate around z
degree_z = (float)(180*atan(delta_y/delta_x)/PI);
if(delta_x<0)
degree_z += 180;
//end rotate around z
glRotatef(degree_x,1,0,0);
glRotatef(degree_y,0,1,0);
glRotatef(degree_z,0,0,1);
}
}
else // one of the delta_x, delta_y, delta_z is zero
{
if(delta_x==0 && delta_y==0 && delta_z==0)
{
g_out.Insert("delta_x, y, z are all zero, something goes wrong!
");
}
if(delta_x==0 && delta_y==0)
{
if(delta_z<0)
glRotatef(180,1,0,0);
}
else if(delta_x==0 && delta_z==0)
{
if(delta_y>0)
glRotatef(-90,1,0,0);
else
glRotatef(90,1,0,0);
}
else if(delta_y==0 && delta_z==0)
{
if(delta_x>0)
glRotatef(90,0,1,0);
else
glRotatef(-90,0,1,0);
}
else if(delta_y==0)
{
//just rotate around y
degree = (float)(180*atan(delta_x/delta_z)/PI);
if(delta_z<0)
degree += 180;
glRotatef(degree,0,1,0);
}
else if(delta_z==0)
{
//just rotate around z
degree = (float)(180*atan(delta_y/delta_x)/PI);
if(delta_x<0)
degree += 180;
// it is strange, this line should be putted above the following,
// opengl use stack?
glRotatef(degree,0,0,1);
glRotatef(90,0,1,0);
}
else if(delta_x==0)
{
//just rotate around x
degree = (float)(180*atan(delta_y/delta_z)/PI);
if(delta_z<0)
degree += 180;
degree *= -1; //counter clockwise
glRotatef(degree,1,0,0);
}
}
length = sqrt(delta_x*delta_x+
delta_y*delta_y + delta_z*delta_z);
gluCylinder(pObj, radius1,
radius2,
length, 20, 20); // Draw our cylinder
glPopMatrix(); // End the current scope of this matrix
if(use_texture==1)
glDisable(GL_TEXTURE_2D);
gluDeleteQuadric(pObj); // Free the Quadric
}