<bdo id='4RvS7'></bdo><ul id='4RvS7'></ul>

<tfoot id='4RvS7'></tfoot>
    1. <small id='4RvS7'></small><noframes id='4RvS7'>

        <legend id='4RvS7'><style id='4RvS7'><dir id='4RvS7'><q id='4RvS7'></q></dir></style></legend>
        <i id='4RvS7'><tr id='4RvS7'><dt id='4RvS7'><q id='4RvS7'><span id='4RvS7'><b id='4RvS7'><form id='4RvS7'><ins id='4RvS7'></ins><ul id='4RvS7'></ul><sub id='4RvS7'></sub></form><legend id='4RvS7'></legend><bdo id='4RvS7'><pre id='4RvS7'><center id='4RvS7'></center></pre></bdo></b><th id='4RvS7'></th></span></q></dt></tr></i><div id='4RvS7'><tfoot id='4RvS7'></tfoot><dl id='4RvS7'><fieldset id='4RvS7'></fieldset></dl></div>
      1. OpenGL - 围绕 Y 轴旋转“曲线"

        时间:2023-09-17
        • <tfoot id='pTDEr'></tfoot>

              <small id='pTDEr'></small><noframes id='pTDEr'>

              • <bdo id='pTDEr'></bdo><ul id='pTDEr'></ul>

                <i id='pTDEr'><tr id='pTDEr'><dt id='pTDEr'><q id='pTDEr'><span id='pTDEr'><b id='pTDEr'><form id='pTDEr'><ins id='pTDEr'></ins><ul id='pTDEr'></ul><sub id='pTDEr'></sub></form><legend id='pTDEr'></legend><bdo id='pTDEr'><pre id='pTDEr'><center id='pTDEr'></center></pre></bdo></b><th id='pTDEr'></th></span></q></dt></tr></i><div id='pTDEr'><tfoot id='pTDEr'></tfoot><dl id='pTDEr'><fieldset id='pTDEr'></fieldset></dl></div>
                  <tbody id='pTDEr'></tbody>

                  <legend id='pTDEr'><style id='pTDEr'><dir id='pTDEr'><q id='pTDEr'></q></dir></style></legend>
                  本文介绍了OpenGL - 围绕 Y 轴旋转“曲线"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  根据我在 Math Stackexchange 上的问题:em>

                  我正在为我的 3D 图形课程设计一个项目.该项目是用 C++ 和 OpenGL/Glut 构建的.基本上,我创建了一个水平矩形窗口,细分为两个正方形.在左侧,我有一个二维坐标平面,它允许用户指向并单击并定义轮廓曲线".然后我需要将这条曲线绕 Y 轴缠绕 n 次.

                  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.

                  那么,有人能指导我如何使用三角学来计算连续点的 X 和 Z 值吗?例如,如果用户单击并创建点:

                  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:

                  (1, 1, 0)

                  并且它们的扫描分辨率 (n) 设置为 10,然后我需要围绕 Y 轴每 36 (360/10) 度重新绘制该点.

                  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.

                  我认为三角函数会在这里帮助我是否正确?如果是这样,有人可以告诉我如何计算 3D 空间中平移点的位置吗?我已经有一段时间没有使用 Trig 了,我相信我们从未离开过 2D 空间.

                  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.

                  编辑:我尝试使用:

                  x'=xcos(theta)-zsin(theta)
                  
                  y'=y
                  
                  z'=xsin(theta)+zcos(theta)
                  

                  ,根据我对 AMPerrine 的答案的理解,我不认为它像我希望的那样工作:

                  , as per my understanding of AMPerrine's answer, and I don't think it worked as I'd hoped:

                  // this is in a loop
                  
                  // setup the new angle
                  double angle = i>0 ? (360/sweepResolutionMod)*i : 0;
                  
                  angle = angle * (M_PI/180);
                  
                  // for each point...
                  for( int i=0; i<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 << "(" << tempX << ", " << tempY << ", 0.0) by " << angle << " 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 << "(" << newX << ", " << newY << ", " << newZ << ")
                  ";
                  
                      // render the new point
                      glVertex3d(newX, newY, newZ);
                  }
                  

                  这不会产生屏幕输出,而是控制台输出:

                  This produces no screen output, but console output of:

                  (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)
                  

                  我不确定这里到底发生了什么,但我很难弄清楚,所以请不要认为我是在试图获得双重声誉或其他任何东西,我只是真的卡住了.

                  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.

                  编辑 2:这是我的透视子视图的整个显示例程:

                  EDIT 2: Here is my whole display routine for my perspective subview:

                  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 << endl;
                  
                      // loop as many number of times as we are going to draw the points around the Y-Axis
                      for( int i=0; i<=sweepResolutionMod; i++ )
                      {
                          cout << endl;
                  
                          // setup the new angle
                          double angle = i>0 ? (360/sweepResolutionMod)*i : 0;
                  
                          angle = angle * (M_PI/180);
                  
                          // for each point...
                          for( int i=0; i<clickedPoints.size(); i++ )
                          {
                              GLfloat tempX = (clickedPoints[i].x-250)/250;
                              GLfloat tempY = (clickedPoints[i].y-250)/250;
                              GLfloat tempZ = 0.0;
                  
                              cout << "(" << tempX << ", " << tempY << ", 0.0) by " << angle << " degrees = ";
                  
                              GLfloat newX = (tempX * cos(angle)) - (tempZ * sin(angle));
                              GLfloat newY = tempY;
                              GLfloat newZ = (tempX * sin(angle)) - (tempZ * cos(angle));
                  
                              cout << "(" << newX << ", " << newY << ", " << newZ << ")
                  ";
                  
                              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() > 1 )
                          {
                              glBegin(GL_LINE_STRIP);
                  
                              for(int i=0; i<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<clickedPoints.size(); i++ )
                          { 
                              glVertex3f((clickedPoints[i].x-250)/250, (clickedPoints[i].y-250)/250, 0.0);     
                          }
                  
                          glEnd();
                          */
                      }
                  
                  
                      glutSwapBuffers();
                  }
                  

                  编辑 3:这是一个糟糕的插图,说明了我需要做什么.我知道视角似乎不对,但我试图获取的是右侧子视图中的绿色水平线"(这是使用上面注释掉的 glRotatef() 代码):

                  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):

                  最终编辑(为了后代!):

                  在与大学老师讨论了一些线性代数之后,我终于开始工作了:

                  Here is what I finally got working, after discussing some linear algebra with a teacher at college:

                  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 << endl;
                  
                     double previousTheta = 0.0;
                  
                     for( int i=0; i<=sweepResolutionMod; i++ )
                     {
                       double theta = i>0 ? (360/sweepResolutionMod)*i : 0;
                  
                       theta = theta * (M_PI/180);
                  
                       if( clickedPoints.size() > 1 )
                       {
                         // the 'vertical' piece
                         glBegin(GL_LINE_STRIP);
                  
                         for(int i=0; i<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<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();
                  }
                  

                  推荐答案

                  编辑 2:好的,我明白你遇到的问题——这是我忘记的限制(所以我之前发布的代码大错特错,根本行不通).问题是你不允许在 glBegin/glEnd 对之间调用 glRotate —— 如果你这样做,它会设置一个错误标志,不再绘制.

                  Edit 2: Okay, I see the problem you're running into -- it's a limitation I'd forgotten about (so the code I'd posted previously was dead wrong and wouldn't work at all). The problem is that you're not allowed to call glRotate between a glBegin/glEnd pair -- if you do, it'll set an error flag, and no more drawing will be done.

                  这确实意味着您几乎必须自己处理轮换.幸运的是,这比您尝试实现的要简单一些:

                  That does mean you pretty much have to handle the rotation yourself. Fortunately, that's a bit simpler than you've tried to make it:

                  static const double pi = 3.1416;
                  
                  for (int point=0; point<NUM_POINTS; point++) {
                      glBegin(GL_LINE_STRIP);
                      for (double theta = 0.0; theta < 2.0 * pi; theta += pi/6.0) {
                          double x = cos(theta);
                          double z = sin(theta);
                          glVertex3d(points[point][0]*x, points[point][1], -1.0-points[point][0]*z);
                      }
                      glEnd();
                  }   
                  

                  按原样,此代码沿 Z 轴使用 -1.0 作为旋转中心.您显然可以将其移动到您想要的位置,但显然不会显示剪切视锥体之外的任何内容.

                  As-is, this code uses -1.0 along the Z axis as the center of rotation. You can obviously move that where you wish, though anything outside your clipping frustum obviously won't display.

                  另请注意,要获得线框,您必须分别绘制垂直"线和水平"线,因此代码如下所示:

                  Also note that to get a wireframe, you'll have to draw both your "vertical", and your "horizontal" lines separately, so the code will look something like this:

                  for (int point=0; point<NUM_POINTS; point++) {
                      glBegin(GL_LINE_STRIP);
                      for (double theta = 0.0; theta < 2.0 * pi; theta += pi/6.0) {
                          double x = cos(theta);
                          double z = sin(theta);
                          glVertex3d(points[point][0]*x, points[point][1], -1.0 - points[point][0]*z);
                      }
                      glEnd();
                  }
                  
                  for (double theta = 0.0; theta < 2.0 * pi; theta += pi/6.0) {
                      glBegin(GL_LINE_STRIP);
                      for (int point=0; point<NUM_POINTS; point++) {
                          double x = cos(theta);
                          double z = sin(theta);
                          glVertex3d(points[point][0]*x, points[point][1], -1.0 - points[point][0]*z);
                      }
                      glEnd();
                  }
                  

                  这篇关于OpenGL - 围绕 Y 轴旋转“曲线"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                  • <small id='PITvu'></small><noframes id='PITvu'>

                    1. <i id='PITvu'><tr id='PITvu'><dt id='PITvu'><q id='PITvu'><span id='PITvu'><b id='PITvu'><form id='PITvu'><ins id='PITvu'></ins><ul id='PITvu'></ul><sub id='PITvu'></sub></form><legend id='PITvu'></legend><bdo id='PITvu'><pre id='PITvu'><center id='PITvu'></center></pre></bdo></b><th id='PITvu'></th></span></q></dt></tr></i><div id='PITvu'><tfoot id='PITvu'></tfoot><dl id='PITvu'><fieldset id='PITvu'></fieldset></dl></div>

                          <bdo id='PITvu'></bdo><ul id='PITvu'></ul>
                          <tfoot id='PITvu'></tfoot>
                          <legend id='PITvu'><style id='PITvu'><dir id='PITvu'><q id='PITvu'></q></dir></style></legend>

                            <tbody id='PITvu'></tbody>