Archived

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

antknei2

quaternion rotation

Recommended Posts

Dobbs    164
Here''s one way to do it, Game Programming Gems called this a "shortest arc quaternion". Vector v1 is the initial direction and v2 is the desired direction, and they should both be unit vectors. The * and / operators for the vectors are the cross and dot product respectively. CQuaternion and CVector are just some basic classes I wrote, they shouldn''t require any explanation.

CQuaternion result;
CVector v3 = v1 * v2;
float d = v1 / v2;
float s = sqrtf((1+d)*2);
result.x = v3.x / s;
result.y = v3.y / s;
result.z = v3.z / s;
result.w = s / 2.0f;
return result;

You''ll probably want to use interpolation techniques like slerp to produce a smooth transition between the two orientations.

Share this post


Link to post
Share on other sites
johnb    351
quote:
Original post by Dobbs
Here''s one way to do it, Game Programming Gems called this a "shortest arc quaternion". Vector v1 is the initial direction and v2 is the desired direction, and they should both be unit vectors. The * and / operators for the vectors are the cross and dot product respectively. CQuaternion and CVector are just some basic classes I wrote, they shouldn''t require any explanation.

CQuaternion result;
CVector v3 = v1 * v2;
float d = v1 / v2;
float s = sqrtf((1+d)*2);
result.x = v3.x / s;
result.y = v3.y / s;
result.z = v3.z / s;
result.w = s / 2.0f;
return result;

You''ll probably want to use interpolation techniques like slerp to produce a smooth transition between the two orientations.


Note that the above code fails (with a divide by zero exception) if v1 and v2 are in opposite directions: for this situation no unique solution and it''s best to just pick an arbitrary axis (v3 in the above code) at right angles to the two inputs: just pick a random vector not parallel to the input vectors and cross product it with one of them, and use pi as the angle of rotation.

Share this post


Link to post
Share on other sites
pixelstar    122
I''m using the above shortest quaternion arc method. It works fine(I think). I''m having a strange problem though.
I want to concatenate the results.
Here''s an abstract example of what I mean:
angle 0 to 20 = +20
angle 20 to 40 = +20
angle 40 to 60 = +20
such that I''d get:
0 to 20 + 20 to 40 + 40 to 60
which should get me:
20 + 40 + 60 = 120
(of course I''m ignoring axis here but you get the picture)
Here''s what I''m doing:

QuaternionIdentity(rotation_sum); a=0;
do {
Normalize(vec1[ a ]);
Normalize(vec2[ a ]);
ShortestArcQuaternion(quat,vec1[ a ],vec2[ a ]);
QuaternionMultiply(rotation_sum,rotation_sum, quat);
CopyQuaternion(FrameRotationOffsetFromZero, rotation_sum);
a++;
}while(a
I''m fairly new to using quaternions in my code. Before I was using YawPitchRoll but changed to pure quaternions. Am I doing something wrong(or perhaps stupid)?

Share this post


Link to post
Share on other sites
minorlogic    150
The code in GPG is naive, complicated and not robust, it is shame that such a code can be found in GPG.
The solution of the problem descreabed by Ken Shoemake in the :

http://www.faqs.org/faqs/graphics/algorithms-faq/
..
5.26: How can I aim a camera in a specific direction?
..

And the related code and math can be found:

http://www.martinb.com/maths/algebra/vectors/angleBetween/index.htm

Recomend to all read the Shoemake''s tutorial, it is best.


Share this post


Link to post
Share on other sites
Bucko    112
The code in GPG does not work as advertised either.
Generate two vectors v0, v1.
Generate a quaternion using the code in the book.
Apply the quaternion to code v0 and it will have rotated about halfway towards v1. This would work splendidly when you want to orient a missile toward a target (it would home in over several frames) but the code does not generate a q rotating v0 into v1.

Share this post


Link to post
Share on other sites