Jump to content
  • Advertisement
Sign in to follow this  
spek

Rotating a vector

This topic is 4358 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, Probably this is a simple question for you, but I'm a disaster with math. I have a vector (a normal). I want to rotate it 90 degrees up,down,left or right. Uhmm... that's it. How to do that? The Y+ axis is upwards in my case by the way. [edit] Maybe I should give some extra details. The code is used for rendering a hemicube. I know a camera and a direction(the normal). I put the camera on that point, and first I render "forward". forward==normal. But I also need to take a snapshot from the left/right/up and down from that vector. Greetings, Rick

Share this post


Link to post
Share on other sites
Advertisement
The way is use a rotation matrix. The rotation matrix is composed of the direction vectors for the x,y,z axes. If you are using DirectX, OpenGL or another engine you can use the functions of the API/engine...functions like D3DXMatrixYawPitchRoll() of d3dx can do this work.

Build the rotation matrix and then its just multiply it by the vector:
Rotation Matrix:
|Rxx Ryx Rzx|
|Rxy Ryy Rzy|
|Rxz Ryz Rzz|

The first colum is the x,y,z direction of the X axis, the 2nd is the y and the 3rd is the Z.

|Rxx Ryx Rzx| |vx|
|Rxy Ryy Rzy|* |vy|
|Rxz Ryz Rzz| |vz|

Multiply line by collum.

you'll get the rotated vector:

[Rxx*vx + Ryx*vy + Rzx*vz, Rxy*vx + Ryy*vy + Rzy*vz, Rxz*vx + Ryz*vy + Rzz*vz]

This is the way to go...using this method you can rotate your vector in any angle in any axis. Its just build the rotation matrix and the multiply it by the vector.

Hope this helps and also hope I didnt say anything wrong ;)

Share this post


Link to post
Share on other sites
I can use OpenGL multMatrix, but I like to calculate the rotated vector without. So, if I understand it right, my code should look like this:

result.x = Rxx*normal.x + Ryx*normal.y + Rzx*normal.z;
result.y = Rxy*normal.x + Ryy*normal.y + Rzy*normal.z;
result.z = Rxz*normal.x + Ryz*normal.y + Rzz*normal.z;

Where result is the final direction for the camera.

However, I don't know what to fill for those Rxx,Rxy etc. values. Sorry, I'm not good in this stuff!

For example, I want to rotate to the left. Rxx,Rxy and Rxz represent the X-axis. Does that mean:
Rxx = -1
Rxy = 0
Rxz = 0
Assuming that normally Y+ is up, Z+ is forwards, and X+ is to the right? Ifso, what to fill for the other 2 axises?

Thanks for helping!
Rick

Share this post


Link to post
Share on other sites
These matrices will rotate the vector clockwise, just multiply it to the correct matrix.

2d:

|cos(theta) sin(theta) |
|-sin(theta) cos(theta)|





3d:

(around the x axis)
|1 0 0 |
|0 cos(theta) sin(theta)|
|0 -sin(theta) cos(theta)|

(around the y axis)
|cos(theta) 0 -sin(theta)|
|0 1 0|
|sin(theta) 0 cos(theta)|

(around the z axis)
|cos(theta) sin(theta) 0|
|-sin(theta) cos(theta) 0|
| 0 0 1|


Share this post


Link to post
Share on other sites
I think I'm still doing it wrong. I got this function:

function rotateVector( const dir : vector3f; const facing : integer ) : vector3f;
begin
case facing of
C_FORWARD : result := dir;
C_RIGHT : begin
result[0] := 1*dir[0] + 0 *dir[1] + 0 *dir[2];
result[1] := 0*dir[0] + cos(90) *dir[1] + sin(90)*dir[2];
result[2] := 0*dir[0] + -sin(90)*dir[1] + cos(90)*dir[2];
end;
C_LEFT : begin
result[0] := 1*dir[0] + 0 *dir[1] + 0 *dir[2];
result[1] := 0*dir[0] + cos(-90) *dir[1] + sin(-90)*dir[2];
result[2] := 0*dir[0] + -sin(-90)*dir[1] + cos(-90)*dir[2];
end;
C_DOWN : begin
result[0] := cos(90))*dir[0] + 0*dir[1] + -sin(90)*dir[2];
result[1] := 0 *dir[0] + 1*dir[1] + 0 *dir[2];
result[2] := sin(90) *dir[0] + 0*dir[1] + cos(90) *dir[2];
end;
C_UP : begin
result[0] := cos(-90)*dir[0] + 0*dir[1] + -sin(-90)*dir[2];
result[1] := 0 *dir[0] + 1*dir[1] + 0 *dir[2];
result[2] := sin(-90)*dir[0] + 0*dir[1] + cos(-90) *dir[2];
end;
end;
end; // rotateVector

Notice that cos and sin use radians, but I removed the conversion so its easier to read.

Probably I'm using it wrong, or doing the multiplication wrong. For examply, if i want to rotate the vector {1,0,0} 90 degrees to the "left" (90 degrees counter clockwise around X axis), I get the same result as facing forward or to the right.

Left/right/up/down are a little bit strange of course. What is "left"? I mean the left side of the hemicube I try to render.

Greetings,
Rick

Share this post


Link to post
Share on other sites
Note that cos(90), sin(90), cos(-90) and sin(-90) are constants so you can simply write 0, 1, 0, -1 instead.
I find quite difficult to understand what you mean with up, right... There are 6 direction of rotation in 3d but in your code there are only 4 of these.

Share this post


Link to post
Share on other sites
Sorry, its difficult for me to explain.

I'm trying to render a hemiCube. This cube has 5 faces (front,left,right,top,bottom). To be more precise, I'm trying to make a tool that generates radiosity lightmaps. So for each patch in the world, I need to measure the surrounding area. I do that by using hemiCubes.

I render this cube by placing the camera on some point. That's simple. First I render the front face. That's simple as well. For each point, I also got a normal. So I simply use that normal as the camera viewing direction. But now I need to rotate that direction if I want to render left,right,top and bottom.

Thanks for helping everybody!
Rick

Share this post


Link to post
Share on other sites
So if I understand correctly your front face is oriented in the direction of the normal and the other face in the direction of up, left, right vectors... You don't need to do rotations. You need to define an up or a left vector. You can use the cross product to find all the vectors you need.
For example if you define the normal and the up vectors you can find all the other vectors with these formulas:
left = cross(up, normal)
right = cross(normal, up)
down = cross(left, normal)

Share this post


Link to post
Share on other sites
Thanks for the help! But... It's still not correct. When the normal is {0,0,1}, the result seems to be correct. But when I try with another vector, for example {1,0,0} as normal, the right,up and down are exactly the same vectors. These are the results with normal {1,0,0}:

forward = {1,0, 0} // correct
left = {0,0,-1} // correct
right = {0,0,+1} // correct
up = {0,0, 0}
down = {0,0, 0}

So, up and down are not correct in this case. This is my code now:

glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPerspective(90, 1, 0.01, 1000);
glMatrixMode(GL_MODELVIEW);

{ dir = the normal, pos = camera position }
case facing of
C_FORWARD : target := dir;
C_LEFT : target := cross( vector(0,1,0) , dir );
C_RIGHT : target := cross( dir, vector(0,1,0) );
C_UP : target := cross( dir, vector(1,0,0) );
C_DOWN : target := cross( vector(1,0,0) , dir );
end;

glLoadIdentity;
camera.Direction := target;
camera.Position := pos;
camera.Apply;

// Cross product function:
function cross( const v1, v2 : vector3f ) : vector3f;
begin
result[X] := v1[Y]*v2[Z] - v1[Z]*v2[Y];
result[Y] := v1[Z]*v2[X] - v1[X]*v2[Z];
result[Z] := v1[X]*v2[Y] - v1[Y]*v2[X];
end;


Maybe I use the wrong up/left vector? But in that case, how to know the proper up/left vector?

Greetings,
Rick

Share this post


Link to post
Share on other sites
Quote:
Original post by spek
I can use OpenGL multMatrix, but I like to calculate the rotated vector without. So, if I understand it right, my code should look like this:



result.x = Rxx*normal.x + Ryx*normal.y + Rzx*normal.z;

result.y = Rxy*normal.x + Ryy*normal.y + Rzy*normal.z;

result.z = Rxz*normal.x + Ryz*normal.y + Rzz*normal.z;


Where result is the final direction for the camera.


It is correct.
The rotation matrix is composed of three vectors where they're all perpendicular. It is like the axis of the world origin x,y,z but you can rotate it...think about rotate the world axis, it is what you do with rotation matrices: you rotate the three vectors in a way that they're always perpendicular. There're several ways of rotate a matrix: create a rotation matrix for the rotation in each axis and then multiply them, rotate a matrix by a deirection vector axis, rotate a matrix by a quaternion...google for and you'll find out how to create these kinds of rotation matrices. I'll explain the most basic one: rotate by x axis and then by y and then by z axis and finally multiply each one.

To rotate by the X axis you must do:

| 1 0 0 |
| 0 cos a -sin a |
| 0 sin a cos a |


By the Y axis

| cos a 0 sin a |
| 0 1 0 |
| -sin a 0 cos a |


By the Z axis

| cos a -sin a 0 |
| sin a cos a 0 |
| 0 0 1 |


I've written it by analizing how it works so I hope theres nothing wrong :P...Did you understand? Play with these matrices for you to know how them work. create some situations to rotate a matrix and do the computations by hand and see the results. I'm sure you'll understand how it works this way...it is funny ;)!...

lets supose you want to rotate a matrix in 30 degrees in the Y axis (yaw) and then by 60 degrees in the X axis(pitch). Remeber that the rotations are local here soh rotate by Y and then by X is different of rotate by X and then by Y. Its just build the matrices the way I've shown above and then multiply then in the correct order: Y * X, and you'll get the rotation matrix. if you multiply it by the vector you'll rotate the vector by the matrix.

I dont know what more should I talk but I hope the things I talked are usefull and I hope you've understand how it works.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!