在Android中,API提供了视野角度的字段:
Camera.Parameters.getHorizontalViewAngle()
Camera.Parameters.getVerticalViewAngle()
确保导入CoreMotion头文件:
#import <CoreMotion/CoreMotion.h>
定义一些类属性:
@property (nonatomic, strong) CMMotionManager *motionManager;
@property (nonatomic, strong) NSOperationQueue *deviceQueue;
启动运动管理器:
- (void)startMotionManager
{
self.deviceQueue = [[NSOperationQueue alloc] init];
self.motionManager = [[CMMotionManager alloc] init];
self.motionManager.deviceMotionUpdateInterval = 5.0 / 60.0;
[self.motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXArbitraryZVertical
toQueue:self.deviceQueue
withHandler:^(CMDeviceMotion *motion, NSError *error)
{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
CGFloat x = motion.gravity.x;
CGFloat y = motion.gravity.y;
CGFloat z = motion.gravity.z;
// 围绕z轴旋转了多少
CGFloat rotationAngle = atan2(y, x) + M_PI_2; // 弧度
CGFloat rotationAngleDegrees = rotationAngle * 180.0f / M_PI; // 度数
// 向前和向后倾斜了多少
CGFloat r = sqrtf(x*x + y*y + z*z);
CGFloat tiltAngle = (r == 0.0 ? 0.0 : acosf(z/r); // 弧度
CGFloat tiltAngleDegrees = tiltAngle * 180.0f / M_PI - 90.0f); // 度数
}];
}];
}
完成后,停止运动管理器:
- (void)stopMotionManager
{
[self.motionManager stopDeviceMotionUpdates];
self.motionManager = nil;
self.deviceQueue = nil;
}
if ([CMMotionManager class])
{
// ok, core motion exists
}
如果你对我选择每秒十二次的相对随意有疑问,iOS事件处理指南建议在仅检查设备方向时每秒10-20次。
AVCaptureDevice *camera;
camera = ...
float fov = [[camera activeFormat] videoFieldOfView];
NSLog("FOV=%f(deg)", fov);