2
$\begingroup$

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.

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

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.

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.

EDIT: I attempted to use:

$x'=x\cos\theta-z\sin\theta$

$y'=y$

$z'=x\sin\theta+z\cos\theta$

, 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

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.

EDIT 2: Updated loop to use radians.

FINAL EDIT (for future generations!):

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
  • 0
    Are these points supposed to be in the same horizontal plane as the original? In that case it's still a 2D problem ($y$ is constant).2011-10-26
  • 1
    @AMPerrine, No. I should have clarified. The left subwindow is a 2 dimensional x/y grid. The right window is a 3D perspective view. So you define a profile curve in terms of x and y (z=0), and I then wrap that curve around the y axis every 360/n degrees, in 3D space. Essentially creating a solid object from a profile curve. Think a single slice of the right mirrored half of a wine glass.2011-10-26
  • 0
    Rotating by 360 degrees is supposed to be the same as "do nothing"...2011-10-26
  • 0
    @J.M.: I know that, however, it is not doing that.2011-10-26
  • 0
    Are you converting the angle to radians first? I believe those functions expect radians as input.2011-10-26
  • 0
    @AMPerrine: I did, after it was pointed out on my x-post (http://stackoverflow.com/q/7904281/420001), but my numbers went way off, into the -x.Xex range.2011-10-26
  • 1
    I think I'd need to see those results to try to diagnose the problem. However if you are not converting to radians it has no chance of working at all--GIGO and all that.2011-10-26
  • 0
    @AMPerrine: I updated my loop, to use radians.2011-10-26
  • 0
    I did some spot checking and you seem to be getting the correct values. Where is the problem?2011-10-26
  • 0
    Are you referring to the $z$ values in the full rotation? Those are effectively zero as they should be, just off a bit due to lack of precision in the trig functions or in defining pi. You can't display them to that precision anyway, so it doesn't really matter. Round to some arbitrary place if you want to make absolutely sure the first and last points match up, but I don't think it will really present any problems.2011-10-26

1 Answers 1

3

Each point in the curve can be rotated about the $y$-axis by an angle $\theta$ using the following:

$x'=x\cos\theta-z\sin\theta$

$y'=y$

$z'=x\sin\theta+z\cos\theta$

But if $z$ is always zero this of course becomes even simpler.

  • 0
    This is in 3D space, so Z is not always zero. So this will go directly from (x, y, z) to a rotated (x, y, z)? No intermediaries? I ask because elsewhere it was suggested that I convert to cylindrical coordinates to do the rotation, then back to euclidean coordinates to render, and I just wanted to make sure your answer here does indeed maintain the point in the manner of (x, y, z).2011-10-26
  • 0
    The formula given will work for rotating around the $y$-axis, and will give the same results as those conversions. I was originally going to suggest converting to polar before thinking about it further. From my understanding the original point is always of the form $(x,y,0)$. In that case you can drop off the $z$ terms.2011-10-26
  • 0
    I'm confused as to why the Z coordinate is irrelevant. If my point starts at (1, 1, 0), and I rotate it, say, 45 degrees around the Y axis, my new point should most definitely have a change in Z, right?2011-10-26
  • 0
    Your new point will have a $z$-coordinate of $x\sin\theta$. If you choose to rotate that point again, you will need the full formula. But I would prefer to rotate the original point by 36, 72, 108, etc. degrees to generate the full set of points (for precision reasons).2011-10-26
  • 0
    Ah, so you're saying it will only yield a Z of zero on the first iteration. Which makes sense, because the first point would be on the z=0. And yes, I definitely plan on calculating the points off of the initial point with an incremented $\theta$ to preserve accuracy. I'll give this a go in a bit, and report back. Thanks!2011-10-26
  • 0
    Well, I tried what you suggested, but I don't think it worked. Please see my edit.2011-10-26
  • 0
    What eventually worked for me, as I've updated my question, was by setting the following: $x'=x\cos\theta+z\sin\theta$ and $z'=z\cos\theta-x\sin\theta$. I think you were on the right track, but maybe mismultiplied a matrix?2011-10-26
  • 0
    What I posted was correct--you can do the derivation yourself or find it online. If you look at your equations, you have simply substituted $-\theta$ for $\theta$ in my formula, so there should be no difference in the resulting solid other than the order in which the vertices were generated.2011-10-27
  • 0
    Hm, I see. Well, I just ended up stripping down the function and rewriting it, perhaps I had a bit of otherwise bad logic. Regardless, thank you so much for your time spent helping me with this. You've guided me perfectly! :)2011-10-27