Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversion from quaternion to euler? #136

Open
nopjia opened this issue Apr 7, 2020 · 3 comments
Open

Conversion from quaternion to euler? #136

nopjia opened this issue Apr 7, 2020 · 3 comments

Comments

@nopjia
Copy link

nopjia commented Apr 7, 2020

Is there a way to go from quaternion to euler? (Similar to when you read from Quaternion.eulerAngles.)

There are plenty of methods on the quaternion to produce a quaternion from euler angles of various rotation orders, but not the other way around.

@unpacklo
Copy link
Collaborator

unpacklo commented Apr 7, 2020

There currently isn't, but it's on the list of things to add. We have some code internally at Unity which requires this so we have a few implementations already, it's just a matter of verifying its numerical quality and adding tests to ensure it works the way we expect.

@WaynGames
Copy link

WaynGames commented Aug 10, 2020

Implementation taken from wikipedia and ported to c#, for those who need :

using Unity.Mathematics;

public static class QuaternionExtensions
{
    public static float ComputeXAngle(this quaternion q)
    {
        float sinr_cosp = 2 * (q.value.w * q.value.x + q.value.y * q.value.z);
        float cosr_cosp = 1 - 2 * (q.value.x * q.value.x + q.value.y * q.value.y);
        return math.atan2(sinr_cosp, cosr_cosp);
    }

    public static float ComputeYAngle(this quaternion q)
    {
        float sinp = 2 * (q.value.w * q.value.y - q.value.z * q.value.x);
        if (math.abs(sinp) >= 1)
            return math.PI / 2 * math.sign(sinp); // use 90 degrees if out of range
        else
            return math.asin(sinp);
    }

    public static float ComputeZAngle(this quaternion q)
    {
        float siny_cosp = 2 * (q.value.w * q.value.z + q.value.x * q.value.y);
        float cosy_cosp = 1 - 2 * (q.value.y * q.value.y + q.value.z * q.value.z);
        return math.atan2(siny_cosp, cosy_cosp);
    }

    public static float3 CoputeAngles(this quaternion q)
    {
        return new float3(ComputeXAngle(q), ComputeYAngle(q), ComputeZAngle(q));
    }

    public static quaternion FromAngles(float3 angles)
    {

        float cy = math.cos(angles.z * 0.5f);
        float sy = math.sin(angles.z * 0.5f);
        float cp = math.cos(angles.y * 0.5f);
        float sp = math.sin(angles.y * 0.5f);
        float cr = math.cos(angles.x * 0.5f);
        float sr = math.sin(angles.x * 0.5f);

        float4 q;
        q.w = cr * cp * cy + sr * sp * sy;
        q.x = sr * cp * cy - cr * sp * sy;
        q.y = cr * sp * cy + sr * cp * sy;
        q.z = cr * cp * sy - sr * sp * cy;

        return q;

    }
}

@jimchan3301
Copy link

Someone mentioned that this function is in the Unity.Physics package: https://forum.unity.com/threads/is-there-a-conversion-method-from-quaternion-to-euler.624007/#post-6329286. This link is a discussion about how to convert from quaternions to Euler angles.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants