How to create a rotation matrix for this?

Started by
8 comments, last by Waterwalker 14 years, 10 months ago
Hello all, I have a 3D object displayed on the view. Assume that the direction pointing into the screen is (Vx, Vy, Vz)(perpendicular to the screen). In other words, the start of this vector is outside of the screen and the end of this vector is inside of the screen. The direction of the vector is determined by (Vx, Vy, Vz). Given a point P (Px, Py, Pz) on the vector, I need to rotate the whole view 180 degrees based on the point P so that the vector is pointing to outside of the screen. How do I implement this in OpenGL? In other words, how to compute the rotation matrix? Thank you -Daniel
Advertisement
I'm not sure what you're getting at here. So you have a vector which points "into the screen", by which I assume that you mean that this vector's view-space coordinates have a negative Z value. You can certainly rotate a vector 180 degrees, of course -- just negate it -- but I don't think that's what you're asking for. And you can rotate the view 180 degrees in many ways, but there's not any info you've given that would suggest which way you want. You mention a point "on the vector", but vectors have no location in space; it's meaningless to say that a point is on a vector or not on a vector.

What, exactly, are you trying to accomplish? In semantic terms, not math.
And what about the 3d object you mention ? Are you trying to rotate the object so that it's always facing the camera ?
Have you tried
glRotated(180,0,1,0);

This will spin your object 180 degrees about the y-axis. If your Up direction is not 0,1,0 then change your rotation vector accordingly
You can only rotate about the center point (0,0,0). However, if you want P to be your rotation center simply translate your coordinate system by -P, apply the rotation and then translate back by +P. In gl it looks something like that:

glMatrixMode(GL_MODELVIEW);glLoadIdentity();glTranslate(-p.x, -p.y, -p.z);glRotated(180, 0.0, 1.0, 0.0);glTranslate(p.x, p.y, p.z);


Obviously this assumes that you are using the standard up axis (0, 1, 0). If your camera can rotate about the x or z axis (thus changing the camera's up vector from the mentioned default) you need to set the corresponding vector to glRotated.

[Edited by - Waterwalker on June 6, 2009 11:07:16 AM]
------------------------------------I always enjoy being rated up by you ...
Hello all,

First, Thanks for all the helps.

I am sorry that I didn't describe the problem clearly at the first time. Let me try again as follows:

I have a 3D object displayed on the view. Given two points on the world coordinate V1 and V2, a line L can be determined by connecting the point V1 and V2. I choose the V1 and V2 so that the induced line L is always pointing into the screen and perpendicular to the screen. Now, I want to rotate the whole scene based on the point V1 and axis (0, 1, 0) on screen coordinate for 180 degrees. Thus, after the operation, the 3D object is flipped 180 degree and the induced line L will be pointing outside the screen.

How do I implement this in OpenGL? In other words, how to compute the rotation matrix?

Thank you
Just as I wrote. But here we go again to use your own notation

glMatrixMode(GL_MODELVIEW);glLoadIdentity();glTranslate(-V1.x, -V1.y, -V1.z);glRotated(180, view_up.x, view_up.y, view_up.z);glTranslate(V1.x, V1.y, V1.z);


To rotate around the point V1 you need to move this point to the origin, thus translating with its inverse. Then you rotate about 180 degrees on the choosen axis. In this case the up_vector of your current view. This is a vector perpendicular to your line (V1, V2) and pointing upwards. Above I have named this vector view_up since its the up vector of your local coordinate system. Finally, move the result of the transformation back to the location V1.

That's it.
------------------------------------I always enjoy being rated up by you ...
Make a matrix like this->

cross is up and line crossed together.
crossup is cross and line crossed together once youve crossed cross.
Make sure you normalize it before you do the second cross.
normalize up, line and cross.

cross.x cross.y cross.z ,0
crossup.x crossup.y crossup.z ,0
line.x line.y line.z ,1

its a 4x4 matrix, multiply it to everything you need to rotate
and what you want should happen.
Quote:Original post by rouncED
Make a matrix like this->

cross is up and line crossed together.
crossup is cross and line crossed together once youve crossed cross.
Make sure you normalize it before you do the second cross.
normalize up, line and cross.

cross.x cross.y cross.z ,0
crossup.x crossup.y crossup.z ,0
line.x line.y line.z ,1

its a 4x4 matrix, multiply it to everything you need to rotate
and what you want should happen.


Hello rouncED,

In fact, I was looking for the 4x4 matrix as you illustrated above because the system I am using now only accept a rotation matrix to do the rotation.
Here is the question:

I don't quite follow your annotation.

Q1> what is cross? crossup? line?
May you give me a little details.

Q2> the fourth row of the matrix is all ZERO?

Thank you
-Daniel

What rouncED posted was just the rotational part of the matrix and the last entry of the last line should be a 0 rather than a 1. What he aimed at was the general layout of a transformation matrix that boils down to:

right.x   right.y   right.z   0up.x      up.y      up.z      0dir.x     dir.y     dir.z     0pos.x     pos.y     pos.z     1


What you refered to as line from V1V2 in your own post can be considered the dir (direction) of your view. The up is the up vector of your view while right is the right vector of your view. Those three vectors are orthogonal to each other and span your view's coordinate system.

rouncED refered to right as cross which you can calculate by a vector cross product of dir (your line) and up as he pointed out. What he refered to as crossup is the recalculated up vector build by vector cross product of right (his cross) and dir (your line). Recalculating the up vector this way ensures the three vector right, up, and dir are orthogonal to each other.

But in the end this matrix does help you nothing because it describes the orientation of an object and you cannot build this from your input. Of course you could cheat and invert your line V1V2 (dir) and the right vector because you want to rotate about 180 degrees on the up vector thus effectively inverting the right and dir vectors of your orientation. But this would still lack the transformation of the rotation center to the origin which is imperative for your rotation to take effect at position V1.

To do what you want to do you need to do what I showed you. If you need a combined matrix of this operation read it back from OpenGL or use your own matrix class to perform the same operations like so:

Matrix4x4 inv_translation = Matrix4x4::Identity();Matrix4x4 translation = Matrix4x4::Identity();Matrix4x4 rotation = Matrix4x4::Identity();inv_translation.SetTranslation(-V1.x, -V1.y, -V1.z);rotation.BuildRotationMatrixForAxis(180 /* degrees */, up_vector);translation.SetTranslation(V1.x, V1.y, V1.z);Matrix4x4 composed_result = inv_translation * rotation * translation;


The method BuildRotationMatrixForAxis creates a rotation matrix for an arbitrary axis with the given angle in degrees. You can look up the equation in any linear algebra book or Google of course. The up_vector is your view's up axis, which is usually (0, 1, 0) if your camera can't tilt.
------------------------------------I always enjoy being rated up by you ...

This topic is closed to new replies.

Advertisement