You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从JavaScript的4x4相机变换矩阵提取x/y/z轴弧度制旋转值

从4x4相机变换矩阵提取弧度制欧拉角方案

你提到的world to obj矩阵即视图矩阵,作用是将世界坐标系下的坐标转换到相机局部坐标系,其左上角3×3子矩阵存储了旋转信息(无缩放前提下)。提取欧拉角前需要先确认两个前提:

  • 矩阵的存储顺序(WebGL/Three.js等常用框架默认是列优先存储)
  • 矩阵生成时使用的欧拉角旋转顺序,以下示例默认使用相机场景常用的Y-X-Z(偏航-俯仰-滚转)顺序,如果你用的是其他顺序需要调整计算逻辑。

实现代码(JavaScript)

假设输入矩阵是长度为16的列优先数组,和gl-matrix、Three.js的Matrix4存储格式兼容:

function extractEulerFromViewMatrix(mat) {
  // 提取3x3旋转矩阵分量(列优先)
  const m11 = mat[0], m12 = mat[4], m13 = mat[8];
  const m21 = mat[1], m22 = mat[5], m23 = mat[9];
  const m31 = mat[2], m32 = mat[6], m33 = mat[10];

  let x, y, z;

  // 计算俯仰角(X轴旋转)
  const sinX = -m23;
  if (Math.abs(sinX) >= 1) {
    // 处理万向锁特殊情况
    x = sinX > 0 ? Math.PI / 2 : -Math.PI / 2;
    // 此时偏航和滚转耦合,默认将滚转设为0计算偏航
    y = Math.atan2(-m31, m11);
    z = 0;
  } else {
    x = Math.asin(sinX);
    y = Math.atan2(m13, m33);
    z = Math.atan2(m21, m22);
  }

  // 返回弧度制欧拉角,顺序X、Y、Z
  return { x, y, z };
}

注意事项

  • 如果你的矩阵存在缩放,需要先对3x3子矩阵的每一列做归一化处理,再代入上述公式计算,否则旋转值会有偏差
  • 如果你的矩阵是行优先存储,需要把上述代码中分量的行列索引互换,例如m12对应mat[1],m21对应mat[4]以此类推
  • 欧拉角存在天然的万向锁缺陷,如果你需要无歧义的旋转表示,建议提取四元数代替欧拉角

参考效果

无旋转状态下的相机变换效果:
无旋转状态相机变换效果

各轴施加1弧度旋转+轨道运动的效果:
各轴施加1弧度旋转+轨道运动效果

内容的提问来源于stack exchange,提问作者c.hum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 03:36:03