The difference between the two quaternions

solvable


I create a 3D portal system in my engine (for example, a game in Portal). Each of the portals has its own orientation stored in the quaternion. To display a virtual scene in one of the portals, I need to calculate the difference between the two quaternions, and use the result to rotate the virtual scene.

When creating the first portal on the left wall and the second on the right wall, the rotation from one to the other will occur only on one axis, but, for example, when the first portal is created on the floor and the second on the right wall, rotation from one to the other can be two axes, and this problem, because the rotation goes wrong.

I think the problem exists because the orientation, for example the X axis and the Z axis, are stored together in the same quaternion, and I need this separately for manual multiplication of X * Z (or Z * X ), but how to do this with only one quaternion (difference quaternion)? Or is there another way to fix the rotation of the scene?

EDIT:

Here, in this figure, there are two ports P1 and P2, the arrows show how they rotate. When I look at P1, I will see what P2 is seeing. To find the rotation that I need to rotate the main scene to be like a virtual scene in this shot, I do the following:

  • Getting the difference from Quaternion P2 to Quaternion P1
  • 180 Degree Rotating Y-axis (UP Portal)
  • Using the result to rotate a virtual scene

This method above only works when the difference occurs with only one axis. When one portal is on the floor or on the ceiling, this will not work, because the difference quaternion is built on more than one axis. As suggested, I tried to multiply the quaternion P1 by the quaternion P2 and vice versa, but this does not work.

enter image description here

EDIT 2:

To find the difference from P2 to P1, I do the following:

 Quat q1 = P1->getOrientation(); Quat q2 = P2->getOrientation(); Quat diff = Quat::diff(q2, q1); // q2 * diff = q1 // 

Here's the Quat :: diff function:

 GE::Quat GE::Quat::diff(const Quat &a, const Quat &b) { Quat inv = a; inv.inverse(); return inv * b; } 

Inverse:

 void GE::Quat::inverse() { Quat q = (*this); q.conjugate(); (*this) = q / Quat::dot((*this), (*this)); } 

Paired:

 void GE::Quat::conjugate() { Quat q; qx = -this->x; qy = -this->y; qz = -this->z; qw = this->w; (*this) = q; } 

Spot product:

 float GE::Quat::dot(const Quat &q1, const Quat &q2) { return q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w; } 

Operator *:

 const GE::Quat GE::Quat::operator* ( const Quat &q) const { Quat qu; qu.x = this->w*qx + this->x*qw + this->y*qz - this->z*qy; qu.y = this->w*qy + this->y*qw + this->z*qx - this->x*qz; qu.z = this->w*qz + this->z*qw + this->x*qy - this->y*qx; qu.w = this->w*qw - this->x*qx - this->y*qy - this->z*qz; return qu; } 

Operator/:

 const GE::Quat GE::Quat::operator/ (float s) const { Quat q = (*this); return Quat(qx / s, qy / s, qz / s, qw / s); } 

All this works because I tested it with the GLM library

+8
math rotation quaternions
source share
5 answers

I solved my problem. As it turned out, I do not need the difference between the two rotations. Just multiply one rotation by 180 degrees rotation, and then multiply by the inverse second rotation this 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 calculating the translation in this way:

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

If you want to find a diff quaternion such that diff * q1 == q2 , 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 quaternions of rotation, they should all be units of quaternions. This makes finding the opposite easy: since abs(q1) = 1 , your inverse(q1) = conjugate(q1) can be found simply by negating the components i , j and k .


However, to describe the geometric configuration based on the scene, you probably don't really want to do this because you also need to calculate the translation correctly.

The easiest way to do it right is to convert your quaternions into 4x4 rotation matrices and multiply them in the appropriate order using 4x4 transformation matrices, as described in most introductory computer graphics.

Of course, you can compose Euclidean transformations manually, keeping your rotations in the form of a quaternion while applying quaternions to a separate translation vector. However, this method tends to be technically obscure and prone to coding errors: there are good reasons why the 4x4 matrix form is common, and one of the big ones is that it seems easier to do it right.

+9
source share

No, you need to multiply the two quaternions together to get the final quaternion that you want.

Say your first rotation is q1 and the second is q2 . You want to apply them in this order.

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

Link

For a quick guide on calculating one quaternion, refer to my previous answer on stack overflow

Edit:

To clarify, you would run into a similar problem with rotation matrices and Euler angles. You define your transforms with respect to X, Y, and Z, and then multiply them together to get the resulting transformation matrix ( wiki ). You have the same problem. Rotation matrices and quaternions are in most cases equivalent to the representation of rotations. Quaternions are preferable mainly because they are slightly easier to imagine (and easier to remove gimbal locks)

+1
source share

Quaternions work as follows: the local reference system is represented in the form of imaginary directions of the quaternion i, j, k. For example, for an observer standing in the portal door 1 and looking in the direction of the arrow, the direction i can represent the direction of the arrow, j is up and k = ij indicates to the right of the observer. In global coordinates represented by quaternion q1, axes in three-dimensional coordinates

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

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

Now the task is to find the unit quaternion q, so that the 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, which means that the forwards become inverse and the left becomes correct, i.e.

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

which is easily achieved by equating

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

But the details can be different, mainly that the other axis can represent the up direction instead of j.


If the global sketch system 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 implemented by

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

as

 (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 with the actual values โ€‹โ€‹in your implementation will show how to change the axis and direction of the quaternions.

+1
source share

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

Imagine, to get dQ from Q1 to Q2, I will explain why dQ = Q1 * ยท Q2 instead of Q2 ยท Q1 *

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

This is not Q ยท v ยท Q *, which is the action of rotating an object.

If you rotate 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

-one
source share

All Articles