#### Archived

This topic is now archived and is closed to further replies.

# Vector based rotation question

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

## Recommended Posts

I need to rotate an object based on its direction, so I looked into how rotation matrixes work. Here is some code I found (S1CA may find it farmilliar ) but it seems to be made for right-handed coords. EDIT: Changed code to working version for anyone who is interested

D3DXVECTOR3 vLook, vUp, vRight, vTemp = D3DXVECTOR3(0,1,0);

//get the normalised facing direction vector

D3DXVec3Normalize(&vLook, lpDirection);

//get right vector perpendicular to "facing" and another vector

D3DXVec3Cross(&vRight, &vLook, &vTemp);
D3DXVec3Normalize(&vRight, &vRight);

//get *real* up vector from other real vectors

D3DXVec3Cross(&vUp, &vLook, &vRight);
D3DXVec3Normalize(&vUp, &vUp);

//make final matrix

D3DXMatrixIdentity(lpRetMatrix);

lpRetMatrix->m00 = vRight.x;
lpRetMatrix->m01 = vRight.y;
lpRetMatrix->m02 = vRight.z;

lpRetMatrix->m10 = vUp.x ;
lpRetMatrix->m11 = vUp.y;
lpRetMatrix->m12 = vUp.z;

lpRetMatrix->m20 = vLook.x;
lpRetMatrix->m21 = vLook.y;
lpRetMatrix->m22 = vLook.z ;

//put the translation into the matrix

lpRetMatrix->m30 = lpPosition->x;
lpRetMatrix->m31 = lpPosition->y;
lpRetMatrix->m32 = lpPosition->z;

I invert the X axis of the look matrix, which works in most cases. Sometimes it doesn't though, how do I properly make a rotation matrix for left-handed systems? [edited by - Cybertron on May 7, 2002 5:55:10 PM]

##### Share on other sites
hi

to rotate an object around an arbitrary axis, you may use the D3DMatrixRotationAxis function, specifying the local Z (direction) axis of your object.

tibo

##### Share on other sites
1. Changing the order of the parameters for the cross product will get you the perpendicular in the opposite direction...

2. Negating Z is a more usual way to go between LHS and RHS.

3. There is one potential issue with that code (which I''m sure I mentioned at the time). If the lookAt direction is the same or exactly opposite to the temporary ''up'' vector (parallel to), then that code will fail. If you need to test for that (i.e. you''re ever looking straight up or straight down) you should test whether the vectors are parallel...

p = fabs( lookAt DOT tempUp )

if p=1 the tempUp is the same direction as the lookAt (or exactly opposite) so you you should choose a different tempUp - i.e. 0,0,1 or 1,0,0.

4. We use a slightly different form of the same kind of operation in our left handed stuff all the time (ours uses a dot product projection instead of the first crossproduct)

The code I posted was from memory though rather than tested code - try swapping one or both of the cross product orders.

--
Simon O''Connor
Creative Asylum Ltd
www.creative-asylum.com

##### Share on other sites
When I change the code that gets vRigh it works perfectly while panning horizontally, But when I pitch vertically it does not. Changing the code for vUp makes the object dissapear!

So reversing the order of the first Cross product fixes the horizontal differences of the LHS and RHS, but how do I fix the vertical differences?

##### Share on other sites
I fixed it, Here is the solution

lpRetMatrix->m00 = vRight.x;
lpRetMatrix->m01 = vRight.y;
lpRetMatrix->m02 = vRight.z;

lpRetMatrix->m10 = vUp.x ;
lpRetMatrix->m11 = vUp.y;
lpRetMatrix->m12 = vUp.z;

lpRetMatrix->m20 = vLook.x;
lpRetMatrix->m21 = vLook.y;
lpRetMatrix->m22 = vLook.z ;

It was just accessing the wrong item of the matrix, I noticed it while looking at some similar code that gets the vectors out of a matrix

##### Share on other sites
Aha - the old row major versus column major matrix issue. It happens to me once in a while too - particularly when reading books which have matrices the other way round or trying to plug matrices I''m familiar with into APIs I''m not so familiar with .

The way I personally confirm which way the matrix elements go is to see where translations get set - to the right or to the bottom.

BTW: Another way of finding out whether the direction vector is the same or exact opposite (parallel) to the temporary up vector is to check the vRight vector after you''ve done the first cross product. If all of it''s elements are 0, the two vectors are parallel and therefore you need to choose a different temporary up vector.

--
Simon O''Connor
Creative Asylum Ltd
www.creative-asylum.com

##### Share on other sites
The funny thing is using the wrong matrix positions is it still worked most of the time!

If the vectors are parallel and normalized, woudn''t the look vector have a Y value of 1 or -1? that would be faster than a dot or cross product

##### Share on other sites
quote:
Original post by Cybertron
The funny thing is using the wrong matrix positions is it still worked most of the time!

If the vectors are parallel and normalized, woudn''t the look vector have a Y value of 1 or -1? that would be faster than a dot or cross product

Using the matrix the other way round is simply doing a "transpose", which for a square rotation matrix such as the one you''re trying to create is also it''s inverse.

Checking the Y for 1 or -1 would also work (though you''ll have to check the range with epsilon - it''d be bad to simply do an "if (in.y == 1.0f)" since IEEE floats can''t always represent certain values exactly - particularly after maths operations between numbers of greatly different magnitude)

--
Simon O''Connor
Creative Asylum Ltd
www.creative-asylum.com