Search Unity

How to Mirror a Euler Angle or Rotation

Discussion in 'Scripting' started by largo65, May 25, 2011.

  1. largo65

    largo65

    Joined:
    May 12, 2010
    Posts:
    12
    Hi,
    I was wondering what is the best way to mirror a local euler angle or rotation of an object by an axis.(See attached image)

    I have two objects, one located at (1,0,0) and the other (-1,0,0) and then I'm rotating one object to get the mirror effect on the other, but I'm not having any luck messing with the values in the eulers and rotation themselves:

    Code (csharp):
    1. public class Mirror : MonoBehaviour
    2. {
    3.     public Transform obj1;
    4.     public Transform obj2;
    5.  
    6.     void Update ()
    7.     {  
    8.         obj2.localRotation = new Quaternion(obj1.localRotation.x * -1.0f,
    9.                                             obj1.localRotation.y,
    10.                                             obj1.localRotation.z,
    11.                                             obj1.localRotation.w);
    12.    
    13.     }
    14. }
    Is there a special method in the Quaternion or Vector3 class to achieve this effect? ( or some other way :))
     

    Attached Files:

    Aestial likes this.
  2. Marrrk

    Marrrk

    Joined:
    Mar 21, 2011
    Posts:
    1,032
  3. largo65

    largo65

    Joined:
    May 12, 2010
    Posts:
    12
    Thanks alot Marrrk! :) The solution is to have the "w" in the rotation negative:

    Code (csharp):
    1. obj2.localRotation = new Quaternion(obj1.localRotation.x * -1.0f,
    2.                                             obj1.localRotation.y,
    3.                                             obj1.localRotation.z,
    4.                                             obj1.localRotation.w * -1.0f);
    5.  
    6.  
     
    Melanzue, Vagabond_, MM47 and 4 others like this.
  4. claudiohorvi

    claudiohorvi

    Joined:
    Sep 22, 2014
    Posts:
    1
    I know this is an old thread, but this is something that must be considered when the mirrored rotation is part of a sequence of rotations:
    - Any single rotation (x, y, z, w) is "almost" equivalent to (-x, -y, -z, -w). The "almost" is important as it introduces an extra twist. In itself it does not change the end result, but if you are doing any kind of interpolation, you get some side effects.
    - In the code published by largo65, the mirror of (w, x, y, z) is (-x, y, z, -w). Mathematically this is the mirror with the extra twist. The correct mirror, without the twist is (x, -y, -z, w) [as is explained by kdmiller3 in the link referred to by Marrk]

    I found out this problem when I used the proposed mirror rotations in a sequence of mirrored and non-mirrored rotations. The (-x, y, z, -w) mirror-rotations introduced the side effects during the interpolations, which were removed using the (x, -y, -z, w) mirror-rotations.
     
    doneykoo likes this.
  5. RonniHN

    RonniHN

    Joined:
    Aug 25, 2014
    Posts:
    4
    This works perfectly! Thanks :D
     
  6. BenVlodgi

    BenVlodgi

    Joined:
    Nov 20, 2014
    Posts:
    3
    claudiohorvi solution worked great for me, but only if the mirror was vertical.
    I found a better solution here [Maths - Reflection using Quaternions]
    This solution works for any orientation of the mirror plane.

    I am actually using this in Unreal, but this thread always popped up when I was searching for this topic, so I'm updating for posterity sake.

    psudocode below:
    Code (CSharp):
    1. var objectQuat; // from world rotation
    2. var mirrorNormalQuat = new Quaternion(plane.x, plane.y, plane.z, 0);
    3.  
    4. var reflectedQuat = mirrorNormalQuat * objectQuat * mirrorNormalQuat;
     
    Last edited: Sep 15, 2018
  7. customphase

    customphase

    Joined:
    Aug 19, 2012
    Posts:
    246
    Although this does mostly work well, for some reason it kept giving me a 180 degree rotation of mirrored rotation, if the normal was equal to Z+ or Z- axis. Which is weird, because with every other axis it worked as it should. So instead i went with a little more simple approach, which worked flawlessly for me:
    Code (CSharp):
    1. Vector3 forw = transform.forward;
    2. Vector3 mirrored = Vector3.Reflect(forw, mirrorNormal);
    3. transform.rotation = Quaternion.LookRotation(mirrored, transform.up);
     
    Last edited: Feb 10, 2019
    levi9000, JTLittle and kilik128 like this.
  8. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,769
    Quote old thread. But there is
    Quaternion.Inverse ( my quaternion );
    for that purpose
     
    kilik128 likes this.
  9. customphase

    customphase

    Joined:
    Aug 19, 2012
    Posts:
    246
    Thats not quite what we needed. We needed a mirror, not a reverse. Mirror operation requires a mirror plane normal.
     
    Airmouse and Antypodish like this.
  10. nomadic

    nomadic

    Joined:
    Mar 4, 2010
    Posts:
    44
    Code (CSharp):
    1.  
    2.     private Quaternion ReflectRotation(Quaternion source, Vector3 normal)
    3.     {
    4.         return Quaternion.LookRotation(Vector3.Reflect(source * Vector3.forward, normal), Vector3.Reflect(source * Vector3.up, normal));
    5.     }
     
  11. TheVirtualMunk

    TheVirtualMunk

    Joined:
    Sep 6, 2019
    Posts:
    150
    Posted a complete solution here with script for mirroring a gameobject(s) relative to a plane using information from this thread.
    Cheers!