How to Mirror a Euler Angle or Rotation

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:

public class Mirror : MonoBehaviour 
{
    public Transform obj1;
    public Transform obj2;

    void Update () 
    {   
        obj2.localRotation = new Quaternion(obj1.localRotation.x * -1.0f,
                                            obj1.localRotation.y,
                                            obj1.localRotation.z,
                                            obj1.localRotation.w);

    }
}

Is there a special method in the Quaternion or Vector3 class to achieve this effect? ( or some other way :))

586648--20879--$Image.jpg

1 Like

Maybe this thread may help you: http://www.gamedev.net/topic/599824-mirroring-a-quaternion-against-the-yz-plane/

Thanks alot Marrrk! :) The solution is to have the "w" in the rotation negative:

obj2.localRotation = new Quaternion(obj1.localRotation.x * -1.0f,
                                            obj1.localRotation.y,
                                            obj1.localRotation.z,
                                            obj1.localRotation.w * -1.0f);
7 Likes

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.

1 Like

[quote=“anon_72169410”, post:3, topic: 445934]
Thanks alot Marrrk! :slight_smile: The solution is to have the “w” in the rotation negative:

obj2.localRotation = new Quaternion(obj1.localRotation.x * -1.0f,
                                            obj1.localRotation.y,
                                            obj1.localRotation.z,
                                            obj1.localRotation.w * -1.0f);

[/quote]

This works perfectly! Thanks :smile:

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:

var objectQuat; // from world rotation
var mirrorNormalQuat = new Quaternion(plane.x, plane.y, plane.z, 0);

var reflectedQuat = mirrorNormalQuat * objectQuat * mirrorNormalQuat;
5 Likes

[quote=“BenVlodgi”, post:6, topic: 445934]
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:

var objectQuat; // from world rotation
var mirrorNormalQuat = new Quaternion(plane.x, plane.y, plane.z, 0);

var reflectedQuat = mirrorNormalQuat * objectQuat * mirrorNormalQuat;

[/quote]

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:

Vector3 forw = transform.forward;
Vector3 mirrored = Vector3.Reflect(forw, mirrorNormal);
transform.rotation = Quaternion.LookRotation(mirrored, transform.up);
3 Likes

Quote old thread. But there is
Quaternion.Inverse ( my quaternion );
for that purpose

1 Like

[quote=“Antypodish”, post:8, topic: 445934]
Quote old thread. But there is
Quaternion.Inverse ( my quaternion );
for that purpose
[/quote]
Thats not quite what we needed. We needed a mirror, not a reverse. Mirror operation requires a mirror plane normal.

2 Likes
    private Quaternion ReflectRotation(Quaternion source, Vector3 normal)
    {
        return Quaternion.LookRotation(Vector3.Reflect(source * Vector3.forward, normal), Vector3.Reflect(source * Vector3.up, normal));
    }
4 Likes

Posted a complete solution here with script for mirroring a gameobject(s) relative to a plane using information from this thread.
Cheers!