Difference between the two quaternions

微笑、不失礼 提交于 2019-11-30 03:42:54

If you want to find a quaternion diff such that diff * q1 == q2, then you need to use the multiplicative inverse:

diff * q1 = q2  --->  diff = q2 * inverse(q1)

where:  inverse(q1) = conjugate(q1) / abs(q1)

and:  conjugate( quaternion(re, i, j, k) ) = quaternion(re, -i, -j, -k)

If your quaternions are rotation quaternions, they should all be unit quaternions. This makes finding the inverse easy: since abs(q1) = 1, your inverse(q1) = conjugate(q1) can be found by just negating the i, j, and k components.


However, for the kind of scene-based geometric configuration you describe, you probably don't actually want to do the above, because you also need to compute the translation correctly.

The most straightforward way to do everything correctly is to convert your quaternions into 4x4 rotation matrices, and multiply them in the appropriate order with 4x4 translation matrices, as described in most introductory computer graphics texts.

It is certainly possible to compose Euclidean transformations by hand, keeping your rotations in quaternion form while applying the quaternions incrementally to a separate translation vector. However, this method tends to be technically obscure and prone to coding error: there are good reasons why the 4x4 matrix form is conventional, and one of the big ones is that it appears to be easier to get it right that way.

I solved my problem. As it turned out I don't need any difference between two rotations. Just multiply one rotation by rotation in 180 degrees, and then multiply by inverse of second rotation that way (using matrices):

Matrix m1 = p1->getOrientation().toMatrix();
Matrix m2 = p2->getOrientation().toMatrix();
Matrix model = m1 * Matrix::rotation(180, Vector3(0,1,0)) * Matrix::inverse(m2);

and translation calculating this way:

Vector3 position = -p2->getPosition();
position = model * position + p1->getPosition();
model = Matrix::translation(position) * model;
AndyG

No, you have to multiply two quaternions together to get the final quaternion you desire.

Let's say that your first rotation is q1 and the second is q2. You want to apply them in that order.

The resulting quaternion will be q2 * q1, which will represent your composite rotation (recall that quaternions use left-hand multiplication, so q2 is being applied to q1 by multiplying from the left)

Reference

For a brief tutorial on computing a single quaternion, refer to my previous stack overflow answer

Edit:

To clarify, you'd face a similar problem with rotation matrices and Euler angles. You define your transformations about X, Y, and Z, and then multiply them together to get the resulting transformation matrix (wiki). You have the same issue here. Rotation matrices and Quaternions are equivalent in most ways for representing rotations. Quaternions are preferred mostly because they're a bit easier to represent (and easier for addressing gimbal lock)

Quaternions work the following way: the local frame of reference is represented as the imaginary quaternion directions i,j,k. For instance, for an observer standing in the portal door 1 and looking in the direction of the arrow, direction i may represent the direction of the arrow, j is up and k=ij points to the right of the observer. In global coordinates represented by the quaternion q1, the axes in 3D coordinates are

q1*(i,j,k)*q1^-1=q1*(i,j,k)*q1',

where q' is the conjugate, and for unit quaternions, the conjugate is the inverse.

Now the task is to find a unit quaternion q so that directions q*(i,j,k)*q' in local frame 1 expressed in global coordinates coincide with the rotated directions of frame 2 in global coordinates. From the sketch that means forwards becomes backwards and left becomes right, that is

q1*q*(i,j,k)*q'*q1'=q2*(-i,j,-k)*q2'
                   =q2*j*(i,j,k)*j'*q2'

which is readily achieved by equating

q1*q=q2*j or q=q1'*q2*j.

But details may be different, mainly that another axis may represent the direction "up" instead of j.


If the global system of the sketch is from the bottom, so that global-i points forward in the vertical direction, global-j up and global-k to the right, then local1-(i,j,k) is global-(-i,j,-k), giving

q1=j. 

local2-(i,j,k) is global-(-k,j,i) which can be realized by

q2=sqrt(0.5)*(1+j), 

since

(1+j)*i*(1-j)=i*(1-j)^2=-2*i*j=-2*k and 
(1+j)*k*(1-j)=(1+j)^2*k= 2*j*k= 2*i

Comparing this to the actual values in your implementation will indicate how the assignment of axes and quaternion directions has to be changed.

Check https://www.emis.de/proceedings/Varna/vol1/GEOM09.pdf

Imagine to get dQ from Q1 to Q2, I'll explain why dQ = Q1*·Q2, instead of Q2·Q1*

This rotates the frame, instead of an object. For any vector v in R3, the rotation action of operator L(v) = Q*·v·Q

It's not Q·v·Q*, which is object rotation action.

If you rotates Q1 and then Q1* and then Q2, you can write (Q1·Q1*·Q2)*·v·(Q1·Q1*·Q2) = (Q1*·Q2)*·Q1*·v·Q1·(Q1*·Q2) = dQ*·Q1*·v·Q1·dQ

So dQ = Q1*·Q2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!