Sign in to follow this  
litebox

Get rotation quaternion between two vectors

Recommended Posts

Hi, I realize some model, when player (first person camera) can "get" objects in game world and carries it in another place. I have some feeler ahead the player's camera, that check intersection with objects, and when it is, then user can get intersected object and move it. It's works, but I have one fault - I don't take into account different between object center and intersection point (see screenshot):
[attachment=1853:rotationQuat.jpg]


So when I apply to moved object modelFeelerView transformation matrix:
[code]
mat4 modelView = actor.getIModelview(); // matrix of player's camera
mat4 modelFeelerView = modelView * ::translate(vec3(0, 0, -2)); // calculate object transformation - this location in 2 meters ahead the camera[/code]
Then object twitch - his center moved to modelFeelerView-position, so I need add offset vector between objectPos and intersectionPos.

If I add some values in vec3(0, 0, -2) x and y I get necessary result, and If I do next:
[code]
mat4 modelView = actor.getIModelview(); // matrix of player's camera
mat4 modelFeelerView = rotationQuat * modelView * ::translate(vec3(0, 0, -2)); // calculate object transformation - this location in 2 meters ahead the camera and use some rotation of it
[/code]

I get necessary result too.
But problem is that I can't calculate right rotation quaternion or calculate right offset vector.
Second problem, that (I think) I need do all calculations in local camera's coordinate system, cause when I "come up" to object in different directions, I get very different results.
Any ideas how it can be done with vectors, quaternions or matrix transformations? Thanks

Share this post


Link to post
Share on other sites
Any rotation actually equals the product of two reflections, and in your case, a possible pair of reflections are to first reflect over your first vector, and then over the vector half way between your two vectors (both scaled to have length 1):

v1 = normalize(intersectionPos)
v2 = normalize(normalize(intersectionPos) + normalize(objectPos))

Now if you store your vectors as quaternions, with a real part of 0, and an imaginary part that corresponds to your vector, then the dot product can be written as follows:

dot(a,b) = -(ab + ba)/2

And the formula for reflection is
x' = x - 2n dot(n,x)

So we have
x' = x - 2n dot(n,x)
x' = x - 2n (-(nx + xn)/2)
x' = x + nnx + nxn
x' = x - x + nxn
x' = nxn

So the rotation is
x' = v_2 v_1 n v_1 v_2
x' = conj(v_1v_2) n (v_1 v_2)

Share this post


Link to post
Share on other sites
Thanks for answer. But I don't understand some moments (
[color=#1C2837][size=2]what is "[/size][/color][color=#1C2837][size=2]conj" and w[/size][/color][color=#1C2837][size=2]hat is "n"?[/size][/color]

Share this post


Link to post
Share on other sites
I'm sorry, I actually made a typo. With n, I just mean any normal vector of a plane you want to reflect in.

[size="2"][color="#1C2837"]But in the last two lines I actually meant x (ie. the vector you want to rotate)[/color][/size]
[color=#1C2837][size=2]
[/size][/color]
[color=#1C2837][size=2]x' = v2 v1 x v1 v2
x' = conj(v1 v2) x (v1 v2) [/size][/color]
[color=#1C2837][size=2]
[/size][/color]
[color=#1C2837][size=2]conj(x) is the quaternion conjugate, ie, the quaternion x, with the sign of the imaginary parts changed.[/size][/color]
[color=#1C2837][size=2]
[/size][/color]
[color=#1C2837][size=2]You probably know that to rotate a vector x by a quaternion h, you have to compute[/size][/color]
[color=#1C2837][size=2]
[/size][/color]
[color=#1C2837][size=2]x' = conj(h)xh[/size][/color]
[color=#1C2837][size=2]
[/size][/color]
[color=#1C2837][size=2]and it just so happens that if two quaternions v1 and v2 have 0 real part, then conj(v1 v2) = v2 v1, so to get your rotation quaternion, all you have to do [/size][/color]
[color=#1C2837][size=2]is compute v1 and v2, and then multiply them. The result thereof is the quaternion you want.[/size][/color]

Share this post


Link to post
Share on other sites
I have always found the ModelView term confusing :D. In any case, this is how I would do this (using my own matrix terms). The reference is world coordinate system - I think it is better to keep calculations in world space in case you want to add collisions and such later.
First the matrixes:

O2W - ObjectToWorld - object local coordinate system (if not rotated, it is simply translate(center) )
W2O - WorldToObject - inverse of O2W
V2W - ViewToWorld - the local coordinate system of camera (player)
W2V - World3View - inverse of V2W

Now, if you want to attach the object to camera (player), you can calculate the transformation matrix from object local coordinate system to camera coordinate system at the moment when it is attached

O2V = W2V * O2W

Now the following is always true:

O2W = V2W * O2V

And while the object is "attached" to camera, the O2V is constant and you can use this formula, to calculate the new object position (local coordinate system relative to world) each frame.

If you have to adjust object in some way (like keep box side aligned to viewer), you have to modify O2V matrix the moment object is picked up - like removing rotation.

Share this post


Link to post
Share on other sites
Thanks god, it works! :)
[b]lauris71[/b], thanks a lot for clearly, nice and, [font=Arial, sans-serif][size=2]most importantly, workable pattern! :) I break my mind while I try to find right transform matrix ))[/size][/font]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this