Search Unity

Get the difference between two quaternions and add it to another quaternion

Discussion in 'Scripting' started by dienat, Jan 18, 2018.

Thread Status:
Not open for further replies.
  1. dienat

    dienat

    Joined:
    May 27, 2016
    Posts:
    417
    Hi,

    I would like to make this but with quaternions.

    Vector 3 A - Vector3 B = Vector3 C

    Vector3 D+=Vector3 C

    I want to get the difference of one quaternion variable in the actual frame and the last frame update and then add that difference to another quaternion

    Anyone knows how to do it?
     
  2. apushak

    apushak

    Joined:
    Jan 13, 2015
    Posts:
    5
    You can do this using quaternion multiplication. To get the difference C between quaternions A and B you do this:

    C = A * Quaternion.Inverse(B);

    To add the difference to D you do this:

    D = C * D;

    Because quaternion multiplication is not commutative, (A * B != B * A) it's important which quaternion is on the left side of the multiplication and which is on the right.
     
  3. Nir_Tevel

    Nir_Tevel

    Joined:
    Apr 23, 2019
    Posts:
    8
    Since transform.rotation is in world space, you don't always get the same results when comparing different rotations between objects.
    Consider this scenario:
    You want to get the delta from Transform A rotation to transform B rotation. B is not rotated at all.
    When you rotate A 30 degrees on the z axis, you get the delta: 0,0,0.26, 0.96
    If you rotate both A and B 180 degrees on the y axis and change the z rotation for A to 30 degrees, you get 0,0,-0.26,0.96
    Although the relative rotation between them is visually identical, the reported delta is different.

    You can fix this by comparing the rotation of each to the worlds' rotation and then comparing the results:

    Code (CSharp):
    1. aQuaternion = Quaternion.identity * Quaternion.Inverse(A.rotation);
    2. bQuaternion = Quaternion.identity * Quaternion.Inverse(B.rotation);
    3. deltaQuaternion = bQuaternion * Quaternion.Inverse(aQuaternion);
     
  4. AnKOu

    AnKOu

    Joined:
    Aug 30, 2013
    Posts:
    123
    Why the multiplication with the identity ? Doesn't the result is the same with and without ?
     
    Goularou, LuLusg, curbol and 2 others like this.
  5. luisfinke

    luisfinke

    Joined:
    Dec 2, 2017
    Posts:
    8
    For everyone that comes to this question from a google search like me, the order of multiplication in this answer is actually wrong.
    If you are trying to get the difference
    c
    between two quaternions
    a
    and
    b
    , such that
    a + c = b
    and
    b - c = a
    , the correct formula is:
    diff = Quaternion.Inverse(from) * to
    to calculate the difference.
    Then you can get the value
    to
    with
    from * diff
    , and the value of
    from
    with
    to * Quaternion.Inverse(diff)


    this answer helped me understand why/how the rotation order works. Left side is the global rotation applied, right side is the local rotation.

    sorry for reviving an old thread but this is the top google search result for this question
     
    Last edited: Jun 7, 2022
  6. asdf34524

    asdf34524

    Joined:
    Jul 11, 2022
    Posts:
    1
    Actually, apushak is correct, at least in my testing.
    You can use this utility extension:
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public static class QuaternionExtensions
    4. {
    5.     public static Quaternion Diff(this Quaternion to, Quaternion from)
    6.     {
    7.         return to * Quaternion.Inverse(from);
    8.     }
    9.     public static Quaternion Add(this Quaternion start, Quaternion diff)
    10.     {
    11.         return diff * start;
    12.     }
    13. }
    14.  
    15. var diff = to.Diff(from);
    16. var result = start.Add(diff);
    17.  
     
  7. vakshaynayak

    vakshaynayak

    Joined:
    Aug 10, 2022
    Posts:
    1
    Bro you are god. you saved our project
     
    JonesyLeo likes this.
  8. EssencyStudios

    EssencyStudios

    Joined:
    May 18, 2018
    Posts:
    10
    Bro beers on me, I give italian chefs kiss MUAH MUAH each cheek, smooches you saved me and that post is gold
     
    Schiznitz3301 and JonesyLeo like this.
  9. BanzBowinkel

    BanzBowinkel

    Joined:
    Jun 17, 2015
    Posts:
    16
    This one worked for me! Thanks Nir!!
     
  10. kJlukOo

    kJlukOo

    Joined:
    Nov 20, 2021
    Posts:
    5
    great solution. work perfect for me
     
  11. eonyanov

    eonyanov

    Joined:
    Oct 6, 2014
    Posts:
    21
    I spent 4 hours combining different quaternion options. Thank you very much, you helped me!!!
     
  12. halley

    halley

    Joined:
    Aug 26, 2013
    Posts:
    2,439
    There's a Like button on every post to show appreciation without dredging up old threads on everyone's queue.
     
    Nad_B, Ryiah, Bunny83 and 1 other person like this.
  13. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,998
    Also that post everyone seems to hold up high may teach people the wrong idea because it's not really true / correct. Yes, there are different ways how you can look at certain problems, however the first claim that the multiplication order is "wrong" is actually wrong. Quaternions, especially in Unity, are multiplied right to left, just like matrices. So in order to apply a relative quaternion to a vector or another quaternion you have to place it before the vector / quaternion.

    So the question about the "diff" quaternion can be answered by starting with this:
    Code (CSharp):
    1. diff * from = to
    In order to get "diff" we have to divide both sides by from, so it becomes

    Code (CSharp):
    1. diff * from * inverse(from) = to * inverse(from)
    2. // shortened to
    3. diff = to * inverse(from)
    Quaternions are generally applied like this:

    Code (CSharp):
    1. vRot = Q3 * Q2 * Q1 * v
    Here Q1 is applied first, Q2 is applied to the result of Q1 and finally Q3. Those 3 rotations can be combined into one quaternion

    Code (CSharp):
    1. Q = Q3 * Q2 * Q1
    2. vRot = Q * v
    So what @apushak said in the second post is actually "correct". It may work the other way round, but you will just run into issues when you want to combine multiple rotations.
     
  14. TreyK-47

    TreyK-47

    Unity Technologies

    Joined:
    Oct 22, 2019
    Posts:
    1,821
    Locking this post as it's quite old. If you'd like to continue the convo, please create a new thread.
     
    Bunny83 likes this.
Thread Status:
Not open for further replies.