我們有,裏面有包含我們的球節點sphereNode
一個視圖控制器。 要旋轉球體,我們可以使用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
圍繞y軸旋轉x軸rotateRight
。
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
。
這是我創造了這個小演示:
這種方法有兩個主要缺點。
它只節點周圍旋轉座標原點,只工作,如果正常節點的位置是SCNVector3Zero
它確實需要手勢既不速度考慮在內,也沒有球繼續旋轉時,手勢停止。 使用此方法無法輕鬆實現類似於表格視圖的效果,您可以輕輕地翻動手指,並且表格視圖快速滾動然後放慢。 解決方案之一就是使用物理系統。
爲什麼你想添加一個手勢到場景視圖?搜索hitTest。我可以告訴你,這並不容易。 –
由於sceneview包含一個球。所以我只想把這個手勢應用到球/球體 – user8426652
這是一個錯誤的想法。 –