私たちの球を含むノード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
の周りを回転します。我々は、ノードが翻訳されていない/我々は、ローカル座標系のノードの原点を中心に回転することを前提としているため
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
を掛けます。このアプローチは、2つの主要な欠点を持っている
![Demo](https://i.imgur.com/0C55Dkc.gif)
:
これは私が作成した小さなデモです。
それはそれは考慮にジェスチャーの速さもない取るんや球が時に回転し続けるんだけ座標原点ノードの周りを回転すると、ノードの位置はSCNVector3Zero
ある場合にのみ、正常に動作しますジェスチャーは止まる。 このアプローチでは、指をめくることができ、テーブルビューが速くスクロールして減速するテーブルビューと同様の効果を簡単に達成できません。 解決策の1つは、物理システムを使用することです。
シーンビューにジェスチャを追加したいのはなぜですか? hitTestを検索します。私はそれが簡単ではないとあなたに伝えることができます。 –
シーンビューにボールが含まれているためです。だから私はジェスチャーをボール/球に適用したいだけです – user8426652
それは間違った考えです。 –