Files
design2garmentcode-impl/pygarment/pattern/rotation.py

63 lines
1.9 KiB
Python
Raw Normal View History

2025-07-03 17:03:00 +08:00
"""
Simple Rotation Conversion routines (Maya-Python2.7-Compatible!!)
"""
import numpy as np
import math as m
import sys
# TODO: Maya python 2.7 is long gone.
# Can be substituted with scipy rotation transformation routines for Maya2022+
# Thanks to https://www.meccanismocomplesso.org/en/3d-rotations-and-euler-angles-in-python/ for the code
def _Rx(theta):
return np.matrix([
[1, 0 , 0 ],
[0, m.cos(theta), -m.sin(theta)],
[0, m.sin(theta), m.cos(theta)]])
def _Ry(theta):
return np.matrix([
[m.cos(theta), 0, m.sin(theta)],
[0 , 1, 0 ],
[-m.sin(theta), 0, m.cos(theta)]])
def _Rz(theta):
return np.matrix([
[m.cos(theta), -m.sin(theta), 0],
[m.sin(theta), m.cos(theta) , 0],
[0 , 0 , 1]])
def euler_xyz_to_R(euler):
"""Convert to Rotation matrix.
Expects input in degrees.
Only support Maya convension of intrinsic xyz Euler Angles
"""
return _Rz(np.deg2rad(euler[2])) * _Ry(np.deg2rad(euler[1])) * _Rx(np.deg2rad(euler[0]))
def R_to_euler(R):
"""
Convert Rotation matrix to Euler-angles in degrees (in Maya convension of intrinsic xyz Euler Angles)
NOTE:
Routine produces one of the possible Euler angles, corresponding to input rotations (the Euler angles are not uniquely defined)
"""
tol = sys.float_info.epsilon * 10
if abs(R[0, 0]) < tol and abs(R[1, 0]) < tol:
eul1 = 0
eul2 = m.atan2(-R[2, 0], R[0, 0])
eul3 = m.atan2(-R[1, 2], R[1, 1])
else:
eul1 = m.atan2(R[1, 0], R[0, 0])
sp = m.sin(eul1)
cp = m.cos(eul1)
eul2 = m.atan2(-R[2, 0], cp * R[0, 0] + sp * R[1, 0])
eul3 = m.atan2(sp * R[0, 2] - cp * R[1, 2], cp * R[1, 1] - sp * R[0, 1])
return [np.rad2deg(eul3), np.rad2deg(eul2), np.rad2deg(eul1)]