PDA

View Full Version : rotation



banzai889
10-01-2003, 01:51 AM
hi,
i wonder why my opengl program rotation of an object will suddenly change its direction?
i set it rotate clock wise according the my y axis and some how it suddenly change to anti clock wise during run time and keep continue doing so.
anyone have any idea?

thanks

marcus256
10-01-2003, 02:59 AM
...it's a programming error. Has nothing to with OpenGL (unless you are not using the transformation matrices correctly, in which case it's still a programming error).

Remember that all glRotate/Scale/Translate commands are cumulative, so you need to either use glPushMatrix/PopMatrix or reinit your matrix in the right places.

banzai889
10-01-2003, 03:30 AM
hmmm, so is my code error,
my code in drawing as follows


void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glPushMatrix();

glRotatef(rotY, 0.0, 1.0, 0.0);
glRotatef(rotX, 1.0, 0.0, 0.0);

Reshape(zoom,zoom);

alpha = alpha + (float) inc;
if(alpha > (float) 360.0)
{
alpha -= (float) 360.0;
}
glRotatef(alpha, (float) 0.0, (float) 1.0, (float) 0.0);

draw();
glPopMatrix();

glFlush();
glutSwapBuffers();
}

Tenson
10-01-2003, 04:05 AM
Originally posted by banzai889:
hmmm, so is my code error,
my code in drawing as follows


void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glPushMatrix();

glRotatef(rotY, 0.0, 1.0, 0.0);
glRotatef(rotX, 1.0, 0.0, 0.0);

Reshape(zoom,zoom);

alpha = alpha + (float) inc;
if(alpha > (float) 360.0)
{
alpha -= (float) 360.0;
}
glRotatef(alpha, (float) 0.0, (float) 1.0, (float) 0.0);

draw();
glPopMatrix();

glFlush();
glutSwapBuffers();
}

After each transformation there should be glPopMatrix();

banzai889
10-01-2003, 05:14 AM
no idea
do u mind tell me more please?

nexusone
10-01-2003, 05:22 AM
What is up with the reshape routine in your display code?

Can you post more of your code?

banzai889
10-01-2003, 05:47 AM
#include <math.h>
#include <GL/glut.h>

#define WINDOW_WIDTH 400
#define WINDOW_HEIGHT 400
#define PI 3.1415927

//int diagramNo = 1;
//float zoom = 0;
int diagramNo;
float zoom;
float inc;
float alpha;
int rotX,rotY;
float yRotSpeed;

void calCoordinates(float fi, float teta, float *x, float *y, float *z);
void Reshape(int width, int height);

void init()
{
diagramNo = 1;
inc = 0;
alpha = 0;
zoom = 0;
rotX = 0;
rotY = 0;
yRotSpeed = 0.5;

glShadeModel (GL_FLAT);

glClearColor((float) 0.3, (float) 0.0, (float) 0.5, (float) 0.0);
glEnable(GL_DEPTH_TEST);
}

void calCoordinates(float fi, float teta, float *x, float *y, float *z)
{
if(diagramNo == 2)
{
*x = 0.5*(cos(fi) + 0.5*cos(2*fi));
*y = 0.5*cos(teta)*(2 + sin(fi) - 0.5*sin(2*fi));
*z = 0.5*sin(teta)*(2 + sin(fi) - 0.5*sin(2*fi));
}
else
{
*x = ( 1 + 0.25*cos(teta) ) * cos(fi);
*y = ( 1 + 0.25*cos(teta) ) * sin(fi);
*z = 0.25 * sin(teta);
}

}

void draw()
{
float delta = PI/12.0;
float x, y, z;
float fi, teta;
float fi1 = 0.0;
float teta1 = 0.0;
float fi2 = 2*PI;
float teta2 = 2*PI;


// x axis
glColor3f((float) 1.0, (float) 0.0, (float) 0.0);
glBegin(GL_LINE_STRIP);
glVertex3f(0, 0, 0);
glVertex3f(2, 0, 0);
glEnd();

// y axis
glColor3f((float) 0.0, (float) 0.0, (float) 1.0);
glBegin(GL_LINE_STRIP);
glVertex3f(0, 0, 0);
glVertex3f(0, 2, 0);
glEnd();

// z axis
glColor3f((float) 0.0, (float) 1.0, (float) 0.0);
glBegin(GL_LINE_STRIP);
glVertex3f(0, 0, 0);
glVertex3f(0, 0, 2);
glEnd();


glColor3f((float) 0.0, (float) 1.0, (float) 0.0);

for(fi=fi1; fi<=fi2; fi+=delta)
{
glBegin(GL_LINE_STRIP);
for(teta=teta1; teta<=teta2; teta+=delta)
{
calCoordinates(fi, teta, &x, &y, &z);
glVertex3f(x, y, z);
}
glEnd();
}


for(teta=teta1; teta<=teta2; teta+=delta)
{
glBegin(GL_LINE_STRIP);
for(fi=fi1;fi<=fi2;fi+=delta)
{
calCoordinates(fi,teta,&x,&y,&z);
glVertex3f(x,y,z);
}
glEnd();
}

}

static void SpecialKey(int key, int x, int y)
{

switch (key)
{
case GLUT_KEY_LEFT:
rotY -= 3.0;
break;

case GLUT_KEY_RIGHT:
rotY += 3.0;
break;

case GLUT_KEY_UP:
rotX += 3.0;
break;

case GLUT_KEY_DOWN:
rotX -= 3.0;
break;
}
}


void input(unsigned char key, int x, int y)
{

switch (key)
{
case '1':
diagramNo = 1;
break;

case '2':
diagramNo = 2;
break;

case 'Z':
zoom -= 0.1;
glutPostRedisplay();
break;

case 'z':
zoom += 0.1;
glutPostRedisplay();
break;

case 'R':
if(inc == yRotSpeed)
{
inc = 0;
}
else
{
inc = yRotSpeed;
}

// glutPostRedisplay();
break;

case 'r':

if(inc == yRotSpeed)
{
inc = 0;
}
else
{
inc = yRotSpeed;
}

// glutPostRedisplay();
break;

case 'A':
// glutPostRedisplay();
break;

case 'a':
// glutPostRedisplay();
break;

case 'F':
// glutPostRedisplay();
break;

case 'f':
// glutPostRedisplay();
break;

case 'S':
// glutPostRedisplay();
break;

case 's':
// glutPostRedisplay();
break;

case 'T':
// glutPostRedisplay();
break;

case 't':
// glutPostRedisplay();
break;

case 'C':
// glutPostRedisplay();
break;

case 'c':
// glutPostRedisplay();
break;

case 'p':
// glutPostRedisplay();
break;

case 'P':
// glutPostRedisplay();
break;

case 'W':
// glutPostRedisplay();
break;

case 'w':
// glutPostRedisplay();
break;

}


}


void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glPushMatrix();

glRotatef(rotY, 0.0, 1.0, 0.0);
glRotatef(rotX, 1.0, 0.0, 0.0);

Reshape(zoom,zoom);

alpha = alpha + (float) inc;
if(alpha > (float) 360.0)
{
alpha -= (float) 360.0;
}
glRotatef(alpha, (float) 0.0, (float) 1.0, (float) 0.0);

draw();
glPopMatrix();

glFlush();
glutSwapBuffers();
}


void idle(void)
{
glutPostRedisplay();
}

void Reshape(int width, int height)
{

glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-width,height,-width,height,-10,10);
glMatrixMode(GL_MODELVIEW);
}


int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
glutInitWindowPosition(100, 100);

glutCreateWindow("My Program");
init();

glutDisplayFunc (display);
glutKeyboardFunc (input);
glutSpecialFunc(SpecialKey);
glutReshapeFunc(Reshape);
glutIdleFunc (idle);

glutMainLoop();
return 0;
}

i wonder what is wrong with the direction of rotation, it changes at run time...

10-01-2003, 09:44 AM
alpha = alpha + (float) inc;
if(alpha > (float) 360.0)
{
alpha -= (float) 360.0;
}
glRotatef(alpha, (float) 0.0, (float) 1.0, (float) 0.0);


Hmm, this looks like you're trying to keep the rotation from passing over 360 degrees. How come you're not keeping it from going below 0 degrees?

10-01-2003, 09:47 AM
By the way, you don't have to put (float) before each number, you can just do 1.0f.

If you're on a G3 (Macintosh), then continue using floats. If you're on a G4, then use whatever you want; float or double (it really doesn't matter). If you're on a G5, use floats.

If you're on anything else, then ignore this.

10-01-2003, 12:17 PM
Originally posted by banzai889:


I see a number of problems with the code.

1. The call to glOrtho() MAY not be correct. The first 4 parameters of glOrtho() are left, right, bottom, top, but you've arranged them as the same upper left corner for both left:right and bottom:top. If that is your intent, then you can move on to the next item. Otherwise, you should try this instead:
glOrtho(-width/2.0,width/2.0,-height/2.0,height/2.0,-10,10).

2. Someone has already pointed this out, but in your display() code you call Reshape() with a zoom parameter. The zoom parameter is 0 initially, so that gives glOrtho() the following parameters: glOrtho(-0,0,-0,0,-10,10)
I think you need to remove the Reshape() call from your display code and try using scaling instead. I also think the initial value for zoom should be 1 instead of 0.
3. Someone else already mentioned this, but you need to clamp alpha for 0 is well as 360. You should probably also do that clamping for rotY as well.
4. The only condition I see where your rotation goes negative is when (rotY + alpha) < 0.
Hope this helps.

banzai889
10-01-2003, 04:31 PM
i add in the code to avoid negative angle almost the same technique as the other one i already done but still the object will rotate in 1 direction for few seconds and then it start to rotate in opposite direction
i dont understand why
i want it just rotate clockwise from top of y axis but it change direction during run time
funny

banzai889
10-01-2003, 04:53 PM
i suspect my program is having mirror problem
because when i see it rotate in reverse direction i think i see it mirror image
any one had any idea?

10-02-2003, 02:53 AM
Try something like this...

reshape(...)
glPushMatrix()
glRotatef(rotx...)
glRotatef(roty...)
glPushMatrix()
glRotatef(alpha...)
draw()
glPopMatrix
glPopMatrix

10-02-2003, 09:37 AM
Originally posted by macfiend:
Try something like this...

reshape(...)
glPushMatrix()
glRotatef(rotx...)
glRotatef(roty...)
glPushMatrix()
glRotatef(alpha...)
draw()
glPopMatrix
glPopMatrix

Some other ideas you might consider:

void
input(...)
{
.
.
.
if (inc==yRotSpeed)
{
inc = 0.0;
rotY = alpha;
}
else
{
inc = yRotSpeed;
alpha = rotY;
}
.
.
.
}

void
display()
{
glClear(...); /* same as before */
glLoadIdentity();
glRotatef(rotX,1.0,0.0,0.0);
if (inc == 0.0)
glRotate(rotY,0.0,1.0,0.0);
else
{
alpha+= inc;
if (alpha>360.0)
alpha-= 360.0;
else if (alpha<0.0)
alpha+= 360.0;
glRotatef(alpha,0.0,1.0,0.0);
}
draw();
glFlush();
glutSwapBuffers();
}

I've separated rotY and alpha in this code because rotY and alpha support different functions. The alpha variable is for animation and the rotY is for user interaction, so it doesn't make sense to do both at the same time. The alpha variable is set to rotY in input() so that when animation is started it starts at the same angle as rotY. The rotY variable is set to alpha when animation ends so that it doesn't reset the rotation back to the previous rotY value. You could also consider combining alpha and rotY into a single variable.

You might also try to slow down the animation by placing code in the idle() function that calls glutPostRedisplay() only after a certain amount of time has past. Start out with something like one per second, then add another set of keys that would speed up and slow down the animation. That way it will be easier to determine if the rotation actually reverses or if it's simple a trick of the eye as you have stated.