Reputation: 61
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
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
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