Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Add a quaternion to euler angles

Discussion in 'Scripting' started by rnner9000, Oct 2, 2020.

  1. rnner9000

    rnner9000

    Joined:
    Sep 6, 2020
    Posts:
    8
    In a game I want to display a rotation of an object. The user can then rotate the object by selecting an arbitary axis and dragging this axis by an angle (angle axis). After that the change by this rotation is calculated as a quaternion.

    Code (CSharp):
    1. var rot = Quaternion.AngleAxis(angle, axis); // get the desired rotation
    2.  
    3. // apply rotation to object
    4. transform.rotation *= Quaternion.Inverse(myRot) * rot * myRot;
    5. totalEulerAngles = AddQuaterionToEuler(totalEulerAngles, rot); // <-- this function is needed
    The rotation is displayed ingame as an euler angle. I could convert the resulting quaternion for this. However the euler angle will always be wrapped between 0 and 270 for each axis and {x: 180, y: 180, z: 0} might be displayed as {x: 0, y: 0, z: 180}.

    So a function is needed AddQuaternionToEuler that adds a quaternion to an existing euler angle. The resulting euler angle should be the total rotation with more then 360 degrees possible if the user rotates the object around itself.

    I have been searching for some hours for this but didn't find any approach on doing this.
     
  2. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,833
    In general, you could convert the Quaternion to Euler angles, then add the vectors.

    totalEulerAngles = totalEulerAngles + rot.eulerAngles



    But in your particular situation, you started with an axis rotation and converted it to a Quaternion. Rather than doing a round-trip conversion process that might-or-might-not give you back the original value...why not just add the original angle to the appropriate axis?

    Also, this line:
    transform.rotation *= Quaternion.Inverse(myRot) * rot * myRot;

    is just a complicated and expensive way of doing
    transform.rotation = rot * myRot;


    But if you're going to maintain a totalEulerAngles variable, you should probably instead use
    transform.eulerAngles = totalEulerAngles;

    otherwise, it's possible your Quaternion and your totalEulerAngles might slowly drift apart due to floating point error in the conversion process. (Probably not, but why give it the chance? Also, this approach probably save a little bit of math.)
     
    Joe-Censored likes this.
  3. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    if I understood this correctly, what you're missing is how to add two quaternions together to create a compound rotation.

    Code (csharp):
    1. var originalRotation = Quaternion.AngleAxis(angle, axis);
    2. var someUserRotation = Quaternion.Euler(eulerAngles);
    3. var compoundRotation = originalRotation * someUserRotation;
    4. // apply compoundRotation to object
    edit:
    nah I was mislead by your further explanation, check out Antistone's solution
     
    Last edited: Oct 2, 2020
    rnner9000 likes this.
  4. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,043
    actually, it appears to be just
    transform.rotation *= rot;


    Quaternion.Inverse(myRot) and myRot effectively cancel each other out
     
    rnner9000 likes this.
  5. rnner9000

    rnner9000

    Joined:
    Sep 6, 2020
    Posts:
    8
    Thank you thats what i was searching for!