如何按度旋转和锁定SCNNode的旋转?

时间:2019-06-06 22:09:52

标签: swift rotation scenekit degrees radians

我需要将可以自由旋转的模型旋转到精确的角度,而不管旋转了多少次。

我有一个UIPanGestureRecognizer,它可以围绕Y轴自由旋转3D模型。但是,当平移停止时,我正在努力将其锁定到整数度,并且正在努力知道它在0-359之间的度数旋转。

let translation = recognizer.translation(in: self.view)

var newAngleY = Double(translation.x) * (Double.pi) / 180.0
newAngleY += self.currentAngle

self.shipNode?.eulerAngles.y = Float(newAngleY)

if (recognizer.state == .ended)
{
   self.currentAngle = newAngleY
}

它可以自由旋转,但是所有尝试将其锁定到最接近的精确度,并且能够“知道”其旋转度为0-359。

我知道:

let degrees = newAngleY * ( 180 / Double.pi)

我知道,如果度数> 360,则-= 360(伪代码)

但是,虽然UIPanGestureRecognizer正在执行此操作,但这些检查似乎失败了,我也不知道为什么。是因为它仍在平移时无法编辑ViewController的私有属性吗?

1 个答案:

答案 0 :(得分:0)

您可以在手势发生时编辑该值。

很多选择,所以这似乎是最简单的开始:

您可以仅在状态更改时尝试使用euler,并且仅在.x> .x *(某些值,例如1.1)时尝试使用。这样可以提供一种更“贴切”的方法,例如:

 var currentLocation = CGPoint.zero
 var beginLocation = CGPoint.zero

 @objc func handlePan(recognizer: UIPanGestureRecognizer) {
    currentLocation = recognizer.location(in: gameScene)

    var newAngleY = Double(translation.x) * (Double.pi) / 180.0
    newAngleY += self.currentAngle

    switch recognizer.state
    {
     case UIGestureRecognizer.State.began: break
     case UIGestureRecognizer.State.changed:
         if(currentLocation.x > beginLocation.x * 1.1)
         {
           gNodes.bnode.eulerAngles.y = Float(newAngleY)
           beginLocation.x = currentLocation.x
         }
         if(currentLocation.x < beginLocation.x * 0.9) { .etc. }
         break
         case UIGestureRecognizer.State.ended:
           gNodes.bnode.eulerAngles.y = Float(newAngleY)
           break
    }
}

然后,您可以切换到SCNAction(更改数学)以提供更多控制权,例如

let vAction = SCNAction.rotateTo(x: 0, y: vAmount, z: 0, duration: 0)
bnode.runAction(vAction)