SCNNode Z旋转轴保持不变,而X和Y轴在节点旋转时发生变化 [英] SCNNode Z-rotation axis stays constant, while X and Y axes change when node is rotated
问题描述
我有一个用户可以通过平移手势旋转的节点.用户可以选择X,Y或Z轴并进行平移,节点将围绕该轴旋转.
I have a node that the user can rotate via a pan gesture. The user can select either X, Y, or Z axis and pan, and the node will rotate around that axis.
问题:节点的正面朝向摄像机.假设用户向右平移并围绕Y轴旋转节点.节点的正面现在朝向右侧.如果用户切换到X轴并向下平移,则节点的前部将从其初始的面向右方向向下旋转(或从用户的角度来看为顺时针方向).这是期望的行为.当用户切换到Z旋转时会出现问题.如果用户切换到Z轴旋转并向右平移,则该节点将向下旋转(从用户角度来看为顺时针方向).
The Issue: The node's front is facing the camera. Let's say the user pans to the right and rotates the node around the Y axis. The node's front is now facing the right. If the user switches to the X axis and pans down, the node's front will rotate downward (or clockwise from the user's perspective) from it's initial right-facing orientation. This is desired behavior. The problem arises when the user switches to the Z rotation. If the user switches to Z axis rotation and pans right, the node will rotate down (clockwise from the user's perspective).
从本质上讲,节点的Z轴始终是恒定的,永远不会偏离其初始方向,但是X轴和Y轴的确会发生变化,受其他轴的旋转的影响.
Essentially, the Z axis of the node is always constant, never moving from it's initial orientation, but the X and Y axes do change, affected by other axes' rotations.
任何人都可以解释是什么原因造成的吗?
Can anyone explain what's causing this?
下面是我用来旋转节点的代码:
Below is the code I'm using to rotate the node:
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
}
}
推荐答案
As I wrote earlier in your post it's a Gimbal Lock
issue. Gimbal Lock is the loss of one DoF in a three-dimensional mechanism. There are two variables in SceneKit: eulerAngles
(intrinsic euler angles, expressed in radians, represent a sequence of 3 rotations about the x-y-z axis with the following order: Z
-Y
-X
or roll
, yaw
, pitch
) and orientation
(node’s orientation, expressed as quaternion).
要摆脱ARKit和SceneKit中的万向节锁定,您需要使用单元四元数,其四元数满足以下方程式:
To get rid of gimbal lock in ARKit and SceneKit you need to use unit quaternions, whose components satisfy the equation:
(x * x) + (y * y) + (z * z) + (w * w) == 1
要正确应用四元数,您还需要使用此结构的第四个组件(w
).四元数用SCNVector4表示,其中x
-y
-z
值是归一化的分量,w
字段包含以弧度为单位的旋转角度或以牛顿米为单位的扭矩大小.
For applying quaternions correctly you need to use the fourth component of this structure too (w
). Quaternions are expressed in SCNVector4, where x
-y
-z
values are normalized components, and the w
field contains the rotation angle, in radians, or torque magnitude, in newton-meters).
万向节锁定在将(三个万向节中的两个)轴驱动为平行配置时发生.
Gimbal Lock occurs when the axes (of two of the three gimbals) are driven into a parallel configuration.
这篇关于SCNNode Z旋转轴保持不变,而X和Y轴在节点旋转时发生变化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!