title: OpenGL - Rotate a 'Curve' About the Y-Axis
body: <p><em>As per my <a href="https://math.stackexchange.com/questions/75951/computing-points-in-3d-space">question</a> on Math Stackexchange:</em></p>
  
  <p>I am working on a project for my 3D Graphics class. The project is built with C++ and OpenGL / Glut. Basically, I create a horizontal rectangle window, subdivided into two squares. On the left, I have a two dimensional coordinate plane, which allows the users to point and click and define a profile 'curve'. I then need to wrap this curve around the Y-axis n number of times. </p>
  
  <p>So, would anyone be able to guide me as to how I would use Trigonometry to calculate the X and Z values of the successive points? If for example, a user clicks and creates the point:</p>
  
  <p>(1, 1, 0)</p>
  
  <p>And their sweep resolution (n) is set to, say, 10, then I need to redraw that point every 36 (360/10) degrees around the Y-axis.</p>
  
  <p>Am I correct in assuming that Trigonometry will help me here? If so, can someone please enlighten me a bit as to how to calculate the location of a translated point in 3D space? It's been a while since I took Trig, and I don't believe we ever left 2D space.</p>
  
  <p><strong>EDIT</strong>: I attempted to use:</p>
  
  <pre><code>x'=xcos(theta)-zsin(theta)
  
  y'=y
  
  z'=xsin(theta)+zcos(theta)
  </code></pre>
  
  <p>, as per my understanding of AMPerrine's <a href="https://math.stackexchange.com/questions/75951/computing-points-in-3d-space/75958#75958">answer</a>, and I don't think it worked as I'd hoped:</p>
  
  <pre><code>// this is in a loop
  
  // setup the new angle
  double angle = i&gt;0 ? (360/sweepResolutionMod)*i : 0;
  
  angle = angle * (M_PI/180);
  
  // for each point...
  for( int i=0; i&lt;clickedPoints.size(); i++ )
  {
      // initial point, normalized
      GLfloat tempX = (clickedPoints[i].x-250)/250;
      GLfloat tempY = (clickedPoints[i].y-250)/250;
      GLfloat tempZ = 0.0;
  
      // log the initial point
      cout &lt;&lt; "(" &lt;&lt; tempX &lt;&lt; ", " &lt;&lt; tempY &lt;&lt; ", 0.0) by " &lt;&lt; angle &lt;&lt; " radians = ";
  
      // generate the new point
      GLfloat newX = (tempX * cos(angle)) - (tempZ * sin(angle));
      GLfloat newY = tempY;
      GLfloat newZ = (tempX * sin(angle)) - (tempZ * cos(angle));
  
      // log the new point
      cout &lt;&lt; "(" &lt;&lt; newX &lt;&lt; ", " &lt;&lt; newY &lt;&lt; ", " &lt;&lt; newZ &lt;&lt; ")\n";
  
      // render the new point
      glVertex3d(newX, newY, newZ);
  }
  </code></pre>
  
  <p>This produces no screen output, but console output of:</p>
  
  <pre><code>(0.048, -0.296, 0.0) by 0 radians = (0.048, -0.296, 0)
  (0.376, -0.508, 0.0) by 0 radians = (0.376, -0.508, 0)
  (0.72, -0.204, 0.0) by 0 radians = (0.72, -0.204, 0)
  (0.652, 0.176, 0.0) by 0 radians = (0.652, 0.176, 0)
  (0.368, 0.504, 0.0) by 0 radians = (0.368, 0.504, 0)
  
  (0.048, -0.296, 0.0) by 0.628319 radians = (0.0388328, -0.296, 0.0282137)
  (0.376, -0.508, 0.0) by 0.628319 radians = (0.30419, -0.508, 0.221007)
  (0.72, -0.204, 0.0) by 0.628319 radians = (0.582492, -0.204, 0.423205)
  (0.652, 0.176, 0.0) by 0.628319 radians = (0.527479, 0.176, 0.383236)
  (0.368, 0.504, 0.0) by 0.628319 radians = (0.297718, 0.504, 0.216305)
  
  (0.048, -0.296, 0.0) by 1.25664 radians = (0.0148328, -0.296, 0.0456507)
  (0.376, -0.508, 0.0) by 1.25664 radians = (0.11619, -0.508, 0.357597)
  (0.72, -0.204, 0.0) by 1.25664 radians = (0.222492, -0.204, 0.684761)
  (0.652, 0.176, 0.0) by 1.25664 radians = (0.201479, 0.176, 0.620089)
  (0.368, 0.504, 0.0) by 1.25664 radians = (0.113718, 0.504, 0.349989)
  
  ...
  
  (0.048, -0.296, 0.0) by 6.28319 radians = (0.048, -0.296, -1.17566e-17)
  (0.376, -0.508, 0.0) by 6.28319 radians = (0.376, -0.508, -9.20934e-17)
  (0.72, -0.204, 0.0) by 6.28319 radians = (0.72, -0.204, -1.76349e-16)
  (0.652, 0.176, 0.0) by 6.28319 radians = (0.652, 0.176, -1.59694e-16)
  (0.368, 0.504, 0.0) by 6.28319 radians = (0.368, 0.504, -9.0134e-17)
  </code></pre>
  
  <p>I'm not sure what exactly is going on here, but I'm having a terrible time trying to figure it out, so please don't think I'm trying to get double reputation or anything, I'm just really stuck.</p>
  
  <p><strong>EDIT</strong> 2: Here is my whole display routine for my perspective subview:</p>
  
  <pre><code>void displayPersp(void)
  {
      glClear(GL_COLOR_BUFFER_BIT);
  
      glMatrixMode (GL_MODELVIEW);
      glLoadIdentity ();  
  
      gluLookAt (-2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0);
  
      // draw the axis
      glBegin(GL_LINES);
      // x
      glVertex3f(500.0, 0.0, 0.0);
      glVertex3f(-500.0, 0.0, 0.0);
      // y
      glVertex3f(0.0, -500.0, 0.0);
      glVertex3f(0.0, 500.0, 0.0);
      // z
      glVertex3f(0.0, 0.0, -500.0);
      glVertex3f(0.0, 0.0, 500.0);
  
      glEnd(); 
  
      cout &lt;&lt; endl;
  
      // loop as many number of times as we are going to draw the points around the Y-Axis
      for( int i=0; i&lt;=sweepResolutionMod; i++ )
      {
          cout &lt;&lt; endl;
  
          // setup the new angle
          double angle = i&gt;0 ? (360/sweepResolutionMod)*i : 0;
  
          angle = angle * (M_PI/180);
  
          // for each point...
          for( int i=0; i&lt;clickedPoints.size(); i++ )
          {
              GLfloat tempX = (clickedPoints[i].x-250)/250;
              GLfloat tempY = (clickedPoints[i].y-250)/250;
              GLfloat tempZ = 0.0;
  
              cout &lt;&lt; "(" &lt;&lt; tempX &lt;&lt; ", " &lt;&lt; tempY &lt;&lt; ", 0.0) by " &lt;&lt; angle &lt;&lt; " degrees = ";
  
              GLfloat newX = (tempX * cos(angle)) - (tempZ * sin(angle));
              GLfloat newY = tempY;
              GLfloat newZ = (tempX * sin(angle)) - (tempZ * cos(angle));
  
              cout &lt;&lt; "(" &lt;&lt; newX &lt;&lt; ", " &lt;&lt; newY &lt;&lt; ", " &lt;&lt; newZ &lt;&lt; ")\n";
  
              glVertex3d(newX, newY, newZ);
          }
  
          // the following was my old solution, using OpenGL's rotate(), but that
          // didn't allow me to get back the new point's coordinates.
  
          /*
          glRotatef(angle, 0.0, 1.0, 0.0);
  
          // draw a line?
          if( clickedPoints.size() &gt; 1 )
          {
              glBegin(GL_LINE_STRIP);
  
              for(int i=0; i&lt;clickedPoints.size(); i++ )
              {     
                  glVertex3f((clickedPoints[i].x-250)/250, (clickedPoints[i].y-250)/250, 0.0);     
              }
  
              glEnd();
          }
  
          // everyone gets points
          glBegin(GL_POINTS);
  
          for(int i=0; i&lt;clickedPoints.size(); i++ )
          { 
              glVertex3f((clickedPoints[i].x-250)/250, (clickedPoints[i].y-250)/250, 0.0);     
          }
  
          glEnd();
          */
      }
  
  
      glutSwapBuffers();
  }
  </code></pre>
  
  <p>EDIT 3: Here is a terrible illustration that illustrates what I need to do. I know the perspective seems off, but what I'm attempting to acquire is the green 'horizontals' in the right subview (this is using the commented out glRotatef() code above):</p>
  
  <p><img src="https://i.stack.imgur.com/Qcpno.jpg" alt="Pic"></p>
  
  <p><strong>FINAL EDIT</strong> (for future generations!):</p>
  
  <p>Here is what I finally got working, after discussing some linear algebra with a teacher at college:</p>
  
  <pre><code>void displayPersp(void)
  {
     glClear(GL_COLOR_BUFFER_BIT);
  
     gluLookAt (-2.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0);
  
     glMatrixMode (GL_MODELVIEW);
     glLoadIdentity ();  
  
     // draw the axis
     glBegin(GL_LINES);
       // x
       glVertex3f(500.0, 0.0, 0.0);
       glVertex3f(-500.0, 0.0, 0.0);
       // y
       glVertex3f(0.0, -500.0, 0.0);
       glVertex3f(0.0, 500.0, 0.0);
       // z
       glVertex3f(0.0, 0.0, -500.0);
       glVertex3f(0.0, 0.0, 500.0);
  
     glEnd(); 
  
     cout &lt;&lt; endl;
  
     double previousTheta = 0.0;
  
     for( int i=0; i&lt;=sweepResolutionMod; i++ )
     {
       double theta = i&gt;0 ? (360/sweepResolutionMod)*i : 0;
  
       theta = theta * (M_PI/180);
  
       if( clickedPoints.size() &gt; 1 )
       {
         // the 'vertical' piece
         glBegin(GL_LINE_STRIP);
  
         for(int i=0; i&lt;clickedPoints.size(); i++ )
         {     
           // normalize
           GLfloat tempX = (clickedPoints[i].x-250)/250;
           GLfloat tempY = (clickedPoints[i].y-250)/250;
           GLfloat tempZ = 0.0;
  
           // new points
           GLfloat newX = ( tempX * cos(theta) ) + ( tempZ * sin(theta) );
           GLfloat newY = tempY;
           GLfloat newZ = ( tempZ * cos(theta) ) - ( tempX * sin(theta) );
  
           glVertex3f(newX, newY, newZ);     
         }
  
         glEnd();
  
         // the 'horizontal' piece
         if( previousTheta != theta )
         {
           glBegin(GL_LINES);
  
           for(int i=0; i&lt;clickedPoints.size(); i++ )
           {     
             // normalize
             GLfloat tempX = (clickedPoints[i].x-250)/250;
             GLfloat tempY = (clickedPoints[i].y-250)/250;
             GLfloat tempZ = 0.0;
  
             // new points
             GLfloat newX = ( tempX * cos(theta) ) + ( tempZ * sin(theta) );
             GLfloat newY = tempY;
             GLfloat newZ = ( tempZ * cos(theta) ) - ( tempX * sin(theta) );
  
             // previous points
             GLfloat previousX = ( tempX * cos(previousTheta) ) + ( tempZ * sin(previousTheta) );
             GLfloat previousY = tempY;
             GLfloat previousZ = ( tempZ * cos(previousTheta) ) - ( tempX * sin(previousTheta) );
  
             // horizontal component           
             glVertex3f(newX, newY, newZ);     
             glVertex3f(previousX, previousY, previousZ);     
           }
  
           glEnd();
         }
       }
  
       previousTheta = theta;
     }
  
     glutSwapBuffers();
  }
  </code></pre>