부풍 2009. 9. 18. 20:38

########################################################################################################################################

나사 기둥부분 만들기
- RenderHead() 아래에 추가

// Creates the shaft of the bolt as a cylinder with one end
// closed.
void RenderShaft(void)
 {
 float x,y,angle;   // Used to calculate cylinder wall
 float height = 75.0f;  // Height of the cylinder
 float diameter = 20.0f;  // Diameter of the cylinder
 float normal[3],corners[4][3]; // Storeage for vertices calculations
 float step = (3.1415f/50.0f); // Approximate the cylinder wall with
         // 100 flat segments.

 
 // Set material color for head of screw
 glColor3f(0.0f, 0.0f, 0.7f);

 // counter clock-wise polygons face out (the default for triangles)
 glFrontFace(GL_CCW);  


 // First assemble the wall as 100 quadrilaterals formed by
 // placing adjoining triangles together
 glBegin(GL_TRIANGLES);

 // Go around and draw the sides
 for(angle = 0.0f; angle < (2.0f*3.1415f); angle += step)
  {
  // Calculate x and y position of the next vertex
  x = diameter*(float)sin(angle);
  y = diameter*(float)cos(angle);
 
  // Get the coordinate for this point and extrude the
  // length of the cylinder.
  corners[0][0] = x;
  corners[0][1] = y;
  corners[0][2] = -height;

  corners[1][0] = x;
  corners[1][1] = y;
  corners[1][2] = 0.0f;

  // Get the next point and do the same
  x = diameter*(float)sin(angle+step);
  y = diameter*(float)cos(angle+step);

  // If finished, use know starting point to close the surface
  if(angle+step < 3.1415*2.0) // Not Finished
   {
   corners[2][0] = x;
   corners[2][1] = y;
   corners[2][2] = 0.0f;

   corners[3][0] = x;
   corners[3][1] = y;
   corners[3][2] = -height;
   }
  else
   {
   // Finished, use the staring point
   corners[2][0] = 0.0f;
   corners[2][1] = diameter;
   corners[2][2] = 0.0f;

   corners[3][0] = 0.0f;
   corners[3][1] = diameter;
   corners[3][2] = -height;
   }

  // Instead of using real normal to actual flat section
  // Use what the normal would be if the surface was really
  // curved. Since the cylinder goes up the Z axis, the normal
  // points from the Z axis out directly through each vertex.
  // Therefore we can use the vertex as the normal, as long as
  // we reduce it to unit length first.
 
  // First Triangle ////////////////////////////////////////
  // Fill the normal vector with the coordinate points
  normal[0] = corners[0][0];
  normal[1] = corners[0][1];
  normal[2] = corners[0][2];
 
  // Reduce to length of one and specify for this point
  ReduceToUnit(normal);
  glNormal3fv(normal);
  glVertex3fv(corners[0]);

  // Get vertex, caluclate unit normal and go
  normal[0] = corners[1][0];
  normal[1] = corners[1][1];
  normal[2] = corners[1][2];
  ReduceToUnit(normal);
  glNormal3fv(normal);
  glVertex3fv(corners[1]);

  // Get vertex, caluclate unit normal and go
  normal[0] = corners[2][0];
  normal[1] = corners[2][1];
  normal[2] = corners[2][2];
  ReduceToUnit(normal);
  glNormal3fv(normal);
  glVertex3fv(corners[2]);


  // Second Triangle ////////////////////////////////////////

  // Get vertex, caluclate unit normal and go
  normal[0] = corners[2][0];
  normal[1] = corners[2][1];
  normal[2] = corners[2][2];
  ReduceToUnit(normal);
  glNormal3fv(normal);
  glVertex3fv(corners[2]);

  // Get vertex, caluclate unit normal and go
  normal[0] = corners[3][0];
  normal[1] = corners[3][1];
  normal[2] = corners[3][2];
  ReduceToUnit(normal);
  glNormal3fv(normal);
  glVertex3fv(corners[3]);

  // Get vertex, caluclate unit normal and go
  normal[0] = corners[0][0];
  normal[1] = corners[0][1];
  normal[2] = corners[0][2];
  ReduceToUnit(normal);
  glNormal3fv(normal);
  glVertex3fv(corners[0]);
  }

 glEnd(); // Done with cylinder sides

 // Begin a new triangle fan to cover the bottom
 glBegin(GL_TRIANGLE_FAN);

 // Normal points down the Z axis
 glNormal3f(0.0f, 0.0f, -1.0f);
 
 // Center of fan is at the origin
 glVertex3f(0.0f, 0.0f, -height);
 
 // Spin around matching step size of cylinder wall
 for(angle = 0.0f; angle < (2.0f*3.1415f); angle += step)
  {
  // Calculate x and y position of the next vertex
  x = diameter*(float)sin(angle);
  y = diameter*(float)cos(angle);

  // Specify the next vertex for the triangle fan
  glVertex3f(x, y, -height);
  }

 // Close the fan
 glVertex3f(0.0f, diameter, -height);
 glEnd();
 }


########################################################################################################################################

나사 강선부분 만들기
- RenderShaft() 아래에 추가

// Creates the head of the bolt
void RenderThread(void)
 {
 float x,y,z,angle;    // Calculate coordinates and step angle
 float height = 75.0f;   // Height of the threading
 float diameter = 20.0f;   // Diameter of the threading
 float normal[3],corners[4][3]; // Storeage for calculate normal and corners
 float step = (3.1415f/32.0f); // one revolution
 float revolutions = 7.0f;  // How many time around the shaft
 float threadWidth = 2.0f;  // How wide is the thread
 float threadThick = 3.0f;  // How thick is the thread
 float zstep = .125f;   // How much does the thread move up
         // the Z axis each time a new segment
         // is drawn.

 // 360 degrees in radians
 #define PI2 (2.0f*3.1415f)

 // Set material color for head of screw
 glColor3f(0.0f, 0.0f, 0.4f);
 

 z = -height+2; // Starting spot almost to the end

 // Go around and draw the sides until finished spinning up
 for(angle = 0.0f; angle < PI2*revolutions; angle += step)
  {
  // Calculate x and y position of the next vertex
  x = diameter*(float)sin(angle);
  y = diameter*(float)cos(angle);
 
  // Store the next vertex next to the shaft
  corners[0][0] = x;
  corners[0][1] = y;
  corners[0][2] = z;

  // Calculate the position away from the shaft
  x = (diameter+threadWidth)*(float)sin(angle);
  y = (diameter+threadWidth)*(float)cos(angle);

  corners[1][0] = x;
  corners[1][1] = y;
  corners[1][2] = z;

  // Calculate the next position away from the shaft
  x = (diameter+threadWidth)*(float)sin(angle+step);
  y = (diameter+threadWidth)*(float)cos(angle+step);

  corners[2][0] = x;
  corners[2][1] = y;
  corners[2][2] = z + zstep;

  // Calculate the next position along the shaft
  x = (diameter)*(float)sin(angle+step);
  y = (diameter)*(float)cos(angle+step);

  corners[3][0] = x;
  corners[3][1] = y;
  corners[3][2] = z+ zstep;
 

  // We'll be using triangels, so make
  // counter clock-wise polygons face out
  glFrontFace(GL_CCW); 
  glBegin(GL_TRIANGLES); // Start the top section of thread

   // Calculate the normal for this segment
   calcNormal(corners, normal);
   glNormal3fv(normal);

   // Draw two triangles to cover area
   glVertex3fv(corners[0]);
   glVertex3fv(corners[1]);
   glVertex3fv(corners[2]);

   glVertex3fv(corners[2]);
   glVertex3fv(corners[3]);
   glVertex3fv(corners[0]);

  glEnd();


  // Move the edge along the shaft slightly up the z axis
  // to represent the bottom of the thread
  corners[0][2] += threadThick;
  corners[3][2] += threadThick;

  // Recalculate the normal since points have changed, this
  // time it points in the opposite direction, so reverse it
  calcNormal(corners, normal);
  normal[0] = -normal[0];
  normal[1] = -normal[1];
  normal[2] = -normal[2];
   
  // Switch to clock-wise facing out for underside of the
  // thread.
  glFrontFace(GL_CW);

  // Draw the two triangles
  glBegin(GL_TRIANGLES);
   glNormal3fv(normal);

   glVertex3fv(corners[0]);
   glVertex3fv(corners[1]);
   glVertex3fv(corners[2]);

   glVertex3fv(corners[2]);
   glVertex3fv(corners[3]);
   glVertex3fv(corners[0]);

  glEnd();

  // Creep up the Z axis
  z += zstep;
  }
 }