创建一个全为零的SCNQuaternion 并没有任何意义。您已指定沿由全零“单位”向量指定的轴旋转 0。如果您尝试使用此修改后的代码版本,在尝试更改 topNode 的方向后,您会发现没有任何变化。您仍在围绕所有 3 个分量为零的轴旋转:
let topNode = SCNNode()
topNode.camera = frontCamera
topNode.position = SCNVector3(4, 0, 0)
print(topNode.orientation, topNode.rotation)
-> SCNVector4(x: 0.0, y: 0.0, z: 0.0, w: 1.0) SCNVector4(x: 0.0, y: 0.0, z: 0.0, w: 0.0)
topNode.orientation = SCNQuaternion(0, 0, 0, 0)
print(topNode.orientation, topNode.rotation)
->SCNVector4(x: 0.0, y: 0.0, z: 0.0, w: 1.0) SCNVector4(x: 0.0, y: 0.0, z: 0.0, w: 3.14159)
您已将 X 轴 4 个单位移出以放置相机 (topNode.position)。在通常的方向上,这意味着向右 4 个单位,正 Y 从屏幕底部延伸到顶部,正 Z 从屏幕延伸到您的眼睛。您想绕 Y 轴旋转。相机的方向在其父节点的负 Z 轴下方。所以让我们顺时针旋转 1/4 方向,然后尝试设置 rotation(比四元数更容易思考):
topNode.rotation = SCNVector4Make(0, 1, 0, Float(M_PI_2))
print(topNode.orientation, topNode.rotation)
-> SCNVector4(x: 0.0, y: 1.0, z: 0.0, w: -4.37114e-08) SCNVector4(x: 0.0, y: 1.0, z: 0.0, w: 3.14159)
您可能会发现在操作相机时注销甚至显示相机节点的rotation、orientation 和eulerAngles(它们都表达相同的概念,只是使用不同的轴)很有帮助手动。
为了完整起见,这里是完整的viewDidLoad:
@IBOutlet weak var sceneView: SCNView!
override func viewDidLoad() {
super.viewDidLoad()
sceneView.scene = SCNScene()
let sphere = SCNSphere(radius: 1.0)
let sphereNode = SCNNode(geometry: sphere)
sceneView.scene?.rootNode.addChildNode(sphereNode)
let frontCamera = SCNCamera()
frontCamera.yFov = 45
frontCamera.xFov = 45
let topNode = SCNNode()
topNode.camera = frontCamera
topNode.position = SCNVector3(4, 0, 0)
sceneView.scene?.rootNode.addChildNode(topNode)
print(topNode.orientation, topNode.rotation)
topNode.orientation = SCNQuaternion(0, 0, 0, 0)
print(topNode.orientation, topNode.rotation)
topNode.rotation = SCNVector4Make(0, 1, 0, Float(M_PI_2))
print(topNode.orientation, topNode.rotation)
}