CoreMotion - 在iPhone上横向移动,自下而上

时间:2017-11-04 09:08:25

标签: ios swift accelerometer core-motion

我正在制作一款能够制作横向全景视频的应用程序。在横向上,它支持两个方向:从左到右,从下到上。

因此,当用户将手机从左向右移动或向右旋转时,我想从左向右移动箭头。当垂直向上移动设备时,也希望将箭头从底部移动到顶部。 在具有全景选项的原生iPhone相机应用程序中,我们可以看到正确的模拟,

我的问题是1)我怎么知道用户是从左到右还是从右到左移动手机。因为像iPhone全景,我想在用户搬回时停止录制。

另外2)我怎么知道用户正在垂直向上移动手机

已添加:2017年11月10日: 我确实在AppStore中看到了一个名为Spincle的应用程序。从左向右旋转设备时,它会移动箭头以拍摄360度图像。我只是设法使用俯仰和滚动来实现这一点(参见下面的代码)。但是,如果我们将设备放在地板或屋顶上,这将无效。

import UIKit
import CoreMotion
class ViewController: UIViewController {
    private let motionManager = CMMotionManager()
    let arrowView = UIView()
    func startMotion() {
        var initialAttitude: CMAttitude?
        motionManager.deviceMotionUpdateInterval = 1
        let queue = OperationQueue.current!
        let statusBarOrientation = UIApplication.shared.statusBarOrientation
        motionManager.startDeviceMotionUpdates(using: CMAttitudeReferenceFrame.xArbitraryZVertical, to: queue) { (motiondata, err) in
            guard let data = motiondata else { return }
            if initialAttitude == nil {
                initialAttitude = data.attitude
            } else {
                let attitude = data.attitude
                // translate the attitude
                attitude.multiply(byInverseOf: initialAttitude!)
                // calculate pitch and roll of the change from our initial attitude
                let pitch = self.radiansToDegrees(attitude.pitch)
                let roll = self.radiansToDegrees(attitude.roll)
                print("\nroll = \(roll), pitch = \(pitch), yaw = \(self.radiansToDegrees(attitude.yaw))")
                print("x = \(data.userAcceleration.x), y = \(data.userAcceleration.y), z = \(data.userAcceleration.z)")
                DispatchQueue.main.async {
                    var rect = self.arrowView.frame
                    var addXPixel = self.view.frame.size.width/45
                    var addYPixel = self.view.frame.size.height/45
                    if statusBarOrientation == .landscapeRight {
                        addXPixel *= -1
                    } else {
                        addYPixel *= -1
                    }
                    rect.origin.x = (CGFloat(pitch) * addXPixel)
                    rect.origin.y = (self.view.frame.size.height/2 - 20) + (CGFloat(roll) * addYPixel)
                    self.arrowView.frame = rect
                }
            }
        }
    }
    func stopMotion() {
        motionManager.stopDeviceMotionUpdates()
    }
    func radiansToDegrees(_ radian: Double) -> Float {
        return Float(radian * 180.0/Double.pi)
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(arrowView)
        arrowView.backgroundColor = UIColor.red
    }
    @IBAction func tappedButton() {
        arrowView.frame = CGRect(x: 0, y: self.view.frame.size.height/2 - 20, width: 40, height: 40)
        startMotion()
    }
}

问题是它会向左右移动,箭头向上或向下移动

1 个答案:

答案 0 :(得分:1)

您可以使用CLHeading检查手机的标题,并编写算法以通过计算- (void)locationManager:(CLLocationManager*)manager didUpdateHeading:(CLHeading*)newHeading 度来确定左右/底部移动。

x=0.2  
r_1=3
n=1000

for i in range (n):
        x_n1=r_1*x*(1 -x)
        plt.plot([x, x], [x, x_n1], color='green')
        plt.plot([x, x_n1], [x_n1, x_n1], color='green')
        x=x_n1
plt.show()

#33