Swift ARKit无法在垂直平面上正确旋转SCNNode

Swift ARKit无法在垂直平面上正确旋转SCNNode,swift,rotation,scenekit,augmented-reality,arkit,Swift,Rotation,Scenekit,Augmented Reality,Arkit,我想旋转一个SCNNode,它是一个绘画图像 我可以在地板上旋转它,但我不能在墙上正确旋转它 (我正在使用UIRotationGestureRecognitor) 有人知道如何在墙上正确旋转它吗?谢谢大家! 您正在代码中使用eulerAngles实例属性: var eulerAngles: SCNVector3 { get set } 根据苹果的文档: SceneKit按照组件的相反顺序应用相对于节点枢轴属性的eulerAngles旋转:首先roll(Z),然后yaw(Y),然后pitch(

我想旋转一个SCNNode,它是一个绘画图像

我可以在地板上旋转它,但我不能在墙上正确旋转它

(我正在使用UIRotationGestureRecognitor)


有人知道如何在墙上正确旋转它吗?谢谢大家!

您正在代码中使用
eulerAngles
实例属性:

var eulerAngles: SCNVector3 { get set }
根据苹果的文档:

SceneKit按照组件的相反顺序应用相对于节点枢轴属性的
eulerAngles
旋转:首先
roll
Z),然后
yaw
Y),然后
pitch
X

…但三分量旋转可能导致。 常平架锁定是指当三个常平架中的两个轴被驱动成平行配置时,在三维、三个常平架机构中失去一个自由度,“锁定”系统,使其在退化的二维空间中旋转

因此,需要使用四分量旋转特性:

var rotation: SCNVector4 { get set }
指定前三个组件(XYZ)中旋转轴的方向,以及第四个组件(W)中以
弧度表示的旋转角度

如果您想了解更多有关
SCInvector4
结构和四分量旋转(及其以弧度表示的W分量)的信息,请查看

p.S.

RealityKit框架中而不是
scinvector4
结构中,您需要使用
SIMD4
通用结构或
simd\u float4
类型别名

var rotation: simd_float4 { get set }

我尝试了
SCNNode-eulerAngles
SCNNode-rotation
但是我没有运气

我想这是因为我在添加绘画时调用了
SCNNode.transform()
。当以后我修改
SCNNode.euleranges
并调用
SCNNode.rotation()
时,它们可能会对第一次
变换产生影响

我最终通过使用
SCNMatrix4Rotate
,而不是使用
eulerAngles
rotation
使它工作起来

  func addPainting(_ hitResult: ARHitTestResult, _ grid: Grid) {
    ...
    let newPaintingNode = SCNNode(geometry: planeGeometry)
    newPaintingNode.transform = SCNMatrix4(hitResult.anchor!.transform)
    newPaintingNode.transform = SCNMatrix4Rotate(newPaintingNode.transform, -Float.pi / 2.0, 1.0, 0.0, 0.0)
    newPaintingNode.position = SCNVector3(hitResult.worldTransform.columns.3.x, hitResult.worldTransform.columns.3.y, hitResult.worldTransform.columns.3.z)
    self.paintingNode = newPaintingNode
    ...
  }
...
  @objc func rotateNode(_ gesture: UIRotationGestureRecognizer){

    if let _ = self.paintingNode {

      // Get The Current Rotation From The Gesture
      let rotation = Float(gesture.rotation)

      if gesture.state == .began {
        self.rotationZ = rotation
      }

      if gesture.state == .changed {
        let diff = rotation - self.rotationZ
        self.paintingNode?.transform = SCNMatrix4Rotate(self.paintingNode!.transform, diff, 0.0, 0.0, 1.0)
        self.rotationZ = rotation
      }

    }

  }

上述代码适用于垂直和水平面。

谢谢您的回复!我尝试使用SConvector4,但结果仍然很奇怪。有时工作正常,有时不正常。我更改了
rotateNode()
并添加了
self.paintingNode?.rotation=scinvector4(x:0,y:0,z:1,w:currentAngleZ+rotation)
self.paintingAlignment==“垂直”
时,您的
w
值是弧度还是度?进行旋转时,您使用的是
local
轴还是
world
轴?并认为正<代码> z <代码>值为逆时针旋转(<代码> ccw < /代码>),而否定<代码> z <代码>值为时钟旋转(<代码> CW < /代码>)。谢谢您,并为迟来的答复表示歉意。我的
w
值以弧度为单位。我不知道我使用的是
local
axis还是
world
axis。。。
var rotation: simd_float4 { get set }
  func addPainting(_ hitResult: ARHitTestResult, _ grid: Grid) {
    ...
    let newPaintingNode = SCNNode(geometry: planeGeometry)
    newPaintingNode.transform = SCNMatrix4(hitResult.anchor!.transform)
    newPaintingNode.transform = SCNMatrix4Rotate(newPaintingNode.transform, -Float.pi / 2.0, 1.0, 0.0, 0.0)
    newPaintingNode.position = SCNVector3(hitResult.worldTransform.columns.3.x, hitResult.worldTransform.columns.3.y, hitResult.worldTransform.columns.3.z)
    self.paintingNode = newPaintingNode
    ...
  }
...
  @objc func rotateNode(_ gesture: UIRotationGestureRecognizer){

    if let _ = self.paintingNode {

      // Get The Current Rotation From The Gesture
      let rotation = Float(gesture.rotation)

      if gesture.state == .began {
        self.rotationZ = rotation
      }

      if gesture.state == .changed {
        let diff = rotation - self.rotationZ
        self.paintingNode?.transform = SCNMatrix4Rotate(self.paintingNode!.transform, diff, 0.0, 0.0, 1.0)
        self.rotationZ = rotation
      }

    }

  }