我有以下可以正常工作的辅助函数:
func rotationToEuler(rotation: SCNVector4) -> SCNVector3 {
let node = SCNNode()
node.rotation = rotation
return node.eulerAngles
}
func eulerToRotation(eulerAngles: SCNVector3) -> SCNVector4 {
let node = SCNNode()
node.eulerAngles = eulerAngles
return node.rotation
}
但是,它创建了用于转换的虚拟节点,这感觉有点“hacky”,因为我们没有对该节点执行任何其他操作(例如将其添加到场景中等)。
我想知道是否有更好的方法?
您可以使用Spatial API。
import Spatial
import simd
func rotationToEuler(rotation: SCNVector4) -> SCNVector3 {
SCNVector3(
Rotation3D(angle: .radians(Double(rotation.w)), axis: .init(x: rotation.x, y: rotation.y, z: rotation.z))
.eulerAngles(order: .xyz)
.angles
)
}
func eulerToRotation(eulerAngles: SCNVector3) -> SCNVector4 {
let rotation = Rotation3D(eulerAngles: .init(angles: [eulerAngles.x, eulerAngles.y, eulerAngles.z], order: .xyz))
return SCNVector4(
simd_double4(rotation.axis.vector, rotation.angle.radians)
)
}
请注意,
simd
在这里并不是绝对必要的。我只是使用它,这样我就不必在eulerToRotation
中在浮点数和双精度数之间转换4次。