PDA

View Full Version : Retrieving Coordinates after rotations



J_Ramone
04-15-2001, 04:26 PM
Hello Guys,

I'm rotating my camera using glRotatef, this work's fine, but my problem is how can I get the new coordinates.

For example I draw a line, after I make a rotation. If I draw a new line, they're coordinates is wrong. But if I rotate the camera to the original angle, the line is in correct position.

How can I make this tranformation?

http://www.opengl.org/discussion_boards/ubb/smile.gif

Thanks for the moment.

Joe Ramone

ffish
04-15-2001, 06:16 PM
Joe Ramone,

You can use:

GLfloat current_matrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, current_matrix);

at any time to get the current transformation matrix, but it's a bad idea (very slow). I only use it occasionally while debugging and never in stable code. You shouldn't use any of the glGet* calls if you can help it.

For any other purposes it's best to keep track of your transformation matrices yourself. I usually have a singleton matrix object that holds the current matrix.

Hope that helps,
Toby

KurtCob
04-18-2001, 05:09 AM
Hello guys,

I'm with the same problem, can someone explain how could we solf this ?

Tnks
Best RGDS

Kurt

Deiussum
04-18-2001, 08:30 AM
I'm if I understand exactly what you mean, but if I understand you right, you want to draw multiple lines, each with different rotations?

Try something like this pseudo-code




for each line
{
glPushMatrix();
glRotate(line.angRot, line.xRotAxis, line.yRotAxis, line.zRotAxis);
line.Draw();
glPopMatrix();
}

KurtCob
04-18-2001, 11:05 AM
Tnks Deiussum,

but is not exactly this, what we want to do is: draw lines in different planes, you know, I draw one line with XZ plane, than I use glRotate, to have XY or another, so lets imagine that I'm in the origin, then I draw some line, now I change the plane to have another view, I try to draw a line again, the line is displayed but not right, like if I was in the original view.

Any help will be apreciated.

Tnks
Best regards
Kurt

Deiussum
04-18-2001, 11:24 AM
Ok... let's see if I got this now...

When you mean "change the plane" you mean something like change your point of view?

If that's the case then all you need to do is something like this...

DoTransformationsForPointOfView();
DoLineRotate();
DrawLine();

Typically the DoTransformationsForPointOfView could be done with something such as gluLookAt(); (Most of the time you will probably want a glLoadIdentity(); before the gluLookAt().)

Sorry if this is something you already know and I'm totally missing the problem again... http://www.opengl.org/discussion_boards/ubb/smile.gif

KurtCob
04-18-2001, 01:20 PM
Will this just work with gluLookAt ???

I think now you understand my problem, but let explain a little more, lets imagine that I have one "view" that is called "Front View", I call this (Im using glRotate() to have it working), then I draw some line, it is working, but now I have to draw some line in a diferent view, like "Top View", this is working also (also using glRotate), but when I draw the line, it is not working, the line is not drawn, but if I change the view for the first one, (like the original view) I have the line there, drawn in the wrong way.

Hope Im clear enough.

Tnks
Best RGDS

Kurt

KurtCob
04-19-2001, 02:30 AM
No one could figured out what we want to do ? Need we to be more clear in ower question ?

Tnks
Best regards
Kurt

Deiussum
04-19-2001, 05:35 AM
It sounds like what you need to do is to separate your view and model transformations. Try something like this around your main display function.

glPushMatrix();
DrawScene();
glPopMatrix();

Whenever you change view do this...

glLoadIdentity();
DoYourViewTransformations();

The MODELVIEW matrix in OpenGL is exactly that, a combination of the view and model transformations. You generally want the matrix to be setup like so...

Assume M = MODELVIEW matrix, W = model matrix, V = viewmatrix

M = V * W

So you basically do your view transformations first, and then your model/object transformations.

I'm not quite sure what else could be wrong with what you are trying to do. Maybe some code snippets would help.

KurtCob
04-19-2001, 07:12 AM
Ok, I will post some code here, but not yet, because I have it only at home, and now I'm at work. Anyway tnks for all your help.

RGDS

Kurt

KurtCob
04-19-2001, 09:18 AM
In the WM_SIZE event I have:

glViewPort(left, top, right, bottom);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(left, right, top, bottom, -500, 500);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

in the WM_PAINT event I have :

glPushMatrix();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glRotated(RotX, 1.0, 0.0, 0.0);
glRotated(RotY, 0.0, 1.0, 0.0);
glRotated(RotZ, 0.0, 0.0, 1.0);
---> Drawing Code
glPopMatrix();
glFlush();
SwapBuffers(hDC);
ValidateRect(hWnd, NULL);

When I change the (let's say) viewing plane, I just change the angles of RotX, RotY and RotZ.

Am I making a mistake ?

Tnks
Best RGDS
Kurt

Deiussum
04-19-2001, 10:44 AM
Aha!

I believe I understand what your problem is now. http://www.opengl.org/discussion_boards/ubb/smile.gif (Code can be so much easier to understand sometimes...) http://www.opengl.org/discussion_boards/ubb/smile.gif

The problem is that when you do rotations like this...

glRotated(RotX, 1.0, 0.0, 0.0);
glRotated(RotY, 0.0, 1.0, 0.0);
glRotated(RotZ, 0.0, 0.0, 1.0);

You are going to get different results than if you did somthing like

glRotated(RotZ, 0.0, 0.0, 1.0);
glRotated(RotX, 1.0, 0.0, 0.0);
glRotated(RotY, 0.0, 1.0, 0.0);

The order of the rotations makes a big difference.

The easiest way to think about it in my mind is in world coordinates, which means that the rotations are actually done in reverse of what you specify them.

Picture taking a line that is straight up in the y axis.

Now picture rotating that line 45 degrees around the X axis so that the top half of the line goes away from you...

Now picture the line in that position being rotated 45 degrees to the left around the Y axis.

You should be picturing a line that goes from the upper left at a going to the lower right coming towards you.

Ok... now let's go in the reverse order.

Rotate the line 45 degrees around the y axis. Since the line is on the Y axis initially, there is essentially no change.

Now you do the x axis rotation 45 degrees away from you.

You should now be picturing a line that is straight up and down where the top is further away from you than the bottom.

What I believe you are trying to do is to rotate the line from the position it is currently in to the direction you specify, which can get a bit messy. Trying to do this with 3 separate axis rotations is not going to work and results in something affectionately called gimbal lock.

There are a number of possible solutions, but I will present one for you. Store the view rotations in a matrix rather than as separate angle rotations. Then when you apply a new rotation, PRE multiply the new rotation to the current view matrix. Then in your code you would do a glLoadMatrix() instead of 3 discrete glRotations.

Here's an example to try and illustrate what I mean. Assume you are storing your view matrix in a matrix called M. And you want to do the following rotations in this order.

1) Rotate around the X axis 45 degrees.
(Equivalent to glRotatef(45, 1, 0, 0))
2) Rotate around the Y axis 45 degrees.
(Equivalent to glRotatef(45, 0, 1, 0))
3) Rotate around the Z axis -30 degrees.
(Equivalent to glRotatef(-30, 0, 0, 1))

Initially set your matrix M to the identity matrix, which we will call I.

M = I

Next, determine the matrix R1 which represents rotation #1. After you calculate matrix R1 do this

M = R1 * M (Now M == R1 * I)

Next Determine the matrix R2 which represents rotation #2. Then you now have

M = R2 * M (Now M == R2 * R1 * I)

Finally determine the matrix R3 which represents rotation #3.

M = R3 * M (Now M == R3 * R2 * R1 * I)

Note: Multiplying a matrix by I gives you that same matrix so you essentially have R3 * R2 * R1, which should give you the results you expect.

So basically what you now have is equivalent to
glRotatef(-30, 0, 0, 1);
glRotatef(45, 0, 1, 0);
glRotatef(45, 1, 0, 0);

The nice thing about this is you can apply as many rotations, and rotations in any order that you want and it should always give you the result you expect. Basically in code you wouldn't create separate R1, R2, R3 matrices but would do something like,

R = GetNewRotationMatrix();
M = R * M;

Now... if you want to know how to multiply matrices and how to determine rotational matrices, you can probably find several good resources. The formula for rotational matrices are described pretty well in one of the appendices of the Red book. There are probably many resources that describe how to multiply matrices together available on the web, and there are even some code snippets todo that on the forum here somewhere.