PDA

View Full Version : right-hand rule - glRotate wrong direction?



newsb
08-11-2011, 01:30 PM
Hi all,

I'm an openGL newbie. I don't understand the righthand rule here: "fElect1" is a variable that keeps increasing - minimal example (however not compilable) follows:

-----------
// Angle of revolution around the nucleus
static GLfloat fElect1 = 0.0f;

// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Reset the modelview matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); // Replace current matrix with 4*4 identity matrix!


// Translate the whole scene out and into view
// This is the initial viewing transformation
glTranslatef(0.0f, 0.0f, -100.0f); // translates in direction (x,y,z)

// Red Nucleus - IN THE CENTER - NOT MOVING...
glColor3ub(255, 0, 0); // Sphere args: (radius, slices, stacks!)

// *** CREATE THS FIRST RED SPHERE (NON-MOVING): ***
glutSolidSphere(10.0f, 15, 15); // <============= SPHERE (IN CENTER)


glRotatef(fElect1, 0.0f, 0.0f, 1.0f); // around the vector x,y,z...
glTranslatef(40.0f, 0.0f, 0.0f);
// Sphere args: (radius, slices, stacks!)
glutSolidSphere(6.0f, 15, 15); // <============= SPHERE
glPopMatrix();
-----------

The last sphere goes CW around the center of the screen, as "fElect1" increases. Right is x, y is up, so z is outwards from the screen to the viewer, right?

I think the sphere should go CCW because positive rotation around the z-axis tells me that I put my right thumb pointing towards myself and then positive direction of rotation is in the fingertips direction, which is CCW. But the sphere goes the other way around.

I don't understand this - please advice. I hope I made myself clear and understandable.

BionicBytes
08-12-2011, 01:46 AM
The last sphere goes CW around the center of the screen, as "fElect1" increases. Right is x, y is up, so z is outwards from the screen to the viewer, right?

Correct.

Incidentally, you have included this line
glPopMatrix();
Which you don't need as you are always starting with identity. Perhaps you should post some actual code so we can better see what's going on.

newsb
08-13-2011, 04:40 AM
Hi,

Ok, but I'm using some code from "OpenGL SuperBible 4th edition" - http://www.opengl.org/sdk/docs/books/SuperBible/ -

It includes GLee.h and gltools.h - which I didn't include here. I don't know if it's easy for you to compile if these files are mising... Anyway, here's the code and my question again:

--------------------
#include "../../shared/gltools.h" // OpenGL toolkit

// Rotation amounts
static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;


// Called to draw scene
void RenderScene(void)
{
// Angle of revolution around the nucleus
static GLfloat fElect1 = 0.0f;

// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Reset the modelview matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity(); // Replace current matrix with 4*4 identity matrix!



// Translate the whole scene out and into view
// This is the initial viewing transformation
// glTranslatef(0.0f, 0.0f, -100.0f); // translates in direction (x,y,z)
glTranslatef(0.0f, 0.0f, 100.0f); // translates in direction (x,y,z)

// Red Nucleus - IN THE CENTER - NOT MOVING...
glColor3ub(255, 0, 0); // Sphere args: (radius, slices, stacks!)

// *** CREATE THS FIRST RED SPHERE: ***
glutSolidSphere(10.0f, 15, 15); // <============= SPHERE (IN CENTER)

// Yellow Electrons - this sets alpha=1 (full intensity) + RGB:
glColor3ub(255,255,0); // parameters mean: RED, GREEN, BLUE.




// ========= LOOK HERE - THIS CONCERNS MY QUESTION =========
glPushMatrix();
glRotatef(360.0f-45.0f,0.0f, 0.0f, 1.0f); // Rotates [Angle (deg), ...
glRotatef(fElect1, 0.0f, 1.0f, 0.0f); // around the vector x,y,z]
glTranslatef(0.0f, 0.0f, 60.0f);
// Sphere args: (radius, slices, stacks!)
glutSolidSphere(6.0f, 15, 15); // <============= SPHERE
glPopMatrix();


// Increment the angle of revolution
fElect1 += 1.0f;
if(fElect1 > 360.0f)
fElect1 = 0.0f;




// Show the image
glutSwapBuffers();
}


// This function does any needed initialization on the rendering
// context.
void SetupRC()
{
glEnable(GL_DEPTH_TEST); // Hidden surface removal
glFrontFace(GL_CCW); // Counter clock-wise polygons face out
glEnable(GL_CULL_FACE); // Do not calculate inside of jet

// Black background
glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
}


void TimerFunc(int value)
{
glutPostRedisplay();
glutTimerFunc(10, TimerFunc, 1);
}


void ChangeSize(int w, int h)
{
GLfloat nRange = 100.0f;

// Prevent a divide by zero
if(h == 0)
h = 1;

// Set Viewport to window dimensions
glViewport(0, 0, w, h);


// Reset coordinate system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// Establish clipping volume (left, right, bottom, top, near, far)
if (w <= h)
glOrtho (-nRange, nRange, nRange*h/w, -nRange*h/w, -nRange*2.0f, nRange*2.0f);
else
glOrtho (-nRange*w/h, nRange*w/h, nRange, -nRange, -nRange*2.0f, nRange*2.0f);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

int main(int argc, char* argv[])
{
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutCreateWindow("OpenGL Atom");
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
glutTimerFunc(500, TimerFunc, 1);
SetupRC();
glutMainLoop();

return 0;
}

--------------------

hmm... The formatting is gone on this forum?!? Anyway: Question again:

The last sphere goes CW around the center of the screen, as "fElect1" increases. Right is x, y is up, so z is outwards from the screen to the viewer, right?

I think the sphere should go CCW because positive rotation around the z-axis tells me that I put my right thumb pointing towards myself and then positive direction of rotation is in the fingertips direction, which is CCW. But the sphere goes the other way around.

I don't understand this - who can explain it to me?

MaxH
08-13-2011, 04:18 PM
It's more likely people will help you if you put your code between [ code] and [ /code] tags like below. Good luck.



#include "../../shared/gltools.h" // OpenGL toolkit

// Rotation amounts

static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;


// Called to draw scene

void RenderScene(void)
{
// Angle of revolution around the nucleus
static GLfloat fElect1 = 0.0f;

// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Reset the modelview matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

// Translate the whole scene out and into view
// This is the initial viewing transformation
// glTranslatef(0.0f, 0.0f, -100.0f); // translates in direction (x,y,z)
glTranslatef(0.0f, 0.0f, 100.0f); // translates in direction (x,y,z)

// Red Nucleus - IN THE CENTER - NOT MOVING...
glColor3ub(255, 0, 0); // Sphere args: (radius, slices, stacks!)

// *** CREATE THS FIRST RED SPHERE: ***
glutSolidSphere(10.0f, 15, 15); // <============= SPHERE (IN CENTER)

// Yellow Electrons - this sets alpha=1 (full intensity) + RGB:
glColor3ub(255,255,0); // parameters mean: RED, GREEN, BLUE.


// ========= LOOK HERE - THIS CONCERNS MY QUESTION =========

glPushMatrix();
glRotatef(360.0f-45.0f,0.0f, 0.0f, 1.0f); // Rotates [Angle (deg), ...
glRotatef(fElect1, 0.0f, 1.0f, 0.0f); // around the vector x,y,z]
glTranslatef(0.0f, 0.0f, 60.0f);
// Sphere args: (radius, slices, stacks!)
glutSolidSphere(6.0f, 15, 15); // <============= SPHERE
glPopMatrix();


// Increment the angle of revolution
fElect1 += 1.0f;
if(fElect1 > 360.0f)
fElect1 = 0.0f;

// Show the image
glutSwapBuffers();
}

// This function does any needed initialization on the rendering context.
void SetupRC()
{
glEnable(GL_DEPTH_TEST); // Hidden surface removal
glFrontFace(GL_CCW); // Counter clock-wise polygons face out
glEnable(GL_CULL_FACE); // Do not calculate inside of jet

// Black background
glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
}

void TimerFunc(int value)
{
glutPostRedisplay();
glutTimerFunc(10, TimerFunc, 1);
}

void ChangeSize(int w, int h)
{
GLfloat nRange = 100.0f;

// Prevent a divide by zero
if (h == 0) h = 1;

// Set Viewport to window dimensions
glViewport(0, 0, w, h);


// Reset coordinate system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// Establish clipping volume (left, right, bottom, top, near, far)
if (w <= h)
glOrtho (-nRange, nRange, nRange*h/w, -nRange*h/w, -nRange*2.0f, nRange*2.0f);
else
glOrtho (-nRange*w/h, nRange*w/h, nRange, -nRange, -nRange*2.0f, nRange*2.0f);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

int main (int argc, char* argv[])
{
glutInit(&amp;argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(800, 600);
glutCreateWindow("OpenGL Atom");
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
glutTimerFunc(500, TimerFunc, 1);
SetupRC();
glutMainLoop();

return 0;
}

MaxH
08-13-2011, 10:51 PM
[1] glRotatef (360.0f-45.0f,0.0f, 0.0f, 1.0f);
[2] glRotatef (fElect1, 0.0f, 1.0f, 0.0f);
[3] glTranslatef (0.0f, 0.0f, 60.0f);
[4] glutSolidSphere (6.0f, 15, 15);
These are the 4 lines from your code where the animation is supposed to take place.
Previous to these lines a red sphere is displayed in the center of the screen.
Comment out lines 1,2,3 and run your code.
You'll only see the red sphere because the yellow sphere is totally inside the red sphere.
Now uncomment line 3. This translates the yellow ball directly towards the camera.
Now you'll see a big red dot inside of which is a smaller yellow dot.
Now uncomment line 2. This animates the yellow ball rotating around the red ball.
Since you're rotating around the Y axis (screen vertical axis),
the yellow dot will simply appear to move from right to left across the screen.
Remember that transformations are applied in order of proximity to the object being drawn.
So line 3 is applied to the sphere, then line 2, then line 1.
What the heck are you trying to do in line 1?
It rotates the entire scene around the Z axis which points directly out of the screen?
All this would do is make the ball move in a line tipped 45 degs to the horizontal, instead of directly from right to left.
The code as you've posted it, would only show a ball moving back and forth along a diagonal line.
Nothing would appear to be moving in a circle.
Not sure where you are getting this idea that something is rotating the wrong way.
It is totally indeterminate from the code you've posted.
I strongly suggest that you use Perspective projection instead of Ortho.
It will give you a clearer understanding of which way things are moving,
because when a ball comes towards the camera it will get bigger.

Good luck.

newsb
08-16-2011, 04:52 PM
MaxH:

Thanks a lot for your answer and time spend on my question - I'm very sorry for the late reply - typically it should only take 1-2 days for me to reply. In the weekend I was away and I came back with a cold and couldn't really do much serious before now.

Please remember I'm a newbie and as such I'm not fully aware of what is (was) happening. Although it helps now as I've improved the code to include perspective projection - based on your suggestion and I googled around for other explanations.

Regarding line 1: I think this is a copy/paste mistake from my side. The original code was a bit longer, but I have cutted it a bit down here and I think the line with 360 degrees something should have been deleted and not included in the first place.

As for the question about doing homework, it's not homework. I'm reading the book to try to learn openGL in my own pace but nobody forces me to do it. I know about the righthand rule from solid mechanics and not from computer science. As an engineer I know about matrices and linear algebra but sorry to say that now I cannot reconstruct the example where I thought the yellow ball where moving in the wrong direction. Apparantly it rotates in the correct direction now - sorry for spending my your time (and my own).

However I really appreciate your help and commenting/uncommenting code lines above. I think I'll just read more in the opengL bible and post to a new thread/topic when something unclear arises again...

Alfonse Reinheart
08-16-2011, 05:32 PM
As for the question about doing homework

That wasn't a real question; it's just part of his signature.

MaxH
08-17-2011, 10:42 AM
Please remember I'm a newbie and as such I'm not fully aware of what is (was) happening. Although it helps now as I've improved the code to include perspective projection - based on your suggestion and I googled around for other explanations.

Apparantly it rotates in the correct direction now ...
I always like to have the option of displaying an XYZ triad somewhere in the scene. It clarifies things a lot. Also, always have interactive rotations implemented so you can view your scene from any angle. OpenGL operates by the right-hand rule. Anytime you see something that appears to be rotating left-handed, it means you are misinterpreting what you are seeing. Add perspective, rotate the scene to a different angle, display an XYZ triad, etc.

newsb
08-17-2011, 03:10 PM
That wasn't a real question; it's just part of his signature.

Ah, also thought so for a few minutes... thanks.

newsb
08-17-2011, 03:12 PM
Apparantly it rotates in the correct direction now...
I always like to have the option of displaying an XYZ triad somewhere in the scene. It clarifies things a lot. Also, always have interactive rotations implemented so you can view your scene from any angle. OpenGL operates by the right-hand rule. Anytime you see something that appears to be rotating left-handed, it means you are misinterpreting what you are seeing. Add perspective, rotate the scene to a different angle, display an XYZ triad, etc.

I did that another place - and added perspective projection to this code and added 3 lines in red,green and blue going in x-, y- and z-direction (however it would be nice if there was an arrowhead in the ends, but it's ok).

Since it's my first time doing these things - it usually takes a lot of hours to do even simple things but I sometimes find good inspiration on google (or in this forum).

Thanks to everyone... I'll stay here at least until I've read the openGL bible, I think...