Unity中如何获取ZYX顺序欧拉角?矩阵转ZYX欧拉角求方法
Unity中ZYX旋转顺序欧拉角的获取与矩阵转换
一、获取ZYX旋转顺序的欧拉角
Unity内置的Quaternion.eulerAngles采用的是ZXY旋转顺序,想要得到ZYX顺序的欧拉角,需要自行实现转换逻辑。以下是直接基于四元数计算的方法:
public static Vector3 QuaternionToEulerZYX(Quaternion q) { Vector3 euler = new Vector3(); // 计算Z轴旋转角(Yaw) double sinyCosp = 2 * (q.w * q.z + q.x * q.y); double cosyCosp = 1 - 2 * (q.y * q.y + q.z * q.z); euler.z = (float)Math.Atan2(sinyCosp, cosyCosp); // 计算Y轴旋转角(Pitch) double sinp = 2 * (q.w * q.y - q.z * q.x); if (Math.Abs(sinp) >= 1) euler.y = (float)Math.CopySign(Math.PI / 2, sinp); // 处理万向锁情况 else euler.y = (float)Math.Asin(sinp); // 计算X轴旋转角(Roll) double sinrCosp = 2 * (q.w * q.x + q.y * q.z); double cosrCosp = 1 - 2 * (q.x * q.x + q.y * q.y); euler.x = (float)Math.Atan2(sinrCosp, cosrCosp); // 转换为Unity常用的角度值(弧度转角度) euler *= Mathf.Rad2Deg; return euler; }
二、4×4矩阵转ZYX顺序欧拉角
Unity没有提供直接将4×4矩阵转换为ZYX顺序欧拉角的内置函数,需要从矩阵的旋转子矩阵(左上3×3部分)提取角度,实现代码如下:
public static Vector3 MatrixToEulerZYX(Matrix4x4 matrix) { Vector3 euler = new Vector3(); // 提取矩阵中的3×3旋转部分 Matrix4x3 rotMatrix = matrix.GetRotation(); // 计算Z轴旋转角 euler.z = Mathf.Atan2(rotMatrix.m10, rotMatrix.m00); // 计算Y轴旋转角 double pitch = Math.Asin(-rotMatrix.m20); if (Math.Abs(pitch) >= Math.PI / 2 - 0.0001) { // 接近万向锁时的特殊处理 euler.y = (float)pitch; euler.x = 0; euler.z += Mathf.Atan2(-rotMatrix.m01, rotMatrix.m11); } else { euler.y = (float)pitch; // 计算X轴旋转角 euler.x = Mathf.Atan2(rotMatrix.m21, rotMatrix.m22); } // 转换为角度值 euler *= Mathf.Rad2Deg; return euler; }
注意事项
- 欧拉角本身存在万向锁缺陷,当Y轴旋转角接近±90度时,X轴和Z轴的旋转会出现耦合,这是欧拉角的固有特性,与旋转顺序无关;
- 上述函数返回的角度范围为[-180, 180],如果需要匹配Unity默认的[0, 360]范围,可对每个轴执行
angle = angle < 0 ? angle + 360 : angle处理。
内容的提问来源于stack exchange,提问作者Mr Bi
相关产品推荐
相关产品推荐

