## Getting position after transformation without drawing?

hyn
Unregistered

Post: #1
I have a point I want to rotate around an arbitrary axis AND know its object-space coordinates (not window coordinates) after rotation.

I can't use gluProject() because it returns window coordinates, not object-space. And there seems to be no version of gluProject() that returns an object-space coordinate.

Is there no easy way, can someone tell me the calculations involved?
Is it as simple as dot-producting my point with the modelview matrix?

Thank you,

-hyn
Member
Posts: 184
Joined: 2004.07
Post: #2
Hey hyn,

If you already have an OpenGL matrix you want to transform with, you can use glGetFloatv(MODELVIEW... or something like that to load the matrix, and then you just do a normal matrix multiplication with your vertex to transform it.
hyn
Unregistered

Post: #3
Is there a specific order in which I should call the operations?
If I recall correctly order of rotations doesn't matter.

I need to do 3 rotations:

1. 23.5 degrees about z axis.
2. Rotate x degrees about x axis.
3. Rotate y degrees about y axis.

But doing the following gives me odd results (normals are correct but positions are not):

Code:
```//  rotate coords on z axis costant degrees newMatrix = [self matrixRotate: identity angle: 23.5 x: 0.0 y: 0.0 z: 1.0]; newCoords = [self matrixVmul: newMatrix with: coords]; //  rotate same coords again on x axis x degrees newMatrix = [self matrixRotate: newMatrix angle: rotateX x: 1.0 y: 0.0 z: 0.0]; newCoords = [self matrixVmul: newMatrix with: newCoords]; //  rotate same coords again on y axis y degrees newMatrix = [self matrixRotate: newMatrix angle: rotateY x: 0.0 y: 1.0 z: 0.0]; newCoords = [self matrixVmul: newMatrix with: newCoords];```

matrixRotate does the exact same thing as kberg's Mat4_rot except it returns by value.
Same with matrixVmul.

I am also investigating the possibility of mistyping the code (I can't use copy paste from this networked computer to my working computer).

Also, I couldn't use sinf cosf sqrtf, they don't seem to be defined in math.h?
I used sin cos sqrt instead, which may be a problem?
Member
Posts: 184
Joined: 2004.07
Post: #4
sinf cosf sqrtf are just the float version of sin cos sqrt (instead of double.) so they're just less precise, but for your purposes it probably doesn't matter at all.

Matrix multiplication order does matter, but since you're just doing rotations, you should be able to transform both positions and normals with the same set of matrix multiplications. What exactly is happening to your positions?
hyn
Unregistered

Post: #5
Ok, dumb mistake. I was passing in degrees (instead of radians) in 'angle'.
Now the positions are closer to where it should be, but still not close enough.
They seem to rotate in excess by a bit about a fixed axis.
Member
Posts: 72
Joined: 2006.10
Post: #6
I think your problem is the following:

Since Matrix operations stack, I don't think that you should multiply the vector three times, but only once with the final matrix:

Code:
```//  rotate coords on z axis costant degrees newMatrix = [self matrixRotate: identity angle: 23.5 x: 0.0 y: 0.0 z: 1.0]; //  rotate same coords again on x axis x degrees newMatrix = [self matrixRotate: newMatrix angle: rotateX x: 1.0 y: 0.0 z: 0.0]; //  rotate same coords again on y axis y degrees newMatrix = [self matrixRotate: newMatrix angle: rotateY x: 0.0 y: 1.0 z: 0.0]; newCoords = [self matrixVmul: newMatrix with: coords];```

The first rotation was applied three times, the second on two times, and the last one once...

- Sohta
Member
Posts: 72
Joined: 2006.10
Post: #7
Just thought of something.
If you want to save yourself all this trouble, you CAN use gluProject(). It simply is a matter of passing identity as the projection matrix instead of the one you fetch from GL.

- Sohta
hyn
Unregistered

Post: #8
Yes, I just realized that and changed it.
It fixed the starting position but the excess rotation is still there.
It looks like a math problem, I will check my code again... I would paste it if I could but the code is on my other computer.
hyn
Unregistered

Post: #9
And it would return object-space coordinates?
Member
Posts: 72
Joined: 2006.10
Post: #10
Simple, The modelview matrix, tranforms GL coordinates into GL coordinates ( think as in a camera ), the projection matrix transforms ( projects ) GL coordinates into screen coordinates. That's their respective purpose... So if you ignore the projection matrix, you get whatever transformation you wanted.

gluProject is a simple mathematical function:
it takes the input vector, multiplies it by both passed matrices, and returns the result...

Code:
```GLfloat lIdentity[16] = {... } ; GLFloat lModelView[16] ; glPushMatrix(); glLoadIdentity(); glRotatef( 23.5, 0.0  , 0.0 , 1.0 ) ; glRotatef( rotateX , 1.0 , 0.0 , 0.0 ) ; glRotatef( rotateY , 0.0 , 1.0 , 0.0 ); glGetfloatfv( GL_MODELVIEW_MATRIX , lModelView ) ; gluProject( x , y , z , lModelView , lIdentity , &outX , &outY , &outZ ); glPopmatrix();```

Edit: HEY! your post changed! mine doesn't make much sense anymore

- Sohta
hyn
Unregistered

Post: #11
Yeah, sorry. I misread your post, I thought you wrote "pass in identity as modelview matrix".

I tried your approach, though, passing in identity as projection matrix. I actually got window coordinates.
Member
Posts: 72
Joined: 2006.10
Post: #12
You shouldn't just read the modelview matrix ( since it also contains the camera transformations ). Instead, you should do as in the sample code I wrote:

push it
apply transformations
pop it

- Sohta
hyn
Unregistered

Post: #13
Hm. I still get window coordinates.
Sample values:

Code:
```2004-08-04 20:30:22.609 appname[7689] Coords: 689.033813, 614.114014, 0.854608 2004-08-04 20:30:22.609 appname[7689] Coords: 674.286987, 646.422302, 0.817250 2004-08-04 20:30:22.609 appname[7689] Coords: 425.501709, 505.337494, 0.970633 2004-08-04 20:30:22.686 appname[7689] Coords: 731.874939, 598.971802, 0.849627 2004-08-04 20:30:22.687 appname[7689] Coords: 689.033813, 614.114014, 0.854608 2004-08-04 20:30:22.687 appname[7689] Coords: 674.286987, 646.422302, 0.817250 2004-08-04 20:30:22.687 appname[7689] Coords: 425.501709, 505.337494, 0.970633 2004-08-04 20:30:22.711 appname[7689] Coords: 731.874939, 598.971802, 0.849627 2004-08-04 20:30:22.711 appname[7689] Coords: 689.033813, 614.114014, 0.854608 2004-08-04 20:30:22.711 appname[7689] Coords: 674.286987, 646.422302, 0.817250 2004-08-04 20:30:22.711 appname[7689] Coords: 425.501709, 505.337494, 0.970633 2004-08-04 20:30:22.731 appname[7689] Coords: 731.874939, 598.971802, 0.849627 2004-08-04 20:30:22.732 appname[7689] Coords: 689.033813, 614.114014, 0.854608 2004-08-04 20:30:22.732 appname[7689] Coords: 674.286987, 646.422302, 0.817250 2004-08-04 20:30:22.732 appname[7689] Coords: 425.501709, 505.337494, 0.970633 2004-08-04 20:30:22.795 appname[7689] Coords: 731.874939, 598.971802, 0.849627 2004-08-04 20:30:22.811 appname[7689] Coords: 689.033813, 614.114014, 0.854608 2004-08-04 20:30:22.826 appname[7689] Coords: 674.286987, 646.422302, 0.817250 2004-08-04 20:30:22.840 appname[7689] Coords: 425.501709, 505.337494, 0.970633```

And my code:

Code:
```glPushMatrix();         glLoadIdentity();         glRotatef(kEarthTilt, 0.0, 0.0, 1.0);         glRotatef(earthRotateX, 1.0, 0.0, 0.0);         glRotatef(earthRotateY, 0.0, 1.0, 0.0);         glGetDoublev(GL_MODELVIEW_MATRIX, modelview);         glGetIntegerv(GL_VIEWPORT, viewport);                  gluProject(coords.x, coords.y, coords.z, modelview, projection, viewport, &currentPosition[0], &currentPosition[1], &currentPosition[2]);                  coords.x = currentPosition[0];         coords.y = currentPosition[1];         coords.z = currentPosition[2];         NSLog(@"Coords: %f, %f, %f", coords.x, coords.y, coords.z);                  glPopMatrix();```
Member
Posts: 72
Joined: 2006.10
Post: #14
sry, I completely forgot, glProject also uses the viewPort ...

Honestly, though, what you really should do is search the web for gluProject, have a look at the maths involved behind it and understand how it works for yourself.

However, I will give you the answer, since I commited myself to help you on this one.

the viewPort should be { 0 , 0 , 1 , 1 }

- Sohta
hyn
Unregistered

Post: #15