views:

869

answers:

3

I am trying to translate an OpenGl object around in a helical pattern. I cannot figure this out. Problem is I know I need to increment the angle for the x, y, and z coordinates, but the translate function that I use only moves the object by a translate amount which is specific to the object. The Axis I am using is Y up, Z toward the screen and X to the right.

public override void Move(Figure fig)
{
   double angle = 0;
   double x = RADIUS * Math.Cos(angle);
   double y = (angle / RADIUS);
   double z = RADIUS * Math.Sin(angle);
   fig.Translate(x, y, z);
   angle += .5;
}
public void Translate(double fx, double fy, double fz)
{
   translateAmt[0] += fx;
   translateAmt[1] += fy;
   translateAmt[2] += fz;

}
A: 

I think you are missing some code.

In move, angle always starts with zero, so the x,y,z values will always be the same, as the next time you go into Move it will be zero again.

You should be passing in the angle, perhaps, into Move, so that this value will continue to change.

You may need to pass it in as a pointer so that you can update it within the function and have it actually be updated, or, have Move return a double and return angle;.

I expect that your changing of the angle by 0.5 isn't correct, it may need to be based on the repetition number * some value, but you may want to fix your first problem first.

James Black
+1  A: 

Here are two ways you could approach this:

Procedurally

Check out the ProcessHelix function in NeHe Lesson 36. A little bit hard to read but you should be able to see the basic loop and calculations used to get the points along a helix.

2 Translations and a Rotation

If you perform these transformations in the proper order you can get the helical motion. This is the order you would imagine doing it in your head:

  1. Translate the object away from the origin (e.g. +x) the radius of your helix
  2. Rotate the object around the origin (y axis), creating circular motion
  3. Translate the object along the y axis, creating helical motion.

So in OpenGL, you'd do those backwards, as the last matrix specified is the first one applied... translate in +y (time dependent), rotate around y (time dependent), and translate in x.

nselikoff
A: 

Got it working!

  private const double RADIUS = 1;
  private const double INTERVAL = 0.1;
  private double theta = 5;
  private double alpha = 0;
  private const double ANGLE = 10;

public override void Move(Figure fig)
  {
     double x = RADIUS * Math.Cos(theta);
     double y = 0;
     double z = RADIUS * Math.Sin(theta);
     double deltaX = z * Math.Cos(alpha) - x * Math.Sin(alpha);
     double deltaZ = x * Math.Cos(alpha) + z * Math.Sin(alpha);
     fig.Translate(deltaX, y, deltaZ);
     fig.Rotate(ANGLE, 0, 0, 1);
     alpha += INTERVAL;
  }
Spenser