def create_field_euler_angles_rotation_matrix(fieldmodule: Fieldmodule, euler_angles: Field) -> Field: """ From OpenCMISS-Zinc graphics_library.cpp, matrix transposed to row major. Matrix is product RzRyRx, giving rotation about x, then y, then z with positive angles rotating by right hand rule about axis. :param fieldmodule: The fieldmodule to create the field in. :param euler_angles: 3-component field of angles in radians, components: 0 = azimuth (about z) 1 = elevation (about y) 2 = roll (about x) :return: 3x3 rotation matrix field suitable for pre-multiplying vector v i.e. v' = Mv """ assert euler_angles.getNumberOfComponents() == 3 with ChangeManager(fieldmodule): azimuth = fieldmodule.createFieldComponent(euler_angles, 1) cos_azimuth = fieldmodule.createFieldCos(azimuth) sin_azimuth = fieldmodule.createFieldSin(azimuth) elevation = fieldmodule.createFieldComponent(euler_angles, 2) cos_elevation = fieldmodule.createFieldCos(elevation) sin_elevation = fieldmodule.createFieldSin(elevation) roll = fieldmodule.createFieldComponent(euler_angles, 3) cos_roll = fieldmodule.createFieldCos(roll) sin_roll = fieldmodule.createFieldSin(roll) minus_one = fieldmodule.createFieldConstant([-1.0]) cos_azimuth_sin_elevation = cos_azimuth * sin_elevation sin_azimuth_sin_elevation = sin_azimuth * sin_elevation matrix_components = [ cos_azimuth * cos_elevation, cos_azimuth_sin_elevation * sin_roll - sin_azimuth * cos_roll, cos_azimuth_sin_elevation * cos_roll + sin_azimuth * sin_roll, sin_azimuth * cos_elevation, sin_azimuth_sin_elevation * sin_roll + cos_azimuth * cos_roll, sin_azimuth_sin_elevation * cos_roll - cos_azimuth * sin_roll, minus_one * sin_elevation, cos_elevation * sin_roll, cos_elevation * cos_roll ] rotation_matrix = fieldmodule.createFieldConcatenate(matrix_components) return rotation_matrix
def create_field_euler_angles_rotation_matrix(fieldmodule: Fieldmodule, euler_angles: Field) -> Field: """ From OpenCMISS-Zinc graphics_library.cpp, transposed. :param fieldmodule: :param euler_angles: 3-component field of angles in radians, components: 1 = azimuth (about z) 2 = elevation (about rotated y) 3 = roll (about rotated x) :return: 3x3 rotation matrix field suitable for pre-multiplying [x, y, z]. """ assert euler_angles.getNumberOfComponents() == 3 with ChangeManager(fieldmodule): azimuth = fieldmodule.createFieldComponent(euler_angles, 1) cos_azimuth = fieldmodule.createFieldCos(azimuth) sin_azimuth = fieldmodule.createFieldSin(azimuth) elevation = fieldmodule.createFieldComponent(euler_angles, 2) cos_elevation = fieldmodule.createFieldCos(elevation) sin_elevation = fieldmodule.createFieldSin(elevation) roll = fieldmodule.createFieldComponent(euler_angles, 3) cos_roll = fieldmodule.createFieldCos(roll) sin_roll = fieldmodule.createFieldSin(roll) minus_one = fieldmodule.createFieldConstant([-1.0]) cos_azimuth_sin_elevation = cos_azimuth*sin_elevation sin_azimuth_sin_elevation = sin_azimuth*sin_elevation matrix_components = [ cos_azimuth*cos_elevation, cos_azimuth_sin_elevation*sin_roll - sin_azimuth*cos_roll, cos_azimuth_sin_elevation*cos_roll + sin_azimuth*sin_roll, sin_azimuth*cos_elevation, sin_azimuth_sin_elevation*sin_roll + cos_azimuth*cos_roll, sin_azimuth_sin_elevation*cos_roll - cos_azimuth*sin_roll, minus_one*sin_elevation, cos_elevation*sin_roll, cos_elevation*cos_roll] rotation_matrix = fieldmodule.createFieldConcatenate(matrix_components) return rotation_matrix