Position + Euler Angles to Transformation Matrix

Question:

I have a position and three Euler angles from a Unity scene:

# position
cam_pos = [-0.1219461, -0.04402884, -1.995793]
# rotation (in degrees)
cam_rot = [-1.261, 176.506, 0.038]

In Unity the coordinate system is LHS and the Euler angle convention is Z,X,Y. I’d like to know how to turn this rotation+translation information into a 4×4 transformation matrix. Right now what I’ve got is:

import numpy as np
import pyquaternion as pyq

cam_pos = [-0.1219461, -0.04402884, -1.995793]
cam_rot = [-1.261, 176.506, 0.038]

qx = pyq.Quaternion(axis=[1, 0, 0], angle=np.radians(cam_rot[0]))
qy = pyq.Quaternion(axis=[0, 1, 0], angle=np.radians(cam_rot[1]))
qz = pyq.Quaternion(axis=[0, 0, 1], angle=np.radians(cam_rot[2]))
qr = qz * qx * qy

trans = np.zeros((4,4))
trans[0:3, 0:3] = rotmat
trans[0:3, 3] = cam_pos
trans[3, 3] = 1

which gives me

[[-9.98140077e-01 -6.63064448e-04  6.09585697e-02 -1.21946100e-01]
 [-2.00317624e-03  9.99757601e-01 -2.19254941e-02 -4.40288400e-02]
 [-6.09292554e-02 -2.20068252e-02 -9.97899457e-01 -1.99579300e+00]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00  1.00000000e+00]]

But after plotting the result in with some other data, I’m pretty sure I’ve fundamentally misunderstood something about the math here. Any help is greatly appreciated!

Asked By: Mr Squid

||

Answers:

In Unity, eulerAngles represent rotations in the following sequence: around Z-axis, around X-axis, and around Y-axis.

We can represent this in a 4×4 transformation matrix by applying each of these rotations in matrix form:

Rotation Matricies
(taken from: https://en.wikibooks.org/wiki/Cg_Programming/Unity/Rotations)

This will give you the upper-left 3×3 values of the 4×4 matrix.

Here are some snippets in python:

import math

# ...

cam_rot_rad = [math.radian(rot) for rot_deg in cam_rot]

x_rad = cam_rot_rad[0]
y_rad = cam_rot_rad[1]
z_rad = cam_rot_rad[2]

rot_z = np.identity(4)

rot_z[0,0] = math.cos(z_rad)
rot_z[0,1] = -math.sin(z_rad)
rot_z[1,0] = math.sin(z_rad)
rot_z[1,1] = math.cos(z_rad)

rot_x = np.identity(4)

rot_x[1,1] = math.cos(x_rad)
rot_x[1,2] = -math.sin(x_rad)
rot_x[2,1] = math.sin(x_rad)
rot_x[2,2] = math.cos(x_rad)

rot_y = np.identity(4)

rot_y[0,0] = math.cos(y_rad)
rot_y[0,2] = math.sin(y_rad)
rot_y[2,0] = -math.sin(y_rad)
rot_y[2,2] = math.cos(y_rad)

# xform = rot_y*rot_x*rot_z
xform = np.dot(rot_y, np.dot(rot_x, rot_z))

# this could also be achieved by multiplying a 4x4 translation matrix
xform[0:3, 3] = cam_pos
Answered By: SharkWithLasers
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.