Euler Angles to Quaternion Conversion

Euler Angles to Quaternion Conversion

GeorgK
Advisor Advisor
1,849 Views
5 Replies
Message 1 of 6

Euler Angles to Quaternion Conversion

GeorgK
Advisor
Advisor

Hello together,

 

is there a function to convert the Euler angles to Quaternion and back? Or do I have to calculate it manually?

 

https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles

 

Thank you

 

Georg

0 Likes
Accepted solutions (2)
1,850 Views
5 Replies
Replies (5)
Message 2 of 6

fullevent
Advisor
Advisor

Hello @GeorgK,

 

i'm not sure if it this what you're looking for.. but here is a inventor-rule i have used to write angles into components (which are always disabled in the iproperties)

run the rule > type the x-, then the y- and finally the z-angle > select the occurrence you want to rotate and thats it.. 

i hope it helps you a little 🙂

 

Rule-Code:

Dim oTG As TransientGeometry
oTG = ThisApplication.TransientGeometry
Dim oMatrix1 As Matrix
oMatrix1 = oTG.CreateMatrix
Dim oAsm As AssemblyDocument
oAsm = ThisApplication.ActiveDocument
Dim oOcc As ComponentOccurrence
'oOcc = oAsm.SelectSet(1)
oOcc = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAssemblyOccurrenceFilter, "Select an Occurrence..")
Dim oMatrix As Matrix
oMatrix = oOcc.Transformation
Dim dCells(15) As Double
oMatrix.GetMatrixData(dCells)
dPi = Atan(1)*4

Dim dPhi As Double		' x-Winkel
dPhi = InputBox("Phi", "iLogic", "Grad")
Dim dTheta As Double	' y-Winkel
dTheta = InputBox("Theta", "iLogic", "Grad")
Dim dPsi As Double		' z-Winkel
dPsi = InputBox("Psi", "iLogic", "Grad")

dPhi_b = dPhi/180*dPi
dTheta_b = dTheta/180*dPi
dPsi_b = dPsi/180*dPi


oMatrix1 = oOcc.Transformation

oMatrix1.Cell(1,1) = Cos(dTheta_b)*Cos(dPsi_b)
oMatrix1.Cell(1,2) = Cos(dTheta_b)*Sin(dPsi_b)
oMatrix1.Cell(1,3) = -Sin(dTheta_b)
oMatrix1.Cell(2,1) = Sin(dPhi_b)*Sin(dTheta_b)*Cos(dPsi_b)-Cos(dPhi_b)*Sin(dPsi_b)
oMatrix1.Cell(2,2) = Sin(dPhi_b)*Sin(dTheta_b)*Sin(dPsi_b)+Cos(dPhi_b)*Cos(dPsi_b)
oMatrix1.Cell(2,3) = Sin(dPhi_b)*Cos(dTheta_b)
oMatrix1.Cell(3,1) = Cos(dPhi_b)*Sin(dTheta_b)*Cos(dPsi_b)+Sin(dPhi_b)*Sin(dPsi_b)
oMatrix1.Cell(3,2) = Cos(dPhi_b)*Sin(dTheta_b)*Sin(dPsi_b)-Sin(dPhi_b)*Cos(dPsi_b)
oMatrix1.Cell(3,3) = Cos(dPhi_b)*Cos(dTheta_b)

oOcc.Transformation = oMatrix1

Aleksandar Krstic
Produkt- und Projektmanager

0 Likes
Message 3 of 6

GeorgK
Advisor
Advisor

Hello Aleks,

 

thank you for your help. I need the Quaternion for more calculations. It's shorter and the Gimbal Lock is no problem.

 

Georg

0 Likes
Message 4 of 6

chandra.shekar.g
Autodesk Support
Autodesk Support

@GeorgK,

 

Hoping that System.Windows.Media.Media3D namespace would help for more calculation of Quaternion

 

https://msdn.microsoft.com/en-us/library/system.windows.media.media3d.quaternion(v=vs.110).aspx

 

Thanks and regards,


CHANDRA SHEKAR G
Developer Advocate
Autodesk Developer Network



0 Likes
Message 5 of 6

GeorgK
Advisor
Advisor
Accepted solution

There is a nice piece of code:

 

https://github.com/Atropin/QuaternionCalculator/releases/tag/v1.1

 

Keep in mind to calculate it in the order ZYX

 

0 Likes
Message 6 of 6

chandra.shekar.g
Autodesk Support
Autodesk Support
Accepted solution

@GeorgK,

 

Hoping that following C# code would serve the purpose.

 

public static Quaternion ToQ (Vector3 v)
{
    return ToQ (v.y, v.x, v.z);
}

public static Quaternion ToQ (float yaw, float pitch, float roll)
{
    yaw *= Mathf.Deg2Rad;
    pitch *= Mathf.Deg2Rad;
    roll *= Mathf.Deg2Rad;
    float rollOver2 = roll * 0.5f;
    float sinRollOver2 = (float)Math.Sin ((double)rollOver2);
    float cosRollOver2 = (float)Math.Cos ((double)rollOver2);
    float pitchOver2 = pitch * 0.5f;
    float sinPitchOver2 = (float)Math.Sin ((double)pitchOver2);
    float cosPitchOver2 = (float)Math.Cos ((double)pitchOver2);
    float yawOver2 = yaw * 0.5f;
    float sinYawOver2 = (float)Math.Sin ((double)yawOver2);
    float cosYawOver2 = (float)Math.Cos ((double)yawOver2);
    Quaternion result;
    result.w = cosYawOver2 * cosPitchOver2 * cosRollOver2 + sinYawOver2 * sinPitchOver2 * sinRollOver2;
    result.x = cosYawOver2 * sinPitchOver2 * cosRollOver2 + sinYawOver2 * cosPitchOver2 * sinRollOver2;
    result.y = sinYawOver2 * cosPitchOver2 * cosRollOver2 - cosYawOver2 * sinPitchOver2 * sinRollOver2;
    result.z = cosYawOver2 * cosPitchOver2 * sinRollOver2 - sinYawOver2 * sinPitchOver2 * cosRollOver2;

    return result;
}

public static Vector3 FromQ2 (Quaternion q1)
{
    float sqw = q1.w * q1.w;
    float sqx = q1.x * q1.x;
    float sqy = q1.y * q1.y;
    float sqz = q1.z * q1.z;
    float unit = sqx + sqy + sqz + sqw; // if normalised is one, otherwise is correction factor
    float test = q1.x * q1.w - q1.y * q1.z;
    Vector3 v;

    if (test>0.4995f*unit) { // singularity at north pole
        v.y = 2f * Mathf.Atan2 (q1.y, q1.x);
        v.x = Mathf.PI / 2;
        v.z = 0;
        return NormalizeAngles (v * Mathf.Rad2Deg);
    }
    if (test<-0.4995f*unit) { // singularity at south pole
        v.y = -2f * Mathf.Atan2 (q1.y, q1.x);
        v.x = -Mathf.PI / 2;
        v.z = 0;
        return NormalizeAngles (v * Mathf.Rad2Deg);
    }
    Quaternion q = new Quaternion (q1.w, q1.z, q1.x, q1.y);
    v.y = (float)Math.Atan2 (2f * q.x * q.w + 2f * q.y * q.z, 1 - 2f * (q.z * q.z + q.w * q.w));     // Yaw
    v.x = (float)Math.Asin (2f * (q.x * q.z - q.w * q.y));                             // Pitch
    v.z = (float)Math.Atan2 (2f * q.x * q.y + 2f * q.z * q.w, 1 - 2f * (q.y * q.y + q.z * q.z));      // Roll
    return NormalizeAngles (v * Mathf.Rad2Deg);
}

static Vector3 NormalizeAngles (Vector3 angles)
{
    angles.x = NormalizeAngle (angles.x);
    angles.y = NormalizeAngle (angles.y);
    angles.z = NormalizeAngle (angles.z);
    return angles;
}

static float NormalizeAngle (float angle)
{
    while (angle>360)
        angle -= 360;
    while (angle<0)
        angle += 360;
    return angle;
}

Please feel free to contact if there is any queries.

 

If solves problem, click on "Accept as solution" / give a "Kudo".

 

Thanks and regards,


CHANDRA SHEKAR G
Developer Advocate
Autodesk Developer Network