Note that there are some explanatory texts on larger screens.

plurals
  1. POOpenGL - Rotate a 'Curve' About the Y-Axis
    text
    copied!<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>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload