我有一个用户可以通过平移手势旋转的节点。用户可以选择 X、Y 或 Z 轴并进行平移,节点将绕该轴旋转。
问题:节点的正面面向摄像头。假设用户向右平移并绕 Y 轴旋转节点。节点的正面现在面向右侧。如果用户切换到 X 轴并向下平移,节点的正面将从其初始的面向右的方向向下旋转(或从用户的角度来看顺时针旋转)。这是期望的行为。当用户切换到 Z 轴旋转时就会出现问题。如果用户切换到 Z 轴旋转并向右平移,节点将向下旋转(从用户的角度来看顺时针旋转)。
本质上,节点的 Z 轴始终保持不变,永远不会偏离其初始方向,但 X 轴和 Y 轴确实会发生变化,受到其他轴旋转的影响。
谁能解释一下这是什么原因吗?
下面是我用来旋转节点的代码:
let translation = sender.translation(in: sceneView)
var newAngleX = Float(translation.y)*Float((Double.pi)/180.0)
var newAngleY = Float(translation.x)*Float((Double.pi)/180.0)
var newAngleZ = Float(translation.x)*Float((Double.pi)/180.0)
if axisSelected == "x" {
newAngleX += currentAngleX
node.eulerAngles.x = newAngleX
if(sender.state == .ended) {
currentAngleX = newAngleX
}
}
if axisSelected == "y" {
newAngleY += currentAngleY
node.eulerAngles.y = newAngleY
if(sender.state == .ended) {
currentAngleY = newAngleY
}
}
if axisSelected == "z" {
newAngleZ += currentAngleZ
node.eulerAngles.z = newAngleZ
if(sender.state == .ended) {
currentAngleZ = newAngleZ
}
}
最佳答案
正如我之前在 your post 中所写的那样这是一个万向节锁
问题。 万向节锁定是三维机构中一个自由度的损失。 SceneKit 中有两个变量:eulerAngles
(固有欧拉角,以弧度表示,表示绕 x-y-z 轴 3 次旋转的序列,顺序如下:Z
-Y
-X
或 滚动
、偏航
、俯仰
)和方向
(节点的方向,以四元数表示)。
要摆脱 ARKit 和 SceneKit 中的万向节锁定,您需要使用单位四元数,其分量满足以下方程:
(x * x) + (y * y) + (z * z) + (w * w) == 1
为了正确应用四元数,您还需要使用此结构的第四个组件 (w
)。四元数以 SCNVector4 表示,其中 x
-y
-z
值是归一化分量,w
字段包含旋转角度(以弧度为单位)或扭矩大小(以牛顿米为单位)。
万向节锁定发生在(三个万向节中的两个)轴被驱动成平行配置时。
关于ios - SCNNode Z轴旋转轴保持不变,而X轴和Y轴在节点旋转时发生变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50997832/