10

In my project I have a transform and I want to get the orientation of that transform in eulersAngles.

How do I get the eulerAngles from a transform of 4x4 matrix in Swift language?

I need at least the Pitch, I may need the Yaw and I might need the Roll.

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
Calonca
  • 125
  • 1
  • 7

4 Answers4

6

The accepted answer did not work for me. Eventually, I've managed to find the solution, here is a simple extension with the calculations:

extension simd_float4x4 {
    var eulerAngles: simd_float3 {
        simd_float3(
            x: asin(-self[2][1]),
            y: atan2(self[2][0], self[2][2]),
            z: atan2(self[0][1], self[1][1])
        )
    }
}

I've tested it by comparing default ARFrame.camera.eulerAngles provided by Apple and ARFrmae.camera.transform.eulerAngles calculated with the extension.

2

eulerAngles instance property is used for node’s orientation, expressed as pitch, yaw, and roll angles in radians.

var eulerAngles: SCNVector3 { get set }

The order of components is as following:

  • Pitch (X component) is the rotation about the node’s X-axis
  • Yaw (Y component) is the rotation about the node’s Y-axis
  • Roll (Z component) is the rotation about the node’s Z-axis

To use eulerAngles instance property is much simpler than using Rotation 4x4 Matrix. ARKit and SceneKit frameworks use 4x4 Transformation Matrices to translate, rotate, scale and shear 3D objects. Let's see how they work:

The Identity 4x4 Matrix has 16 elements inside:

enter image description here

Between those sixteen elements there are 6 different shearing coefficients:

shear XY
shear XZ
shear YX
shear YZ
shear ZX
shear ZY

In Shear Matrix they are as followings:

enter image description here

Because there are no Rotation coefficients at all in this Matrix, six Shear coefficients along with three Scale coefficients allow you rotate 3D objects about X, Y, and Z axis using magical trigonometry (sin and cos).

Here's an example how to rotate 3D object (CCW) about its Z axis using Shear and Scale elements:

enter image description here

Look at 3 different Rotation patterns (Pitch, Yaw, and Roll) using Shear and Scale elements:

enter image description here

Translation 4x4 Matrix looks like this:

enter image description here

Hope this helps.

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
1

Assuming mij is matrix element in the i-th row and j-th column.

R=atan2(m12, m22)
c2 = sqrt(m00^2 + m01^2)
P = atan2(-m02, c2)
s1 = sin(R), c1 = cos(R)
Y = atan2(s1*m20 - c1*m10, c1*m11-s1*m21)

Source: The math is described in this document really well: https://pdfs.semanticscholar.org/6681/37fa4b875d890f446e689eea1e334bcf6bf6.pdf

As opposed to going to quaternion, there are some corner cases (gimbal lock) you have to worry about that the above solution handles pretty well.

pj_mukh
  • 375
  • 1
  • 9
  • This has been a great help to me to understand. But one issue still remains, that is C2 is always position, therefore P can be only half of 2*pi. to fix that, just add on line. `c2 = copysignf(c2, m[0][0])` to keep the sign of c2 same as m00. – Juguang Aug 13 '20 at 20:20
0

pj_mukh in his answer didn't say how to convert a transform matrix which I had to start with to a rotation matrix, imallett answered that question here

After you get the rotation matrix you can calculate the rotation angles as pj_mukh said

Calonca
  • 125
  • 1
  • 7
  • If the other thread disappeared, your answer would be of no use for future visitors. Please always include the essential parts of the link in your answer. – Mr. T Sep 08 '18 at 11:11
  • the first 3x3 matrix within the 4x4 transformation matrix is the rotation matrix, so my pseudo code works as-is, no real need to explictly extract the rotation matrix if all you want is the roll/pitch/yaw. – pj_mukh Oct 25 '19 at 16:48