ARKit中如何从4x4变换矩阵获取欧拉角(Swift实现)
在Swift中从4x4变换矩阵提取欧拉角(Pitch/Yaw/Roll)
嘿,我刚好在3D开发里常碰到这个需求,这就给你讲清楚怎么实现!首先得明确:欧拉角的计算完全依赖于旋转顺序(比如最常用的Z-Y-X顺序,对应Yaw-Pitch-Roll的旋转逻辑,很多3D框架默认用这个),不同顺序算出来的角度结果会不一样,下面我就以Z-Y-X顺序为例来写代码,这也是最符合你需求的场景。
核心思路
4x4变换矩阵的左上角3x3子矩阵就是旋转矩阵,我们只需要从这个3x3矩阵里提取角度就行。针对Z-Y-X顺序的旋转,三个欧拉角的定义如下:
- Yaw(偏航):绕Z轴的旋转角度
- Pitch(俯仰):绕Y轴的旋转角度
- Roll(翻滚):绕X轴的旋转角度
代码实现
首先我们可以给SIMD矩阵加个扩展,方便提取旋转矩阵部分,然后写一个计算欧拉角的函数:
import simd // 定义欧拉角的元组类型,方便返回结果 typealias EulerAngles = (pitch: Float, yaw: Float, roll: Float) // 给4x4矩阵加扩展,提取左上角的3x3旋转矩阵 extension simd_float4x4 { var rotationMatrix: simd_float3x3 { simd_float3x3( columns: ( simd_float3(columns.0.x, columns.0.y, columns.0.z), simd_float3(columns.1.x, columns.1.y, columns.1.z), simd_float3(columns.2.x, columns.2.y, columns.2.z) ) ) } } // 从4x4变换矩阵计算欧拉角(Z-Y-X顺序) func calculateEulerAngles(from transformMatrix: simd_float4x4) -> EulerAngles { let rotationMatrix = transformMatrix.rotationMatrix // 计算Yaw(Z轴旋转,范围:-π 到 π) let yaw = atan2(rotationMatrix[1][0], rotationMatrix[0][0]) // 计算Pitch(Y轴旋转,范围:-π/2 到 π/2),同时处理万向锁问题 let sinPitch = -rotationMatrix[2][0] var pitch: Float var roll: Float if abs(sinPitch) > 0.9999 { // 接近万向锁状态(Pitch接近±90度),直接计算Pitch,Roll设为0避免异常 pitch = .pi / 2 * sinPitch.sign roll = 0 } else { pitch = asin(sinPitch) // 计算Roll(X轴旋转,范围:-π 到 π) roll = atan2(rotationMatrix[2][1], rotationMatrix[2][2]) } return (pitch: pitch, yaw: yaw, roll: roll) }
示例用法
假设你已经有了transform的4x4矩阵,直接调用函数即可,要是需要转成角度(而不是弧度),记得乘以180 / .pi:
// 替换成你的transform矩阵 let targetTransform: simd_float4x4 = ... let angles = calculateEulerAngles(from: targetTransform) // 输出弧度值 print("Pitch: \(angles.pitch), Yaw: \(angles.yaw), Roll: \(angles.roll)") // 转成角度输出 print("Pitch: \(angles.pitch * 180 / .pi)°") print("Yaw: \(angles.yaw * 180 / .pi)°") print("Roll: \(angles.roll * 180 / .pi)°")
注意事项
- 万向锁问题:当Pitch角度接近±90度时,Yaw和Roll会出现耦合,这时候其中一个角度会失去自由度,代码里已经做了特殊处理避免计算异常。
- 旋转顺序:如果你的项目用的不是Z-Y-X顺序(比如X-Y-Z),需要调整矩阵元素的索引来计算,不同顺序的公式不一样,别直接套代码哦!
- 弧度 vs 角度:Swift里的三角函数返回的都是弧度,要是需要显示角度,一定要做转换。
内容的提问来源于stack exchange,提问作者Calonca
相关产品推荐
相关产品推荐

