title: SceneKit: orbit camera around point with one gesture while allowing camera to rotate with different gesture
body: <p>Assume a SceneKit scene offers a perspective similar to Minecraft. There is one camera. The camera node acts like the "head" of a person while its parent node acts like the "body." The camera node is a child of the parent node, called "userNode."</p>
  
  <p>The goal:</p>
  
  <ul>
  <li><p>Let the user pan with one finger to rotate the camera. In other words, the camera position remains fixed, but the "head" rotates around and lets the user view the scene as if turning around in a circle.</p></li>
  <li><p>Let the user pan with two fingers to orbit the camera around a given point. In other words, the camera position and rotation now change in order to let the user view the same point from different angles.</p></li>
  </ul>
  
  <p>So far, the code below implements the one-finger pan behavior. The question is how to incorporate the two-finger pan behavior.</p>
  
  <p>Option 1: Follow <a href="https://stackoverflow.com/questions/25654772/rotate-scncamera-node-looking-at-an-object-around-an-imaginary-sphere/25674762#25674762">this answer</a>, which explains how to orbit a camera. This seems suboptimal, however, since there is already a camera node in the scene and requires additional nodes while also shifting the scene's point of view between different cameras. </p>
  
  <p>Option 2: Compute the new position and rotation of the camera, which lets you avoid adding another camera node and another orbit node. This feels like the better answer but may be more complex.</p>
  
  <pre><code>func sceneViewPannedTwoFingers(sender: UIPanGestureRecognizer) {
      // Get pan distance &amp; convert to radians
      let translation = sender.translationInView(sender.view!)
      var xRadians = GLKMathDegreesToRadians(Float(translation.x))
  
      // Get X radians only since only moving horizontally
      xRadians = (xRadians / 10) + curXRadians
  
      // Rotate &amp; move camera horizontally
      userNode.rotation = SCNVector4(x: 0, y: 1, z: 0, w: -xRadians)
  
      // Compute new position for camera?
  }
  
  
  func sceneViewPannedOneFinger(sender: UIPanGestureRecognizer) {
      // Get pan distance &amp; convert to radians
      let translation = sender.translationInView(sender.view!)
      var xRadians = GLKMathDegreesToRadians(Float(translation.x))
      var yRadians = GLKMathDegreesToRadians(Float(translation.y))
  
      // Get x &amp; y radians
      xRadians = (xRadians / 10) + curXRadians
      yRadians = (yRadians / 10) + curYRadians
  
      // Limit yRadians to prevent rotating 360 degrees vertically
      yRadians = max(Float(-M_PI_2), min(Float(M_PI_2), yRadians))
  
      // Set rotation values to avoid Gimbal Lock
      cameraNode.rotation = SCNVector4(x: 1, y: 0, z: 0, w: yRadians)
      userNode.rotation = SCNVector4(x: 0, y: 1, z: 0, w: xRadians)
  
      // Save value for next rotation
      if sender.state == UIGestureRecognizerState.Ended {
          curXRadians = xRadians
          curYRadians = yRadians
      }
  
      // Set preview block
      setPreviewBlock()
  }
  </code></pre>
  
  <p>Questions:</p>
  
  <p>1) Is there an easier way to accomplish this in SceneKit?</p>
  
  <p>2) If not, are the two options above the only two options, and if so, which is the better option to choose?</p>
  
  <p>3) For option 2, updating the position of <code>userNode</code>, or the "body", seems simple enough: just compute the new position along a circle given the center's origin, i.e., the orbit point). For the "head", is there anything else to be mindful beyond updating the <code>rotation</code> property of <code>cameraNode</code> (or the "head")? It seems like orienting the camera to always face the orbit point might be more complex since there is a part of the SceneKit API dedicated to it, e.g., <code>SCNLookAtConstraint.</code></p>