确定设备方向及其在一个维度上的角度?

16

我有如下设置:

输入图像的描述

一个iPhone正面朝下放在桌子上(alpha = 0度)。当iPhone向上移动时,alpha角度会增加,如上图所示。

如何计算alpha角度的值,而不用考虑其他可能发生变化的轴线。我只对这个轴线感兴趣。

我该如何获取iPhone从桌子上抬起时的正确alpha角度?我如何被通知alpha值何时发生变化?

2个回答

19
你可以使用 CMMotionManager 类来监测设备的运动变化。 Objective C
// Ensure to keep a strong reference to the motion manager otherwise you won't get updates
self.motionManager = [[CMMotionManager alloc] init];
if (self.motionManager.deviceMotionAvailable) {
    
    self.motionManager.deviceMotionUpdateInterval = 0.1;
    
    // For use in the montionManager's handler to prevent strong reference cycle
    __weak typeof(self) weakSelf = self;

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [self.motionManager startDeviceMotionUpdatesToQueue:queue
                                            withHandler:^(CMDeviceMotion *motion, NSError *error) {
                                                
                                                // Get the attitude of the device
                                                CMAttitude *attitude = motion.attitude;
      
                                                // Get the pitch (in radians) and convert to degrees.                                          
                                                NSLog(@"%f", attitude.pitch * 180.0/M_PI);

                                                dispatch_async(dispatch_get_main_queue(), ^{
                                                    // Update some UI
                                                });
                                                
                                            }];
    
    NSLog(@"Device motion started");
}else {
    NSLog(@"Device motion unavailable");
}

Swift

// Ensure to keep a strong reference to the motion manager otherwise you won't get updates
self.motionManager = CMMotionManager()

if motionManager?.deviceMotionAvailable == true {
        
    motionManager?.deviceMotionUpdateInterval = 0.1
        
    let queue = OperationQueue()
    motionManager?.startDeviceMotionUpdatesToQueue(queue, withHandler: { [weak self] motion, error in
            
        // Get the attitude of the device
        if let attitude = motion?.attitude {
            // Get the pitch (in radians) and convert to degrees.
            print(attitude.pitch * 180.0/Double.pi)

            DispatchQueue.main.async {
                // Update some UI
            }
        }
            
    })
        
    print("Device motion started")
}else {
    print("Device motion unavailable")
}

NSHipster一如既往地提供了丰富的信息,其中有一篇关于CMDeviceMotion的文章也不例外。


谢谢,也许你对这个相关问题有想法?http://stackoverflow.com/questions/31643371/how-can-i-draw-and-rotate-an-arrow-at-an-orientation-in-3d-space - Michael
你如何将更新发送到后台队列?能否请您扩展一下您的示例? - Michael
@confile 在链接的NSHipster文章中描述了使用后台队列的方法。我也已经更新了答案。 - Steve Wilford
1
@SteveWilford 它对于 alpha 或 180 - alpha 给出正值。有没有办法区分它们? - Priyal

5

Swift 4:

  let motionManager = CMMotionManager()

   if motionManager.isDeviceMotionAvailable {

       motionManager.deviceMotionUpdateInterval = 0.1

       motionManager.startDeviceMotionUpdates(to: OperationQueue()) { [weak self] (motion, error) -> Void in

           if let attitude = motion?.attitude {

                print(attitude.pitch * 180 / Double.pi)

                DispatchQueue.main.async{
                    // Update UI
               }
           }

       }

       print("Device motion started")
    }
   else {
       print("Device motion unavailable")
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接