Edison
Edison

Reputation: 61

Quaternion Rotation errors

Recently, I’m using the source to do rotation on my 3D models. However, a problem occurred when calling the function: RotationBetweenVectors, defined in Tutorial 17( link: http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-17-quaternions/). I want to rotate vector _from to vector _to using Quaternion method. Two vectors are defined as following and a quat between them is calculated.

vec3 _from(0, -0.150401f, 0.93125f),  _to(-0.383022f, -0.413672f, 1.24691f);
quat _rot = RotationBetweenVectors(_from, _to);

vec3 _to1 = _rot * _from;
vec3 _to2 = _rot * _from * inverse(_rot);

then I use this quat _rot to multiply vector _from. Unluckly, the result _to1 and _to2 are neither equal to vector _to.

_rot gives {x=0.0775952041 y=-0.140000001 z=-0.0226106234 w=0.986847401}
_to1 gives {x=-0.264032304 y=-0.285160601 z=0.859544873 }
_to2 gives {x=-0.500465572 y=-0.390112638 z=0.697992325 }

I appreciate it if any friend could help me out this problem? Thanks very much!

Upvotes: 2

Views: 1174

Answers (2)

Jadh4v
Jadh4v

Reputation: 130

I believe, you cannot multiply a vec3 to a quat, as you do below:

vec3 _to1 = _rot * _from;

You will have to convert _from from vec3 to a vec4 by adding a 1 in the forth place i.e.

vec4 _from2 = vec4(_from, 1);

Also, convert _rot from a quat to a 4x4 matrix, say _rot2. The tutorial you refer to, mentions that it can be done using:

mat4 RotationMatrix = quaternion::toMat4(quaternion);

Then you should be able to multiply _from2 to _rot2 to get the _to vector.

Upvotes: 0

Amadeus
Amadeus

Reputation: 10675

I see two problems here.

First, if you want a vector v1 to rotate and finish exactly at same position of vector v2, they must be of the same length.

In your case, _to has different length than _from. I suggest you to normalize them:

_to = normalize(_to);
_from = normalize(_from);

Second, as you have prompted, a rotation via quaternion is done by this operator:

v1 = quat * Pin * inverse(quat);

the problem is that Pin must be a quaternion too, not a vector (you have defined _from to be a vec3). Notice that, in your original operator, it could be rewritten as:

vec3 _to2 = (_rot * _from) * inverse(_rot);

where the inner parens results in a vec3 that is multiplied by inverse(_rot).

So, to solve this, it means that your operator must be something like that (a quaternion multiplication):

quat Pin = {0, _from};
quat result = _rot * Pin * inverse(_rot);

Now, you only need to convert this quaternion to a vec3 again:

_to2 = axis(result);

Upvotes: 2

Related Questions