Inventor: Eulerian angles of assembly component

by Vladimir Ananyev

Issue

If we look at the properties of a part in an assembly, we can see the x, y, z coordinates and angles. How can we get the angle values via API?

Solution

There is no direct way to get these angles via API. However, it should be possible to get them via the 4×4 homogeneous transformation matrix.

t11   t12   t13   tx
t21   t22   t23   ty
t31   t32   t33   tz
0     0     0    1

tx, ty, and tz represent the translations along x, y, and z directions.

From the values of other elements of the matrix, one can get the Eulerian/ Cardanian angles.

 

 

Sub GetAngles()

   

    Dim oDoc As AssemblyDocument

    Set oDoc = ThisApplication.ActiveDocument

    Dim oOcc As ComponentOccurrence

    Set oOcc = oDoc.ComponentDefinition.Occurrences(3)

    Dim oMat As Matrix

    Set oMat = oOcc.Transformation

 

    Dim aRotAngles(2) As Double

    Call CalculateRotationAngles(oMat, aRotAngles)

   

    ‘ Print results

    Dim i As Integer

    For i = 0 To 2

      Debug.Print FormatNumber(aRotAngles(i), 3)

    Next i

    Beep

End Sub

 

 

Sub CalculateRotationAngles( _

            ByVal oMatrix As Inventor.Matrix, _

            ByRef aRotAngles() As Double)

    Const PI = 3.14159265358979

    Const TODEGREES As Double = 180 / PI

 

    Dim dB As Double

    Dim dC As Double

    Dim dNumer As Double

    Dim dDenom As Double

    Dim dAcosValue As Double

       

    Dim oRotate As Inventor.Matrix


    Dim oAxis As Inventor.Vector

    Dim oCenter As Inventor.Point

   

    Set oRotate = ThisApplication.TransientGeometry.CreateMatrix

    Set oAxis = ThisApplication.TransientGeometry.CreateVector

    Set oCenter = ThisApplication.TransientGeometry.CreatePoint

 

    oCenter.X = 0

    oCenter.Y = 0

    oCenter.Z = 0

 

    ‘ Choose aRotAngles[0] about x which transforms axes[2] onto the x-z plane

   

    dB = oMatrix.Cell(2, 3)

    dC = oMatrix.Cell(3, 3)

 

    dNumer = dC

    dDenom = Sqr(dB * dB + dC * dC)

 

    ‘ Make sure we can do the division.  If not, then axes[2] is already in the x-z plane

    If (Abs(dDenom) <= 0.000001) Then

        aRotAngles(0) = 0#

    Else

        If (dNumer / dDenom >= 1#) Then

            dAcosValue = 0#

        Else

            If (dNumer / dDenom <= -1#) Then

                dAcosValue = PI

            Else

                dAcosValue = Acos(dNumer / dDenom)

            End If

        End If

   

        aRotAngles(0) = Sgn(dB) * dAcosValue

        oAxis.X = 1

        oAxis.Y = 0

        oAxis.Z = 0

 

        Call oRotate.SetToRotation(aRotAngles(0), oAxis, oCenter)

        Call oMatrix.PreMultiplyBy(oRotate)

    End If

 

   

    ‘ Choose aRotAngles[1] about y which transforms axes[3] onto the z axis

   

    If (oMatrix.Cell(3, 3) >= 1#) Then

        dAcosValue = 0#

    Else

        If (oMatrix.Cell(3, 3) <= -1#) Then

            dAcosValue = PI

        Else

            dAcosValue = Acos(oMatrix.Cell(3, 3))

        End If

    End If

 

    aRotAngles(1) = Math.Sgn(-oMatrix.Cell(1, 3)) * dAcosValue

    oAxis.X = 0

    oAxis.Y = 1

    oAxis.Z = 0

    Call oRotate.SetToRotation(aRotAngles(1), oAxis, oCenter)

    Call oMatrix.PreMultiplyBy(oRotate)

 

   

    ‘ Choose aRotAngles[2] about z which transforms axes[0] onto the x axis

   

    If (oMatrix.Cell(1, 1) >= 1#) Then

        dAcosValue = 0#

    Else

        If (oMatrix.Cell(1, 1) <= -1#) Then

            dAcosValue = PI

        Else

            dAcosValue = Acos(oMatrix.Cell(1, 1))

        End If

    End If

 

    aRotAngles(2) = Math.Sgn(-oMatrix.Cell(2, 1)) * dAcosValue

 

    ‘if you want to get the result in degrees

    aRotAngles(0) = aRotAngles(0) * TODEGREES

    aRotAngles(1) = aRotAngles(1) * TODEGREES

    aRotAngles(2) = aRotAngles(2) * TODEGREES

End Sub

 

 

Public Function Acos(value) As Double

    Acos = Math.Atn(-value / Math.Sqr(-value * value + 1)) + 2 * Math.Atn(1)

End Function

<

p style=”line-height: normal;margin: 0cm 0cm 0pt;background: #eaf1dd” class=”MsoNormal”> 


Comments

2 responses to “Inventor: Eulerian angles of assembly component”

  1. Dear Sir,
    I have a doubt, i have modified your code as shown below. Would like to know, whether the below X,Y,Z assignment is right or wrong.
    For i = 0 To 2
    ‘Debug.Print (FormatNumber(aRotAngles(i), 3))
    If i=0
    MsgBox(“X = ” &FormatNumber(aRotAngles(i), 3))
    Else If i=1
    MsgBox(“Y = ” &FormatNumber(aRotAngles(i), 3))
    Else If i=2
    MsgBox(“Z = ” &FormatNumber(aRotAngles(i), 3))
    End If
    Next i
    Regards,
    Carthik

  2. glBeatriz Avatar
    glBeatriz

    Thanks a bunch! :)

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading