我创建了一个SCNSphere,所以现在它看起来有点像行星。这正是我想要的。我的下一个目标是允许用户使用平移手势识别器旋转球体。他们可以绕X或Y轴旋转它。我只是想知道我怎么才能做到。这就是我到目前为止所拥有的。
origin = sceneView.frame.origin
node.geometry = SCNSphere(radius: 1)
node.geometry?.firstMaterial?.diffuse.contents = UIImage(named: "world.jpg")
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(CategoryViewController.panGlobe(sender:)))
sceneView.addGestureRecognizer(panGestureRecognizer)
func panGlobe(sender: UIPanGestureRecognizer) {
// What should i put inside this method to allow them to rotate the sphere/ball
}发布于 2017-08-24 20:41:55
我们有一个包含节点sphereNode的ViewController,该节点包含我们的球体。要旋转球体,我们可以使用UIPanGestureRecognizer。由于识别器报告我们的手指在屏幕上移动的总距离,因此我们缓存了报告给我们的最后一个点。
var previousPanPoint: CGPoint?
let pixelToAngleConstant: Float = .pi / 180
func handlePan(_ newPoint: CGPoint) {
if let previousPoint = previousPanPoint {
let dx = Float(newPoint.x - previousPoint.x)
let dy = Float(newPoint.y - previousPoint.y)
rotateUp(by: dy * pixelToAngleConstant)
rotateRight(by: dx * pixelToAngleConstant)
}
previousPanPoint = newPoint
}我们使用自上次调用识别器以来手指在每个方向上移动了多少像素来计算dx和dy。使用pixelToAngleConstant,我们将像素值转换为一个角度(以randians为单位)以旋转球体。使用较大的常量可加快旋转速度。
手势识别器返回一个state,我们可以使用它来确定手势是否已开始、结束或手指是否已移动。当手势开始时,我们将手指位置保存在previousPanPoint中。当我们的手指移动时,我们调用上面的函数。当手势结束或取消时,我们清除我们的previousPanPoint。
@objc func handleGesture(_ gestureRecognizer: UIPanGestureRecognizer) {
switch gestureRecognizer.state {
case .began:
previousPanPoint = gestureRecognizer.location(in: view)
case .changed:
handlePan(gestureRecognizer.location(in: view))
default:
previousPanPoint = nil
}
}我们如何旋转球体?函数rotateUp和rotateRight只是调用我们更一般的函数rotate(by: around:),它不仅接受角度,还接受旋转的轴。rotateUp绕x轴旋转,rotateRight绕y轴旋转。
func rotateUp(by angle: Float) {
let axis = SCNVector3(1, 0, 0) // x-axis
rotate(by: angle, around: axis)
}
func rotateRight(by angle: Float) {
let axis = SCNVector3(0, 1, 0) // y-axis
rotate(by: angle, around: axis)
}在这种情况下,rotate(by:around:)是相对简单的,因为我们假设节点没有被平移/我们希望围绕节点的原点旋转局部坐标系。当我们看一般情况时,一切都有点复杂,但这个答案只是一个很小的起点。
func rotate(by angle: Float, around axis: SCNVector3) {
let transform = SCNMatrix4MakeRotation(angle, axis.x, axis.y, axis.z)
sphereNode.transform = SCNMatrix4Mult(sphereNode.transform, transform)
}我们从angle和axis创建一个旋转矩阵,然后将球体的旧transform与计算出的transform相乘,得到新的transform。
这是我创建的小演示:

这种方法有两个主要的缺点。
仅当节点的位置为SCNVector3Zero
发布于 2018-04-11 11:36:23
下面是我尝试过的,不确定它在角度方面是否准确,but...it满足了我的大部分需求……
@objc func handleGesture(_ gestureRecognizer: UIPanGestureRecognizer) {
let translation = gestureRecognizer.translation(in: gestureRecognizer.view!)
let x = Float(translation.x)
let y = Float(-translation.y)
let anglePan = (sqrt(pow(x,2)+pow(y,2)))*(Float)(Double.pi)/180.0
var rotationVector = SCNVector4()
rotationVector.x = x
rotationVector.y = y
rotationVector.z = 0.0
rotationVector.w = anglePan
self.earthNode.rotation = rotationVector
}

https://stackoverflow.com/questions/45851641
复制相似问题